or new CompoundPropertyModel(new PropertyModel(model, "theGetPropertyInMyDomainModelToSubModel")) which basically creates a CPM that refers to a property of another CPM.
personally i do not like CPMs, they are a shortcut that gets abused way too often :) -igor On Fri, Sep 25, 2009 at 11:21 AM, Per Newgro <[email protected]> wrote: > Puhh, very long article. > > Did you've tried > > MyDomainModel myDomainModel; > CompoundPropertyModel model = new CompoundPropertyModel(myDomainModel); > AContainer.add(new MarkupContainer(new PropertyModel(model, > "theGetPropertyInMyDomainModelToSubModel")); > > If MyDomainModel provides an accessor for > theGetPropertyInMyDomainModelToSubModel you can build the chain. > > HTH > Per > > [email protected] schrieb: >> >> heyho everyone, >> >> since i'm not satisfied with the provided models, i started to write my >> own. >> >> the current behaviour with compoundproperty model is, that >> compoundproperty model serves as host for an object and components can use >> properties of that host by having the correct id that has to equal the name >> of the property. >> >> since wicket is a component-oriented framework, there is a use case that >> happens very often. it is that you have some domain-object that you write an >> edit-form for that allows you to edit the properties of this domain-object. >> now if you want to use this edit-form, you have to give it a model, which >> would be a compoundpropertymodel. every component inside can now use it by >> having the correct id. >> >> suppose our domain-object A is in this case a property of another >> domain-object B: B.A . if i want to use the edit-form like it was supposed >> to, i would have to give it a compoundpropertymodel. this means, i have to >> get A out of B and put it inside a new compoundpropertymodel. but i dont >> want to do this. i want to have exactly one object-hosting model off which >> every other component can look up its needed properties. >> >> i believe i'm doing this for reasons of performance, because i believe >> that if a would have another compoundpropertymodel, there would be more >> serialization-work. besides that i would use detachable-models, which would >> worsen the situation, because A would be loaded twice! >> >> the solution for a single object-hosting compoundpropertymodel would be to >> adapt the component ids in A's editform, which is completely unacceptable >> because it would now depend on the fact, that A is now inside another >> object. what if B was a property of C? or if C in turn was a property of D? >> or if A was standalone. only one use case is covered with this solution. its >> not acceptable for a component oriented framework. >> >> thats why i started to write my own models. there should be an >> object-hosting model and some kind of property-model that can use the >> hosting model. the root-markupcontainer would therefor have such a hosting >> model which provided B. this markup-container would hold A's edit-form as a >> child and give it such a property-model that can access the host-model's >> object. now the magic thing, this property-model in turn would serve as host >> for A's edit-form. all the components in this edit-form in turn would have >> such property-models again, that access the edit-forms modelobject and >> resolve the desired properties. >> >> therefor i called this property-model InheritedPropertyModel. another, in >> my eyes, advantage is, that if a component doesnt have its own model, it >> will receive the next model up in the component-hierarchy. and because i >> think this is good, i also made the host-model an inheritedmodel and since >> it is also chainable, i called it InheritedChainableModel. >> >> now i tried to implement those two and there is a problem i'm facing. i >> can't traverse through the component-hierarchy to find the right >> model-object. i need this object so i can run the propertyresolver on it. i >> can only call getDefaultModelObject() to find out. and now there is the >> problem: >> >> imagine the following component hierarchy: >> panel->markupcontainer->form->label >> >> InheritedChainingModel->InheritedPropertyModel->nothing->InheritedPropertyModel >> B->A->nothing->somePropertyOfA >> >> the label calls getObject(): >> this.owner.getParent().getDefaultModelObject() >> the InheritedPropertyModel knows its owner (IComponentAssignedModel) which >> is the label, calls its parent, which is the form and asks for the default >> model-object. since the form doesnt have a model, it's >> getDefaultModelObject() calls: initModel() >> initModel() traverses the component-hierarchy up until it finds the first >> IComponentInheritedModel. it finds it in the markupcontainer and its an >> InheritedPropertyModel. this one now is asked getObject(): >> this.owner.getParent().getDefaultModelObject() >> this one will give the object of the hosting InheritedChainingModel of the >> panel with B in it. now B is given back to the markupcontainer which >> continues its getObject(): >> (W)PropertyResolver.getValue(this.property, target); >> property is "A" and target is B -> A as object is returned to the form >> which in turn continues its getObject(): >> (W)PropertyResolver.getValue(this.property, target); >> since this model is an inherited from markupcontainer, it has the same >> property which is "A", but the target this time is A itself, coming from the >> markupcontainer. >> >> and this is the problem... when i look at a components model, i dont want >> it to be initialized, i just want to know if there is some >> IComponentInheritedModel. getModelImpl() is the way to go, but it is not >> visible. getInnermostModel() calls getDefaultModel(). i dont have a chance. >> or can somebody see a solution to this? i think there isnt any. >> >> since i'm willing to contribute those two models, i propose to change >> something in the wickets component-code. give me a hasModel(). or give me a >> public getModel(). i would do these changes. >> >> tell me your opinion. >> >> regards >> garz >> >> ps: here are the sources of the two models: >> >> public class InheritedPropertyModel<T> >> implements IComponentInheritedModel<T>, IComponentAssignedModel<T> >> { >> >> private String property; >> >> public InheritedPropertyModel(String property) { >> if (Strings.isEmpty(property)) >> throw new IllegalArgumentException("Parameter >> property cannot be null or empty"); >> this.property = property; >> } >> >> �...@suppresswarnings("unchecked") >> �...@override >> public <W> IWrapModel<W> wrapOnInheritance(Component component) { >> return (IWrapModel<W>) new >> AttachedInheritedPropertyModel(); >> } >> >> �...@override >> public final T getObject() { >> throw new RuntimeException("get object call not expected on >> a IComponentAssignedModel"); >> } >> >> �...@override >> public final void setObject(T object) { >> throw new RuntimeException("set object call not expected on >> a IComponentAssignedModel"); >> } >> >> �...@override >> public void detach() { >> } >> >> �...@override >> public IWrapModel<T> wrapOnAssignment(Component component) { >> return new AssignedInheritedPropertyModel<T>(property, >> component); >> } >> >> private class AssignedInheritedPropertyModel<W> >> implements IWrapModel<W> { >> >> private String property; >> private Component owner; >> >> public AssignedInheritedPropertyModel(String property, >> Component owner) { >> this.property = property; >> this.owner = owner; >> } >> >> �...@override >> public IModel<?> getWrappedModel() { >> return InheritedPropertyModel.this; >> } >> >> �...@suppresswarnings("unchecked") >> public W getTarget() { >> return >> (W)this.owner.getParent().getInnermostModel().getObject(); >> } >> >> �...@suppresswarnings("unchecked") >> �...@override >> public W getObject() { >> final W target = getTarget(); >> if (target != null) >> { >> return >> (W)PropertyResolver.getValue(this.property, target); >> } >> return null; >> } >> >> �...@override >> public void setObject(W object) { >> PropertyResolverConverter prc = null; >> prc = new >> PropertyResolverConverter(Application.get().getConverterLocator(), >> Session.get().getLocale()); >> PropertyResolver.setValue(this.property, >> getTarget(), object, prc); >> } >> >> �...@override >> public void detach() { >> >> } >> >> } >> >> private class AttachedInheritedPropertyModel >> implements IWrapModel<T> { >> >> �...@override >> public IModel<T> getWrappedModel() { >> return InheritedPropertyModel.this; >> } >> >> �...@override >> public T getObject() { >> return InheritedPropertyModel.this.getObject(); >> } >> >> �...@override >> public void setObject(T object) { >> InheritedPropertyModel.this.setObject(object); >> } >> >> �...@override >> public void detach() { >> InheritedPropertyModel.this.detach(); >> } >> >> } >> } >> >> public class InheritedChainingModel<T> >> implements IChainingModel<T>, IComponentInheritedModel<T> { >> >> private Object target; >> >> public InheritedChainingModel(final Object object) { >> this.target = object; >> } >> >> �...@override >> public IModel<?> getChainedModel() { >> if (target instanceof IModel<?>) >> { >> return (IModel<?>)target; >> } >> return null; >> } >> >> �...@override >> public void setChainedModel(IModel<?> model) { >> target = model; >> } >> >> �...@suppresswarnings("unchecked") >> �...@override >> public T getObject() { >> if (target instanceof IModel<?>) >> { >> return ((IModel<T>)target).getObject(); >> } >> return (T)target; >> } >> >> �...@suppresswarnings("unchecked") >> �...@override >> public void setObject(T object) { >> if (target instanceof IModel<?>) >> { >> ((IModel<T>)target).setObject(object); >> } >> else >> { >> target = object; >> } >> } >> >> �...@override >> public void detach() { >> if (target instanceof IDetachable) >> { >> ((IDetachable)target).detach(); >> } >> } >> >> �...@suppresswarnings("unchecked") >> �...@override >> public <W> IWrapModel<W> wrapOnInheritance(Component component) { >> return (IWrapModel<W>) new >> AttachedInheritedChainingModel(); >> } >> >> private class AttachedInheritedChainingModel >> extends AbstractWrapModel<T> { >> >> �...@override >> public T getObject() { >> return InheritedChainingModel.this.getObject(); >> } >> >> �...@override >> public void setObject(T object) { >> InheritedChainingModel.this.setObject(object); >> } >> >> �...@override >> public IModel<T> getWrappedModel() { >> return InheritedChainingModel.this; >> } >> >> } >> >> } >> >> pps: as you can see i dont know how to use the wrapOnInheritance() method >> if IComponentInheritedModel exactly and doing an ugly cast: return >> (IWrapModel<W>) new AttachedInheritedChainingModel(); >> maybe you have an idea for this too. >> >> thanks >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
