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/04/06 22:12:18 UTC

svn commit: r1465295 - in /db/torque/torque4/trunk/torque-generator/src: main/java/org/apache/torque/generator/control/ main/java/org/apache/torque/generator/source/model/ main/java/org/apache/torque/generator/source/stream/ test/java/org/apache/torque...

Author: tfischer
Date: Sat Apr  6 20:12:17 2013
New Revision: 1465295

URL: http://svn.apache.org/r1465295
Log:
TORQUE-273 some bug fixes, use configurable prefix- and suffix-list in PropertyAccess

Modified:
    db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java
    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/main/java/org/apache/torque/generator/source/stream/XmlSourceSaxHandler.java
    db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/model/PropertyAccessTest.java

Modified: db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java?rev=1465295&r1=1465294&r2=1465295&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java (original)
+++ db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/control/Controller.java Sat Apr  6 20:12:17 2013
@@ -49,6 +49,8 @@ import org.apache.torque.generator.contr
 import org.apache.torque.generator.control.existingtargetstrategy.SkipExistingTargetFileStrategy;
 import org.apache.torque.generator.outlet.Outlet;
 import org.apache.torque.generator.outlet.OutletResult;
+import org.apache.torque.generator.processor.string.Camelbacker;
+import org.apache.torque.generator.processor.string.WrapReservedJavaWords;
 import org.apache.torque.generator.source.Source;
 import org.apache.torque.generator.source.SourceElement;
 import org.apache.torque.generator.source.SourceException;
@@ -56,6 +58,7 @@ import org.apache.torque.generator.sourc
 import org.apache.torque.generator.source.SourceProcessConfiguration;
 import org.apache.torque.generator.source.SourceProvider;
 import org.apache.torque.generator.source.SourceTransformerDefinition;
+import org.apache.torque.generator.source.model.NoSuchPropertyException;
 import org.apache.torque.generator.source.model.PropertyAccess;
 import org.apache.torque.generator.source.skipDecider.SkipDecider;
 import org.apache.torque.generator.source.transform.SourceTransformer;
@@ -76,6 +79,17 @@ public class Controller
     public static final String NULL_ATTRIBUTE_FIELD_NAME = "value";
 
     /**
+     * The processor which does the camelback processing.
+     */
+    private final Camelbacker camelbacker = new Camelbacker();
+
+    /**
+     * The processor which wraps reserved java words.
+     */
+    private final WrapReservedJavaWords reservedWordsWrapper
+        = new WrapReservedJavaWords();
+
+    /**
      * All known ExistingTargetStrategies.
      * TODO: move to a better place.
      */
@@ -95,6 +109,15 @@ public class Controller
     }
 
     /**
+     * Standard constructor.
+     */
+    public Controller()
+    {
+        camelbacker.setDefaultLowerCase(false);
+        camelbacker.setFirstCharUppercase(false);
+    }
+
+    /**
      * Executes the controller action.
      *
      * @param unitDescriptors the units of generation to execute.
@@ -354,6 +377,8 @@ public class Controller
     {
         for (String attributeName : sourceElement.getAttributeNames())
         {
+            attributeName = camelbacker.process(attributeName);
+            attributeName = reservedWordsWrapper.process(attributeName);
             if (attributeName == null)
             {
                 attributeName = NULL_ATTRIBUTE_FIELD_NAME;
@@ -366,10 +391,20 @@ public class Controller
         }
         for (SourceElement child : sourceElement.getChildren())
         {
-            String propertyName = sourceElement.getName();
+            String propertyName = child.getName();
+            propertyName = camelbacker.process(propertyName);
+            propertyName = reservedWordsWrapper.process(propertyName);
             PropertyAccess propertyAccess = new PropertyAccess(
                     modelElement,
                     propertyName);
+            if (!propertyAccess.isPropertyAccessible())
+            {
+                throw new NoSuchPropertyException(
+                        modelElement,
+                        propertyName,
+                        propertyAccess.getPrefixList(),
+                        propertyAccess.getSuffixList());
+            }
             Object childModelElement = alreadyMapped.get(child);
             if (childModelElement != null)
             {

Modified: 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=1465295&r1=1465294&r2=1465295&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/NoSuchPropertyException.java (original)
+++ db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/NoSuchPropertyException.java Sat Apr  6 20:12:17 2013
@@ -19,6 +19,8 @@ package org.apache.torque.generator.sour
  * under the License.
  */
 
