Git Product home page Git Product logo

moo's Introduction

Hi ๐Ÿ‘‹

I'm Geoffrey Wiseman.

I do software consulting directly as Codiform.

I also work with project teams through organizations like:

I contribute to open-source projects and run some of my own.

I'm:

  • A member of software communities like Stack Overflow.
  • A Canadian ๐Ÿ‡จ๐Ÿ‡ฆ
  • A Father ๐Ÿ‘ช

moo's People

Contributors

basil3whitehouse avatar carldea avatar chenzhang22 avatar dependabot[bot] avatar geoffreywiseman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

moo's Issues

Configurable Default Optional/Required

At the moment, the presence of source fields to match the destination is optional; for some users, a default of required may make more sense. It would be nice if that were a configuration element on a global scale (in addition to on a class-by-class basis, which is raised in another issue)

Support Translation on Update

Currently, translation really only works well with unidirectional translation. Any time you attempt to update a domain object from the DTO where the DTO contains translated properties, this'll be a problem.

Separate Translation Exceptions

There are a number of errors that trigger translation exceptions; sub-exceptions would make it easier to catch and react to possible sources of errors.

update() methods in Moo

Top-level Moo class doesn't have methods for update; you can only update through the currying class. This prevents you from using a pattern that should allow you to use configuration, or get performance improvements through caching.

Make MVEL an Optional Addition

Currently using MVEL as the expression language. What if you don't need it? Or what if your project already has OGNL for some other reason? Would be nice to have the option.

Support for Sorted List and Sorted Map

These cannot easily be copied -- how do we know what sort order to use for different objects? Is that a configuration item? Do we just accept that and move on with the copy and lose the sorting?

Configure Mappings via Java

Much like the 'configure mappings via xml', there are sometimes good reasons to not want to use the annotation approach, and one alternative would be a java-based API.

Lookup Values on Update

When you're updating one graph from another, you may want a way to do a lookup against an identifier of some kind -- for instance, you might want to replace a DTO ID with the domain object it represents. Sounds pretty complicated, though.

Many-to-Many mappings

This may require externalized configuration, but it should be possible to transfer from A and B to C and D.

Translatable Maps

Figure out how to allow translations of maps -- should the key be translated, the value, or both? Presumably configurable, but how?

Once this is done, figure out if you want to support translatable sorted maps, and if so, add them to the tracker.

Don't Translate Static / Final Fields

Fields marked as static and/or final should probably not be copied. Static fields belong to the class, rather than the instance, and final fields aren't supposed to change.

Throw Exception if Nothing Translated

Easy mistake to make -- mismatch two objects that have nothing in common, translation doesn't complain, but nothing was copied. This is really only relevant with optional properties.

Better Error for Update from Null

If you call an update from a null object, you get an NPE deep in Moo that should be resolved much more rapidly and more clearly. You can't do an update from a null instance.

Ignore Property

