You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by kn...@apache.org on 2007/06/05 23:41:05 UTC

svn commit: r544645 - in /incubator/wicket/trunk/jdk-1.4/wicket/src: main/java/org/apache/wicket/model/ main/java/org/apache/wicket/util/lang/ test/java/org/apache/wicket/util/lang/

Author: knopp
Date: Tue Jun  5 14:41:04 2007
New Revision: 544645

URL: http://svn.apache.org/viewvc?view=rev&rev=544645
Log:
WICKET-619 - Models that can should be able to provide information about field/getter/setter

Added:
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/IPropertyReflectionAwareModel.java
Modified:
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/lang/PropertyResolver.java
    incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/util/lang/PropertyResolverTest.java

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java?view=diff&rev=544645&r1=544644&r2=544645
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/AbstractPropertyModel.java Tue Jun  5 14:41:04 2007
@@ -16,6 +16,9 @@
  */
 package org.apache.wicket.model;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
 import org.apache.wicket.Application;
 import org.apache.wicket.Component;
 import org.apache.wicket.Session;
@@ -32,7 +35,11 @@
  * @author Eelco Hillenius
  * @author Jonathan Locke
  */
-public abstract class AbstractPropertyModel implements IChainingModel, IObjectClassAwareModel
+public abstract class AbstractPropertyModel
+		implements
+			IChainingModel,
+			IObjectClassAwareModel,
+			IPropertyReflectionAwareModel
 {
 	/** Any model object (which may or may not implement IModel) */
 	private Object target;
@@ -194,6 +201,57 @@
 		return null;
 	}
 
