Now using RouterConfig internally inside the XML Router.
authorErik Brakkee <erik@brakkee.org>
Sat, 30 Jul 2011 18:19:23 +0000 (20:19 +0200)
committerErik Brakkee <erik@brakkee.org>
Sat, 30 Jul 2011 18:19:23 +0000 (20:19 +0200)
Transformations no longer assigns the id but is just the shortest path algorithm.

20 files changed:
common/pom.xml
common/src/main/java/org/wamblee/xmlrouter/common/Id.java
common/src/test/java/org/wamblee/xmlrouter/common/IdTest.java [new file with mode: 0644]
config/src/main/java/org/wamblee/xmlrouter/config/Config.java
config/src/main/java/org/wamblee/xmlrouter/config/RouterConfig.java
impl/src/main/java/org/wamblee/xmlrouter/impl/ConfigImpl.java
impl/src/main/java/org/wamblee/xmlrouter/impl/ExtendedConfig.java [new file with mode: 0644]
impl/src/main/java/org/wamblee/xmlrouter/impl/ExtendedRouterConfig.java [new file with mode: 0644]
impl/src/main/java/org/wamblee/xmlrouter/impl/RobustDestination.java
impl/src/main/java/org/wamblee/xmlrouter/impl/SingleRouterConfig.java [new file with mode: 0644]
impl/src/main/java/org/wamblee/xmlrouter/impl/Transformations.java
impl/src/main/java/org/wamblee/xmlrouter/impl/XMLRouter.java
impl/src/test/java/org/wamblee/xmlrouter/impl/ConfigImplTest.java [new file with mode: 0644]
impl/src/test/java/org/wamblee/xmlrouter/impl/RobustDestinationTest.java
impl/src/test/java/org/wamblee/xmlrouter/impl/RobustFilterTest.java
impl/src/test/java/org/wamblee/xmlrouter/impl/RobustTransformationTest.java
impl/src/test/java/org/wamblee/xmlrouter/impl/SingleRouterConfigTest.java [new file with mode: 0644]
impl/src/test/java/org/wamblee/xmlrouter/impl/TransformationsTest.java
impl/src/test/java/org/wamblee/xmlrouter/impl/XMLRouterTest.java
subscribe/src/main/java/org/wamblee/xmlrouter/subscribe/DestinationRegistry.java

index d2c06b5fe4b4c304625db696464263fa3d362be2..5b2c35f403b00bc5a2beb2112e9fb9e0cb1ae4a2 100644 (file)
     <name>/xmlrouter/common</name>
     <url>http://wamblee.org</url>
     
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+        </dependency>        
+    </dependencies>
+    
     
     <distributionManagement>
         <site>
index 704aac937c12fb20bc9d8c8ca35a6a14b6230365..f057b416ee8572570b018fd83594fa40869ffd63 100644 (file)
  */
 package org.wamblee.xmlrouter.common;
 
