... In my rush to get out I hit post instead of preview. Now I've come back and reviewed it here's a completed and *corrected* version, hopefully a bit clearer and precise. Excuse any confusion caused.
Jeremy, AbstractPropertyModel _should_ implement IChainingModel; this tells us about its "type" and that's how we know it _will_ dig into passed in models nesting models to get to a buried ModelObject. Whether you think its methods have been correctly implemented and/or utilised here is another matter. People will find the blog entry useful, but the issue I was (dubiously) looking at is a bit more specific to PropertyModel's property expressions. You and Igor are of course right that the contract is _not_ broken (as in my initial post) - I was looking at the property expressions specifically. public class TestPropertyModelsChainingImpl extends WebPage { Point p = new Point(3,4); Model m1 = new Model(p); Model m2 = new Model(new Model(m1)); class Wrapper implements Serializable{Wrapper(Point p){this.object = p;}Point object;} Wrapper w = new Wrapper(p); public TestPropertyModelsChainingImpl() { add(new Label("x1", new PropertyModel(this, "m1.object.x"))); add(new Label("y1", new PropertyModel(this, "w.object.y"))); add(new Label("x2", new PropertyModel(m1, "x"))); add(new Label("y2", new PropertyModel(m2, "y"))); } } <html><body>{,},{,}</body></html> You may need to fix the above html if it doesn't show properly {[span wicket:id="x1"/],[span wicket:id="y1"/]},{[span wicket:id="x2"/],[span wicket:id="y2"/]} That gives {3,4},{3,4} as expected, and the chaining behaviour _is_ correct when a model is passed in to the PropertyModel. Whether add(new Label("x", new PropertyModel(this, "m2.x"))); should also just work is in fact another matter. Hopefully that's more sensible so I don't have to fix it again! Regards - Cemal http://www.jWeekend.co.uk http://jWeekend.co.uk jWeekend wrote: > > Jeremy, > > People will find your blog entry useful, but this issue is a bit more > specific. > > AbstractPropertyModel _should_ implement IChainingModel, that's how you > know it _should_ dig values out model objects which r themselves models. > > Now try this: > > public class TestPropertyModelsChainingImpl extends WebPage { > Point p = new Point(3,4); > Model m = new Model(p); > class Wrapper{Wrapper(Point p){this.object = p;}Point object;} > Wrapper w = new Wrapper(p); > public TestPropertyModelsChainingImpl() { > add(new Label("x", new PropertyModel(this, "m.object.x"))); > add(new Label("y", new PropertyModel(this, "w.object.y"))); > } > } > > <html><body>,</body></html> > > > > > > > > Jeremy Thomerson-5 wrote: >> >> John, Cemal - that method in AbstractPropertyModel absolutely does abide >> by >> the contract - look at what it calls (getTarget()): >> >> public final Object getTarget() >> { >> Object object = target; >> while (object instanceof IModel) >> { >> Object tmp = ((IModel<?>)object).getObject(); >> if (tmp == object) >> break; >> object = tmp; >> } >> return object; >> } >> John - I think you're right - it is unnecessary to implement >> IChainingModel >> since there is no code in the wicket core codebase that calls it's >> methods. >> Just make sure that if you nest models inside of other custom models, you >> do >> call detach properly or you can end up with a memory leak. You can see >> this >> blog post as a simple example: >> http://www.jeremythomerson.com/blog/2008/11/06/wicket-the-power-of-nested-models/ >> >> Hope this helps. >> >> -- >> Jeremy Thomerson >> http://www.wickettraining.com >> >> >> On Thu, Dec 4, 2008 at 9:31 AM, jWeekend >> <[EMAIL PROTECTED]>wrote: >> >>> >>> John, >>> >>> Well spotted. AbstractPropertyModel implements IChainingModel but breaks >>> its >>> contract : >>> * Models that implement this interface will support chaining of >>> IModels. >>> getObject() of a >>> * IChainingModel should do something like: >>> * >>> * <pre> >>> * if ( object instanceof IModel) { return ((IModel)object).getObject()} >>> * else return object; >>> * </pre> >>> >>> Its getObject() implementation does not abide by this. >>> /** >>> * @see org.apache.wicket.model.IModel#getObject() >>> */ >>> public Object getObject() >>> { >>> final String expression = propertyExpression(); >>> if (Strings.isEmpty(expression)) >>> { >>> // Return a meaningful value for an empty >>> property >>> expression >>> return getTarget(); >>> } >>> >>> final Object target = getTarget(); >>> if (target != null) >>> { >>> return PropertyResolver.getValue(expression, >>> target); >>> } >>> return null; >>> } >>> >>> Regards - Cemal >>> http://www.jWeekend.co.uk <http://www.jweekend.co.uk/> >>> http://jWeekend.co.uk <http://jweekend.co.uk/> >>> >>> >>> >>> John Patterson wrote: >>> > >>> > Hi, >>> > >>> > I'm messing about with nested models and see the IChainingModel >>> interface >>> > which is implemented by the PropertyModels but its methods never >>> actually >>> > seems to be used. >>> > >>> > So I'm just checking that I haven't missed anything... for nested >>> models >>> I >>> > don't actually need to implement this right? >>> > >>> > This is its def: >>> > >>> > >>> > public interface IChainingModel<T> extends IModel<T> >>> > { >>> > /** >>> > * Sets the model that is chained inside this model. >>> > * >>> > * @param model >>> > */ >>> > public void setChainedModel(IModel< ? > model); >>> > >>> > /** >>> > * Returns the chained model if there is a chained model. >>> > * >>> > * @return The chained model >>> > */ >>> > public IModel< ? > getChainedModel(); >>> > >>> > } >>> > >>> > Thanks, >>> > >>> > John >>> > >>> > >>> > >>> >>> -- >>> View this message in context: >>> http://www.nabble.com/IChainingModel-tp20835085p20835745.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] >>> >>> >> >> > > -- View this message in context: http://www.nabble.com/IChainingModel-tp20835085p20853246.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]