equality based on the ids of the contents of SingleRouterConfig.
authorErik Brakkee <erik@brakkee.org>
Mon, 8 Aug 2011 22:09:24 +0000 (00:09 +0200)
committerErik Brakkee <erik@brakkee.org>
Mon, 8 Aug 2011 22:09:24 +0000 (00:09 +0200)
config/src/main/java/org/wamblee/xmlrouter/config/Config.java
impl/src/main/java/org/wamblee/xmlrouter/impl/ConfigImpl.java
impl/src/main/java/org/wamblee/xmlrouter/impl/RobustIdentifiable.java
impl/src/main/java/org/wamblee/xmlrouter/impl/SingleRouterConfig.java
impl/src/test/java/org/wamblee/xmlrouter/impl/ConfigImplTest.java
impl/src/test/java/org/wamblee/xmlrouter/impl/SingleRouterConfigTest.java
impl/src/test/java/org/wamblee/xmlrouter/impl/XMLRouterConfigServiceTest.java
impl/src/test/java/org/wamblee/xmlrouter/impl/XMLRouterTest.java

index 17c0c4123255acb198018268dcaee089d4378c46..baa4c8b4d72d0f6d2c38bba418ba7f354882721c 100644 (file)
@@ -15,7 +15,7 @@
  */
 package org.wamblee.xmlrouter.config;
 
-import java.util.List;
+import java.util.Collection;
 
 import org.wamblee.xmlrouter.common.Id;
 
@@ -51,5 +51,5 @@ public interface Config<T extends Identifiable> extends Identifiable<Config> {
     /**
      * @return All available items.
      */
-    List<T> values();
+    Collection<T> values();
 }
\ No newline at end of file
index 980bd07601277b1c52b1580df5e44a8a2a7f135c..a1733ab41bf84a9b84cb3986f460586871bd763e 100644 (file)
@@ -17,13 +17,14 @@ package org.wamblee.xmlrouter.impl;
 
 import static org.wamblee.xmlrouter.impl.MessageUtil.*;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.wamblee.xmlrouter.common.Id;
 import org.wamblee.xmlrouter.config.Config;
