hlship 2004/03/01 14:56:27 Modified: hivemind/xdocs descriptor.xml case1.xml hivemind/framework/src/test/hivemind/test/config TestConversion.java hivemind/framework/src/java/org/apache/hivemind/parse ConversionDescriptor.java DescriptorParser.java hivemind/framework/src/java/org/apache/hivemind/schema/rules CreateObjectRule.java hivemind/framework/src/java/org/apache/hivemind HiveMindMessages.properties Added: hivemind/framework/src/test/hivemind/test/config DuplicateAttribute.xml ComplexAttributeName.xml ConversionParentMethod.xml ComplexNameItem.java Log: Rename parentMethod attribute of <conversion> to parent-method.
Add tests for parent-method and a few other code coverage gaps. Mangle attribute names with dashes into equivalent property names (i.e., "complex-name" to "complexName"). Revision Changes Path 1.31 +12 -3 jakarta-commons-sandbox/hivemind/xdocs/descriptor.xml Index: descriptor.xml =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/descriptor.xml,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- descriptor.xml 1 Mar 2004 01:08:02 -0000 1.30 +++ descriptor.xml 1 Mar 2004 22:56:27 -0000 1.31 @@ -179,7 +179,7 @@ </tr> <tr> - <td>parentMethod</td> + <td>parent-method</td> <td>string</td> <td>no</td> <td>The name of a method of the parent object used to add the created object @@ -192,6 +192,13 @@ Contains: ↦ </p> + <p> + Each attribute will be mapped to a property. A limited amount of name mangling occurs: if the attribute name + contains dashes, they are removed, and the character following is converted to upper case. So, + an attribute named "complex-attribute-name" would be mapped to a property named "complexAttributeName". Only + attributes identified with a &attribute; element will be mapped, others will be ignored. + </p> + </section> <section name="create-instance"> @@ -394,7 +401,9 @@ <td> The corresponding property (of the Java object specified by the enclosing &conversion;). If not specified, the property name - will match the attribute name. + will be based upon the attribute name (with the same + mangling described in the description of + &conversion;). </td> </tr> 1.13 +12 -23 jakarta-commons-sandbox/hivemind/xdocs/case1.xml Index: case1.xml =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/case1.xml,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- case1.xml 26 Feb 2004 23:07:34 -0000 1.12 +++ case1.xml 1 Mar 2004 22:56:27 -0000 1.13 @@ -123,19 +123,12 @@ Id of a service that implements the Executable interface. </description> </attribute> - <rules> - <create-object - class="com.panorama.framework.startup.service.Task" - /> - <read-attribute attribute="order" property="order" - translator="int"/> - <read-attribute attribute="title" property="title"/> - <read-attribute attribute="class" property="executable" - translator="object"/> - <read-attribute attribute="service-id" property="executable" - translator="service"/> - <invoke-parent method="addElement"/> - </rules> + + <conversion class="com.panorama.framework.startup.service.Task"> + <map attribute="class" property="executable" translator="object"/> + <map attribute="service-id" property="executable" translator="service"/> + </conversion> + <element name="invoke-static"> <description>Used to invoke a public static method of a class.</description> @@ -146,15 +139,11 @@ <description>Name of method to invoke; default is "init".</description> </attribute> - <rules> - <create-object - class="com.panorama.framework.startup.service.StaticTask" - /> - <read-attribute attribute="class" property="className"/> - <read-attribute attribute="method" property="methodName" - /> - <invoke-parent method="setExecutable"/> - </rules> + + <conversion class="com.panorama.framework.startup.service.StaticTask" parent-method="setExecutable"> + <map attribute="class" property="className"/> + <map attribute="method" property="methodName"/> + </conversion> </element> </element> </schema> 1.2 +62 -1 jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/config/TestConversion.java Index: TestConversion.java =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/config/TestConversion.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- TestConversion.java 1 Mar 2004 01:08:02 -0000 1.1 +++ TestConversion.java 1 Mar 2004 22:56:27 -0000 1.2 @@ -53,6 +53,27 @@ assertSame(builderFactory, d.getFactory()); } + public void testParentMethod() throws Exception + { + Registry r = buildFrameworkRegistry("ConversionParentMethod.xml"); + + List l = r.getConfiguration("hivemind.test.config.ConversionParentMethod"); + + assertEquals(1, l.size()); + + DataItem d = (DataItem) l.get(0); + + assertEquals("builder", d.getName()); + assertEquals(5, d.getCount()); + + ServiceImplementationFactory builderFactory = + (ServiceImplementationFactory) r.getService( + "hivemind.BuilderFactory", + ServiceImplementationFactory.class); + + assertSame(builderFactory, d.getFactory()); + } + public void testPropertyNameDefaultsToAttributeName() throws Exception { Registry r = buildFrameworkRegistry("Basics2.xml"); @@ -74,6 +95,19 @@ assertSame(builderFactory, d.getFactory()); } + public void testComplexAttributeName() throws Exception + { + Registry r = buildFrameworkRegistry("ComplexAttributeName.xml"); + + List l = r.getConfiguration("hivemind.test.config.ComplexAttributeName"); + + assertEquals(1, l.size()); + + ComplexNameItem cni = (ComplexNameItem) l.get(0); + + assertEquals("fred", cni.getComplexAttributeName()); + } + public void testExtraAttributeNames() throws Exception { interceptLogging(); @@ -92,6 +126,33 @@ assertEquals("lamb", d.getName()); assertEquals(95, d.getCount()); + + ServiceImplementationFactory builderFactory = + (ServiceImplementationFactory) r.getService( + "hivemind.BuilderFactory", + ServiceImplementationFactory.class); + + assertSame(builderFactory, d.getFactory()); + } + + public void testDuplicateAttribute() throws Exception + { + interceptLogging(); + + Registry r = buildFrameworkRegistry("DuplicateAttribute.xml"); + + assertLoggedMessagePattern( + "Mapping for attribute item-name \\(at .*\\) conflicts with a previous " + + "mapping \\(at .*\\) and has been ignored\\."); + + List l = r.getConfiguration("hivemind.test.config.DuplicateAttribute"); + + assertEquals(1, l.size()); + + DataItem d = (DataItem) l.get(0); + + assertEquals("wesley", d.getName()); + assertEquals(15, d.getCount()); ServiceImplementationFactory builderFactory = (ServiceImplementationFactory) r.getService( 1.1 jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/config/DuplicateAttribute.xml Index: DuplicateAttribute.xml =================================================================== <?xml version="1.0"?> <!-- $Id: DuplicateAttribute.xml,v 1.1 2004/03/01 22:56:27 hlship Exp $ --> <module id="hivemind.test.config" version="1.0.0"> <configuration-point id="DuplicateAttribute"> <schema> <element name="data-item"> <attribute name="item-name" required="true"/> <attribute name="count"/> <attribute name="service-id"/> <conversion class="hivemind.test.config.DataItem"> <map attribute="item-name" property="name"/> <map attribute="service-id" property="factory" translator="service"/> <map attribute="item-name" property="fred"/> </conversion> </element> </schema> </configuration-point> <contribution configuration-id="DuplicateAttribute"> <data-item item-name="wesley" count="15" service-id="hivemind.BuilderFactory"/> </contribution> </module> 1.1 jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/config/ComplexAttributeName.xml Index: ComplexAttributeName.xml =================================================================== <?xml version="1.0"?> <!-- $Id: ComplexAttributeName.xml,v 1.1 2004/03/01 22:56:27 hlship Exp $ --> <module id="hivemind.test.config" version="1.0.0"> <configuration-point id="ComplexAttributeName"> <schema> <element name="data-item"> <attribute name="complex-attribute-name" required="true"/> <conversion class="hivemind.test.config.ComplexNameItem"/> </element> </schema> </configuration-point> <contribution configuration-id="ComplexAttributeName"> <data-item complex-attribute-name="fred"/> </contribution> </module> 1.1 jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/config/ConversionParentMethod.xml Index: ConversionParentMethod.xml =================================================================== <?xml version="1.0"?> <!-- $Id: ConversionParentMethod.xml,v 1.1 2004/03/01 22:56:27 hlship Exp $ --> <module id="hivemind.test.config" version="1.0.0"> <configuration-point id="ConversionParentMethod"> <schema> <element name="data-item"> <attribute name="item-name" required="true"/> <attribute name="count"/> <attribute name="service-id"/> <conversion class="hivemind.test.config.DataItem" parent-method="addElement"> <map attribute="item-name" property="name"/> <map attribute="service-id" property="factory" translator="service"/> </conversion> </element> </schema> </configuration-point> <contribution configuration-id="ConversionParentMethod"> <data-item item-name="builder" count="5" service-id="hivemind.BuilderFactory"/> </contribution> </module> 1.1 jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/config/ComplexNameItem.java Index: ComplexNameItem.java =================================================================== package hivemind.test.config; import org.apache.hivemind.impl.BaseLocatable; public class ComplexNameItem extends BaseLocatable { private String _complexAttributeName; public String getComplexAttributeName() { return _complexAttributeName; } public void setComplexAttributeName(String string) { _complexAttributeName = string; } } 1.2 +46 -3 jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/hivemind/parse/ConversionDescriptor.java Index: ConversionDescriptor.java =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/hivemind/parse/ConversionDescriptor.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ConversionDescriptor.java 1 Mar 2004 01:08:02 -0000 1.1 +++ ConversionDescriptor.java 1 Mar 2004 22:56:27 -0000 1.2 @@ -58,6 +58,12 @@ setLocation(location); } + /** + * Adds a mapping for an attribute; these come from <map> + * elements nested within the <conversion> element. A check + * for duplicate attribute mappings (that is, duplicated attribute name), + * and an error is logged (and the duplicate ignored). + */ public void addAttributeMapping(AttributeMappingDescriptor descriptor) { String attributeName = descriptor.getAttributeName(); @@ -90,6 +96,11 @@ _parentMethodName = string; } + /** + * Invoked once all <map> elements have been processed; this creates + * [EMAIL PROTECTED] org.apache.hivemind.schema.Rule}s that are added + * to the [EMAIL PROTECTED] ElementModelImpl}. + */ public void addRulesForModel() { _elementModel.addRule(new CreateObjectRule(_className)); @@ -116,7 +127,7 @@ _elementModel.addRule( new ReadAttributeRule( attributeName, - attributeName, + constructPropertyName(attributeName), _defaultTranslator, getLocation())); } @@ -124,7 +135,7 @@ { String propertyName = amd.getPropertyName(); if (propertyName == null) - propertyName = attributeName; + propertyName = constructPropertyName(attributeName); _elementModel.addRule( new ReadAttributeRule( @@ -146,4 +157,36 @@ getLocation())); } + private String constructPropertyName(String attributeName) + { + int dashx = attributeName.indexOf('-'); + if (dashx < 0) + return attributeName; + + int length = attributeName.length(); + StringBuffer buffer = new StringBuffer(length); + + buffer.append(attributeName.substring(0, dashx)); + boolean toUpper = true; + + for (int i = dashx + 1; i < length; i++) + { + char ch = attributeName.charAt(i); + + if (ch == '-') + { + toUpper = true; + continue; + } + + if (toUpper) + ch = Character.toUpperCase(ch); + + buffer.append(ch); + + toUpper = false; + } + + return buffer.toString(); + } } 1.4 +87 -1 jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/hivemind/parse/DescriptorParser.java Index: DescriptorParser.java =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/hivemind/parse/DescriptorParser.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- DescriptorParser.java 29 Feb 2004 20:57:09 -0000 1.3 +++ DescriptorParser.java 1 Mar 2004 22:56:27 -0000 1.4 @@ -176,6 +176,13 @@ private static final int STATE_COLLECT_SERVICE_PARAMETERS = 12; /** + * Used with the <conversion> element (an alternative to + * using <rules>. Finds <map> elements. + */ + + public static final int STATE_CONVERSION = 13; + + /** * Represents building Element hierarchy as a light-wieght DOM. */ @@ -313,6 +320,20 @@ CUSTOM_ATTRIBUTES.put("class", Boolean.TRUE); } + private final Map CONVERSION_ATTRIBUTES = new HashMap(); + { + CONVERSION_ATTRIBUTES.put("class", Boolean.TRUE); + CONVERSION_ATTRIBUTES.put("parent-method", Boolean.FALSE); + } + + private final Map MAP_ATTRIBUTES = new HashMap(); + + { + MAP_ATTRIBUTES.put("attribute", Boolean.TRUE); + MAP_ATTRIBUTES.put("property", Boolean.FALSE); + MAP_ATTRIBUTES.put("translator", Boolean.FALSE); + } + private final Map OCCURS_MAP = new HashMap(); { @@ -798,6 +819,11 @@ beginCollectServiceParameters(qName); break; + case STATE_CONVERSION : + + beginConversion(qName); + break; + default : unexpectedElement(qName); @@ -816,6 +842,11 @@ endLWDom(); break; + case STATE_CONVERSION : + + endConversion(); + break; + default : break; } @@ -1208,6 +1239,25 @@ return; } + if (elementName.equals("conversion")) + { + ConversionDescriptor cd = + new ConversionDescriptor(elementModel, getTranslator("smart"), getLocation()); + + push(elementName, cd, STATE_CONVERSION); + + checkAttributes(CONVERSION_ATTRIBUTES); + + cd.setClassName(getAttribute("class")); + + String methodName = getAttribute("parent-method"); + + if (methodName != null) + cd.setParentMethodName(methodName); + + return; + } + if (elementName.equals("rules")) { push(elementName, elementModel, STATE_RULES); @@ -1223,6 +1273,42 @@ } unexpectedElement(elementName); + } + + private void beginConversion(String elementName) + { + if (elementName.equals("map")) + { + ConversionDescriptor cd = (ConversionDescriptor) peekObject(); + + AttributeMappingDescriptor amd = new AttributeMappingDescriptor(); + + push(elementName, amd, STATE_NO_CONTENT); + + checkAttributes(MAP_ATTRIBUTES); + + amd.setAttributeName(getAttribute("attribute")); + amd.setPropertyName(getAttribute("property")); + + String translator = getAttribute("translator"); + if (translator == null) + translator = "smart"; + + amd.setTranslator(getTranslator(translator)); + + cd.addAttributeMapping(amd); + + return; + } + + unexpectedElement(elementName); + } + + private void endConversion() + { + ConversionDescriptor cd = (ConversionDescriptor) peekObject(); + + cd.addRulesForModel(); } private void beginRules(String elementName) 1.3 +10 -1 jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/hivemind/schema/rules/CreateObjectRule.java Index: CreateObjectRule.java =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/hivemind/schema/rules/CreateObjectRule.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- CreateObjectRule.java 29 Feb 2004 20:57:08 -0000 1.2 +++ CreateObjectRule.java 1 Mar 2004 22:56:27 -0000 1.3 @@ -33,6 +33,15 @@ { private String _className; + public CreateObjectRule() + { + } + + public CreateObjectRule(String className) + { + _className = className; + } + /** * Creates the new object and pushes it onto the processor's stack. If the * object implement [EMAIL PROTECTED] LocationHolder} then 1.5 +2 -2 jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/hivemind/HiveMindMessages.properties Index: HiveMindMessages.properties =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/hivemind/HiveMindMessages.properties,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- HiveMindMessages.properties 1 Mar 2004 01:08:03 -0000 1.4 +++ HiveMindMessages.properties 1 Mar 2004 22:56:27 -0000 1.5 @@ -62,7 +62,7 @@ DescriptorParser.invalid-id-format=Attribute {0} ({1}) of element {2} (at {3}) is not a valid id. DescriptorParser.unable-to-resolve-schema=Unable to resolve reference to schema ''{0}'' at {1}. -ConversionDescriptor.dupe-attribute-mapping=Mapping for attribute {0} (at {1}) conflicts with a previous mapping (at {2}) as has been ignored. +ConversionDescriptor.dupe-attribute-mapping=Mapping for attribute {0} (at {1}) conflicts with a previous mapping (at {2}) and has been ignored. ConversionDescriptor.extra-mappings=Mappings for unknown attribute(s) {0} (for element {1} at {2}) have been ignored. ExternalParser.missing-resource=Unable to locate {0}. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]