Now more testing.
*/
public class Id<T> implements Comparable<Id<T>> {
- private long id;
+ private String id;
/**
* Constructs the id.
*
* @param aId
* Integer id.
+ * @throws NullPointerException
+ * in case the id is null.
*/
- public Id(long aId) {
+ public Id(String aId) {
+ if (aId == null) {
+ throw new NullPointerException("id is null");
+ }
id = aId;
}
/**
* @return The underlying id.
*/
- public long getId() {
+ public String getId() {
return id;
}
@Override
public int hashCode() {
- return ((Long) id).hashCode();
+ return id.hashCode();
}
@Override
@Override
public String toString() {
- return id + "";
+ return id;
}
@Override
public int compareTo(Id<T> aId) {
- return ((Long) id).compareTo((Long) aId.getId());
+ return id.compareTo(aId.getId());
}
}
@Test
public void testGetSet() {
- Id<IdTest> id = new Id<IdTest>(100L);
- assertEquals(100L, id.getId());
+ Id<IdTest> id = new Id<IdTest>("hello");
+ assertEquals("hello", 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);
+ Id<IdTest> id1 = new Id<IdTest>("a");
+ Id<IdTest> id2 = new Id<IdTest>("b");
+ Id<IdTest> id3 = new Id<IdTest>("a");
assertEquals(id1, id3);
assertFalse(id1.equals(id2));
assertFalse(id1.equals(null));
- assertFalse(id1.equals("hello"));
+ assertFalse(id1.equals("a"));
assertEquals(id1.hashCode(), id3.hashCode());
assertTrue(id1.compareTo(id2) < 0);
assertTrue(id2.compareTo(id1) > 0);
assertEquals(0, id1.compareTo(id3));
}
+
+ @Test(expected = NullPointerException.class)
+ public void testNullNotAccepted() {
+ Id<IdTest> id = new Id<IdTest>(null);
+ }
}
*/
package org.wamblee.xmlrouter.config;
-import java.util.Map;
+import java.util.List;
import org.wamblee.xmlrouter.common.Id;
* @param <T>
* Type for which ids are generated.
*/
-public interface Config<T> {
+public interface Config<T> extends Identifiable<Config> {
/**
- * Adds a item
+ * Adds an item. No item with the same id may exist.
*
* @param aT
* item
- * @return Unique id.
*/
- Id<T> add(T aT);
+ void add(T aT);
/**
* Removes the item with a given id.
boolean remove(Id<T> aId);
/**
- * @return All available ids.
+ * @return All available items.
*/
- Map<Id<T>, T> map();
+ List<T> values();
}
\ No newline at end of file
* @author Erik Brakkee
*
*/
-public interface DocumentType {
+public interface DocumentType extends Identifiable<DocumentType> {
/**
* Symbolic name for the document type.
* @author Erik Brakkee
*
*/
-public interface Filter {
+public interface Filter extends Identifiable<Filter> {
/**
* Determines if a given document will be processed or not.
--- /dev/null
+/*
+ * 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.config;
+
+import org.wamblee.xmlrouter.common.Id;
+
+/**
+ * Classes implementing this interface must provide a unique id to identify
+ * their contents and behavior. If the content or behavior of an object changes,
+ * then a different id should be returned. Conversely, it is required for the id
+ * to keep as constant as possible. Also, a given object should return the same
+ * id throughout its lifecycle (from the moment it's {@link #getId()} method is
+ * called until the moment it can no longer be referenced.
+ *
+ * @author Erik Brakkee
+ *
+ */
+public interface Identifiable<T> {
+
+ /**
+ * Returns the unique id for the object.
+ *
+ * @return Unique id.
+ */
+ Id<T> getId();
+}
*
* @author Erik Brakkee
*/
-public interface RouterConfig {
+public interface RouterConfig extends Identifiable<RouterConfig> {
/**
* @return Document types.
* configuration.
* @return Id of the applied configuration.
*/
- Id<RouterConfig> apply(RouterConfig aConfig, Id<RouterConfig> aOldConfig);
+ void apply(RouterConfig aConfig, Id<RouterConfig> aOldConfig);
/**
* Clears the configuration for a given id.
* @author Erik Brakkee
*
*/
-public interface Transformation {
-
- /**
- * @return Name for the transformation.
- */
- String getName();
+public interface Transformation extends Identifiable<Transformation> {
/**
* From type that can be transformed.
*/
package org.wamblee.xmlrouter.impl;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.Config;
public class CompositeConfig<T> implements ExtendedConfig<T> {
- private Map<Id<T>, T> configs;
+ private Id<Config> id;
+ private List<T> configs;
- public CompositeConfig() {
- configs = new LinkedHashMap<Id<T>, T>();
+ public CompositeConfig(Id<Config> aId) {
+ id = aId;
+ configs = new ArrayList<T>();
+ }
+
+ @Override
+ public Id<Config> getId() {
+ // TODO test id.
+ return id;
}
public void add(Config<T> aConfig) {
- for (Id<T> id : aConfig.map().keySet()) {
- configs.put(id, aConfig.map().get(id));
+ // TODO check duplicate config.
+ for (T item : aConfig.values()) {
+ configs.add(item);
}
}
@Override
- public Map<Id<T>, T> map() {
+ public List<T> values() {
return configs;
}
return false;
}
- private void notSupported() {
- throw new RuntimeException("readonly instance");
- }
-
@Override
- public Id<T> add(T aT) {
+ public void add(T aT) {
notSupported();
- return null;
+ }
+
+ private void notSupported() {
+ throw new RuntimeException("readonly instance");
}
}
import java.util.Collection;
+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.RouterConfig;
import org.wamblee.xmlrouter.config.Transformation;
+// TODO test this class.
public class CompositeRouterConfig implements ExtendedRouterConfig {
+ private Id<RouterConfig> id;
private CompositeConfig<DocumentType> documentTypes;
private CompositeConfig<Transformation> transformations;
private CompositeConfig<Filter> filters;
- public CompositeRouterConfig(Collection<RouterConfig> aConfigs) {
- documentTypes = new CompositeConfig<DocumentType>();
- transformations = new CompositeConfig<Transformation>();
- filters = new CompositeConfig<Filter>();
+ public CompositeRouterConfig(Id<RouterConfig> aId,
+ Collection<RouterConfig> aConfigs) {
+ id = aId;
+ documentTypes = new CompositeConfig<DocumentType>(new Id<Config>(
+ "documentTypes"));
+ transformations = new CompositeConfig<Transformation>(new Id<Config>(
+ "transformations"));
+ filters = new CompositeConfig<Filter>(new Id<Config>("filters"));
for (RouterConfig config : aConfigs) {
documentTypes.add(config.documentTypeConfig());
transformations.add(config.transformationConfig());
}
}
+ // TODO test id.
+
+ @Override
+ public Id<RouterConfig> getId() {
+ return id;
+ }
+
@Override
public Config<DocumentType> documentTypeConfig() {
return documentTypes;
*/
package org.wamblee.xmlrouter.impl;
+import java.util.ArrayList;
import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.Iterator;
+import java.util.List;
import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.Config;
+import org.wamblee.xmlrouter.config.Identifiable;
/**
* Default implementation of the {@link Config} interface.
*
* @param <T>
*/
-public abstract class ConfigImpl<T> implements ExtendedConfig<T> {
+public abstract class ConfigImpl<T extends Identifiable> implements
+ ExtendedConfig<T> {
- private boolean dirty;
- private AtomicLong next;
- private Map<Id<T>, T> registered;
+ private Id<Config> id;
+ private List<T> registered;
/**
* Constructs the object.
*/
- public ConfigImpl(AtomicLong aNext) {
- dirty = false;
- next = aNext;
- registered = new LinkedHashMap<Id<T>, T>();
+ public ConfigImpl(Id<Config> aId) {
+ // TODO test for null.
+ id = aId;
+ registered = new ArrayList<T>();
+ }
+
+ @Override
+ public Id<Config> getId() {
+ return id;
}
/*
* @see org.wamblee.xmlrouter.config.Config#add(T)
*/
@Override
- public synchronized Id<T> add(T aT) {
+ public synchronized void add(T aT) {
+ // TODO test duplicate ids.
notNull(aT);
- long seqno = next.incrementAndGet();
- Id<T> id = new Id<T>(seqno);
- registered.put(id, wrap(id, aT));
- dirty = true;
- return id;
+ registered.add(wrap(aT));
}
/**
* 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);
+ public abstract T wrap(T aT);
/*
* (non-Javadoc)
@Override
public synchronized boolean remove(Id<T> aId) {
notNull(aId);
- dirty = true;
- return registered.remove(aId) != null;
+ Iterator<T> i = registered.iterator();
+ while (i.hasNext()) {
+ T t = i.next();
+ if (t.getId().equals(aId)) {
+ i.remove();
+ return true;
+ }
+ }
+ return false;
}
@Override
- public Map<Id<T>, T> map() {
- return Collections.unmodifiableMap(registered);
+ public List<T> values() {
+ return Collections.unmodifiableList(registered);
}
private void notNull(T aT) {
*
*/
public enum Constants {
- UNKNOWN_DOCUMENT_TYPE, UNKNOWN_DESTINATION_NAME, UNKNOWN_NAME
+ UNKNOWN_DOCUMENT_TYPE, UNKNOWN_DESTINATION_NAME, UNKNOWN_NAME, UNKNOWN_ID
}
import javax.xml.transform.dom.DOMSource;
-import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.DocumentType;
/**
* @author Erik Brakkee
*
*/
-public class RobustDocumentType implements DocumentType {
+public class RobustDocumentType extends RobustIdentifiable<DocumentType>
+ implements DocumentType {
private static final Logger LOGGER = Logger
.getLogger(RobustDocumentType.class.getName());
- private Id<DocumentType> id;
private DocumentType type;
/**
* @param aType
* Document type to wrap.
*/
- public RobustDocumentType(Id<DocumentType> aId, DocumentType aType) {
- id = aId;
+ public RobustDocumentType(DocumentType aType) {
+ super(aType);
type = aType;
}
try {
String name = type.getName();
if (name == null) {
- LOGGER.log(Level.WARNING, "Document type " + id +
+ LOGGER.log(Level.WARNING, "Document type " + getId() +
" returned null for name");
return Constants.UNKNOWN_DOCUMENT_TYPE.toString();
}
return name;
} catch (Exception e) {
- LOGGER.log(Level.WARNING, "Document type " + id +
+ LOGGER.log(Level.WARNING, "Document type " + getId() +
" threw exception", e);
return Constants.UNKNOWN_DOCUMENT_TYPE.toString();
}
try {
return type.isInstance(aSource);
} catch (Exception e) {
- LOGGER.log(Level.WARNING, "Document type " + id +
+ LOGGER.log(Level.WARNING, "Document type " + getId() +
" threw exception", e);
return false;
}
try {
return type.validate(aSource);
} catch (Exception e) {
- LOGGER.log(Level.WARNING, "Document type " + id +
+ LOGGER.log(Level.WARNING, "Document type " + getId() +
" threw exception", e);
return false;
}
import javax.xml.transform.dom.DOMSource;
-import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.Filter;
/**
* @author Erik Brakkee
*
*/
-public class RobustFilter implements Filter {
+public class RobustFilter extends RobustIdentifiable<Filter> implements Filter {
private static final Logger LOGGER = Logger.getLogger(RobustFilter.class
.getName());
- private Id<Filter> id;
private Filter filter;
/**
* @param aFilter
* Filter to wrap.
*/
- public RobustFilter(Id<Filter> aId, Filter aFilter) {
- id = aId;
+ public RobustFilter(Filter aFilter) {
+ super(aFilter);
filter = aFilter;
}
try {
return filter.isAllowed(aDocumentType, aSource);
} catch (Exception e) {
- LOGGER.log(Level.WARNING, "Filter " + id +
+ LOGGER.log(Level.WARNING, "Filter " + getId() +
" threw exception, assuming filter returns true", e);
return true;
}
--- /dev/null
+/*
+ * 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.logging.Level;
+import java.util.logging.Logger;
+
+import org.wamblee.xmlrouter.common.Id;
+import org.wamblee.xmlrouter.config.Identifiable;
+
+/**
+ * Robust identifiable provides robustness for identifiable objects.
+ *
+ * @author Erik Brakkee
+ *
+ * @param <T>
+ */
+public class RobustIdentifiable<T> implements Identifiable<T> {
+ private static final Logger LOGGER = Logger
+ .getLogger(RobustIdentifiable.class.getName());
+
+ private Id<T> id;
+
+ // TODO test this class.
+ // TODO test that id is constant even though delegated changes its id.
+
+ public RobustIdentifiable(Identifiable<T> aIdentifiable) {
+ // TODO test id is null
+ // TODO getId() throws exception
+ try {
+ id = aIdentifiable.getId();
+ if (id == null) {
+ id = new Id<T>(Constants.UNKNOWN_ID.toString());
+ throw new RuntimeException(
+ "Temporary to catch nulls during refactoring");
+ }
+ } catch (Exception e) {
+ LOGGER
+ .log(Level.WARNING, "Identifiable getId() threw exception", e);
+ }
+
+ }
+
+ @Override
+ public Id<T> getId() {
+ return id;
+ }
+
+ // TODO test equals, hashcode.
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object aObj) {
+ if (aObj == null) {
+ return false;
+ }
+ if (!getClass().isInstance(aObj)) {
+ return false;
+ }
+ RobustIdentifiable<T> obj = (RobustIdentifiable<T>) aObj;
+ return id.equals(obj.getId());
+ }
+}
import javax.xml.transform.dom.DOMSource;
import org.wamblee.xml.XMLDocument;
-import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.Transformation;
/**
* @author Erik Brakkee
*
*/
-public class RobustTransformation implements Transformation {
+public class RobustTransformation extends RobustIdentifiable<Transformation>
+ implements Transformation {
private static final Logger LOGGER = Logger
.getLogger(RobustTransformation.class.getName());
- private Id<Transformation> id;
private Transformation transformation;
/**
* @param aTransformation
* Wrapped transformation.
*/
- public RobustTransformation(Id<Transformation> aId,
- Transformation aTransformation) {
- id = aId;
+ public RobustTransformation(Transformation aTransformation) {
+ super(aTransformation);
transformation = aTransformation;
}
- @Override
- public String getName() {
- try {
- String name = transformation.getName();
- if (name == null) {
- logTypeReturnedNull("from");
- return Constants.UNKNOWN_DOCUMENT_TYPE.toString();
- }
- return name;
- } catch (Exception e) {
- logNameThrewException(e);
- return Constants.UNKNOWN_DOCUMENT_TYPE.toString();
- }
- }
-
@Override
public String getFromType() {
try {
private void logTranformationThrewException(DOMSource aEvent, Exception aE) {
LOGGER.log(Level.WARNING,
- "transformation " + id + " threw exception for event " +
+ "transformation " + getId() + " threw exception for event " +
new XMLDocument(aEvent).print(true), aE);
}
private void logTransformationReturnedNull(DOMSource aEvent) {
- LOGGER.log(Level.WARNING, "transformation " + id +
+ LOGGER.log(Level.WARNING, "transformation " + getId() +
" returned null for event " + new XMLDocument(aEvent).print(true));
}
*/
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.RouterConfig;
import org.wamblee.xmlrouter.config.Transformation;
/**
* @author Erik Brakkee
*/
public class SingleRouterConfig implements ExtendedRouterConfig {
- private AtomicLong sequenceNumbers;
+ private Id<RouterConfig> id;
private ExtendedConfig<DocumentType> documentTypes;
private ExtendedConfig<Transformation> transformations;
private ExtendedConfig<Filter> filters;
* @param aSequenceNumberGenerator
* Sequence number generator to use.
*/
- public SingleRouterConfig(AtomicLong aSequenceNumberGenerator) {
- sequenceNumbers = aSequenceNumberGenerator;
- documentTypes = new ConfigImpl<DocumentType>(sequenceNumbers) {
+ public SingleRouterConfig(Id<RouterConfig> aId) {
+ id = aId;
+ documentTypes = new ConfigImpl<DocumentType>(new Id<Config>(
+ "documentTypes")) {
@Override
- public DocumentType wrap(Id<DocumentType> aId, DocumentType aT) {
- return new RobustDocumentType(aId, aT);
+ public DocumentType wrap(DocumentType aT) {
+ return new RobustDocumentType(aT);
}
};
- transformations = new ConfigImpl<Transformation>(sequenceNumbers) {
+ transformations = new ConfigImpl<Transformation>(new Id<Config>(
+ "transformations")) {
@Override
- public Transformation wrap(Id<Transformation> aId,
- Transformation aTransformation) {
- return new RobustTransformation(aId, aTransformation);
+ public Transformation wrap(Transformation aTransformation) {
+ return new RobustTransformation(aTransformation);
}
};
- filters = new ConfigImpl<Filter>(sequenceNumbers) {
+ filters = new ConfigImpl<Filter>(new Id<Config>("filters")) {
@Override
- public Filter wrap(Id<Filter> aId, Filter aFilter) {
- return new RobustFilter(aId, aFilter);
+ public Filter wrap(Filter aFilter) {
+ return new RobustFilter(aFilter);
}
};
}
+ // TODO test getId.
+ @Override
+ public Id<RouterConfig> getId() {
+ return id;
+ }
+
@Override
public Config<DocumentType> documentTypeConfig() {
return documentTypes;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.Transformation;
/**
*/
public class TransformationPaths {
- private Map<Id<Transformation>, Transformation> transformations;
+ private Collection<Transformation> transformations;
private List<String> vertices;
private TransformationPath[][] matrix;
- private Map<String, List<TransformationPath>> sequences;
-
/**
* Construct the transformations.
*/
- public TransformationPaths(
- Map<Id<Transformation>, Transformation> aTransformations) {
+ public TransformationPaths(Collection<Transformation> aTransformations) {
transformations = aTransformations;
vertices = new ArrayList<String>();
matrix = new TransformationPath[0][0];
// Obtain possible starting points.
Set<String> v = new HashSet<String>();
- for (Transformation transformation : transformations.values()) {
+ for (Transformation transformation : transformations) {
v.add(transformation.getFromType());
v.add(transformation.getToType());
}
for (int i = 0; i < nvertices; i++) {
matrix[i][i] = new TransformationPath();
}
- for (Transformation transformation : transformations.values()) {
+ for (Transformation transformation : transformations) {
int from = vertices.indexOf(transformation.getFromType());
int to = vertices.indexOf(transformation.getToType());
TransformationPath path = new TransformationPath(transformation);
private void publishImpl(String aSource, DOMSource aEvent) {
long time = clock.currentTimeMillis();
- Id<DOMSource> id = new Id<DOMSource>(nextEventId.getAndIncrement());
+ Id<DOMSource> id = new Id<DOMSource>(nextEventId.getAndIncrement() + "");
List<String> types = determineDocumentTypes(aEvent);
EventInfo info = new EventInfo(time, aSource, id, types, aEvent);
// allow the event.
boolean result = destination.receive(transformed);
listener.delivered(aInfo, ts, destinationId.getId(),
- destination.getName(), result);
+ result);
delivered = delivered || result;
}
private boolean isAllowedByFilters(String aType, DOMSource aEvent) {
boolean allowed = true;
- for (Filter filter : config.getRouterConfig().filterConfig().map()
- .values()) {
+ for (Filter filter : config.getRouterConfig().filterConfig().values()) {
if (!filter.isAllowed(aType, aEvent)) {
allowed = false;
}
private List<String> determineDocumentTypes(DOMSource aEvent) {
List<String> res = new ArrayList<String>();
for (DocumentType type : config.getRouterConfig().documentTypeConfig()
- .map().values()) {
+ .values()) {
if (type.isInstance(aEvent)) {
res.add(type.getName());
}
return res;
}
- private void logEvent(String aMessage, String aSource, DOMSource aEvent) {
- LOGGER.log(Level.WARNING,
- aMessage + ": " + eventToString(aSource, aEvent));
- }
-
private String eventToString(String aSource, DOMSource aEvent) {
return "source '" + aSource + "': Event: '" +
new XMLDocument(aEvent).print(true) + "'";
public Id<Destination> registerDestination(Destination aDestination) {
notNull("destination", aDestination);
long seqno = sequenceNumbers.getAndIncrement();
- Id<Destination> id = new Id<Destination>(seqno);
+ Id<Destination> id = new Id<Destination>(seqno + "");
destinations.put(id, new RobustDestination(id, aDestination));
return id;
}
*/
package org.wamblee.xmlrouter.impl;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import org.wamblee.xmlrouter.common.Id;
public XMLRouterConfigService(XMLRouterConfiguration aConfig) {
sequence = new AtomicLong(1L);
config = aConfig;
- routerConfigs = new ConfigImpl<RouterConfig>(sequence) {
- public RouterConfig wrap(Id<RouterConfig> aId, RouterConfig aT) {
+ routerConfigs = new ConfigImpl<RouterConfig>(new Id<Config>("config")) {
+ public RouterConfig wrap(RouterConfig aT) {
return aT;
}
};
@Override
public RouterConfig emptyConfig() {
- return new SingleRouterConfig(sequence);
+ // TODO check and document API impacts.
+ String id = UUID.randomUUID().toString();
+ return new SingleRouterConfig(new Id<RouterConfig>(id));
}
@Override
- public Id<RouterConfig> apply(RouterConfig aConfig,
- Id<RouterConfig> aOldConfig) {
+ public void apply(RouterConfig aConfig, Id<RouterConfig> aOldConfig) {
if (aOldConfig != null) {
routerConfigs.remove(aOldConfig);
}
- Id<RouterConfig> id = routerConfigs.add(aConfig);
+ routerConfigs.add(aConfig);
update();
- return id;
}
@Override
private void update() {
ExtendedRouterConfig newconfig = new CompositeRouterConfig(
- routerConfigs.map().values());
+ new Id<RouterConfig>("routerconfig"), routerConfigs.values());
config.setRouterConfig(newconfig);
}
import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.RouterConfig;
/**
public XMLRouterConfigurationImpl(ExtendedRouterConfig aConfig) {
config = aConfig;
transformations = new TransformationPaths(config.transformationConfig()
- .map());
+ .values());
}
public XMLRouterConfigurationImpl() {
- this(new CompositeRouterConfig(new ArrayList<RouterConfig>()));
+ this(new CompositeRouterConfig(new Id<RouterConfig>("routerconfig"),
+ new ArrayList<RouterConfig>()));
}
@Override
public void setRouterConfig(ExtendedRouterConfig aConfig) {
TransformationPaths newTransformations = new TransformationPaths(
- aConfig.transformationConfig().map());
+ aConfig.transformationConfig().values());
wlock.lock();
try {
import org.junit.Before;
import org.junit.Test;
import org.wamblee.xmlrouter.common.Id;
+import org.wamblee.xmlrouter.config.Config;
+import org.wamblee.xmlrouter.config.Identifiable;
public class ConfigImplTest {
- private static interface MyType {
+ private static interface MyType extends Identifiable {
}
private static class MyTypeWrapper implements MyType {
- private Id<MyType> id;
private MyType type;
- public MyTypeWrapper(Id<MyType> aId, MyType aType) {
- id = aId;
+ public MyTypeWrapper(MyType aType) {
type = aType;
}
public MyType getType() {
return type;
}
+
+ @Override
+ public Id getId() {
+ return type.getId();
+ }
}
private AtomicLong sequence;
@Before
public void setUp() {
sequence = new AtomicLong(1L);
- config = new ConfigImpl<MyType>(sequence) {
+ config = new ConfigImpl<MyType>(new Id<Config>("mytype")) {
@Override
- public MyType wrap(Id<MyType> aId, MyType aT) {
- return new MyTypeWrapper(aId, aT);
+ public MyType wrap(MyType aT) {
+ return new MyTypeWrapper(aT);
}
};
}
@Test
public void testAdd() {
MyType type1 = mock(MyType.class);
+ when(type1.getId()).thenReturn(new Id("type1"));
- Id<MyType> id1 = config.add(type1);
+ 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());
+ assertEquals(1, config.values().size());
+ assertTrue(config.values().get(0) instanceof MyTypeWrapper);
+ assertSame(type1, ((MyTypeWrapper) config.values().get(0)).getType());
// 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));
+ when(type2.getId()).thenReturn(new Id("type2"));
+ config.add(type2);
+
+ assertEquals(2, config.values().size());
}
@Test
public void testRemove() {
MyType type1 = mock(MyType.class);
- Id<MyType> id1 = config.add(type1);
+ when(type1.getId()).thenReturn(new Id("type1"));
+
+ config.add(type1);
- assertNotNull(id1);
- assertEquals(1, config.map().size());
+ assertEquals(1, config.values().size());
- config.remove(id1);
- assertTrue(config.map().isEmpty());
+ assertTrue(config.remove(new Id("type1")));
+ assertTrue(config.values().isEmpty());
}
@Test(expected = UnsupportedOperationException.class)
public void testUnmodifiable() {
- config.map().put(new Id<MyType>(100L), mock(MyType.class));
+ config.values().add(mock(MyType.class));
}
}
@Before
public void setUp() {
destination = mock(Destination.class);
- robust = new RobustDestination(new Id<Destination>(100), destination);
+ robust = new RobustDestination(new Id<Destination>("100"), destination);
source = mock(DOMSource.class);
}
import org.junit.Before;
import org.junit.Test;
-import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.DocumentType;
public class RobustDocumentTypeTest {
@Before
public void setUp() {
documentType = mock(DocumentType.class);
- robust = new RobustDocumentType(new Id<DocumentType>(10), documentType);
+ robust = new RobustDocumentType(documentType);
source = mock(DOMSource.class);
}
import org.junit.Before;
import org.junit.Test;
-import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.Filter;
public class RobustFilterTest {
@Before
public void setUp() {
filter = mock(Filter.class);
- robust = new RobustFilter(new Id<Filter>(10), filter);
+ robust = new RobustFilter(filter);
source = mock(DOMSource.class);
}
import org.junit.Before;
import org.junit.Test;
-import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.Transformation;
public class RobustTransformationTest {
@Before
public void setUp() {
transformation = mock(Transformation.class);
- robust = new RobustTransformation(new Id<Transformation>(100),
- transformation);
+ robust = new RobustTransformation(transformation);
source = mock(DOMSource.class);
resSource = mock(DOMSource.class);
}
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.RouterConfig;
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);
+ config = new SingleRouterConfig(new Id<RouterConfig>("routerconfig"));
}
@Test
public void testDocumentType() {
DocumentType type1 = mock(DocumentType.class);
+ when(type1.getId()).thenReturn(new Id<DocumentType>("type1"));
DocumentType type2 = mock(DocumentType.class);
+ when(type1.getId()).thenReturn(new Id<DocumentType>("type2"));
- Id<DocumentType> id1 = config.documentTypeConfig().add(type1);
-
- Id<DocumentType> id2 = config.documentTypeConfig().add(type2);
- assertFalse(id1.equals(id2));
-
- assertEquals(2, config.documentTypeConfig().map().size());
- assertTrue(config.documentTypeConfig().map().get(id1) instanceof RobustDocumentType);
+ config.documentTypeConfig().add(type1);
+ config.documentTypeConfig().add(type2);
+ assertEquals(2, config.documentTypeConfig().values().size());
+ assertTrue(config.documentTypeConfig().values().get(0) instanceof RobustDocumentType);
}
@Test
public void testTransformation() {
Transformation transformation1 = mock(Transformation.class);
+ when(transformation1.getId()).thenReturn(new Id<Transformation>("t1"));
Transformation transformation2 = mock(Transformation.class);
+ when(transformation1.getId()).thenReturn(new Id<Transformation>("t2"));
- Id<Transformation> id1 = config.transformationConfig().add(
- transformation1);
+ config.transformationConfig().add(transformation1);
- Id<Transformation> id2 = config.transformationConfig().add(
- transformation2);
- assertFalse(id1.equals(id2));
+ config.transformationConfig().add(transformation2);
- assertEquals(2, config.transformationConfig().map().size());
- assertTrue(config.transformationConfig().map().get(id1) instanceof RobustTransformation);
+ assertEquals(2, config.transformationConfig().values().size());
+ assertTrue(config.transformationConfig().values().get(0) instanceof RobustTransformation);
}
@Test
public void testFilter() {
Filter filter1 = mock(Filter.class);
+ when(filter1.getId()).thenReturn(new Id<Filter>("f1"));
Filter filter2 = mock(Filter.class);
+ when(filter1.getId()).thenReturn(new Id<Filter>("f2"));
- Id<Filter> id1 = config.filterConfig().add(filter1);
+ config.filterConfig().add(filter1);
- Id<Filter> id2 = config.filterConfig().add(filter2);
- assertFalse(id1.equals(id2));
+ config.filterConfig().add(filter2);
- assertEquals(2, config.filterConfig().map().size());
- assertTrue(config.filterConfig().map().get(id1) instanceof RobustFilter);
+ assertEquals(2, config.filterConfig().values().size());
+ assertTrue(config.filterConfig().values().get(0) instanceof RobustFilter);
}
}
import static junit.framework.Assert.*;
+import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.List;
import javax.xml.transform.dom.DOMSource;
}
@Override
- public String getName() {
- return "myname";
+ public Id<Transformation> getId() {
+ return new Id<Transformation>("myname");
}
@Override
private TransformationPaths transformations;
- private Map<Id<Transformation>, Transformation> createTransformations(
- long aStartId, Transformation... aTransformations) {
- Map<Id<Transformation>, Transformation> res = new LinkedHashMap<Id<Transformation>, Transformation>();
+ private List<Transformation> createTransformations(long aStartId,
+ Transformation... aTransformations) {
+ List<Transformation> res = new ArrayList<Transformation>();
- long id = aStartId;
for (Transformation t : aTransformations) {
- res.put(new Id<Transformation>(id++), t);
+ res.add(t);
}
return res;
}
@Test
public void testWithoutTransformations() {
transformations = new TransformationPaths(
- new HashMap<Id<Transformation>, Transformation>());
+ new ArrayList<Transformation>());
Collection<String> res = transformations.getPossibleTargetTypes("a");
assertEquals(1, res.size());
import org.junit.Before;
import org.junit.Test;
import org.wamblee.general.SystemClock;
+import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.DocumentType;
import org.wamblee.xmlrouter.config.RouterConfig;
import org.wamblee.xmlrouter.config.Transformation;
public void testOneTransformationOneDestination() {
RouterConfig routerConfig = registerDocumentType("any");
Transformation transformation = mock(Transformation.class);
- when(transformation.getName()).thenReturn("trans");
+ when(transformation.getId())
+ .thenReturn(new Id<Transformation>("trans"));
when(transformation.getFromType()).thenReturn("any");
when(transformation.getToType()).thenReturn("bla");
when(transformation.transform(same(source1))).thenReturn(source2);
when(destination.receive(any(DOMSource.class))).thenReturn(true);
routerService.publish("bla", source1);
verify(listener).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(transformation).transform(source1);
verify(destination).receive(same(source2));
import java.util.Arrays;
import java.util.Collection;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import javax.xml.transform.dom.DOMSource;
import org.wamblee.xmlrouter.common.Id;
import org.wamblee.xmlrouter.config.DocumentType;
import org.wamblee.xmlrouter.config.Filter;
+import org.wamblee.xmlrouter.config.RouterConfig;
import org.wamblee.xmlrouter.config.Transformation;
import org.wamblee.xmlrouter.listener.EventInfo;
import org.wamblee.xmlrouter.listener.EventListener;
@Before
public void setUp() {
- routerConfig = new SingleRouterConfig(new AtomicLong(1L));
+ routerConfig = new SingleRouterConfig(new Id<RouterConfig>(
+ "routerconfig"));
config = new XMLRouterConfigurationImpl(routerConfig);
EventListener logListener = new LoggingEventListener(Level.INFO);
listener = spy(logListener);
router.publish("any", source1);
verify(listener).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(destinationSpy).receive(same(source1));
// Unregister the destination.
DocumentType type = mock(DocumentType.class);
when(type.isInstance(any(DOMSource.class))).thenReturn(true);
when(type.getName()).thenReturn(aType);
- Id<DocumentType> typeId = routerConfig.documentTypeConfig().add(type);
+ routerConfig.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 = routerConfig.documentTypeConfig().add(type);
+ routerConfig.documentTypeConfig().add(type);
}
private Destination registerDestination(boolean aResult, String... types) {
router.publish("any", source1);
verify(listener).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(destinationSpy2).receive(same(source1));
.registerDestination(destinationSpy2);
router.publish("any", source1);
verify(listener).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(destinationSpy, never()).receive(same(source1));
verify(destinationSpy2).receive(same(source1));
.registerDestination(destinationSpy2);
router.publish("any", source1);
verify(listener).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(destinationSpy, never()).receive(same(source1));
verify(destinationSpy2).receive(same(source1));
public void testOneTransformationOneDestination() {
registerDocumentType("any");
Transformation transformation = mock(Transformation.class);
- when(transformation.getName()).thenReturn("trans");
+ when(transformation.getId())
+ .thenReturn(new Id<Transformation>("trans"));
when(transformation.getFromType()).thenReturn("any");
when(transformation.getToType()).thenReturn("bla");
when(transformation.transform(same(source1))).thenReturn(source2);
when(destination.receive(any(DOMSource.class))).thenReturn(true);
router.publish("bla", source1);
verify(listener).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(transformation).transform(source1);
verify(destination).receive(same(source2));
public void testMisbehavingTransformationOneDestination() {
registerDocumentType("any");
Transformation transformation = mock(Transformation.class);
- when(transformation.getName()).thenReturn("trans");
+ when(transformation.getId())
+ .thenReturn(new Id<Transformation>("trans"));
when(transformation.getFromType()).thenReturn("any");
when(transformation.getToType()).thenReturn("bla");
doThrow(new RuntimeException("x")).when(transformation).transform(
private Transformation createTransformation(String aFrom, String aTo,
DOMSource aSource, DOMSource aTarget) {
Transformation transformation = mock(Transformation.class);
- when(transformation.getName()).thenReturn("trans");
+ when(transformation.getId())
+ .thenReturn(new Id<Transformation>("trans"));
when(transformation.getFromType()).thenReturn(aFrom);
when(transformation.getToType()).thenReturn(aTo);
when(transformation.transform(same(aSource))).thenReturn(aTarget);
.thenReturn(Arrays.asList("bla", "bla2"));
reset(transformation);
- when(transformation.getName()).thenReturn("trans");
+ when(transformation.getId())
+ .thenReturn(new Id<Transformation>("trans"));
when(transformation.getFromType()).thenReturn("any");
when(transformation.getToType()).thenReturn("bla");
when(transformation.transform(same(source1))).thenReturn(null);
when(destination.receive(any(DOMSource.class))).thenReturn(true);
router.publish("bla", source1);
verify(listener).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(transformation).transform(source1);
verify(transformation2).transform(source1);
router.publish("source", source1);
verify(listener, times(2)).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(dest1).receive(same(source1));
verify(dest2).receive(same(source1));
router.publish("source", source1);
verify(listener, times(2)).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(dest).receive(same(source1));
verify(dest).receive(same(source2));
router.publish("source", source1);
verify(listener).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
+ anyListOf(Transformation.class), anyString(), eq(true));
verify(dest).receive(same(source3));
}
router.publish("source", source1);
verify(listener).delivered(any(EventInfo.class),
- anyListOf(Transformation.class), anyLong(), anyString(), eq(false));
+ anyListOf(Transformation.class), anyString(), eq(false));
}
}
@Override
@ReadLock
public void delivered(EventInfo aInfo, List<Transformation> aSequence,
- long aDestinationId, String aDestinationName, boolean aSuccessFlag) {
+ String aDestinationId, boolean aSuccessFlag) {
for (EventListener logger : loggers) {
try {
- logger.delivered(aInfo, aSequence, aDestinationId,
- aDestinationName, aSuccessFlag);
+ logger
+ .delivered(aInfo, aSequence, aDestinationId, aSuccessFlag);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Logger threw exception", e);
}
* Sequence of transformations performed.
* @param aDestinationId
* Id of the destination the event was delivered to.
- * @param aDestinationName
- * Destination name.
* @param aSuccessFlag
* Whether or not event delivery succeeded.
*/
void delivered(EventInfo aInfo, List<Transformation> aSequence,
- long aDestinationId, String aDestinationName, boolean aSuccessFlag);
+ String aDestinationId, boolean aSuccessFlag);
/**
* Called when an event could not be delivered to any destination.
@Override
public void delivered(EventInfo aEvent, List<Transformation> aSequence,
- long aDestinationId, String aDestinationName, boolean aSuccessFlag) {
+ String aDestinationId, boolean aSuccessFlag) {
if (LOGGER.isLoggable(level)) {
- LOGGER
- .log(level, "event delivered: " + aEvent + ", sequence '" +
- getSequenceString(aSequence) + "', destinationId " +
- aDestinationId + ", destinationName '" + aDestinationName +
- "'");
+ LOGGER.log(level, "event delivered: " + aEvent + ", sequence '" +
+ getSequenceString(aSequence) + "', destinationId " +
+ aDestinationId + "'");
}
}
buf.append(", ");
}
Transformation transformation = aSequence.get(i);
- buf.append(transformation.getName());
+ buf.append(transformation.getId());
buf.append("(");
buf.append(transformation.getFromType());
buf.append("->");
public class CompositeEventListenerTest {
- private static final String DESTINATION_NAME = "dest";
- private static final long DESTINATION_ID = 12L;
+ private static final String DESTINATION_ID = "destid";
private CompositeEventListener composite;
private EventInfo source;
public void testNoListeners() {
// verify no exceptions occur.
composite.delivered(mock(EventInfo.class), getTransformations(),
- DESTINATION_ID, DESTINATION_NAME, true);
+ DESTINATION_ID, true);
composite.notDelivered(mock(EventInfo.class));
}
}
private void invokeDelivered() {
- composite.delivered(source, getTransformations(), DESTINATION_ID,
- DESTINATION_NAME, true);
+ composite.delivered(source, getTransformations(), DESTINATION_ID, true);
}
private void invokeNotDelivered() {
private void checkInvokeDelivered(EventListener listener) {
verify(listener).delivered(same(source), eq(getTransformations()),
- eq(DESTINATION_ID), eq(DESTINATION_NAME), eq(true));
+ eq(DESTINATION_ID), eq(true));
}
@Test