+import org.wamblee.xmlrouter.config.ConfigException;
 import org.wamblee.xmlrouter.config.Identifiable;
 
 /**
@@ -37,7 +38,7 @@ public abstract class ConfigImpl<T extends Identifiable<T>> implements
     ExtendedConfig<T> {
 
     private Id<Config> id;
-    private List<T> registered;
+    private Map<Id<T>, T> registered;
 
     /**
      * Constructs the object.
@@ -45,7 +46,7 @@ public abstract class ConfigImpl<T extends Identifiable<T>> implements
     public ConfigImpl(Id<Config> aId) {
         notNull("id", aId);
         id = aId;
-        registered = new ArrayList<T>();
+        registered = new HashMap<Id<T>, T>();
     }
 
     @Override
@@ -61,7 +62,10 @@ public abstract class ConfigImpl<T extends Identifiable<T>> implements
     @Override
     public synchronized void add(T aT) {
         notNull("aT", aT);
-        registered.add(wrap(id.getId() + ".", aT));
+        if (registered.containsKey(aT.getId())) {
+            throw new ConfigException("Duplicate id '" + aT.getId() + "'");
+        }
+        registered.put(aT.getId(), wrap(id.getId() + ".", aT));
     }
 
     /**
@@ -83,19 +87,33 @@ public abstract class ConfigImpl<T extends Identifiable<T>> implements
     @Override
     public synchronized boolean remove(Id<T> aId) {
         notNull("aId", aId);
-        Iterator<T> i = registered.iterator();
-        while (i.hasNext()) {
-            T t = i.next();
-            if (t.getId().equals(aId)) {
-                i.remove();
-                return true;
-            }
+        T value = registered.get(aId);
+        if (value != null) {
+            registered.remove(aId);
+            return true;
         }
         return false;
     }
 
     @Override
-    public List<T> values() {
-        return Collections.unmodifiableList(registered);
+    public Collection<T> values() {
+        return Collections.unmodifiableCollection(registered.values());
+    }
+
+    @Override
+    public boolean equals(Object aObj) {
+        if (aObj == null) {
+            return false;
+        }
+        if (!(aObj instanceof ConfigImpl)) {
+            return false;
+        }
+        ConfigImpl obj = (ConfigImpl) aObj;
+        return registered.keySet().equals(obj.registered.keySet());
+    }
+
+    @Override
+    public int hashCode() {
+        return registered.keySet().hashCode();
     }
 }
index 4e54fe30acd8c124949b887b62b452b586dc1499..47b000055ea98025606c59d7a55d84daa8dcb1f4 100644 (file)
@@ -55,7 +55,7 @@ public class RobustIdentifiable<T> implements Identifiable<T> {
 
     private void throwConfigException(String aMsg, Exception aException) {
         LOGGER.log(Level.WARNING, aMsg, aException);
-        throw new ConfigException("id is null");
+        throw new ConfigException(aMsg);
     }
 
     @Override
index 40cbcc5116234491680c7a9428f0d3e5201c7017..8eab34b708996198b73c4cbfd271462937ff1119 100644 (file)
@@ -22,7 +22,6 @@ import org.wamblee.xmlrouter.config.Filter;
 import org.wamblee.xmlrouter.config.RouterConfig;
 import org.wamblee.xmlrouter.config.Transformation;
 
-// TODO implement equality based on ids for the single routerconfig. 
 // TODO implement copying of routerconfig. 
 
 /**
@@ -33,6 +32,7 @@ import org.wamblee.xmlrouter.config.Transformation;
  */
 public class SingleRouterConfig implements ExtendedRouterConfig {
     private Id<RouterConfig> id;
+
     private ExtendedConfig<DocumentType> documentTypes;
     private ExtendedConfig<Transformation> transformations;
     private ExtendedConfig<Filter> filters;
@@ -88,4 +88,25 @@ public class SingleRouterConfig implements ExtendedRouterConfig {
     public Config<Filter> filterConfig() {
         return filters;
     }
+
+    @Override
+    public boolean equals(Object aObj) {
+        if (aObj == null) {
+            return false;
+        }
+        if (!(aObj instanceof SingleRouterConfig)) {
+            return false;
+        }
+        SingleRouterConfig obj = (SingleRouterConfig) aObj;
+
+        return documentTypes.equals(obj.documentTypes) &&
+            transformations.equals(obj.transformations) &&
+            filters.equals(obj.filters);
+    }
+
+    @Override
+    public int hashCode() {
+        return documentTypes.hashCode() + transformations.hashCode() +
+            filters.hashCode();
+    }
 }
index 044cb1f32f9240a00da2a2347d7e518ae13015df..8ebdb9f4aa16c2246dc5ff50b494239fab9dc1c8 100644 (file)
@@ -75,10 +75,12 @@ public class ConfigImplTest {
         config.add(type1);
 
         assertEquals(1, config.values().size());
-        assertTrue(config.values().get(0) instanceof MyTypeWrapper);
-        assertSame(type1, ((MyTypeWrapper) config.values().get(0)).getType());
-        assertEquals(CONFIG_TYPE + "." + type1.getId().getId(), config.values()
-            .get(0).getId().getId());
+        MyType firstValue = config.values().iterator().next();
+
+        assertTrue(firstValue instanceof MyTypeWrapper);
+        assertSame(type1, ((MyTypeWrapper) firstValue).getType());
+        assertEquals(CONFIG_TYPE + "." + type1.getId().getId(), firstValue
+            .getId().getId());
 
         // add another one.
         MyType type2 = mock(MyType.class);
@@ -97,7 +99,7 @@ public class ConfigImplTest {
 
         assertEquals(1, config.values().size());
 
-        assertTrue(config.remove(new Id(CONFIG_TYPE + "." + "type1")));
+        assertTrue(config.remove(new Id("type1")));
         assertTrue(config.values().isEmpty());
     }
 
@@ -105,4 +107,43 @@ public class ConfigImplTest {
     public void testUnmodifiable() {
         config.values().add(mock(MyType.class));
     }
+
+    @Test
+    public void testEquals() {
+
+        Config<MyType> config1 = new ConfigImpl<MyType>(new Id<Config>(
+            CONFIG_TYPE)) {
+            @Override
+            public MyType wrap(String aPrefix, MyType aT) {
+                return new MyTypeWrapper(aPrefix, aT);
+            }
+        };
+        assertFalse(config1.equals(null));
+        assertFalse(config1.equals("hello"));
+        Config<MyType> config2 = new ConfigImpl<MyType>(new Id<Config>(
+            CONFIG_TYPE)) {
+            @Override
+            public MyType wrap(String aPrefix, MyType aT) {
+                return new MyTypeWrapper(aPrefix, aT);
+            }
+        };
+        assertEquals(config1, config2);
+        assertEquals(config1.hashCode(), config2.hashCode());
+
+        MyType type1 = mock(MyType.class);
+        when(type1.getId()).thenReturn(new Id("type1"));
+
+        config1.add(type1);
+        assertFalse(config1.equals(config2));
+
+        MyType type2 = mock(MyType.class);
+        when(type2.getId()).thenReturn(new Id("type1"));
+
+        config2.add(type2);
+        assertEquals(config1, config2);
+        assertEquals(config1.hashCode(), config2.hashCode());
+
+        assertTrue(config2.remove(type2.getId()));
+        assertFalse(config1.equals(config2));
+    }
 }
index 6ec16b1b8d5857f7c7eaf9f48eb1a02a0422e586..3df429315aeed8c33bf39eb6ab35078013126807 100644 (file)
@@ -47,7 +47,9 @@ public class SingleRouterConfigTest {
         config.documentTypeConfig().add(type2);
 
         assertEquals(2, config.documentTypeConfig().values().size());
-        assertTrue(config.documentTypeConfig().values().get(0) instanceof RobustDocumentType);
+        Object firstValue = config.documentTypeConfig().values().iterator()
+            .next();
+        assertTrue(firstValue instanceof RobustDocumentType);
     }
 
     @Test
@@ -62,7 +64,9 @@ public class SingleRouterConfigTest {
         config.transformationConfig().add(transformation2);
 
         assertEquals(2, config.transformationConfig().values().size());
-        assertTrue(config.transformationConfig().values().get(0) instanceof RobustTransformation);
+        Object firstValue = config.transformationConfig().values().iterator()
+            .next();
+        assertTrue(firstValue instanceof RobustTransformation);
     }
 
     @Test
@@ -77,6 +81,59 @@ public class SingleRouterConfigTest {
         config.filterConfig().add(filter2);
 
         assertEquals(2, config.filterConfig().values().size());
-        assertTrue(config.filterConfig().values().get(0) instanceof RobustFilter);
+        Object firstValue = config.filterConfig().values().iterator().next();
+        assertTrue(firstValue instanceof RobustFilter);
+    }
+
+    @Test
+    public void testEqualityEmptyConfig() {
+        RouterConfig config1 = new SingleRouterConfig(new Id<RouterConfig>(
+            "routerconfig"));
+        RouterConfig config2 = new SingleRouterConfig(new Id<RouterConfig>(
+            "routerconfig"));
+        assertEquals(config1, config2);
+    }
+
+    @Test
+    public void testEqualsNonEmpty() {
+        RouterConfig config1 = new SingleRouterConfig(new Id<RouterConfig>(
+            "routerconfig"));
+
+        assertFalse(config1.equals(null));
+        assertFalse(config.equals("hello"));
+
+        RouterConfig config2 = new SingleRouterConfig(new Id<RouterConfig>(
+            "routerconfig"));
+        DocumentType type1 = mock(DocumentType.class);
+        when(type1.getId()).thenReturn(new Id<DocumentType>("type1"));
+        DocumentType type2 = mock(DocumentType.class);
+        when(type2.getId()).thenReturn(new Id<DocumentType>("type1"));
+        Filter filter1 = mock(Filter.class);
+        when(filter1.getId()).thenReturn(new Id<Filter>("f1"));
+        Filter filter2 = mock(Filter.class);
+        when(filter2.getId()).thenReturn(new Id<Filter>("f1"));
+        Transformation transformation1 = mock(Transformation.class);
+        when(transformation1.getId()).thenReturn(new Id<Transformation>("t1"));
+        Transformation transformation2 = mock(Transformation.class);
+        when(transformation2.getId()).thenReturn(new Id<Transformation>("t1"));
+
+        config1.documentTypeConfig().add(type1);
+        assertFalse(config1.equals(config2));
+
+        config2.documentTypeConfig().add(type2);
+        assertEquals(config1, config2);
+        assertEquals(config1.hashCode(), config2.hashCode());
+
+        config1.transformationConfig().add(transformation1);
+        config2.transformationConfig().add(transformation2);
+
+        assertEquals(config1, config2);
+        assertEquals(config1.hashCode(), config2.hashCode());
+
+        config1.filterConfig().add(filter1);
+        config2.filterConfig().add(filter2);
+
+        assertEquals(config1, config2);
+        assertEquals(config1.hashCode(), config2.hashCode());
     }
 }
index 4086fa36482ce044f21be82821b8c998a1feac08..e56b5c07d1e7dea33f2992448c0dbb63414f1e5f 100644 (file)
@@ -18,7 +18,7 @@ package org.wamblee.xmlrouter.impl;
 import static junit.framework.Assert.*;
 import static org.mockito.Mockito.*;
 
-import java.util.List;
+import java.util.Collection;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -56,21 +56,22 @@ public class XMLRouterConfigServiceTest {
         verify(config).setRouterConfig(captor.capture());
         RouterConfig received = captor.getValue();
 
-        List<DocumentType> docTypes = received.documentTypeConfig().values();
+        Collection<DocumentType> docTypes = received.documentTypeConfig()
+            .values();
         assertEquals(1, docTypes.size());
         assertEquals("myapp.id.documenttypes.doctype" + aSuffix, docTypes
-            .get(0).getId().toString());
+            .iterator().next().getId().toString());
 
-        List<Transformation> transformations = received.transformationConfig()
-            .values();
+        Collection<Transformation> transformations = received
+            .transformationConfig().values();
         assertEquals(1, transformations.size());
         assertEquals("myapp.id.transformations.t1" + aSuffix, transformations
-            .get(0).getId().toString());
+            .iterator().next().getId().toString());
 
-        List<Filter> filters = received.filterConfig().values();
+        Collection<Filter> filters = received.filterConfig().values();
         assertEquals(1, filters.size());
-        assertEquals("myapp.id.filters.f1" + aSuffix, filters.get(0).getId()
-            .toString());
+        assertEquals("myapp.id.filters.f1" + aSuffix, filters.iterator().next()
+            .getId().toString());
     }
 
     private RouterConfig createRouterConfig(String routerConfigId,
index ae40327050f34eae08805923a65397fc5096d0a1..c1776f475e8723e677530c2c0382f7e56890a23f 100644 (file)
@@ -341,8 +341,8 @@ public class XMLRouterTest {
     private Transformation createTransformation(String aFrom, String aTo,
         DOMSource aSource, DOMSource aTarget) {
         Transformation transformation = mock(Transformation.class);
-        when(transformation.getId())
-            .thenReturn(new Id<Transformation>("trans"));
+        when(transformation.getId()).thenReturn(
+            new Id<Transformation>(UUID.randomUUID().toString()));
         when(transformation.getFromType()).thenReturn(aFrom);
         when(transformation.getToType()).thenReturn(aTo);
         when(transformation.transform(same(aSource))).thenReturn(aTarget);