+	/**
+	 * @see org.apache.wicket.model.IPropertyReflectionAwareModel#getPropertyField()
+	 */
+	public Field getPropertyField()
+	{
+		String expression = propertyExpression();
+		if (Strings.isEmpty(expression) == false) 
+		{
+			Object target = getTarget();
+			if (target != null) 
+			{
+				return PropertyResolver.getPropertyField(expression, target);
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @see org.apache.wicket.model.IPropertyReflectionAwareModel#getPropertyGetter()
+	 */
+	public Method getPropertyGetter()
+	{
+		String expression = propertyExpression();
+		if (Strings.isEmpty(expression) == false) 
+		{
+			Object target = getTarget();
+			if (target != null) 
+			{
+				return PropertyResolver.getPropertyGetter(expression, target);
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * @see org.apache.wicket.model.IPropertyReflectionAwareModel#getPropertySetter()
+	 */
+	public Method getPropertySetter()
+	{
+		String expression = propertyExpression();
+		if (Strings.isEmpty(expression) == false) 
+		{
+			Object target = getTarget();
+			if (target != null) 
+			{
+				return PropertyResolver.getPropertySetter(expression, target);
+			}
+		}
+		return null;
+	}
+	
 	/**
 	 * @return The property expression for the component
 	 */

Added: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/IPropertyReflectionAwareModel.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/IPropertyReflectionAwareModel.java?view=auto&rev=544645
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/IPropertyReflectionAwareModel.java (added)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/model/IPropertyReflectionAwareModel.java Tue Jun  5 14:41:04 2007
@@ -0,0 +1,53 @@
+/*
+ * 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 java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * Optional interface implemented by models that are able to provide
+ * reflection information about object property they interact with.
+ * 
+ * The model doesn't have to support all propery information in this 
+ * interface. It is valid to return null for any method.
+ * 
+ * @author Matej Knopp
+ */
+public interface IPropertyReflectionAwareModel
+{
+	/**
+	 * Returns the field of model property or null if the field doesn't exist.
+	 * @return Field or null
+	 */
+	public Field getPropertyField();
+	
+	/**
+	 * Returns the getter method of model property or null if the method
+	 * doesn't exist.
+	 * @return Method or null
+	 */
+	public Method getPropertyGetter();
+	
+	
+	/**
+	 * Returns the setter metod of model property or null if the method doesn't
+	 * exist.
+	 * @return Method or null
+	 */
+	public Method getPropertySetter();
+}

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/lang/PropertyResolver.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/lang/PropertyResolver.java?view=diff&rev=544645&r1=544644&r2=544645
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/lang/PropertyResolver.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/lang/PropertyResolver.java Tue Jun  5 14:41:04 2007
@@ -138,7 +138,7 @@
 	/**
 	 * @param expression
 	 * @param object
-	 * @return
+	 * @return class of the target property object
 	 */
 	public final static Class getPropertyClass(String expression, Object object)
 	{
@@ -151,6 +151,57 @@
 		return setter.getTargetClass();
 	}
 
+	/**
+	 * @param expression
+	 * @param object
+	 * @return Field for the property expression or null if such field doesn't
+	 *         exist (only getters and setters)
+	 */
+	public final static Field getPropertyField(String expression, Object object)
+	{
+		ObjectAndGetSetter setter = getObjectAndGetSetter(expression, object, true);
+		if (setter == null)
+		{
+			throw new WicketRuntimeException("Null object returned for expression: " + expression
+					+ " for getting the target classs of: " + object);
+		}
+		return setter.getField();
+	}
+
+	/**
+	 * @param expression
+	 * @param object
+	 * @return Getter method for the property expression or null if such getter
+	 *         doesn't exist (only field)
+	 */
+	public final static Method getPropertyGetter(String expression, Object object)
+	{
+		ObjectAndGetSetter setter = getObjectAndGetSetter(expression, object, true);
+		if (setter == null)
+		{
+			throw new WicketRuntimeException("Null object returned for expression: " + expression
+					+ " for getting the target classs of: " + object);
+		}
+		return setter.getGetter();
+	}
+
+	/**
+	 * @param expression
+	 * @param object
+	 * @return Setter method for the property expression or null if such setter
+	 *         doesn't exist (only field)
+	 */
+	public final static Method getPropertySetter(String expression, Object object)
+	{
+		ObjectAndGetSetter setter = getObjectAndGetSetter(expression, object, true);
+		if (setter == null)
+		{
+			throw new WicketRuntimeException("Null object returned for expression: " + expression
+					+ " for getting the target classs of: " + object);
+		}
+		return setter.getSetter();
+	}
+	
 	private static ObjectAndGetSetter getObjectAndGetSetter(final String expression,
 			final Object object, boolean tryToCreateNull)
 	{
@@ -264,7 +315,7 @@
 						method = findMethod(clz, exp);
 						if (method != null)
 						{
-							getAndSetter = new MethodGetAndSet(method);
+							getAndSetter = new MethodGetAndSet(method, null);
 						}
 						else
 						{
@@ -344,7 +395,7 @@
 						}
 						else
 						{
-							getAndSetter = new MethodGetAndSet(method);
+							getAndSetter = new MethodGetAndSet(method, field);
 						}
 					}
 					else
@@ -355,7 +406,8 @@
 			}
 			else
 			{
-				getAndSetter = new MethodGetAndSet(method);
+				field = findField(clz, exp);
+				getAndSetter = new MethodGetAndSet(method, field);
 			}
 			getAndSetters.put(exp, getAndSetter);
 		}
@@ -488,11 +540,38 @@
 			return getAndSetter.getValue(value);
 		}
 
+		/**
+		 * @return class of property value
+		 */
 		public Class getTargetClass()
 		{
 			return getAndSetter.getTargetClass(this.value);
 		}
 
+		/**
+		 * @return Field or null if no field exists for expression
+		 */
+		public Field getField()
+		{
+			return getAndSetter.getField();
+		}
+
+		/**
+		 * @return Getter method or null if no getter exists for expression
+		 */
+		public Method getGetter()
+		{
+			return getAndSetter.getGetter();
+		}
+
+		/**
+		 * @return Setter method or null if no setter exists for expression
+		 */
+		public Method getSetter()
+		{
+			return getAndSetter.getSetter();
+		}
+
 	}
 
 
@@ -528,9 +607,58 @@
 		public void setValue(final Object object, final Object value,
 				PropertyResolverConverter converter);
 
+		/**
+		 * @return Field or null if there is no field
+		 */
+		public Field getField();
+
+		/**
+		 * @return Getter method or null if there is no getter
+		 */
+		public Method getGetter();
+
+		/**
+		 * @return Setter of null if there is no setter
+		 */
+		public Method getSetter();
+	}
+
+	private static abstract class AbstractGetAndSet implements IGetAndSet
+	{
+		/**
+		 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getField()
+		 */
+		public Field getField()
+		{
+			return null;
+		}
+
+		/**
+		 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getGetter()
+		 */
+		public Method getGetter()
+		{
+			return null;
+		}
+
+		/**
+		 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getSetter()
+		 */
+		public Method getSetter()
+		{
+			return null;
+		}
+
+		/**
+		 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getTargetClass(java.lang.Object)
+		 */
+		public Class getTargetClass(Object object)
+		{
+			return null;
+		}
 	}
 
-	private static final class MapGetSet implements IGetAndSet
+	private static final class MapGetSet extends AbstractGetAndSet
 	{
 		final private String key;
 
@@ -565,17 +693,9 @@
 			// map and try to make one of the class if finds?
 			return null;
 		}
-
-		/**
-		 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getTargetClass(Object)
-		 */
-		public Class getTargetClass(Object object)
-		{
-			return null;
-		}
 	}
 
-	private static final class ListGetSet implements IGetAndSet
+	private static final class ListGetSet extends AbstractGetAndSet
 	{
 		final private int index;
 
@@ -627,17 +747,9 @@
 			// list and try to make one of the class if finds?
 			return null;
 		}
-
-		/**
-		 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getTargetClass(Object)
-		 */
-		public Class getTargetClass(Object object)
-		{
-			return null;
-		}
 	}
 
-	private static final class ArrayGetSet implements IGetAndSet
+	private static final class ArrayGetSet extends AbstractGetAndSet
 	{
 		final private int index;
 
@@ -693,7 +805,7 @@
 		}
 	}
 
