ok, the proposed solutions work. didnt stumble about that ones. :D didnt think with the possibilty that PropertyModels are IChainingModels themselves. drawback of this solution is, that every component has to have its own model, but i think in the end this is not necessarly a bad thing performancewise because initModel() hasnt to be done. but if i wanted to use components without their own models, this solution wouldnt work, because:
panel->markupcontainer->form InheritedChainingModel->nothing->PropertyModel(markupcontainer-model, "A") B->nothing->A so in markupcontainer, a propertymodel is created like this: new PropertyModel(getDefaultModel(), "A") and it is given to the form: getDefaultModel() is asked for the model. it looks for the model on the markupcontainer, doesnt find one, initModel() is called. There the for-loop is initialized with: Component current = getParent(). Problem: markupcontainer does not have a parent right now... so the model would have to look up the parent-model by itself and this isnt possible as explained. so with the existing model-design, at least the explained use case isnt possible (model-less components). thx for the help, will stick to the proposed solution. maybe you could think about if model-less components which look up their models in the upper component-hierarchy are a good thing. i dont know. you have more experience, you could know. :) regarz igor.vaynberg wrote: > > 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] > > > -- View this message in context: http://www.nabble.com/2-new-models-for-wicket-tp25616506p25625683.html Sent from the Wicket - User mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