+import java.util.List;
+
 import org.apache.torque.generator.source.SourceException;
 
 /**
@@ -38,11 +40,17 @@ public class NoSuchPropertyException ext
      *        accessed.
      * @param name the name of the property which was unsuccessfully accessed.
      */
-    public NoSuchPropertyException(Object target, String name)
+    public NoSuchPropertyException(
+            Object target,
+            String name,
+            List<String> prefixList,
+            List<String> suffixList)
     {
         super("Neither public field nor public getter/setter"
                 + " exists for property "
-                + name
+                + getSuffixedNames(name, suffixList)
+                + " and no public field exists for property "
+                + getPrefixedNames(name, prefixList)
                 + " of class "
                 + target.getClass().getName());
     }
@@ -56,4 +64,36 @@ public class NoSuchPropertyException ext
     {
         super(message);
     }
+
+    private static String getSuffixedNames(
+            String name,
+            List<String> suffixList)
+    {
+        StringBuilder result = new StringBuilder();
+        for (String suffix: suffixList)
+        {
+            if (result.length() != 0)
+            {
+                result.append(" or ");
+            }
+            result.append(name).append(suffix);
+        }
+        return result.toString();
+    }
+
+    private static String getPrefixedNames(
+            String name,
+            List<String> prefixList)
+    {
+        StringBuilder result = new StringBuilder();
+        for (String prefix : prefixList)
+        {
+            if (result.length() != 0)
+            {
+                result.append(" or ");
+            }
+            result.append(prefix).append(name);
+        }
+        return result.toString();
+    }
 }

Modified: 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=1465295&r1=1465294&r2=1465295&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/PropertyAccess.java (original)
+++ db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/model/PropertyAccess.java Sat Apr  6 20:12:17 2013
@@ -28,7 +28,9 @@ import java.lang.reflect.Modifier;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -52,6 +54,20 @@ public class PropertyAccess
     private String propertyName;
 
     /**
+     * List of all possible prefixes for field names.
+     * I.e. if the property name is "name", "prefix" + "name" is also tried
+     * as field name if "prefix" is contained in this list.
+     */
+    private List<String> prefixList;
+
+    /**
+     * List of all possible suffixes for field and method names.
+     * I.e. if the property name is "name", "name" + "suffix" is also tried
+     * as field name and base method name if "suffix" is contained in this list.
+     */
+    private List<String> suffixList;
+
+    /**
      * The public field corresponding to the property name,
      * or null if no such field exists.
      */
@@ -76,15 +92,55 @@ public class PropertyAccess
      * The property is assumed to be a public field, or if no such field exists
      * on the target object, by getters and setters using the java beans
      * naming conventions.
+     * The searched field and method suffixes are "s", "Array", "List",
+     * the searched field prefixes are "_".
+     * It is not an error to call this constructor on fields which do not exist.
+     *
+     * @param target the target object, not null.
+     * @param propertyName the name of the property, not null.
+     *
+     * @throws SourceException if reflection access to fields or methods fails.
+     * @throws NullPointerException if target or propertyName are null.
+     */
+    public PropertyAccess(
+                Object target,
+                String propertyName)
+            throws SourceException
+    {
+        this(target,
+                propertyName,
+                Arrays.asList(new String[] {"_"}),
+                Arrays.asList(new String[] {"s", "Array", "List"}));
+    }
+
+    /**
+     * Constructs a reflection access to a property of an object.
+     * The property is assumed to be a public field, or if no such field exists
+     * on the target object, by getters and setters using the java beans
+     * naming conventions.
+     * As second order preference, the suffix list is worked first,
+     * if no match is found there the prefix list is tried.
      * It is not an error to call this constructor on fields which do not exist.
      *
      * @param target the target object, not null.
      * @param propertyName the name of the property, not null.
+     * @param prefixList List of all possible prefixes for field names.
+     *        I.e. if the property name is "name",
+     *        "prefix" + "name" is also tried as field name
+     *        if "prefix" is contained in this list.
+     * @param suffixList List of all possible suffixes for field and method
+     *        names.  I.e. if the property name is "name",
+     *        "name" + "suffix" is also tried as field name and base method name
+     *        if "suffix" is contained in this list.
      *
      * @throws SourceException if reflection access to fields or methods fails.
      * @throws NullPointerException if target or propertyName are null.
      */