Should be a way to explicitly mark a field/method as not being a property, either to override a parent class, or to bypass the default access mode (if access mode is field, perhaps a particular field shouldn't be considered a property?)

Cache Translators

If you're going to be doing the same translations over and over, you should be able to hang on to something that would cache much of the reflection without hanging on to the 'translated instances'.

This would likely be an instance of 'moo' rather than of Translator.

Required Fields

By default, Moo will throw an exception if there's a field in the destination that cannot be found in the source and isn't marked to be ignored.

You can, however, configure moo to not 'require' source properties using Configuration#setSourcePropertiesRequired. If you do this, there's no way of indicating that a particular property /is/ required, which might be useful -- you want to make optional properties default, but you want to mark a particular property as being required.

I don't expect to be using a lot of optional properties, so this is potentially a minor point at this stage, but something I might revisit if it turns out to be something I do more often.

Annotations to Configure Defensive Copying

@copy(true), @copy(false)?

Basically, there may be instances where people want to configure defensive copying on a field by field basis. Actually, I can't think of a good reason for this, but filing it away so that people can vote for it if they feel so inclined.

Build Distribution

In addition to the main module, create a distribution module that bundles the JAR with the javadoc, the sources and a readme in a ZIP file for easier consumption.

This is only relevant if we pass a certain threshold of consumption -- once people are using the project, it may make sense to do this kind of work.

Update 'Domain'

Allow for the DTO to be merged back into the domain object via an update. This is mostly relevant when you're in a DTO model.

Select a License

Moo will be licensed in a relatively open way, but selecting a specific license requires more attention than I've been able to give.

Cache Source Properties

This used to be a request to cache field expressions, which have essentially become source properties.

This can only really be done once we move to a model where translators are aware of both the source and the destination more completely. Right now, translators are very destination-focused, so caching source properties seems a little silly.

Update Collection Support

Collection support for updates is tricky; you need to understand the difference between an add, remove, update and replace. That requires you to have some kind of comparison framework which might vary per project to determine which objects are 'the same'. This could be some kind of 'equalator', sorta like a comparator. It could, in fact, be a comparator, although that interface offers more than we need.

'Component' Mappings

As per Hibernate, the ability to adjust the structure of the objects from a nested form to a flattened form. Possibly addressed well with @translation already, but at the very least a good bidirectional test case should be established.

Configuration File for Moo

Although the default configuration works well for me and Java annotations allow for relatively simple tweaks to translation to happen with a minimum of fuss, there are times when it's just not very suitable. For instance, imagine a complex set of translations between a bunch of similar classes that would have different source and destination fields. Storing all that information on each domain object might result in conflicts and would certainly be very messy. In that scenario, externalized configuration could be crucial, whether that's XML, YAML, Java code (like Guice did for CI), or whatever.

In essence, if I were going to do this, I would probably seriously consider a plan like:

  • Change the existing configuration into a model API that doesn't know anything about the source of the configuration. This would be the core module's approach to configuration, and could be done with pure Java, no annotations, no XML, no nothing.
  • Extract the annotations into their own module with code that can scan domain classes and generate core configuration based on the annotation.
  • Optionally add other ways (e.g. XML file) of achieving the same effect.

Prevent Duplicate Properties

Avoid duplicate properties (method + field, or superclass + subclass) using careful ordering. This requires some thought, to make sure it's done right, or it would have been included in 1.1.

@Translation with External Objects

Sometimes, it may be necessary to involve external objects in translation; MVEL supports context objects that we could use, and OGNL something pretty similar to that.

Source Field Validation

Is it necessary to allow validation on the source data (e.g. must not be null, for starters, but possibly other items?

Configure Mappings via XML

If you're working with two objects that are both created elsewhere, or where you're not intending to annotate either end for translation, it would be useful to support XML configuration of the mappings.

Access Modes

Add support for setting the 'default access' mode for setting values -- field vs. property. Allow that to be overridden on a field-by-field basis.

Collection Type by Destination

Allow a mapping from List to Set, etc; check the destination type rather than blindly assuming that the source collection type is the correct one.

Update Properties of Properties

When you're doing an update, the top-level object is updated, all properties of that top-level object are replaced, even if they are themselves objects with a bunch of properties. It may be important to allow those sub-objects to get updated as well.

Use @Translation on Update

Currently, update doesn't consider the @Property(translation="") path. That works for the cases I need it to now, but it doesn't allow true bidirectional translation. Of course, complex translation paths could have weird edge cases with update.

Value Coercions

Might be nice if you could supply some automatic coercions for types that you expect to be able to translate generally. Although it's possible that this is best handled by expansions to @translate except for extreme cases where there's a lot of automatic coercion necessary.

Translation / Update Lookups

The ability to do a translation using a lookup rather than a direct translation. For instance, Moo is being used in a project with a lookup entity for relationship types. The relationship type is an entity on the server-side database, but when translated to the DTO layer, is trimmed to those pieces needed by the client.

So when the value is changed and sent back to the server, the server should look up the corresponding domain object for the new value, rather than translating the incomplete new value back directly.

This needs some thought on correct design for the configuration to this, so I won't speculate about an approach without thinking it through a little further.

Translation using External Context Objects

Sometimes, it may be necessary to involve external objects in translation; MVEL supports context objects that we could use, and OGNL something pretty similar to that. This can be useful for utility objects (e.g. convert this URL) as well as outside information.

I've needed this before, so it's safe to assume I'll need it again.

Unidirectional Translation

Might be important sometimes to allow translation in one direction but not in the other; this may not be a big deal without support for @translation on @update which is where it would be more likely to arise as an issue.

Configurable Collection-Translation Strategy

Defensive Copying is the simplest approach that will work in most scenarios, but there might be other times when you don't need a defensive copy, or you desire a specific choice, and this gives you more options.

Configurable Defensive Copying

Moo does defensive copying of arrays and collections. That makes a lot of sense in the general case, but if you know that your instance will be immediately serialized to XML, then a defensive copy is largely wasted. It would be nice to make this configurable.

Session-Level Configuration

Might sometimes want to override general values for a particular session; I don't have a specific use case for this yet, just filing this away as something to consider. If you've got a case you want to talk about, comment away.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.