-public class Id<T> {
+/**
+ * This class provides a generic typesafe id wrapping a long value.
+ * 
+ * @author Erik Brakkee
+ * 
+ * @param <T>
+ *            Type the id refers to.
+ */
+public class Id<T> implements Comparable<Id<T>> {
 
     private long id;
 
+    /**
+     * Constructs the id.
+     * 
+     * @param aId
+     *            Integer id.
+     */
     public Id(long aId) {
         id = aId;
     }
 
+    /**
+     * @return The underlying id.
+     */
     public long getId() {
         return id;
     }
@@ -47,4 +64,9 @@ public class Id<T> {
     public String toString() {
         return id + "";
     }
+
+    @Override
+    public int compareTo(Id<T> aId) {
+        return ((Long) id).compareTo((Long) aId.getId());
+    }
 }
diff --git a/common/src/test/java/org/wamblee/xmlrouter/common/IdTest.java b/common/src/test/java/org/wamblee/xmlrouter/common/IdTest.java
new file mode 100644 (file)
index 0000000..183d885
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2005-2010 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.common;
+
+import static junit.framework.Assert.*;
+
+import org.junit.Test;
+
+public class IdTest {
+
+    @Test
+    public void testGetSet() {
+        Id<IdTest> id = new Id<IdTest>(100L);
+        assertEquals(100L, id.getId());
+    }
+
+    @Test
+    public void testEqualsHashCodeCompare() {
+        Id<IdTest> id1 = new Id<IdTest>(100L);
+        Id<IdTest> id2 = new Id<IdTest>(200L);
+        Id<IdTest> id3 = new Id<IdTest>(100L);
+        assertEquals(id1, id3);
+        assertFalse(id1.equals(id2));
+        assertFalse(id1.equals(null));
+        assertFalse(id1.equals("hello"));
+        assertEquals(id1.hashCode(), id3.hashCode());
+
+        assertTrue(id1.compareTo(id2) < 0);
+        assertTrue(id2.compareTo(id1) > 0);
+        assertEquals(0, id1.compareTo(id3));
+    }
+}
index b90b34c4bfb58a0739d760d0b545a139bf19df0c..263b0b66bfe7c0fbad9087dc6c8b2de21462cbdd 100644 (file)
  */
 package org.wamblee.xmlrouter.config;
 
-import java.util.Collection;
+import java.util.Map;
 
 import org.wamblee.xmlrouter.common.Id;
 
 /**
- * Basic configuration interface for managing a set of configuration items of a
- * given type with unique ids.
+ * Interface for managing a set of configuration items of a given type with
+ * unique ids.
  * 
  * @author Erik Brakkee
  * 
@@ -51,15 +51,5 @@ public interface Config<T> {
     /**
      * @return All available ids.
      */
-    Collection<Id<T>> ids();
-
-    /**
-     * Gets the item for the given id.
-     * 
-     * @param aId
-     *            Item id.
-     * @return Item, or null if not found.
-     */
-    T get(Id<T> aId);
-
+    Map<Id<T>, T> map();
 }
\ No newline at end of file
index 9e53f4995929d585f42889929902e32407fdea72..57ddae740cc78a438190733c9242ca550b9f27ed 100644 (file)
@@ -15,7 +15,6 @@
  */
 package org.wamblee.xmlrouter.config;
 
-
 /**
  * Configuration API for the XML router.
  * 
@@ -23,15 +22,18 @@ package org.wamblee.xmlrouter.config;
  */
 public interface RouterConfig {
 
-    // Documents
-
-    Config<DocumentType> getDocumentTypeConfig();
-
-    // Transformations
-
-    Config<Transformation> getTransformationConfig();
+    /**
+     * @return Document types.
+     */
+    Config<DocumentType> documentTypeConfig();
 
-    // Filters
+    /**
+     * @return Transformations.
+     */
+    Config<Transformation> transformationConfig();
 
-    Config<Filter> getFilterConfig();
+    /**
+     * @return Filters.
+     */
+    Config<Filter> filterConfig();
 }
index 789f75c5178db2da3579c10cd14f1fd96c193932..54c0c6d2357604103284b1d818c754a2e1fdc551 100644 (file)
@@ -15,7 +15,6 @@
  */
 package org.wamblee.xmlrouter.impl;
 
-import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -31,16 +30,18 @@ import org.wamblee.xmlrouter.config.Config;
  * 
  * @param <T>
  */
-public abstract class ConfigImpl<T> implements Config<T> {
+public abstract class ConfigImpl<T> implements ExtendedConfig<T> {
 
+    private boolean dirty;
     private AtomicLong next;
     private Map<Id<T>, T> registered;
 
     /**
      * Constructs the object.
      */
-    public ConfigImpl() {
-        next = new AtomicLong(1);
+    public ConfigImpl(AtomicLong aNext) {
+        dirty = false;
+        next = aNext;
         registered = new LinkedHashMap<Id<T>, T>();
     }
 
@@ -50,14 +51,24 @@ public abstract class ConfigImpl<T> implements Config<T> {
      * @see org.wamblee.xmlrouter.config.Config#add(T)
      */
     @Override
-    public Id<T> add(T aT) {
+    public synchronized Id<T> add(T aT) {
         notNull(aT);
         long seqno = next.incrementAndGet();
         Id<T> id = new Id<T>(seqno);
         registered.put(id, wrap(id, aT));
+        dirty = true;
         return id;
     }
 
+    /**
+     * This is called to wrap the given object by a safer version.
+     * 
+     * @param aId
+     *            Id.
+     * @param aT
+     *            Object to wrap.
+     * @return Wrapped object.
+     */
     public abstract T wrap(Id<T> aId, T aT);
 
     /*
@@ -68,31 +79,15 @@ public abstract class ConfigImpl<T> implements Config<T> {
      * .Id)
      */
     @Override
-    public boolean remove(Id<T> aId) {
+    public synchronized boolean remove(Id<T> aId) {
         notNull(aId);
+        dirty = true;
         return registered.remove(aId) != null;
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.wamblee.xmlrouter.config.Config#ids()
-     */
-    @Override
-    public Collection<Id<T>> ids() {
-        return Collections.unmodifiableCollection(registered.keySet());
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.wamblee.xmlrouter.config.Config#get(org.wamblee.xmlrouter.common.Id)
-     */
     @Override
-    public T get(Id<T> aId) {
-        notNull(aId);
-        return registered.get(aId);
+    public Map<Id<T>, T> map() {
+        return Collections.unmodifiableMap(registered);
     }
 
     private void notNull(T aT) {
@@ -106,4 +101,14 @@ public abstract class ConfigImpl<T> implements Config<T> {
             throw new NullPointerException("Id is null");
         }
     }
+
+    @Override
+    public boolean isDirty() {
+        return dirty;
+    }
+
+    @Override
+    public void resetDirty() {
+        dirty = false;
+    }
 }
diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/ExtendedConfig.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/ExtendedConfig.java
new file mode 100644 (file)
index 0000000..070a52a
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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 org.wamblee.xmlrouter.config.Config;
+
+public interface ExtendedConfig<T> extends Config<T> {
+
+    boolean isDirty();
+
+    void resetDirty();
+}
diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/ExtendedRouterConfig.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/ExtendedRouterConfig.java
new file mode 100644 (file)
index 0000000..94b7128
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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 org.wamblee.xmlrouter.config.RouterConfig;
+
+/**
+ * Extended interface for the router configuration used internally.
+ * 
+ * @author Erik Brakkee
+ * 
+ */
+public interface ExtendedRouterConfig extends RouterConfig {
+
+    /**
+     * Locks the configuration object from further changes.
+     */
+    // void lock();
+
+    /**
+     * Checks whether or not the configuration has changed.
+     * 
+     * @return True iff dirty.
+     */
+    boolean isDirty();
+
+    /**
+     * Resets the router configuration dirty state.
+     */
+    void resetDirty();
+}
index 487706d6398f77a9462aa0ef5b930d63e122163d..3fc48d73c44cca1e163df3402c2ae886efed6ace 100644 (file)
@@ -12,7 +12,7 @@
  * 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.util.ArrayList;
diff --git a/impl/src/main/java/org/wamblee/xmlrouter/impl/SingleRouterConfig.java b/impl/src/main/java/org/wamblee/xmlrouter/impl/SingleRouterConfig.java
new file mode 100644 (file)
index 0000000..36016ca
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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.util.concurrent.atomic.AtomicLong;
+
+import org.wamblee.xmlrouter.common.Id;
+import org.wamblee.xmlrouter.config.Config;
+import org.wamblee.xmlrouter.config.DocumentType;
+import org.wamblee.xmlrouter.config.Filter;
+import org.wamblee.xmlrouter.config.Transformation;
+
+/**
+ * Represents a single configuration set of a single configuration client of the
+ * XML router.
+ * 
+ * @author Erik Brakkee
+ */
+public class SingleRouterConfig implements ExtendedRouterConfig {
+    private AtomicLong sequenceNumbers;
+    private ExtendedConfig<DocumentType> documentTypes;
+    private ExtendedConfig<Transformation> transformations;
+    private ExtendedConfig<Filter> filters;
+
+    /**
+     * Constructs a router configuration.
+     * 
+     * @param aSequenceNumberGenerator
+     *            Sequence number generator to use.
+     */
+    public SingleRouterConfig(AtomicLong aSequenceNumberGenerator) {
+        sequenceNumbers = aSequenceNumberGenerator;
+        documentTypes = new ConfigImpl<DocumentType>(sequenceNumbers) {
+            @Override
+            public DocumentType wrap(Id<DocumentType> aId, DocumentType aT) {
+                return new RobustDocumentType(aId, aT);
+            }
+        };
+        transformations = new ConfigImpl<Transformation>(sequenceNumbers) {
+            @Override
+            public Transformation wrap(Id<Transformation> aId,
+                Transformation aTransformation) {
+                return new RobustTransformation(aId, aTransformation);
+            }
+        };
+        filters = new ConfigImpl<Filter>(sequenceNumbers) {
+            @Override
+            public Filter wrap(Id<Filter> aId, Filter aFilter) {
+                return new RobustFilter(aId, aFilter);
+            }
+        };
+    }
+
+    @Override
+    public Config<DocumentType> documentTypeConfig() {
+        return documentTypes;
+    }
+
+    @Override
+    public Config<Transformation> transformationConfig() {
+        return transformations;
+    }
+
+    @Override
+    public Config<Filter> filterConfig() {
+        return filters;
+    }
+
+    @Override
+    public boolean isDirty() {
+        return documentTypes.isDirty() || transformations.isDirty() ||
+            filters.isDirty();
+    }
+
+    @Override
+    public void resetDirty() {
+        documentTypes.resetDirty();
+        filters.resetDirty();
+        transformations.resetDirty();
+    }
+
+}
index c297fac787ce5ea66ca66339435fdd85bc59a8c7..29e995916e78515fad607eb797ccc7923fd514f1 100644 (file)
@@ -18,12 +18,12 @@ package org.wamblee.xmlrouter.impl;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import org.wamblee.xmlrouter.common.Id;
-import org.wamblee.xmlrouter.config.Config;
 import org.wamblee.xmlrouter.config.Transformation;
 
 /**
@@ -35,7 +35,7 @@ import org.wamblee.xmlrouter.config.Transformation;
  */
 public class Transformations {
 
-    private Config<Transformation> transformations;
+    private Map<Id<Transformation>, Transformation> transformations;
     private List<String> vertices;
     private TransformationPath[][] matrix;
 
@@ -45,52 +45,15 @@ public class Transformations {
      * Construct the transformations.
      */
     public Transformations() {
-        transformations = new ConfigImpl<Transformation>() {
-            @Override
-            public Transformation wrap(Id<Transformation> aId,
-                Transformation aType) {
-                return new RobustTransformation(aId, aType);
-            }
-        };
+        transformations = new LinkedHashMap<Id<Transformation>, Transformation>();
         vertices = new ArrayList<String>();
         matrix = new TransformationPath[0][0];
     }
 
-    public Config<Transformation> getTransformationConfig() {
-        return new Config<Transformation>() {
-            @Override
-            public Id<Transformation> add(Transformation aT) {
-                return addTransformation(aT);
-            }
-
-            @Override
-            public Transformation get(Id<Transformation> aId) {
-                return transformations.get(aId);
-            }
-
-            @Override
-            public Collection<Id<Transformation>> ids() {
-                return transformations.ids();
-            }
-
-            @Override
-            public boolean remove(Id<Transformation> aId) {
-                return transformations.remove(aId);
-            }
-        };
-    }
-
-    /**
-     * Adds a transformation. Leads to recomputation of shortest paths.
-     * 
-     * @param aTransformation
-     *            Transformation to add.
-     * @return Id of the transformation.
-     */
-    public Id<Transformation> addTransformation(Transformation aTransformation) {
-        Id<Transformation> id = transformations.add(aTransformation);
+    public void replaceTransformations(
+        Map<Id<Transformation>, Transformation> aTransformations) {
+        transformations = aTransformations;
         computeTransformationSequences();
-        return id;
     }
 
     /**
@@ -149,8 +112,7 @@ public class Transformations {
 
         // Obtain possible starting points.
         Set<String> v = new HashSet<String>();
-        for (Id<Transformation> id : transformations.ids()) {
-            Transformation transformation = transformations.get(id);
+        for (Transformation transformation : transformations.values()) {
             v.add(transformation.getFromType());
             v.add(transformation.getToType());
         }
@@ -164,8 +126,7 @@ public class Transformations {
         for (int i = 0; i < nvertices; i++) {
             matrix[i][i] = new TransformationPath();
         }
-        for (Id<Transformation> id : transformations.ids()) {
-            Transformation transformation = transformations.get(id);
+        for (Transformation transformation : transformations.values()) {
             int from = vertices.indexOf(transformation.getFromType());
             int to = vertices.indexOf(transformation.getToType());
             TransformationPath path = new TransformationPath(transformation);
@@ -196,17 +157,6 @@ public class Transformations {
             .size();
     }
 
-    /**
-     * Removes a transformation.
-     * 
-     * @param aId
-     *            Id of the transformation.
-     */
-    public void removeTransformation(Id<Transformation> aId) {
-        transformations.remove(aId);
-        computeTransformationSequences();
-    }
-
     @Override
     public String toString() {
         StringBuffer buf = new StringBuffer();
index 99b36354f1fa30a21d057b8995793c8b9283dddc..8fa78f4a18af15854b1c835dc4378daa44cee59d 100644 (file)
@@ -58,9 +58,9 @@ public class XMLRouter implements RouterConfig, Gateway, DestinationRegistry {
     private Clock clock;
     private AtomicLong nextEventId;
 
-    private Config<DocumentType> documentTypes;
+    private ExtendedRouterConfig routerConfig;
     private Transformations transformations;
-    private Config<Filter> filters;
+
     private Map<Id<Destination>, Destination> destinations;
 
     public XMLRouter(Clock aClock, EventListener aListener) {
@@ -68,41 +68,36 @@ public class XMLRouter implements RouterConfig, Gateway, DestinationRegistry {
         listener = aListener;
         clock = aClock;
         nextEventId = new AtomicLong(clock.currentTimeMillis());
-        documentTypes = new ConfigImpl<DocumentType>() {
-            @Override
-            public DocumentType wrap(Id<DocumentType> aId, DocumentType aType) {
-                return new RobustDocumentType(aId, aType);
-            }
-        };
+        routerConfig = new SingleRouterConfig(sequenceNumbers);
         transformations = new Transformations();
-        filters = new ConfigImpl<Filter>() {
-            @Override
-            public Filter wrap(Id<Filter> aId, Filter aFilter) {
-                return new RobustFilter(aId, aFilter);
-            }
-        };
         destinations = new LinkedHashMap<Id<Destination>, Destination>();
     }
 
     @Override
-    public Config<DocumentType> getDocumentTypeConfig() {
-        return documentTypes;
+    public Config<DocumentType> documentTypeConfig() {
+        return routerConfig.documentTypeConfig();
     }
 
     @Override
-    public Config<Transformation> getTransformationConfig() {
-        return transformations.getTransformationConfig();
+    public Config<Transformation> transformationConfig() {
+        return routerConfig.transformationConfig();
     }
 
     @Override
-    public Config<Filter> getFilterConfig() {
-        return filters;
+    public Config<Filter> filterConfig() {
+        return routerConfig.filterConfig();
     }
 
     @Override
     public void publish(String aSource, DOMSource aEvent) {
-
         long time = clock.currentTimeMillis();
+
+        if (routerConfig.isDirty()) {
+            transformations.replaceTransformations(routerConfig
+                .transformationConfig().map());
+            routerConfig.resetDirty();
+        }
+
         Id<DOMSource> id = new Id<DOMSource>(nextEventId.getAndIncrement());
         List<String> types = determineDocumentTypes(aEvent);
         EventInfo info = new EventInfo(time, aSource, id, types, aEvent);
@@ -209,8 +204,7 @@ public class XMLRouter implements RouterConfig, Gateway, DestinationRegistry {
 
     private boolean isAllowedByFilters(String aType, DOMSource aEvent) {
         boolean allowed = true;
-        for (Id<Filter> id : filters.ids()) {
-            Filter filter = filters.get(id);
+        for (Filter filter : routerConfig.filterConfig().map().values()) {
             if (!filter.isAllowed(aType, aEvent)) {
                 allowed = false;
             }
@@ -220,8 +214,8 @@ public class XMLRouter implements RouterConfig, Gateway, DestinationRegistry {
 
     private List<String> determineDocumentTypes(DOMSource aEvent) {
         List<String> res = new ArrayList<String>();
-        for (Id<DocumentType> id : documentTypes.ids()) {
-            DocumentType type = documentTypes.get(id);
+        for (DocumentType type : routerConfig.documentTypeConfig().map()
+            .values()) {
             if (type.isInstance(aEvent)) {
                 res.add(type.getName());
             }
@@ -229,13 +223,6 @@ public class XMLRouter implements RouterConfig, Gateway, DestinationRegistry {
         return res;
     }
 
-    private void logEvent(String aMessage, String aSource, DOMSource aEvent,
-        Exception aException) {
-        LOGGER.log(Level.WARNING, aMessage + ": source '" + aSource +
-            "': Event: '" + new XMLDocument(aEvent).print(true) + "'",
-            aException);
-    }
-
     private void logEvent(String aMessage, String aSource, DOMSource aEvent) {
         LOGGER.log(Level.WARNING,
             aMessage + ": " + eventToString(aSource, aEvent));
diff --git a/impl/src/test/java/org/wamblee/xmlrouter/impl/ConfigImplTest.java b/impl/src/test/java/org/wamblee/xmlrouter/impl/ConfigImplTest.java
new file mode 100644 (file)
index 0000000..98296d4
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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 static junit.framework.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.wamblee.xmlrouter.common.Id;
+
+public class ConfigImplTest {
+
+    private static interface MyType {
+
+    }
+
+    private static class MyTypeWrapper implements MyType {
+        private Id<MyType> id;
+        private MyType type;
+
+        public MyTypeWrapper(Id<MyType> aId, MyType aType) {
+            id = aId;
+            type = aType;
+        }
+
+        public MyType getType() {
+            return type;
+        }
+    }
+
+    private AtomicLong sequence;
+    private ExtendedConfig<MyType> config;
+
+    @Before
+    public void setUp() {
+        sequence = new AtomicLong(1L);
+        config = new ConfigImpl<MyType>(sequence) {
+            @Override
+            public MyType wrap(Id<MyType> aId, MyType aT) {
+                return new MyTypeWrapper(aId, aT);
+            }
+        };
+    }
+
+    @Test
+    public void testAdd() {
+        MyType type1 = mock(MyType.class);
+        assertFalse(config.isDirty());
+
+        Id<MyType> id1 = config.add(type1);
+
+        assertNotNull(id1);
+        assertEquals(1, config.map().size());
+        assertTrue(config.map().get(id1) instanceof MyTypeWrapper);
+        assertSame(type1, ((MyTypeWrapper) config.map().get(id1)).getType());
+        assertTrue(config.isDirty());
+
+        config.resetDirty();
+        assertFalse(config.isDirty());
+
+        // add another one.
+        MyType type2 = mock(MyType.class);
+        Id<MyType> id2 = config.add(type2);
+        assertNotNull(id2);
+        assertEquals(2, config.map().size());
+        assertFalse(id1.equals(id2));
+        assertTrue(config.isDirty());
+
+    }
+
+    @Test
+    public void testRemove() {
+        MyType type1 = mock(MyType.class);
+        Id<MyType> id1 = config.add(type1);
+
+        assertNotNull(id1);
+        assertEquals(1, config.map().size());
+
+        config.resetDirty();
+        assertFalse(config.isDirty());
+
+        config.remove(id1);
+        assertTrue(config.map().isEmpty());
+        assertTrue(config.isDirty());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testUnmodifiable() {
+        config.map().put(new Id<MyType>(100L), mock(MyType.class));
+    }
+}
index 4ba1609360697b02a68be83e8545c8aebc98f88a..a42f1c4a5e8a7c56053ed139a1c71482ffb87ca1 100644 (file)
@@ -12,7 +12,7 @@
  * 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 static junit.framework.Assert.*;
index 3a948eb8c9c29cb650dc0f64827e2a019e4c2a34..2c7e742efa06892257ee10039ed5277fe4fe8902 100644 (file)
@@ -12,7 +12,7 @@
  * 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 static junit.framework.Assert.*;
index 967b0e2ba3300b41b1951470d141b09cb62bb6c1..d26e9dee1c8d641c1eda8c0f7717685718163961 100644 (file)
@@ -12,7 +12,7 @@
  * 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 static junit.framework.Assert.*;
diff --git a/impl/src/test/java/org/wamblee/xmlrouter/impl/SingleRouterConfigTest.java b/impl/src/test/java/org/wamblee/xmlrouter/impl/SingleRouterConfigTest.java
new file mode 100644 (file)
index 0000000..c6f9920
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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 static junit.framework.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.wamblee.xmlrouter.common.Id;
+import org.wamblee.xmlrouter.config.DocumentType;
+import org.wamblee.xmlrouter.config.Filter;
+import org.wamblee.xmlrouter.config.Transformation;
+
+public class SingleRouterConfigTest {
+
+    private AtomicLong sequence;
+    private ExtendedRouterConfig config;
+
+    @Before
+    public void setUp() {
+        sequence = new AtomicLong(1L);
+        config = new SingleRouterConfig(sequence);
+    }
+
+    @Test
+    public void testDocumentType() {
+        DocumentType type1 = mock(DocumentType.class);
+        DocumentType type2 = mock(DocumentType.class);
+
+        assertFalse(config.isDirty());
+        Id<DocumentType> id1 = config.documentTypeConfig().add(type1);
+        assertTrue(config.isDirty());
+
+        config.resetDirty();
+        assertFalse(config.isDirty());
+        Id<DocumentType> id2 = config.documentTypeConfig().add(type2);
+        assertFalse(id1.equals(id2));
+        assertTrue(config.isDirty());
+
+        assertEquals(2, config.documentTypeConfig().map().size());
+        assertTrue(config.documentTypeConfig().map().get(id1) instanceof RobustDocumentType);
+
+    }
+
+    @Test
+    public void testTransformation() {
+        Transformation transformation1 = mock(Transformation.class);
+        Transformation transformation2 = mock(Transformation.class);
+
+        assertFalse(config.isDirty());
+        Id<Transformation> id1 = config.transformationConfig().add(
+            transformation1);
+        assertTrue(config.isDirty());
+
+        config.resetDirty();
+        assertFalse(config.isDirty());
+        Id<Transformation> id2 = config.transformationConfig().add(
+            transformation2);
+        assertFalse(id1.equals(id2));
+        assertTrue(config.isDirty());
+
+        assertEquals(2, config.transformationConfig().map().size());
+        assertTrue(config.transformationConfig().map().get(id1) instanceof RobustTransformation);
+    }
+
+    @Test
+    public void testFilter() {
+        Filter filter1 = mock(Filter.class);
+        Filter filter2 = mock(Filter.class);
+
+        assertFalse(config.isDirty());
+        Id<Filter> id1 = config.filterConfig().add(filter1);
+        assertTrue(config.isDirty());
+
+        config.resetDirty();
+        assertFalse(config.isDirty());
+        Id<Filter> id2 = config.filterConfig().add(filter2);
+        assertFalse(id1.equals(id2));
+        assertTrue(config.isDirty());
+
+        assertEquals(2, config.filterConfig().map().size());
+        assertTrue(config.filterConfig().map().get(id1) instanceof RobustFilter);
+    }
+}
index 230cd03d73c2e90e3c77fd00abd9c8c3b1579dd0..775e5000b8dc7c01121881f18e5d6731d17e3122 100644 (file)
@@ -18,6 +18,8 @@ package org.wamblee.xmlrouter.impl;
 import static junit.framework.Assert.*;
 
 import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
 
 import javax.xml.transform.dom.DOMSource;
 
@@ -71,10 +73,22 @@ public class TransformationsTest {
         transformations = new Transformations();
     }
 
+    private Map<Id<Transformation>, Transformation> createTransformations(
+        long aStartId, Transformation... aTransformations) {
+        Map<Id<Transformation>, Transformation> res = new LinkedHashMap<Id<Transformation>, Transformation>();
+
+        long id = aStartId;
+        for (Transformation t : aTransformations) {
+            res.put(new Id<Transformation>(id++), t);
+        }
+        return res;
+    }
+
     @Test
     public void testOneTransformation() {
-        Id<Transformation> seqno = transformations
-            .addTransformation(new MyTransformation("A", "B"));
+        transformations.replaceTransformations(createTransformations(10L,
+            new MyTransformation("A", "B")));
+
         System.out.println(transformations.toString());
         TransformationPath path = transformations.getPath("A", "B");
         assertEquals(1, path.size());
@@ -92,25 +106,23 @@ public class TransformationsTest {
 
     @Test
     public void testMultipleTransformations() {
-        Id<Transformation> seqno1 = transformations
-            .addTransformation(new MyTransformation("A", "B"));
-        Id<Transformation> seqno2 = transformations
-            .addTransformation(new MyTransformation("B", "C"));
-        Id<Transformation> seqno3 = transformations
-            .addTransformation(new MyTransformation("C", "A"));
+        transformations.replaceTransformations(createTransformations(10L,
+            new MyTransformation("A", "B"), new MyTransformation("B", "C"),
+            new MyTransformation("C", "A")));
+
         System.out.println(transformations);
         assertEquals(2, transformations.getPath("C", "B").size());
-        assertFalse(seqno1.equals(seqno2));
-        assertFalse(seqno2.equals(seqno3));
-        assertFalse(seqno1.equals(seqno3));
 
-        transformations.removeTransformation(seqno1);
+        transformations.replaceTransformations(createTransformations(10L,
+            new MyTransformation("B", "C"), new MyTransformation("C", "A")));
+
         assertNull(transformations.getPath("C", "B"));
     }
 
     @Test
     public void testUnknownDestination() {
-        transformations.addTransformation(new MyTransformation("A", "B"));
+        transformations.replaceTransformations(createTransformations(10L,
+            new MyTransformation("A", "B")));
         assertNull(transformations.getPath("A", "D"));
     }
 
index 9ee2645a58f8029de45cfae296f4685540790f81..4bcf2a46929b734e060e9b009b548585d86202ca 100644 (file)
@@ -99,7 +99,7 @@ public class XMLRouterTest {
         DocumentType type = mock(DocumentType.class);
         doThrow(new RuntimeException("x")).when(type).isInstance(
             any(DOMSource.class));
-        router.getDocumentTypeConfig().add(type);
+        router.documentTypeConfig().add(type);
         router.publish("xx", mock(DOMSource.class));
         verify(listener).notDelivered(any(EventInfo.class));
         // no exception should occur.
@@ -111,7 +111,7 @@ public class XMLRouterTest {
         Filter filter = mock(Filter.class);
         doThrow(new RuntimeException("x")).when(filter).isAllowed(anyString(),
             any(DOMSource.class));
-        router.getFilterConfig().add(filter);
+        router.filterConfig().add(filter);
         router.publish("xx", mock(DOMSource.class));
         verify(listener).notDelivered(any(EventInfo.class));
         // no exception should occur.
@@ -144,14 +144,14 @@ public class XMLRouterTest {
         DocumentType type = mock(DocumentType.class);
         when(type.isInstance(any(DOMSource.class))).thenReturn(true);
         when(type.getName()).thenReturn(aType);
-        Id<DocumentType> typeId = router.getDocumentTypeConfig().add(type);
+        Id<DocumentType> typeId = router.documentTypeConfig().add(type);
     }
 
     private void registerDocumentType(String aType, DOMSource aSource) {
         DocumentType type = mock(DocumentType.class);
         when(type.isInstance(same(aSource))).thenReturn(true);
         when(type.getName()).thenReturn(aType);
-        Id<DocumentType> typeId = router.getDocumentTypeConfig().add(type);
+        Id<DocumentType> typeId = router.documentTypeConfig().add(type);
     }
 
     private Destination registerDestination(boolean aResult, String... types) {
@@ -269,7 +269,7 @@ public class XMLRouterTest {
         when(transformation.getFromType()).thenReturn("any");
         when(transformation.getToType()).thenReturn("bla");
         when(transformation.transform(same(source1))).thenReturn(source2);
-        router.getTransformationConfig().add(transformation);
+        router.transformationConfig().add(transformation);
 
         Destination destination = mock(Destination.class);
         when(
@@ -301,7 +301,7 @@ public class XMLRouterTest {
         when(transformation.getToType()).thenReturn("bla");
         doThrow(new RuntimeException("x")).when(transformation).transform(
             same(source1));
-        router.getTransformationConfig().add(transformation);
+        router.transformationConfig().add(transformation);
 
         Destination destination = mock(Destination.class);
         when(
@@ -331,7 +331,7 @@ public class XMLRouterTest {
         Transformation transformation = createTransformation("any", "bla",
             source1, null);
 
-        router.getTransformationConfig().add(transformation);
+        router.transformationConfig().add(transformation);
 
         Destination destination = mock(Destination.class);
         when(
@@ -349,7 +349,7 @@ public class XMLRouterTest {
         Transformation transformation2 = createTransformation("any", "bla2",
             source1, source2);
 
-        router.getTransformationConfig().add(transformation2);
+        router.transformationConfig().add(transformation2);
         when(
             destination.chooseFromTargetTypes((Collection<String>) anyObject()))
             .thenReturn(Arrays.asList("bla", "bla2"));
@@ -393,7 +393,7 @@ public class XMLRouterTest {
         registerDocumentType("other", source2);
         Transformation transformation = createTransformation("any", "other",
             source1, source2);
-        router.getTransformationConfig().add(transformation);
+        router.transformationConfig().add(transformation);
 
         router.publish("source", source1);
         verify(listener, times(2)).delivered(any(EventInfo.class),
@@ -411,10 +411,10 @@ public class XMLRouterTest {
 
         Transformation t1 = createTransformation("any", "intermediate",
             source1, source2);
-        router.getTransformationConfig().add(t1);
+        router.transformationConfig().add(t1);
         Transformation t2 = createTransformation("intermediate", "other",
             source2, source3);
-        router.getTransformationConfig().add(t2);
+        router.transformationConfig().add(t2);
 
         router.publish("source", source1);
         verify(listener).delivered(any(EventInfo.class),
index 49bd143e3ac186eba81ef314a5dea44c0a85c9a3..87f926552b361383548d50211393574d2d5cecb0 100644 (file)
@@ -12,7 +12,7 @@
  * 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.subscribe;
 
 import org.wamblee.xmlrouter.common.Id;