-    public PropertyAccess(Object target, String propertyName)
+    public PropertyAccess(
+                Object target,
+                String propertyName,
+                List<String> prefixList,
+                List<String> suffixList)
             throws SourceException
     {
         if (target == null)
@@ -97,11 +153,60 @@ public class PropertyAccess
         }
         this.target = target;
         this.propertyName = propertyName;
-        this.field = determinePublicField(target, propertyName);
+        if (prefixList != null)
+        {
+            this.prefixList = new ArrayList<String>(prefixList);
+        }
+        else
+        {
+            this.prefixList = new ArrayList<String>();
+        }
+        if (suffixList != null)
+        {
+            this.suffixList = new ArrayList<String>(suffixList);
+        }
+        else
+        {
+            this.suffixList = new ArrayList<String>();
+        }
+        this.suffixList.add(0, "");
+
+        for (String suffix : this.suffixList)
+        {
+            this.field = determinePublicField(
+                    target,
+                    propertyName + suffix);
+            if (field != null)
+            {
+                break;
+            }
+        }
         if (this.field == null)
         {
-            PropertyDescriptor propertyDescriptor
-                    = determinePropertyDescriptor(target, propertyName);
+            for (String prefix : this.prefixList)
+            {
+                this.field = determinePublicField(
+                        target,
+                        prefix + propertyName);
+                if (field != null)
+                {
+                    break;
+                }
+            }
+        }
+        if (this.field == null)
+        {
+            PropertyDescriptor propertyDescriptor = null;
+            for (String suffix : this.suffixList)
+            {
+                propertyDescriptor = determinePropertyDescriptor(
+                        target,
+                        propertyName + suffix);
+                if (propertyDescriptor != null)
+                {
+                    break;
+                }
+            }
             if (propertyDescriptor != null)
             {
                 this.readMethod = propertyDescriptor.getReadMethod();
@@ -258,7 +363,11 @@ public class PropertyAccess
         }
         else
         {
-            throw new NoSuchPropertyException(target, propertyName);
+            throw new NoSuchPropertyException(
+                    target,
+                    propertyName,
+                    prefixList,
+                    suffixList);
         }
     }
 
@@ -292,7 +401,11 @@ public class PropertyAccess
         }
         else
         {
-            throw new NoSuchPropertyException(target, propertyName);
+            throw new NoSuchPropertyException(
+                    target,
+                    propertyName,
+                    prefixList,
+                    suffixList);
         }
     }
 
@@ -463,6 +576,11 @@ public class PropertyAccess
         }
     }
 
