[ https://issues.apache.org/jira/browse/LABS-232?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14031880#comment-14031880 ]
jan iversen commented on LABS-232: ---------------------------------- Is this still an issue, if not please close it (or let me close it) > [refactoring][beans] BeanData should be able to fork > ---------------------------------------------------- > > Key: LABS-232 > URL: https://issues.apache.org/jira/browse/LABS-232 > Project: Labs > Issue Type: New Feature > Components: Magma > Affects Versions: Current > Reporter: Simone Gianni > Assignee: Simone Gianni > Fix For: Next > > > Currently every class has one BeanData. This class holds all magma specific > metadata about the class, giving access to PropertyInfo for each property. > That sums up introspection results, annotations and so on. Every package that > needs to add stuff will do it adding it to BeanData or PropertyInfo. > Also, all magma component communicate with the bean using a Handler. The > Handler itself uses BeanData to perform property setting/getting, validation, > formatting and the like. > Anyway, having a single representation of a class is limiting. There is the > need to change this data depending on the current context. For example, a > certain field could be visible or not depending on the role of the current > user, or the view we want to offer. Also validation could change, making some > properties required where they where not, or even adding temporary > properties. Information currently held in this structure is very wide, and > goes from validation to formatting to structural data (like, if it is or not > persisted on the database). > Currently there is a system in place, called ViewCustomizer, which is able to > modify dynamically part of it for a specific need, like hiding or expanding a > property in a specific view. While this system works correctly, it cannot be > expanded to also embrace validation, formatting and everything else. So we > need a different approach. > First of all, we need a way to "fork" different beanDatas, and provide a way > to define which one to use in a specific "scope". The problem is not forking > it (a deep clone is okay, prototype pattern), nor modifying the new "branch" > (ViewCustomizer could be extended, giving it a further extensible API, and > having people implement it). Defining the scope is a problem. > Unfortunately in java the only thing that is "scope dependent" is the stack. > So, we will probably have to pass the modified bean data, or the bean data > modifier, instead of the class/bean where we need to. > So, for example : > return new SmartForm(new WiseModifier(userBean)); > To display a form using the WiseModifier. The WiseModifier class should be a > class extending a specific base class, and implementing a specific method. > For example : > public class WiseModifier extends BeanDataModifier { > public WiseModifier() { > super(User.class); > } > public void modify() { > makeRequired("name"); > addFormatter("birthDay", new DateFormatter().setFormat("short")); > } > } > In this way, the modifiers will be classes, and as such (thru cglib > eventually) compiler friendly and statically determined. Also, the non > modified bean data could be obtained with a "null modifier", or simply still > passing the Class object only (this would also provide backwards > compatibility, keep the easy way, and provide an incremental way to implement > this new system, cause new methods would simply be overriding the default, > class based ones). > It could also be possible, eventually using a CompoundModifier, to combine > different modifiers. So, we could have a modifier that hides a certain part > of a bean, another one that imposes a number of additional checks, and then > use one, the other, or both in a certain context. > Another important aspect could be caching of the resulting beanData. Creating > a beanData is an expensive job, cause it involves reflection, annotation > parsing, creation of a number of (mostly thread safe and stateless) objects > like converters, formatters, validators etc.. > Since forking a bean data could be a lighter job (deep cloning as opposed to > reparsing), proper investigation should be done on the effective timing of > the deep cloning and manipulations. If caching is necessary, then a number of > techniques could be exploited to obtain it. > A modifier could a stateless one, thus applying always the same > modifications. In that case, cache it and stop bothering. > A modifier could have a state that is determinable. For example, a number of > private fields, and a number of if statements based solely on those private > fields. In this case, caching is still possible cause we know the state. > A modifier could have a state which is not determinable, for example an if > statement calling System.currentTimeMillis. In that case no caching is > possible, and a proper warning should be given to the user. > To limit the possibility of uncachable items, the API should be planned from > the ground up with minimal connections to the outside world, or a predefined > way of connecting to it, like getters and setters only, or constructor > parameters only and so on. > (Note that this is exactly what happens in every do-method of any web > handler, in fact the same design principles were in place for the web API > where caching plays an important role. Handlers have a predefined "protocol" > with the outside world, thru getters and setters, making the state > determinable in most cases. this means that the same caching system used in > the web part could be applied to this part if needed) -- This message was sent by Atlassian JIRA (v6.2#6252) --------------------------------------------------------------------- To unsubscribe, e-mail: labs-unsubscr...@labs.apache.org For additional commands, e-mail: labs-h...@labs.apache.org