You are viewing a plain text version of this content. The canonical link for it is here.
Posted to torque-dev@db.apache.org by tf...@apache.org on 2013/03/29 14:32:49 UTC
svn commit: r1462477 - in /db/torque/torque4/trunk/torque-generator/src:
main/java/org/apache/torque/generator/source/model/
test/java/org/apache/torque/generator/source/model/
Author: tfischer
Date: Fri Mar 29 13:32:49 2013
New Revision: 1462477
URL: http://svn.apache.org/r1462477
Log:
TORQUE-273 start utility class for setting properties by reflection
Added:
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/NoSuchPropertyException.java
db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/PropertyAccess.java
db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/model/
db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/model/PropertyAccessTest.java
Added: db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/NoSuchPropertyException.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/NoSuchPropertyException.java?rev=1462477&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/NoSuchPropertyException.java (added)
+++ db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/NoSuchPropertyException.java Fri Mar 29 13:32:49 2013
@@ -0,0 +1,33 @@
+package org.apache.torque.generator.source.model;
+
+/*
+ * 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.
+ */
+
+import org.apache.torque.generator.source.SourceException;
+
+public class NoSuchPropertyException extends SourceException
+{
+ public NoSuchPropertyException(Object target, String name)
+ {
+ super("Neither public field nor public setter exists for property "
+ + name
+ + " of class "
+ + target.getClass().getName());
+ }
+}
Added: db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/PropertyAccess.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/PropertyAccess.java?rev=1462477&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/PropertyAccess.java (added)
+++ db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/PropertyAccess.java Fri Mar 29 13:32:49 2013
@@ -0,0 +1,250 @@
+package org.apache.torque.generator.source.model;
+
+/*
+ * 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.
+ */
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.torque.generator.source.SourceException;
+
+/**
+ * Accesses properties of java classes by reflection.
+ *
+ * @version $Id: $
+ */
+public class PropertyAccess
+{
+ private Object target;
+
+ private String propertyName;
+
+ public PropertyAccess(Object target, String propertyName)
+ {
+ if (target == null)
+ {
+ throw new NullPointerException("target must not be null");
+ }
+ if (propertyName == null)
+ {
+ throw new NullPointerException("propertyName must not be null");
+ }
+ this.target = target;
+ this.propertyName = propertyName;
+ }
+
+ public void setSingleProperty(Object value)
+ throws SourceException
+ {
+ // try public field
+ try
+ {
+ Field field = target.getClass().getField(propertyName);
+ if (Modifier.isPublic(field.getModifiers()))
+ {
+ field.set(target, value);
+ return;
+ }
+ }
+ catch (SecurityException e)
+ {
+ throw createSetFieldException(
+ null,
+ " because access is denied to the field or package",
+ e);
+ }
+ catch (NoSuchFieldException e)
+ {
+ // do nothing, field does not exist
+ }
+ catch (IllegalArgumentException e)
+ {
+ if (value == null) {
+ throw createSetFieldException(
+ value,
+ " because the value is null which is not allowed",
+ e);
+
+ }
+ throw createSetFieldException(
+ value,
+ " because the argument has the wrong type "
+ + value.getClass().getName() ,
+ e);
+ } catch (IllegalAccessException e)
+ {
+ throw createSetFieldException(
+ null,
+ " because the field cannot be accessed",
+ e);
+ }
+
+ // try setter
+ try
+ {
+ PropertyDescriptor propertyDescriptor
+ = PropertyUtils.getPropertyDescriptor(target, propertyName);
+ if (propertyDescriptor == null)
+ {
+ throw new NoSuchPropertyException(target, propertyName);
+ }
+ Method writeMethod = propertyDescriptor.getWriteMethod();
+ if (writeMethod == null)
+ {
+ throw new NoSuchPropertyException(target, propertyName);
+ }
+ writeMethod.invoke(target, value);
+ return;
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new SourceException(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new SourceException(e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new SourceException(e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ if (value == null) {
+ throw createSetFieldException(
+ value,
+ " because the value is null which is not allowed",
+ e);
+
+ }
+ throw createSetFieldException(
+ value,
+ " because the argument has the wrong type "
+ + value.getClass().getName() ,
+ e);
+ }
+ }
+
+ public void setProperty(Object value) throws SourceException
+ {
+ try
+ {
+ setSingleProperty(value);
+ return;
+ }
+ catch (NoSuchPropertyException e)
+ {
+
+ }
+
+ try
+ {
+ String propertyName = this.propertyName;
+ PropertyDescriptor propertyDescriptor
+ = PropertyUtils.getPropertyDescriptor(target, propertyName);
+ if (propertyDescriptor == null) {
+ propertyName = this.propertyName + "s";
+ propertyDescriptor
+ = PropertyUtils.getPropertyDescriptor(target, propertyName);
+ }
+ if (propertyDescriptor == null) {
+ propertyName = this.propertyName + "Array";
+ propertyDescriptor
+ = PropertyUtils.getPropertyDescriptor(target, propertyName);
+ }
+ if (propertyDescriptor == null) {
+ throw new SourceException("No property named "
+ + this.propertyName + ", "
+ + this.propertyName + "s, "
+ + this.propertyName + "Array, "
+ + "found on model element "
+ + target.getClass().getName()
+ + ". This property is needed because the source element"
+ + " has a child element named "
+ + this.propertyName);
+ }
+ Object childModelElement = null;
+ if (propertyDescriptor.getPropertyType().isArray())
+ {
+ Object[] oldChildModelElement = (Object[]) PropertyUtils.getProperty(target, propertyName);
+ int newIndex;
+ if (oldChildModelElement == null) {
+ childModelElement = Array.newInstance(propertyDescriptor.getPropertyType().getComponentType(), 1);
+ newIndex = 0;
+ }
+ else {
+ childModelElement = Array.newInstance(propertyDescriptor.getPropertyType().getComponentType(), oldChildModelElement.length + 1);
+ System.arraycopy(oldChildModelElement, 0, childModelElement, 0, oldChildModelElement.length);
+ newIndex = oldChildModelElement.length;
+ }
+ ((Object[]) childModelElement)[newIndex] = value;
+ }
+ else
+ {
+ childModelElement = value;
+ }
+ try
+ {
+ BeanUtils.setProperty(target, propertyName, childModelElement);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new SourceException(e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new SourceException(e);
+ }
+ } catch (IllegalAccessException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (InvocationTargetException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (NoSuchMethodException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ private SourceException createSetFieldException(
+ Object value,
+ String reason,
+ Throwable cause)
+ {
+ StringBuilder message = new StringBuilder("The field ")
+ .append(propertyName)
+ .append(" of class ")
+ .append(target.getClass().getName());
+ if (value != null) {
+ message.append(" cannot be set to ").append(value);
+ }
+ message.append(reason);
+ return new SourceException(message.toString(), cause);
+ }
+}
Added: db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/model/PropertyAccessTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/model/PropertyAccessTest.java?rev=1462477&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/model/PropertyAccessTest.java (added)
+++ db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/model/PropertyAccessTest.java Fri Mar 29 13:32:49 2013
@@ -0,0 +1,442 @@
+package org.apache.torque.generator.source.model;
+
+/*
+ * 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.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.apache.torque.generator.source.SourceException;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PropertyAccessTest
+{
+ private TestClass testClass;
+
+ @Before
+ public void setUp()
+ {
+ testClass = new TestClass();
+ }
+
+ @Test
+ public void testPropertyAccessTargetNull() throws Exception
+ {
+ try
+ {
+ new PropertyAccess(null, "publicIntField");
+ fail("Exception expected");
+ }
+ catch (NullPointerException e)
+ {
+ assertEquals("target must not be null", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testPropertyAccessPropertyNameNull() throws Exception
+ {
+ try
+ {
+ new PropertyAccess(testClass, null);
+ fail("Exception expected");
+ }
+ catch (NullPointerException e)
+ {
+ assertEquals("propertyName must not be null", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testSetSinglePropertyNotExistentField() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "fieldDoesNotExist");
+ try
+ {
+ propertyAccess.setSingleProperty(2);
+ fail("Exception expected");
+ }
+ catch (NoSuchPropertyException e)
+ {
+ assertEquals("Neither public field nor public setter exists "
+ + "for property fieldDoesNotExist of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessPrivateField() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "privateIntField");
+ try
+ {
+ propertyAccess.setSingleProperty(2);
+ fail("Exception expected");
+ }
+ catch (NoSuchPropertyException e)
+ {
+ assertEquals("Neither public field nor public setter exists "
+ + "for property privateIntField of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessProtectedField() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "protectedIntField");
+ try
+ {
+ propertyAccess.setSingleProperty(2);
+ fail("Exception expected");
+ }
+ catch (NoSuchPropertyException e)
+ {
+ assertEquals("Neither public field nor public setter exists "
+ + "for property protectedIntField of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessField() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "intField");
+ try
+ {
+ propertyAccess.setSingleProperty(2);
+ fail("Exception expected");
+ }
+ catch (NoSuchPropertyException e)
+ {
+ assertEquals("Neither public field nor public setter exists "
+ + "for property intField of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessPublicField() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicIntField");
+ propertyAccess.setSingleProperty(2);
+ assertEquals(2, testClass.publicIntField);
+ }
+
+ @Test
+ public void testAccessPublicFieldFromBaseClass() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicIntFieldFromBaseClass");
+ propertyAccess.setSingleProperty(2);
+ assertEquals(2, testClass.publicIntFieldFromBaseClass);
+ }
+
+ @Test
+ public void testAccessPublicFieldWrongClass() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicIntField");
+ try
+ {
+ propertyAccess.setProperty("abc");
+ fail("Exception expected");
+ }
+ catch (SourceException e)
+ {
+ assertEquals("The field publicIntField of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass cannot be set to abc "
+ + "because the argument has the wrong type "
+ + "java.lang.String",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessIntFieldNull() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicIntField");
+ try
+ {
+ propertyAccess.setSingleProperty(null);
+ fail("Exception expected");
+ }
+ catch (SourceException e)
+ {
+ assertEquals("The field publicIntField of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass because the value is null"
+ + " which is not allowed",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessPublicStringField() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicStringField");
+ propertyAccess.setSingleProperty("abc");
+ assertEquals("abc", testClass.publicStringField);
+ }
+
+ @Test
+ public void testAccessPublicStringFieldNull() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicStringField");
+ testClass.publicStringField = "abc";
+ propertyAccess.setSingleProperty(null);
+ assertEquals(null, testClass.publicStringField);
+ }
+
+ @Test
+ public void testSetSinglePropertyOnlyGetter() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "onlyGetter");
+ try
+ {
+ propertyAccess.setSingleProperty(2);
+ fail("Exception expected");
+ }
+ catch (NoSuchPropertyException e)
+ {
+ assertEquals("Neither public field nor public setter exists "
+ + "for property onlyGetter of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessPrivateSetter() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "privateIntSetter");
+ try
+ {
+ propertyAccess.setSingleProperty(2);
+ fail("Exception expected");
+ }
+ catch (NoSuchPropertyException e)
+ {
+ assertEquals("Neither public field nor public setter exists "
+ + "for property privateIntSetter of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessProtectedSetter() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "protectedIntSetter");
+ try
+ {
+ propertyAccess.setSingleProperty(2);
+ fail("Exception expected");
+ }
+ catch (NoSuchPropertyException e)
+ {
+ assertEquals("Neither public field nor public setter exists "
+ + "for property protectedIntSetter of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessSetter() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "intSetter");
+ try
+ {
+ propertyAccess.setSingleProperty(2);
+ fail("Exception expected");
+ }
+ catch (NoSuchPropertyException e)
+ {
+ assertEquals("Neither public field nor public setter exists "
+ + "for property intSetter of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessPublicSetter() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicIntSetter");
+ propertyAccess.setSingleProperty(2);
+ assertEquals(2, testClass.publicIntField);
+ }
+
+ @Test
+ public void testAccessPublicSetterFromBaseClass() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicIntSetterFromBaseClass");
+ propertyAccess.setSingleProperty(2);
+ assertEquals(2, testClass.publicIntFieldFromBaseClass);
+ }
+
+ @Test
+ public void testAccessPublicSetterWrongClass() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicIntSetter");
+ try
+ {
+ propertyAccess.setProperty("abc");
+ fail("Exception expected");
+ }
+ catch (SourceException e)
+ {
+ assertEquals("The field publicIntSetter of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass cannot be set to abc "
+ + "because the argument has the wrong type "
+ + "java.lang.String",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessIntSetterNull() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicIntSetter");
+ try
+ {
+ propertyAccess.setSingleProperty(null);
+ fail("Exception expected");
+ }
+ catch (SourceException e)
+ {
+ assertEquals("The field publicIntSetter of class "
+ + "org.apache.torque.generator.source.model"
+ + ".PropertyAccessTest$TestClass because the value is null"
+ + " which is not allowed",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAccessPublicStringSetter() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicStringSetter");
+ propertyAccess.setSingleProperty("abc");
+ assertEquals("abc", testClass.publicStringField);
+ }
+
+ @Test
+ public void testAccessPublicStringSetterNull() throws Exception
+ {
+ PropertyAccess propertyAccess
+ = new PropertyAccess(testClass, "publicStringSetter");
+ testClass.publicStringField = "abc";
+ propertyAccess.setSingleProperty(null);
+ assertEquals(null, testClass.publicStringField);
+ }
+
+ public static class TestClass extends TestBaseClass
+ {
+ private int privateIntField;
+
+ protected int protectedIntField;
+
+ int intField;
+
+ public int publicIntField;
+
+ public String publicStringField;
+
+ public int getOnlyGetter()
+ {
+ return 0;
+ }
+
+ private void setPrivateIntSetter(int value)
+ {
+ privateIntField = value;
+ }
+
+ protected void setProtectedIntSetter(int value)
+ {
+ protectedIntField = value;
+ }
+
+ void setIntSetter(int value)
+ {
+ intField = value;
+ }
+
+ public void setPublicIntSetter(int value)
+ {
+ publicIntField = value;
+ }
+
+ public void setPublicStringSetter(String value)
+ {
+ publicStringField = value;
+ }
+ }
+
+ public static class TestBaseClass
+ {
+ public int publicIntFieldFromBaseClass;
+
+ public int publicIntField; // to be overridden
+
+ public void setPublicIntSetterFromBaseClass(int value)
+ {
+ publicIntFieldFromBaseClass = value;
+ }
+
+ public void setPublicIntSetter(int value) // to be overridden
+ {
+ publicIntField = value;
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org