+    public boolean isPropertyAccessible()
+    {
+        return (field != null || readMethod != null || writeMethod != null);
+    }
+
     /**
      * Returns the class of the property.
      *
@@ -533,6 +651,30 @@ public class PropertyAccess
     }
 
     /**
+     * Returns the list of all possible prefixes for field names.
+     * I.e. if the property name is "name", "prefix" + "name" is also tried
+     * as field name if "prefix" is contained in this list.
+     *
+     * @return the prefix list, not null.
+     */
+    public List<String> getPrefixList()
+    {
+        return Collections.unmodifiableList(prefixList);
+    }
+
+    /**
+     * Returns the list of all possible suffixes for field and method names.
+     * I.e. if the property name is "name", "name" + "suffix" is also tried
+     * as field name and base method name if "suffix" is contained in this list.
+     *
+     * @return the suffix list with added "" as first entry, not null.
+     */
+    public List<String> getSuffixList()
+    {
+        return Collections.unmodifiableList(suffixList);
+    }
+
+    /**
      * Adds value as a member of an array to the property of the target object.
      * This method should only be called ifthe property is an array.
      *
@@ -682,7 +824,8 @@ public class PropertyAccess
             .append(propertyName)
             .append(" of class ")
             .append(target.getClass().getName());
-        if (value != null) {
+        if (value != null)
+        {
             message.append(" cannot be set to ").append(value);
         }
         message.append(reason);

Modified: db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/stream/XmlSourceSaxHandler.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/stream/XmlSourceSaxHandler.java?rev=1465295&r1=1465294&r2=1465295&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/stream/XmlSourceSaxHandler.java (original)
+++ db/torque/torque4/trunk/torque-generator/src/main/java/org/apache/torque/generator/source/stream/XmlSourceSaxHandler.java Sat Apr  6 20:12:17 2013
@@ -34,6 +34,10 @@ import org.xml.sax.helpers.DefaultHandle
  */
 public class XmlSourceSaxHandler extends DefaultHandler
 {
+    /** The namespace of the xml schema instance. */
+    private static final String SCHEMA_INSTANCE_NAMESPACE
+        = "http://www.w3.org/2001/XMLSchema-instance";
+
     /**
      * The currently parsed element.
      */
@@ -56,7 +60,7 @@ public class XmlSourceSaxHandler extends
     {
         if (entityReferences == null)
         {
-            throw new NullPointerException("entityReferences msut not be null");
+            throw new NullPointerException("entityReferences must not be null");
         }
         this.entityReferences = entityReferences;
     }
@@ -69,6 +73,11 @@ public class XmlSourceSaxHandler extends
         SourceElement current = new SourceElement(qName);
         for (int i = 0; i < attributes.getLength(); ++i)
         {
+            if (SCHEMA_INSTANCE_NAMESPACE.equals(attributes.getURI(i)))
+            {
+                // ignore schema definitions when reading the model
+                continue;
+            }
             current.setAttribute(
                     attributes.getQName(i), attributes.getValue(i));
         }

Modified: 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=1465295&r1=1465294&r2=1465295&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/model/PropertyAccessTest.java (original)
+++ db/torque/torque4/trunk/torque-generator/src/test/java/org/apache/torque/generator/source/model/PropertyAccessTest.java Sat Apr  6 20:12:17 2013
@@ -43,6 +43,7 @@ import org.junit.Test;
  */
 public class PropertyAccessTest
 {
+    /** the class to set properties on. */
     private TestClass testClass;
 
     @Before
@@ -92,7 +93,10 @@ public class PropertyAccessTest
         catch (NoSuchPropertyException e)
         {
             assertEquals("Neither public field nor public getter/setter exists "
-                    + "for property fieldDoesNotExist of class "
+                    + "for property fieldDoesNotExist or fieldDoesNotExists "
+                    + "or fieldDoesNotExistArray or fieldDoesNotExistList "
+                    + "and no public field exists for property "
+                    + "_fieldDoesNotExist of class "
                     + "org.apache.torque.generator.source.model"
                     + ".PropertyAccessTest$TestClass",
                 e.getMessage());
@@ -112,7 +116,10 @@ public class PropertyAccessTest
         catch (NoSuchPropertyException e)
         {
             assertEquals("Neither public field nor public getter/setter exists "
-                    + "for property privateIntField of class "
+                    + "for property privateIntField or privateIntFields "
+                    + "or privateIntFieldArray or privateIntFieldList "
+                    + "and no public field exists for property "
+                    + "_privateIntField of class "
                     + "org.apache.torque.generator.source.model"
                     + ".PropertyAccessTest$TestClass",
                 e.getMessage());
@@ -132,7 +139,10 @@ public class PropertyAccessTest
         catch (NoSuchPropertyException e)
         {
             assertEquals("Neither public field nor public getter/setter exists "
-                    + "for property protectedIntField of class "
+                    + "for property protectedIntField or protectedIntFields "
+                    + "or protectedIntFieldArray or protectedIntFieldList "
+                    + "and no public field exists for property "
+                    + "_protectedIntField of class "
                     + "org.apache.torque.generator.source.model"
                     + ".PropertyAccessTest$TestClass",
                 e.getMessage());
@@ -152,7 +162,10 @@ public class PropertyAccessTest
         catch (NoSuchPropertyException e)
         {
             assertEquals("Neither public field nor public getter/setter exists "
-                    + "for property intField of class "
+                    + "for property intField or intFields "
+                    + "or intFieldArray or intFieldList "
+                    + "and no public field exists for property "
+                    + "_intField of class "
                     + "org.apache.torque.generator.source.model"
                     + ".PropertyAccessTest$TestClass",
                 e.getMessage());
@@ -168,6 +181,38 @@ public class PropertyAccessTest
         assertEquals(2, testClass.publicIntField);
     }
 
+    /**
+     * Check whether a field ending with s can be accessed without
+     * the ending s.
+     *
+     * @throws Exception if the test fails.
+     */
+    @Test
+    public void testSetPropertyPublicFieldEndingWithS() throws Exception
+    {
+        PropertyAccess propertyAccess
+                = new PropertyAccess(testClass, "publicFieldEndingWith");
+        propertyAccess.setProperty(2);
+        assertEquals(2, testClass.publicFieldEndingWiths);
+    }
+
+    /**
+     * Check whether a field starting with an underscore can be accessed
+     * without the underscore.
+     *
+     * @throws Exception if the test fails.
+     */
+    @Test
+    public void testSetPropertyPublicFieldStartingWithUnderscore()
+            throws Exception
+    {
+        PropertyAccess propertyAccess = new PropertyAccess(
+                testClass,
+                "publicFieldStartingWithUnderscore");
+        propertyAccess.setProperty(2);
+        assertEquals(2, testClass._publicFieldStartingWithUnderscore);
+    }
+
     @Test
     public void testAccessPublicFieldFromBaseClass() throws Exception
     {
@@ -423,7 +468,10 @@ public class PropertyAccessTest
         catch (NoSuchPropertyException e)
         {
             assertEquals("Neither public field nor public getter/setter exists "
-                    + "for property privateIntSetter of class "
+                    + "for property privateIntSetter or privateIntSetters "
+                    +  "or privateIntSetterArray or privateIntSetterList "
+                    + "and no public field exists for property "
+                    + "_privateIntSetter of class "
                     + "org.apache.torque.generator.source.model"
                     + ".PropertyAccessTest$TestClass",
                 e.getMessage());
@@ -443,7 +491,10 @@ public class PropertyAccessTest
         catch (NoSuchPropertyException e)
         {
             assertEquals("Neither public field nor public getter/setter exists "
-                    + "for property protectedIntSetter of class "
+                    + "for property protectedIntSetter or protectedIntSetters "
+                    +  "or protectedIntSetterArray or protectedIntSetterList "
+                    + "and no public field exists for property "
+                    + "_protectedIntSetter of class "
                     + "org.apache.torque.generator.source.model"
                     + ".PropertyAccessTest$TestClass",
                 e.getMessage());
@@ -463,7 +514,10 @@ public class PropertyAccessTest
         catch (NoSuchPropertyException e)
         {
             assertEquals("Neither public field nor public getter/setter exists "
-                    + "for property intSetter of class "
+                    + "for property intSetter or intSetters "
+                    +  "or intSetterArray or intSetterList "
+                    + "and no public field exists for property "
+                    + "_intSetter of class "
                     + "org.apache.torque.generator.source.model"
                     + ".PropertyAccessTest$TestClass",
                 e.getMessage());
@@ -480,6 +534,15 @@ public class PropertyAccessTest
     }
 
     @Test
+    public void testSetPropertyPublicSetterEndingWithS() throws Exception
+    {
+        PropertyAccess propertyAccess
+                = new PropertyAccess(testClass, "publicSetterEndingWith");
+        propertyAccess.setProperty(2);
+        assertEquals(2, testClass.publicFieldEndingWiths);
+    }
+
+    @Test
     public void testSetPropertyPublicSetterFromBaseClass() throws Exception
     {
         PropertyAccess propertyAccess
@@ -595,7 +658,8 @@ public class PropertyAccessTest
     {
         PropertyAccess propertyAccess
                 = new PropertyAccess(testClass, "publicStringArraySetterWithoutGetter");
-        try{
+        try
+        {
             propertyAccess.setProperty("abc");
             fail("Exception expected");
         }
@@ -919,6 +983,10 @@ public class PropertyAccessTest
 
         public Vector<String> publicStringVectorField;
 
+        public int publicFieldEndingWiths;
+
+        public int _publicFieldStartingWithUnderscore;
+
         public int getOnlyGetter()
         {
             return 0;
@@ -1028,6 +1096,12 @@ public class PropertyAccessTest
         {
             return publicStringVectorField;
         }
+
+        public void setPublicSetterEndingWiths(int value)
+        {
+            publicFieldEndingWiths = value;
+        }
+
     }
 
     public static class TestBaseClass



---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org