-	private static final class ArrayLengthGetSet implements IGetAndSet
+	private static final class ArrayLengthGetSet extends AbstractGetAndSet
 	{
 		ArrayLengthGetSet()
 		{
@@ -733,7 +845,7 @@
 		}
 	}
 
-	private static final class ArrayPropertyGetSet implements IGetAndSet
+	private static final class ArrayPropertyGetSet extends AbstractGetAndSet
 	{
 		final private Integer index;
 		final private Method getMethod;
@@ -862,15 +974,17 @@
 		}
 	}
 
-	private static final class MethodGetAndSet implements IGetAndSet
+	private static final class MethodGetAndSet extends AbstractGetAndSet
 	{
 		private Method getMethod;
 		private Method setMethod;
+		private Field field;
 
-		MethodGetAndSet(Method getMethod)
+		MethodGetAndSet(Method getMethod, Field field)
 		{
 			this.getMethod = getMethod;
 			this.getMethod.setAccessible(true);
+			this.field = field;
 		}
 
 		/**
@@ -1013,12 +1127,36 @@
 		{
 			return getMethod.getReturnType();
 		}
+
+		/**
+		 * @see org.apache.wicket.util.lang.PropertyResolver.AbstractGetAndSet#getGetter()
+		 */
+		public Method getGetter()
+		{
+			return getMethod;
+		}
+
+		/**
+		 * @see org.apache.wicket.util.lang.PropertyResolver.AbstractGetAndSet#getSetter()
+		 */
+		public Method getSetter()
+		{
+			return setMethod;
+		}
+
+		/**
+		 * @see org.apache.wicket.util.lang.PropertyResolver.AbstractGetAndSet#getField()
+		 */
+		public Field getField()
+		{
+			return field;
+		}
 	}
 
 	/**
 	 * @author jcompagner
 	 */
-	private static class FieldGetAndSetter implements IGetAndSet
+	private static class FieldGetAndSetter extends AbstractGetAndSet
 	{
 
 		private Field field;
@@ -1094,6 +1232,11 @@
 		public Class getTargetClass(Object object)
 		{
 			return field.getType();
+		}
+
+		public Field getField()
+		{
+			return field;
 		}
 	}
 }

Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/util/lang/PropertyResolverTest.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/util/lang/PropertyResolverTest.java?view=diff&rev=544645&r1=544644&r2=544645
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/util/lang/PropertyResolverTest.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/test/java/org/apache/wicket/util/lang/PropertyResolverTest.java Tue Jun  5 14:41:04 2007
@@ -16,6 +16,8 @@
  */
 package org.apache.wicket.util.lang;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -355,5 +357,71 @@
 		
 		clazz = PropertyResolver.getPropertyClass("addressArray[0].number", person);
 		assertEquals(int.class, clazz);
+	}
+	
+	/**
+	 *
+	 */
+	public void testGetTargetField() {
+		Address address = new Address();
+		
+		Field field = PropertyResolver.getPropertyField("number", address);
+		assertEquals(field.getName(), "number");
+		assertEquals(field.getType(), int.class);
+		
+		Person person = new Person();
+		person.setAddress(new Address());
+		
+		field = PropertyResolver.getPropertyField("address.number", person);
+		assertEquals(field.getName(), "number");
+		assertEquals(field.getType(), int.class);
+		
+		person.setAddressArray(new Address[] { new Address(), new Address() });
+		field = PropertyResolver.getPropertyField("addressArray[0].number", person);
+		assertEquals(field.getName(), "number");
+		assertEquals(field.getType(), int.class);
+	}
+	
+	/**
+	 *
+	 */
+	public void testGetTargetGetter() {
+		Address address = new Address();
+		
+		Method method = PropertyResolver.getPropertyGetter("number", address);
+		assertEquals(method.getName(), "getNumber");
+		assertEquals(method.getReturnType(), int.class);
+		
+		Person person = new Person();
+		person.setAddress(new Address());
+		
+		method = PropertyResolver.getPropertyGetter("address.number", person);
+		assertEquals(method.getName(), "getNumber");
+		assertEquals(method.getReturnType(), int.class);
+		
+		person.setAddressArray(new Address[] { new Address(), new Address() });
+		method = PropertyResolver.getPropertyGetter("addressArray[0].number", person);
+		assertEquals(method.getName(), "getNumber");
+		assertEquals(method.getReturnType(), int.class);
+	}
+	
+	/**
+	 *
+	 */
+	public void testGetTargetSetter() {
+		Address address = new Address();
+		
+		Method method = PropertyResolver.getPropertySetter("number", address);
+		assertEquals(method.getName(), "setNumber");
+		
+		Person person = new Person();
+		person.setAddress(new Address());
+		
+		method = PropertyResolver.getPropertySetter("address.number", person);
+		assertEquals(method.getName(), "setNumber");
+		
+		person.setAddressArray(new Address[] { new Address(), new Address() });
+		method = PropertyResolver.getPropertySetter("addressArray[0].number", person);
+		assertEquals(method.getName(), "setNumber");
 	}
 }