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-unsubscr...@db.apache.org For additional commands, e-mail: torque-dev-h...@db.apache.org