From: Erik Brakkee Date: Tue, 9 Aug 2011 15:23:15 +0000 (+0200) Subject: id prefixes are now done at the very last moment instead of when an item is added. X-Git-Tag: PAX_EXAM_MOCKITO_ISSUE~8 X-Git-Url: http://wamblee.org/gitweb/?a=commitdiff_plain;h=5582d07a1ba9821cc789ea63b71f246e89d13cae;p=xmlrouter id prefixes are now done at the very last moment instead of when an item is added. This provides more logical behavior in the api becuase the ids are not modified. --- diff --git a/config/src/main/java/org/wamblee/xmlrouter/config/Config.java b/config/src/main/java/org/wamblee/xmlrouter/config/Config.java index baa4c8b..aa5c540 100644 --- a/config/src/main/java/org/wamblee/xmlrouter/config/Config.java +++ b/config/src/main/java/org/wamblee/xmlrouter/config/Config.java @@ -29,6 +29,12 @@ import org.wamblee.xmlrouter.common.Id; * Type for which ids are generated. */ public interface Config extends Identifiable { + + /** + * @return The type of contained object. + */ + Class getType(); + /** * Adds an item. No item with the same id may exist. * diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeConfig.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeConfig.java index c9e250e..0c6100d 100644 --- a/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeConfig.java +++ b/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeConfig.java @@ -39,16 +39,24 @@ public class CompositeConfig> implements private static final Id ID = new Id("compositeconfig"); private static final String READ_ONLY_INSTANCE = "read only instance"; + + private Class type; private Set> ids; private List> valueIds; private List values; - public CompositeConfig() { + public CompositeConfig(Class aType) { + type = aType; ids = new HashSet>(); valueIds = new ArrayList>(); values = new ArrayList(); } + @Override + public Class getType() { + return type; + } + @Override public Id getId() { return ID; @@ -60,17 +68,22 @@ public class CompositeConfig> implements throw new ConfigException("duplicate id '" + aConfig.getId().toString() + "'"); } + String prefix = aConfig.getId().getId() + "."; for (T item : aConfig.values()) { - if (valueIds.contains(item.getId())) { + Id newId = new Id(prefix + item.getId()); + if (valueIds.contains(newId)) { throw new ConfigException("duplicate id '" + item.getId().toString() + "'"); } } ids.add(aConfig.getId()); + for (T item : aConfig.values()) { - valueIds.add(item.getId()); - values.add(item); + Id newId = new Id(prefix + item.getId()); + valueIds.add(newId); + values.add(IdentifiablePrefixProxyFactory.getProxy(prefix, item, + Identifiable.class, aConfig.getType())); } } diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeRouterConfig.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeRouterConfig.java index eabbf3e..fa01c06 100644 --- a/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeRouterConfig.java +++ b/impl/src/main/java/org/wamblee/xmlrouter/impl/CompositeRouterConfig.java @@ -34,9 +34,10 @@ public class CompositeRouterConfig implements ExtendedRouterConfig { public CompositeRouterConfig(Id aId, Collection aConfigs) { - documentTypes = new CompositeConfig(); - transformations = new CompositeConfig(); - filters = new CompositeConfig(); + documentTypes = new CompositeConfig(DocumentType.class); + transformations = new CompositeConfig( + Transformation.class); + filters = new CompositeConfig(Filter.class); for (RouterConfig config : aConfigs) { documentTypes.addConfig(config.documentTypeConfig()); transformations.addConfig(config.transformationConfig()); diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/ConfigImpl.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/ConfigImpl.java index 8088be3..0e1da0b 100644 --- a/impl/src/main/java/org/wamblee/xmlrouter/impl/ConfigImpl.java +++ b/impl/src/main/java/org/wamblee/xmlrouter/impl/ConfigImpl.java @@ -37,18 +37,26 @@ import org.wamblee.xmlrouter.config.Identifiable; public abstract class ConfigImpl> implements ExtendedConfig { + private Class type; private Id id; private Map, T> registered; /** * Constructs the object. */ - public ConfigImpl(Id aId) { + public ConfigImpl(Class aType, Id aId) { + notNull("type", aType); notNull("id", aId); + type = aType; id = aId; registered = new HashMap, T>(); } + @Override + public Class getType() { + return type; + } + /** * Copies the config object. * diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/IdentifiablePrefixProxyFactory.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/IdentifiablePrefixProxyFactory.java new file mode 100644 index 0000000..c787c7b --- /dev/null +++ b/impl/src/main/java/org/wamblee/xmlrouter/impl/IdentifiablePrefixProxyFactory.java @@ -0,0 +1,83 @@ +/* + * Copyright 2005-2011 the original author or authors. + * + * 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.wamblee.xmlrouter.impl; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import org.wamblee.xmlrouter.common.Id; +import org.wamblee.xmlrouter.config.Identifiable; + +/** + * This proxy factory creates proxies for identifiable objects that add a prefix + * to the ids. + * + * @author Erik Brakkee + * + * @param + */ +public class IdentifiablePrefixProxyFactory { + + public static final class IdPrefixInvocationHandler implements + InvocationHandler { + + private String prefix; + private T service; + + public IdPrefixInvocationHandler(String aPrefix, T aService) { + prefix = aPrefix; + service = aService; + } + + @Override + public Object invoke(Object aProxy, final Method aMethod, + final Object[] aArgs) throws Throwable { + try { + if (aMethod.getDeclaringClass().equals(Identifiable.class)) { + if (!aMethod.getName().equals("getId")) { + throw new RuntimeException( + "Programming error, Identifiable interface was modified"); + } + Id id = (Id) aMethod.invoke(service, aArgs); + return new Id(prefix + id.getId()); + } + return aMethod.invoke(service, aArgs); + } catch (InvocationTargetException e) { + throw e.getCause(); + } + } + } + + public static T getProxy(String aPrefix, T aService, + Class... aInterfaces) { + InvocationHandler handler = new IdPrefixInvocationHandler(aPrefix, + aService); + Class proxyClass = Proxy.getProxyClass(aService.getClass() + .getClassLoader(), aInterfaces); + T proxy; + try { + proxy = (T) proxyClass.getConstructor( + new Class[] { InvocationHandler.class }).newInstance( + new Object[] { handler }); + return proxy; + } catch (Exception e) { + throw new RuntimeException("Could not create proxy for " + + aService.getClass().getName(), e); + } + } +} diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/SingleRouterConfig.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/SingleRouterConfig.java index deb38f6..4ecaad4 100644 --- a/impl/src/main/java/org/wamblee/xmlrouter/impl/SingleRouterConfig.java +++ b/impl/src/main/java/org/wamblee/xmlrouter/impl/SingleRouterConfig.java @@ -34,7 +34,7 @@ public class SingleRouterConfig implements ExtendedRouterConfig { public static final class DocumentConfig extends ConfigImpl { public DocumentConfig(Id aId) { - super(aId); + super(DocumentType.class, aId); } public DocumentConfig(DocumentConfig aConfig) { @@ -43,14 +43,14 @@ public class SingleRouterConfig implements ExtendedRouterConfig { @Override public DocumentType wrap(String aPrefix, DocumentType aT) { - return new RobustDocumentType(aPrefix, aT); + return new RobustDocumentType("", aT); } } public static final class TransformationConfig extends ConfigImpl { public TransformationConfig(Id aId) { - super(aId); + super(Transformation.class, aId); } public TransformationConfig(TransformationConfig aConfig) { @@ -60,13 +60,13 @@ public class SingleRouterConfig implements ExtendedRouterConfig { @Override public Transformation wrap(String aPrefix, Transformation aTransformation) { - return new RobustTransformation(aPrefix, aTransformation); + return new RobustTransformation("", aTransformation); } } public static final class FilterConfig extends ConfigImpl { public FilterConfig(Id aId) { - super(aId); + super(Filter.class, aId); } public FilterConfig(FilterConfig aConfig) { @@ -75,7 +75,7 @@ public class SingleRouterConfig implements ExtendedRouterConfig { @Override public Filter wrap(String aPrefix, Filter aFilter) { - return new RobustFilter(aPrefix, aFilter); + return new RobustFilter("", aFilter); } } diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouterConfigService.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouterConfigService.java index ff8c6de..da883d2 100644 --- a/impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouterConfigService.java +++ b/impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouterConfigService.java @@ -44,8 +44,8 @@ public class XMLRouterConfigService implements RouterConfigService { application = aApplication; sequence = new AtomicLong(1L); config = aConfig; - routerConfigs = new ConfigImpl(new Id( - aApplication)) { + routerConfigs = new ConfigImpl(RouterConfig.class, + new Id(aApplication)) { public RouterConfig wrap(final String aPrefix, final RouterConfig aT) { return new RouterConfig() { @Override diff --git a/impl/src/test/java/org/wamblee/xmlrouter/impl/CompositeConfigTest.java b/impl/src/test/java/org/wamblee/xmlrouter/impl/CompositeConfigTest.java index 9905046..cd0879d 100644 --- a/impl/src/test/java/org/wamblee/xmlrouter/impl/CompositeConfigTest.java +++ b/impl/src/test/java/org/wamblee/xmlrouter/impl/CompositeConfigTest.java @@ -17,6 +17,7 @@ package org.wamblee.xmlrouter.impl; import static junit.framework.Assert.*; +import java.util.ArrayList; import java.util.List; import org.junit.Test; @@ -27,22 +28,31 @@ import org.wamblee.xmlrouter.config.Identifiable; public class CompositeConfigTest { - public static class IntClass implements Identifiable { + public static interface StringClassInterface extends + Identifiable { - private int value; + } + + public static class StringClass implements StringClassInterface { - public IntClass(int aValue) { + private String value; + + public StringClass(String aValue) { value = aValue; } + public StringClass(int aValue) { + this(aValue + ""); + } + @Override - public Id getId() { - return new Id(value + ""); + public Id getId() { + return new Id(value + ""); } @Override public int hashCode() { - return ((Integer) value).hashCode(); + return value.hashCode(); } @Override @@ -50,50 +60,52 @@ public class CompositeConfigTest { if (aObj == null) { return false; } - if (!(aObj instanceof IntClass)) { + if (!(aObj instanceof StringClass)) { return false; } - IntClass obj = (IntClass) aObj; - return value == obj.value; + StringClass obj = (StringClass) aObj; + return value.equals(obj.value); } } @Test public void testEmptyConfig() { - Config composite = composite(); + Config composite = composite(); assertTrue(composite.values().isEmpty()); } @Test(expected = RuntimeException.class) public void testAddNotAllowed() { - composite().add(new IntClass(10)); + composite().add(new StringClass(10)); } @Test(expected = RuntimeException.class) public void testRemoveNotAllowed() { - composite().remove(new Id("xxx")); + composite().remove(new Id("xxx")); } @Test public void testAddConfig() { - CompositeConfig composite = composite(); - Config c1 = new ConfigImpl(id("c1")) { + CompositeConfig composite = composite(); + Config c1 = new ConfigImpl( + StringClassInterface.class, id("c1")) { @Override public Identifiable wrap(String aPrefix, Identifiable aT) { return aT; } }; - Config c2 = new ConfigImpl(id("c2")) { + Config c2 = new ConfigImpl( + StringClassInterface.class, id("c2")) { @Override public Identifiable wrap(String aPrefix, Identifiable aT) { return aT; } }; - IntClass i1 = new IntClass(10); - IntClass i2 = new IntClass(20); - IntClass i3 = new IntClass(30); - IntClass i4 = new IntClass(40); + StringClass i1 = new StringClass(10); + StringClass i2 = new StringClass(20); + StringClass i3 = new StringClass(30); + StringClass i4 = new StringClass(40); c1.add(i1); c1.add(i2); @@ -101,30 +113,40 @@ public class CompositeConfigTest { c2.add(i4); composite.addConfig(c1); - List values = composite.values(); - assertEquals(2, values.size()); - assertTrue(values.contains(i1)); - assertTrue(values.contains(i2)); + List values = composite.values(); + List ids = new ArrayList(); + for (StringClassInterface intf : values) { + ids.add(intf.getId().getId()); + } + assertTrue(ids.contains("c1.10")); + assertTrue(ids.contains("c1.20")); composite.addConfig(c2); values = composite.values(); assertEquals(4, values.size()); - assertTrue(values.contains(i1)); - assertTrue(values.contains(i2)); - assertTrue(values.contains(i3)); - assertTrue(values.contains(i4)); + + ids = new ArrayList(); + for (StringClassInterface intf : values) { + ids.add(intf.getId().getId()); + } + assertTrue(ids.contains("c1.10")); + assertTrue(ids.contains("c1.20")); + assertTrue(ids.contains("c2.30")); + assertTrue(ids.contains("c2.40")); } @Test(expected = ConfigException.class) public void testDuplicatesNotAllowed() { - CompositeConfig composite = composite(); - Config c1 = new ConfigImpl(id("c1")) { + CompositeConfig composite = composite(); + Config c1 = new ConfigImpl( + StringClassInterface.class, id("c1")) { @Override public Identifiable wrap(String aPrefix, Identifiable aT) { return aT; } }; - Config c2 = new ConfigImpl(id("c1")) { + Config c2 = new ConfigImpl( + StringClassInterface.class, id("c1")) { @Override public Identifiable wrap(String aPrefix, Identifiable aT) { return aT; @@ -136,22 +158,24 @@ public class CompositeConfigTest { @Test public void testDuplicateItem() { - CompositeConfig composite = composite(); - Config c1 = new ConfigImpl(id("c1")) { + CompositeConfig composite = composite(); + Config c1 = new ConfigImpl( + StringClassInterface.class, id("c.x")) { @Override public Identifiable wrap(String aPrefix, Identifiable aT) { return aT; } }; - Config c2 = new ConfigImpl(id("c2")) { + Config c2 = new ConfigImpl( + StringClassInterface.class, id("c")) { @Override public Identifiable wrap(String aPrefix, Identifiable aT) { return aT; } }; - IntClass i1 = new IntClass(10); - IntClass i2 = new IntClass(10); + StringClass i1 = new StringClass("y"); + StringClass i2 = new StringClass("x.y"); c1.add(i1); c2.add(i2); composite.addConfig(c1); @@ -162,11 +186,13 @@ public class CompositeConfigTest { // ok. } assertEquals(1, composite.values().size()); - assertTrue(composite.values().contains(i1)); + assertEquals("c.x.y", composite.values().iterator().next().getId() + .getId()); } - private CompositeConfig composite() { - return new CompositeConfig(); + private CompositeConfig composite() { + return new CompositeConfig( + StringClassInterface.class); } private Id id(String aId) { diff --git a/impl/src/test/java/org/wamblee/xmlrouter/impl/ConfigImplTest.java b/impl/src/test/java/org/wamblee/xmlrouter/impl/ConfigImplTest.java index aa197ea..8586012 100644 --- a/impl/src/test/java/org/wamblee/xmlrouter/impl/ConfigImplTest.java +++ b/impl/src/test/java/org/wamblee/xmlrouter/impl/ConfigImplTest.java @@ -55,7 +55,7 @@ public class ConfigImplTest { public static final class MyTypeConfig extends ConfigImpl { public MyTypeConfig(Id aId) { - super(aId); + super(MyType.class, aId); } public MyTypeConfig(MyTypeConfig aConfig) { @@ -121,22 +121,11 @@ public class ConfigImplTest { @Test public void testEquals() { - Config config1 = new ConfigImpl(new Id( - CONFIG_TYPE)) { - @Override - public MyType wrap(String aPrefix, MyType aT) { - return new MyTypeWrapper(aPrefix, aT); - } - }; + Config config1 = new MyTypeConfig(new Id(CONFIG_TYPE)); assertFalse(config1.equals(null)); assertFalse(config1.equals("hello")); - Config config2 = new ConfigImpl(new Id( - CONFIG_TYPE)) { - @Override - public MyType wrap(String aPrefix, MyType aT) { - return new MyTypeWrapper(aPrefix, aT); - } - }; + Config config2 = new MyTypeConfig(new Id(CONFIG_TYPE)); + assertEquals(config1, config2); assertEquals(config1.hashCode(), config2.hashCode());