Updated Branches: refs/heads/master dda0c067f -> e1d284298
WICKET-2498 IChainingModel implementation Extract the common code related to IChainingModel in default impl Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/e1d28429 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/e1d28429 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/e1d28429 Branch: refs/heads/master Commit: e1d28429865b5564b5ad87f6499ad2793a11767d Parents: dda0c06 Author: Martin Tzvetanov Grigorov <[email protected]> Authored: Fri Mar 2 17:36:05 2012 +0200 Committer: Martin Tzvetanov Grigorov <[email protected]> Committed: Fri Mar 2 17:37:57 2012 +0200 ---------------------------------------------------------------------- .../apache/wicket/model/AbstractPropertyModel.java | 101 +-------- .../org/apache/wicket/model/ChainingModel.java | 173 +++++++++++++++ .../apache/wicket/model/CompoundPropertyModel.java | 88 +------- .../AbstractPropertyModelObjectClassTest.java | 8 +- 4 files changed, 191 insertions(+), 179 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/e1d28429/wicket-core/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java b/wicket-core/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java index c4ee729..a0ca887 100644 --- a/wicket-core/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java +++ b/wicket-core/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java @@ -25,8 +25,6 @@ import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.util.lang.PropertyResolver; import org.apache.wicket.util.lang.PropertyResolverConverter; import org.apache.wicket.util.string.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Serves as a base class for different kinds of property models. By default, this class uses @@ -45,20 +43,12 @@ import org.slf4j.LoggerFactory; * @param <T> * The Model object type */ -public abstract class AbstractPropertyModel<T> +public abstract class AbstractPropertyModel<T> extends ChainingModel<T> implements - IChainingModel<T>, IObjectClassAwareModel<T>, IPropertyReflectionAwareModel<T> { - private static final Logger logger = LoggerFactory.getLogger(AbstractPropertyModel.class); - - /** - * - */ private static final long serialVersionUID = 1L; - /** Any model object (which may or may not implement IModel) */ - private Object target; /** * Constructor @@ -68,48 +58,7 @@ public abstract class AbstractPropertyModel<T> */ public AbstractPropertyModel(final Object modelObject) { - if (modelObject == null) - { - throw new IllegalArgumentException("Parameter modelObject cannot be null"); - } - - if (modelObject instanceof Session) - { - logger.warn("It is not a good idea to reference the Session instance " - + "in models directly as it may lead to serialization problems. " - + "If you need to access a property of the session via the model use the " - + "page instance as the model object and 'session.attribute' as the path."); - } - - target = modelObject; - } - - /** - * Unsets this property model's instance variables and detaches the model. - * - * @see org.apache.wicket.model.IDetachable#detach() - */ - @Override - public void detach() - { - // Detach nested object if it's a detachable - if (target instanceof IDetachable) - { - ((IDetachable)target).detach(); - } - } - - /** - * @see org.apache.wicket.model.IChainingModel#getChainedModel() - */ - @Override - public IModel<?> getChainedModel() - { - if (target instanceof IModel) - { - return (IModel<?>)target; - } - return null; + super(modelObject); } /** @@ -150,15 +99,6 @@ public abstract class AbstractPropertyModel<T> } /** - * @see org.apache.wicket.model.IChainingModel#setChainedModel(org.apache.wicket.model.IModel) - */ - @Override - public void setChainedModel(IModel<?> model) - { - target = model; - } - - /** * Applies the property expression on the model object using the given object argument. * * @param object @@ -174,13 +114,14 @@ public abstract class AbstractPropertyModel<T> { // TODO check, really do this? // why not just set the target to the object? + Object target = getPlainTarget(); if (target instanceof IModel) { ((IModel<T>)target).setObject(object); } else { - target = object; + setPlainTarget(object); } } else @@ -193,36 +134,6 @@ public abstract class AbstractPropertyModel<T> } /** - * @see java.lang.Object#toString() - */ - @Override - public String toString() - { - StringBuilder sb = new StringBuilder("Model:classname=["); - sb.append(getClass().getName()).append("]"); - sb.append(":nestedModel=[").append(target).append("]"); - return sb.toString(); - } - - /** - * @return The target object - */ - public final Object getTarget() - { - Object object = target; - while (object instanceof IModel) - { - Object tmp = ((IModel<?>)object).getObject(); - if (tmp == object) - { - break; - } - object = tmp; - } - return object; - } - - /** * @return model object class */ @Override @@ -249,11 +160,11 @@ public abstract class AbstractPropertyModel<T> // ignore. } } - else if (this.target instanceof IObjectClassAwareModel) + else if (getPlainTarget() instanceof IObjectClassAwareModel) { try { - Class<?> targetClass = ((IObjectClassAwareModel<?>)this.target).getObjectClass(); + Class<?> targetClass = ((IObjectClassAwareModel<?>)getPlainTarget()).getObjectClass(); if (targetClass != null) { return PropertyResolver.getPropertyClass(expression, targetClass); http://git-wip-us.apache.org/repos/asf/wicket/blob/e1d28429/wicket-core/src/main/java/org/apache/wicket/model/ChainingModel.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/model/ChainingModel.java b/wicket-core/src/main/java/org/apache/wicket/model/ChainingModel.java new file mode 100644 index 0000000..97545a4 --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/model/ChainingModel.java @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.wicket.model; + +import org.apache.wicket.Session; +import org.apache.wicket.util.lang.Args; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Default implementation of IChainingModel + * + * @param <T> + * The Model object type + * + * @see CompoundPropertyModel + * @see AbstractPropertyModel + * + * @since 6.0.0 + */ +public abstract class ChainingModel<T> implements IChainingModel<T> +{ + private static final Logger LOG = LoggerFactory.getLogger(ChainingModel.class); + + /** Any model object (which may or may not implement IModel) */ + private Object target; + + public ChainingModel(final Object modelObject) + { + Args.notNull(modelObject, "modelObject"); + + if (modelObject instanceof Session) + { + LOG.warn("It is not a good idea to reference the Session instance " + + "in models directly as it may lead to serialization problems. " + + "If you need to access a property of the session via the model use the " + + "page instance as the model object and 'session.attribute' as the path."); + } + + target = modelObject; + } + + /** + * Unsets this property model's instance variables and detaches the model. + * + * @see org.apache.wicket.model.IDetachable#detach() + */ + @Override + public void detach() + { + // Detach nested object if it's a detachable + if (target instanceof IDetachable) + { + ((IDetachable)target).detach(); + } + } + + /** + * @see org.apache.wicket.model.IModel#setObject(java.lang.Object) + */ + @Override + @SuppressWarnings("unchecked") + public void setObject(T object) + { + if (target instanceof IModel) + { + ((IModel<T>)target).setObject(object); + } + else + { + target = object; + } + } + + /** + * @see org.apache.wicket.model.IModel#getObject() + */ + @Override + @SuppressWarnings("unchecked") + public T getObject() + { + if (target instanceof IModel) + { + return ((IModel<T>)target).getObject(); + } + return (T)target; + } + + /** + * @see org.apache.wicket.model.IChainingModel#getChainedModel() + */ + @Override + public IModel<?> getChainedModel() + { + if (target instanceof IModel) + { + return (IModel<?>)target; + } + return null; + } + + /** + * @see org.apache.wicket.model.IChainingModel#setChainedModel(org.apache.wicket.model.IModel) + */ + @Override + public void setChainedModel(IModel<?> model) + { + target = model; + } + + /** + * @return The target - object or model + */ + protected final Object getPlainTarget() + { + return target; + } + + /** + * Sets a new target - object or model + * @return this object + */ + protected final ChainingModel<T> setPlainTarget(final Object modelObject) + { + this.target = modelObject; + return this; + } + + /** + * @return The innermost model or the object if the target is not a model + */ + // legacy method ... + public final Object getTarget() + { + Object object = target; + while (object instanceof IModel) + { + Object tmp = ((IModel<?>)object).getObject(); + if (tmp == object) + { + break; + } + object = tmp; + } + return object; + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder("Model:classname=["); + sb.append(getClass().getName()).append("]"); + sb.append(":nestedModel=[").append(target).append("]"); + return sb.toString(); + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/e1d28429/wicket-core/src/main/java/org/apache/wicket/model/CompoundPropertyModel.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/model/CompoundPropertyModel.java b/wicket-core/src/main/java/org/apache/wicket/model/CompoundPropertyModel.java index 95fa53a..e0e3dc6 100644 --- a/wicket-core/src/main/java/org/apache/wicket/model/CompoundPropertyModel.java +++ b/wicket-core/src/main/java/org/apache/wicket/model/CompoundPropertyModel.java @@ -17,7 +17,6 @@ package org.apache.wicket.model; import org.apache.wicket.Component; -import org.apache.wicket.util.string.AppendingStringBuffer; /** * A simple compound model which uses the component's name as the property expression to retrieve @@ -36,12 +35,10 @@ import org.apache.wicket.util.string.AppendingStringBuffer; * @param <T> * The model object type */ -public class CompoundPropertyModel<T> implements IComponentInheritedModel<T>, IChainingModel<T> +public class CompoundPropertyModel<T> extends ChainingModel<T> implements IComponentInheritedModel<T> { private static final long serialVersionUID = 1L; - private Object target; - /** * Constructor * @@ -50,7 +47,7 @@ public class CompoundPropertyModel<T> implements IComponentInheritedModel<T>, IC */ public CompoundPropertyModel(final IModel<T> model) { - target = model; + super(model); } /** @@ -61,72 +58,7 @@ public class CompoundPropertyModel<T> implements IComponentInheritedModel<T>, IC */ public CompoundPropertyModel(final T object) { - target = object; - } - - /** - * @see org.apache.wicket.model.IModel#getObject() - */ - @Override - @SuppressWarnings("unchecked") - public T getObject() - { - if (target instanceof IModel) - { - return ((IModel<T>)target).getObject(); - } - return (T)target; - } - - /** - * @see org.apache.wicket.model.IModel#setObject(java.lang.Object) - */ - @Override - @SuppressWarnings("unchecked") - public void setObject(T object) - { - if (target instanceof IModel) - { - ((IModel<T>)target).setObject(object); - } - else - { - target = object; - } - } - - /** - * @see org.apache.wicket.model.IChainingModel#getChainedModel() - */ - @Override - public IModel<?> getChainedModel() - { - if (target instanceof IModel) - { - return (IModel<?>)target; - } - return null; - } - - /** - * @see org.apache.wicket.model.IChainingModel#setChainedModel(org.apache.wicket.model.IModel) - */ - @Override - public void setChainedModel(IModel<?> model) - { - target = model; - } - - /** - * @see org.apache.wicket.model.IDetachable#detach() - */ - @Override - public void detach() - { - if (target instanceof IDetachable) - { - ((IDetachable)target).detach(); - } + super(object); } /** @@ -155,6 +87,7 @@ public class CompoundPropertyModel<T> implements IComponentInheritedModel<T>, IC * id of the Component isn't a valid property for the data object. * * @param property + * the name that will be used to find * @return The IModel that is a wrapper around the current model and the property * @param <S> * the type of the property @@ -222,21 +155,10 @@ public class CompoundPropertyModel<T> implements IComponentInheritedModel<T>, IC } /** - * @see java.lang.Object#toString() - */ - @Override - public String toString() - { - AppendingStringBuffer sb = new AppendingStringBuffer().append("Model:classname=[" + - getClass().getName() + "]"); - sb.append(":nestedModel=[").append(target).append("]"); - return sb.toString(); - } - - /** * Type-infering factory method * * @param <Z> + * the type of the model's object * @param model * model * @return {@link CompoundPropertyModel} instance http://git-wip-us.apache.org/repos/asf/wicket/blob/e1d28429/wicket-core/src/test/java/org/apache/wicket/model/AbstractPropertyModelObjectClassTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/model/AbstractPropertyModelObjectClassTest.java b/wicket-core/src/test/java/org/apache/wicket/model/AbstractPropertyModelObjectClassTest.java index df1e830..1d141fc 100644 --- a/wicket-core/src/test/java/org/apache/wicket/model/AbstractPropertyModelObjectClassTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/model/AbstractPropertyModelObjectClassTest.java @@ -19,6 +19,8 @@ package org.apache.wicket.model; import java.io.Serializable; import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.Test; /** * <p> @@ -29,12 +31,13 @@ import junit.framework.TestCase; * @see <a href="https://issues.apache.org/jira/browse/WICKET-2937">WICKET-2937</a> * @author Pedro Santos */ -public class AbstractPropertyModelObjectClassTest extends TestCase +public class AbstractPropertyModelObjectClassTest extends Assert { /** * */ + @Test public void testCompoundPropertyModel() { assertPropertyModelTargetTypeIsInteger(new CompoundPropertyModel<CustomType>( @@ -44,6 +47,7 @@ public class AbstractPropertyModelObjectClassTest extends TestCase /** * */ + @Test public void testCompoundPropertyModelBind() { CompoundPropertyModel<CustomBean> compoundPropertyModel = new CompoundPropertyModel<CustomBean>( @@ -55,6 +59,7 @@ public class AbstractPropertyModelObjectClassTest extends TestCase /** * */ + @Test public void testModel() { assertPropertyModelTargetTypeIsInteger(new Model<CustomType>(new CustomType())); @@ -78,6 +83,7 @@ public class AbstractPropertyModelObjectClassTest extends TestCase * * @see <a href="https://issues.apache.org/jira/browse/WICKET-3253">WICKET-3253</a> */ + @Test public void testLazyClassResolution() { Model<CustomBean> modelCustomBean = new Model<CustomBean>(null);
