Index: framework/src/java/org/apache/hivemind/impl/SchemaElement.java =================================================================== RCS file: /home/cvspublic/jakarta-hivemind/framework/src/java/org/apache/hivemind/impl/SchemaElement.java,v retrieving revision 1.7 diff -u -r1.7 SchemaElement.java --- framework/src/java/org/apache/hivemind/impl/SchemaElement.java 6 Jan 2005 01:45:12 -0000 1.7 +++ framework/src/java/org/apache/hivemind/impl/SchemaElement.java 16 Mar 2005 21:35:57 -0000 @@ -22,6 +22,8 @@ import java.util.Map; import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.hivemind.ApplicationRuntimeException; import org.apache.hivemind.Attribute; import org.apache.hivemind.Element; @@ -41,6 +43,8 @@ */ final class SchemaElement { + private static final Log LOG = LogFactory.getLog(SchemaElement.class); + private SchemaProcessor _processor; private ElementModel _model; @@ -147,11 +151,17 @@ { Attribute a = (Attribute) l.get(i); String name = a.getName(); - + if (!_knownAttributes.contains(name)) errors.add(ImplMessages.unknownAttribute(name)); - checkUniquness(name, a.getValue(), element.getLocation(), errors); + Translator translator = getAttributeTranslator(name); + + // translate value of attribute + Object translatedValue = translator.translate(_processor.getContributingModule(), + Object.class, a.getValue(), element.getLocation()); + + checkUniqueness(name, translatedValue, element.getLocation(), errors); required.remove(name); } @@ -181,11 +191,12 @@ // TODO: refactor to use the ErrorHandler rather than throw an exception // (these errors are somewhat recoverable). + //_processor.getContributingModule().getErrorHandler().error(LOG, buffer.toString(), element.getLocation(), null); throw new ApplicationRuntimeException(buffer.toString(), element.getLocation(), null); } - private void checkUniquness(String name, String value, Location location, List errors) + private void checkUniqueness(String name, Object value, Location location, List errors) { Map valuesMap = (Map) _attributeValues.get(name); @@ -204,7 +215,7 @@ // A conflict. - errors.add(ImplMessages.uniqueAttributeConstraintBroken(name, value, prior)); + errors.add(ImplMessages.uniqueAttributeConstraintBroken(name, value.toString(), prior)); } void fireBegin(Element element) Index: framework/src/test/org/apache/hivemind/impl/TestSchemaProcessor.java =================================================================== RCS file: /home/cvspublic/jakarta-hivemind/framework/src/test/org/apache/hivemind/impl/TestSchemaProcessor.java,v retrieving revision 1.12 diff -u -r1.12 TestSchemaProcessor.java --- framework/src/test/org/apache/hivemind/impl/TestSchemaProcessor.java 10 Feb 2005 01:04:32 -0000 1.12 +++ framework/src/test/org/apache/hivemind/impl/TestSchemaProcessor.java 16 Mar 2005 21:36:02 -0000 @@ -18,9 +18,13 @@ import hivemind.test.services.impl.StringHolderImpl; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import org.apache.hivemind.Location; import org.apache.hivemind.internal.Module; import org.apache.hivemind.schema.SchemaProcessor; import org.apache.hivemind.schema.Translator; @@ -33,6 +37,7 @@ import org.apache.hivemind.schema.rules.ReadAttributeRule; import org.apache.hivemind.schema.rules.ReadContentRule; import org.apache.hivemind.test.HiveMindTestCase; +import org.apache.hivemind.util.URLResource; import org.easymock.MockControl; /** @@ -185,6 +190,9 @@ List elements = Collections.singletonList(element); + m.getTranslator("service"); + control.setReturnValue(new NullTranslator()); + m.resolveType("hivemind.test.services.impl.StringHolderImpl"); control.setReturnValue(StringHolderImpl.class); @@ -279,6 +287,9 @@ List elements = Collections.singletonList(element); + m.getTranslator("cartoon"); + control.setReturnValue(new NullTranslator()); + m.resolveType("StringHolderImpl"); control.setReturnValue(StringHolderImpl.class); @@ -312,4 +323,133 @@ verifyControls(); } + /** + * Test contributing 2 elements from 2 modules + * to a configuration-point with an attribute + * that is marked unique and is trnaslated + * by translator 'qualified-id' + * + * Both contributed elements use same local + * value in the unique attribute. + * + */ + public void testUniqueElement() + { + ElementModelImpl em = new ElementModelImpl(); + + em.setElementName("cartoon"); + + AttributeModelImpl am = new AttributeModelImpl(); + am.setName("name"); + am.setTranslator("qualified-id"); + am.setUnique(true); + + em.addAttributeModel(am); + + em.addRule(new CreateObjectRule("StringHolderImpl")); + + ReadAttributeRule rule = new ReadAttributeRule(); + rule.setAttributeName("name"); + rule.setPropertyName("value"); + + em.addRule(rule); + + em.addRule(new InvokeParentRule("addElement")); + + SchemaImpl schema = new SchemaImpl(); + schema.addElementModel(em); + + MockControl control1 = newControl(Module.class); + Module m1 = (Module) control1.getMock(); + + MockControl control2 = newControl(Module.class); + Module m2 = (Module) control2.getMock(); + + schema.setModule(m1); + + SchemaProcessorImpl p = new SchemaProcessorImpl(null, schema); + + Location location1 = new LocationImpl(new URLResource("www.flintstone1.com")); + ElementImpl element1 = new ElementImpl(); + element1.setElementName("cartoon"); + element1.addAttribute(new AttributeImpl("name", "flintstone")); + element1.setLocation(location1); + + List elements1 = Collections.singletonList(element1); + + Location location2 = new LocationImpl(new URLResource("www.flintstone2.com")); + ElementImpl element2 = new ElementImpl(); + element2.setElementName("cartoon"); + element2.addAttribute(new AttributeImpl("name", "flintstone")); + element2.setLocation(location2); + + List elements2 = Collections.singletonList(element2); + + MockControl tControl1 = newControl(Translator.class); + Translator t1 = (Translator) tControl1.getMock(); + + m1.getTranslator("qualified-id"); + control1.setReturnValue(t1); + + String flintstoneKeyModule1 = "m1.flintstone"; + t1.translate(m1, Object.class, "flintstone", element1.getLocation()); + tControl1.setReturnValue(flintstoneKeyModule1); + + m1.resolveType("StringHolderImpl"); + control1.setReturnValue(StringHolderImpl.class); + + m1.expandSymbols("flintstone", location1); + control1.setReturnValue("flintstone"); + + m1.getTranslator("qualified-id"); + control1.setReturnValue(t1); + + t1.translate(m1, String.class, "flintstone", element1.getLocation()); + tControl1.setReturnValue(flintstoneKeyModule1); + + m1.resolveType("StringHolderImpl"); + control1.setReturnValue(StringHolderImpl.class); + + MockControl tControl2 = newControl(Translator.class); + Translator t2 = (Translator) tControl2.getMock(); + + m2.getTranslator("qualified-id"); + control2.setReturnValue(t2); + + String flintstoneKeyModule2 = "m2.flintstone"; + t2.translate(m2, Object.class, "flintstone", element2.getLocation()); + tControl2.setReturnValue(flintstoneKeyModule2); + + m2.expandSymbols("flintstone", location2); + control2.setReturnValue("flintstone"); + + m2.getTranslator("qualified-id"); + control2.setReturnValue(t2); + + t2.translate(m2, String.class, "flintstone", element2.getLocation()); + tControl2.setReturnValue(flintstoneKeyModule2); + + replayControls(); + + p.process(elements1, m1); + p.process(elements2, m2); + + List list = p.getElements(); + + assertEquals(2, list.size()); + + + Set keys = new TreeSet(); + for (Iterator iter = list.iterator(); iter.hasNext();) + { + StringHolderImpl element = (StringHolderImpl) iter.next(); + keys.add(element.getValue()); + } + + assertTrue(keys.contains(flintstoneKeyModule1)); + assertTrue(keys.contains(flintstoneKeyModule2)); + + verifyControls(); + } + } \ No newline at end of file Index: framework/src/test/org/apache/hivemind/impl/TestSchemaProcessorShowBug.java =================================================================== RCS file: framework/src/test/org/apache/hivemind/impl/TestSchemaProcessorShowBug.java diff -N framework/src/test/org/apache/hivemind/impl/TestSchemaProcessorShowBug.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ framework/src/test/org/apache/hivemind/impl/TestSchemaProcessorShowBug.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,164 @@ +// Copyright 2004, 2005 The Apache Software Foundation +// +// Licensed 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.hivemind.impl; + +import hivemind.test.services.impl.StringHolderImpl; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.hivemind.Location; +import org.apache.hivemind.internal.Module; +import org.apache.hivemind.schema.Translator; +import org.apache.hivemind.schema.impl.AttributeModelImpl; +import org.apache.hivemind.schema.impl.ElementModelImpl; +import org.apache.hivemind.schema.impl.SchemaImpl; +import org.apache.hivemind.schema.rules.CreateObjectRule; +import org.apache.hivemind.schema.rules.InvokeParentRule; +import org.apache.hivemind.schema.rules.ReadAttributeRule; +import org.apache.hivemind.test.HiveMindTestCase; +import org.apache.hivemind.util.URLResource; +import org.easymock.MockControl; + +/** + * Tests for {@link org.apache.hivemind.schema.SchemaProcessor}and + * {@link org.apache.hivemind.impl.SchemaElement}. + * + * @author Howard Lewis Ship + */ +public class TestSchemaProcessorShowBug extends HiveMindTestCase +{ + + /** + * Test contributing 2 elements from 2 modules + * to a configuration-point with an attribute + * that is marked unique and is trnaslated + * by translator 'qualified-id' + * + * Both contributed elements use same local + * value in the unique attribute. + */ + public void testUniqueElementOld() + { + ElementModelImpl em = new ElementModelImpl(); + + em.setElementName("cartoon"); + + AttributeModelImpl am = new AttributeModelImpl(); + am.setName("name"); + am.setTranslator("qualified-id"); + am.setUnique(true); + + em.addAttributeModel(am); + + em.addRule(new CreateObjectRule("StringHolderImpl")); + + ReadAttributeRule rule = new ReadAttributeRule(); + rule.setAttributeName("name"); + rule.setPropertyName("value"); + + em.addRule(rule); + + em.addRule(new InvokeParentRule("addElement")); + + SchemaImpl schema = new SchemaImpl(); + schema.addElementModel(em); + + MockControl control1 = newControl(Module.class); + Module m1 = (Module) control1.getMock(); + + MockControl control2 = newControl(Module.class); + Module m2 = (Module) control2.getMock(); + + schema.setModule(m1); + + SchemaProcessorImpl p = new SchemaProcessorImpl(null, schema); + + Location location1 = new LocationImpl(new URLResource("www.flintstone1.com")); + ElementImpl element1 = new ElementImpl(); + element1.setElementName("cartoon"); + element1.addAttribute(new AttributeImpl("name", "flintstone")); + element1.setLocation(location1); + + List elements1 = Collections.singletonList(element1); + + Location location2 = new LocationImpl(new URLResource("www.flintstone2.com")); + ElementImpl element2 = new ElementImpl(); + element2.setElementName("cartoon"); + element2.addAttribute(new AttributeImpl("name", "flintstone")); + element2.setLocation(location2); + + List elements2 = Collections.singletonList(element2); + + m1.resolveType("StringHolderImpl"); + control1.setReturnValue(StringHolderImpl.class); + + m1.expandSymbols("flintstone", location1); + control1.setReturnValue("flintstone"); + + MockControl tControl1 = newControl(Translator.class); + Translator t1 = (Translator) tControl1.getMock(); + + m1.getTranslator("qualified-id"); + control1.setReturnValue(t1); + + String flintstoneKeyModule1 = "m1.flintstone"; + t1.translate(m1, String.class, "flintstone", element1.getLocation()); + tControl1.setReturnValue(flintstoneKeyModule1); + + m2.resolveType("StringHolderImpl"); + control2.setReturnValue(StringHolderImpl.class); + + m2.expandSymbols("flintstone", location2); + control2.setReturnValue("flintstone"); + + MockControl tControl2 = newControl(Translator.class); + Translator t2 = (Translator) tControl2.getMock(); + + m2.getTranslator("qualified-id"); + control2.setReturnValue(t2); + + + String flintstoneKeyModule2 = "m2.flintstone"; + t2.translate(m2, String.class, "flintstone", element2.getLocation()); + tControl2.setReturnValue(flintstoneKeyModule2); + + replayControls(); + + p.process(elements1, m1); + p.process(elements2, m2); + + List list = p.getElements(); + + assertEquals(2, list.size()); + + + Set keys = new TreeSet(); + for (Iterator iter = list.iterator(); iter.hasNext();) + { + StringHolderImpl element = (StringHolderImpl) iter.next(); + keys.add(element.getValue()); + } + + assertTrue(keys.contains(flintstoneKeyModule1)); + assertTrue(keys.contains(flintstoneKeyModule2)); + + verifyControls(); + } + +}