+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.concepts.tranform;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Comparator;\r
+import java.util.Set;\r
+import java.util.TreeSet;\r
+\r
+/**\r
+ * Composite transformer which aggregates multiple implementation and selects\r
+ * the one which accepts the input.\r
+ * \r
+ * \r
+ * @author Tony Tkacik\r
+ * \r
+ * @param <I>\r
+ * Input class for transformation\r
+ * @param <P>\r
+ * Product of transformation\r
+ */\r
+public class CompositeConditionalTransformer<I, P> implements\r
+ SimpleConditionalTransformer<I, P>,\r
+ AggregateTransformer<I,P> {\r
+\r
+ private final Comparator<TransformerWithPriority<I, P>> comparator = new Comparator<TransformerWithPriority<I, P>>() {\r
+\r
+ @Override\r
+ public int compare(TransformerWithPriority<I, P> o1,\r
+ TransformerWithPriority<I, P> o2) {\r
+ return Integer.compare(o1.priority, o2.priority);\r
+ }\r
+\r
+ };\r
+ private final Set<TransformerWithPriority<I, P>> transformers;\r
+\r
+ public CompositeConditionalTransformer() {\r
+ // FIXME: Add Ordering\r
+ transformers = new TreeSet<TransformerWithPriority<I, P>>(comparator);\r
+ }\r
+\r
+ @Override\r
+ public boolean isAcceptable(I input) {\r
+ for (SimpleConditionalTransformer<I, P> trans : transformers) {\r
+ if (trans.isAcceptable(input)) {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public P transform(I input) {\r
+ for (SimpleConditionalTransformer<I, P> trans : transformers) {\r
+ if (trans.isAcceptable(input)) {\r
+ return trans.transform(input);\r
+ }\r
+ }\r
+ throw new IllegalStateException(\r
+ "Transformer for provided input is not available.");\r
+ }\r
+\r
+ public void addTransformer(SimpleConditionalTransformer<I, P> transformer,\r
+ int priority) throws IllegalStateException {\r
+ if (transformer == null) {\r
+ throw new IllegalArgumentException(\r
+ "transformer should not be null.");\r
+ }\r
+ TransformerWithPriority<I, P> withPriority = new TransformerWithPriority<I, P>(\r
+ transformer, priority);\r
+ if (false == transformers.add(withPriority)) {\r
+ throw new IllegalStateException("transformer " + transformer\r
+ + "already registered");\r
+ }\r
+ }\r
+\r
+ public void removeTransformer(SimpleConditionalTransformer<I, P> transformer)\r
+ throws IllegalArgumentException {\r
+ if (transformer == null) {\r
+ throw new IllegalArgumentException(\r
+ "transformer should not be null.");\r
+ }\r
+ if (false == transformers.remove(transformer)) {\r
+ throw new IllegalStateException("transformer " + transformer\r
+ + "already registered");\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public Collection<P> transformAll(Collection<? extends I> inputs) {\r
+ Collection<P> ret = new ArrayList<P>();\r
+ for (I i : inputs) {\r
+ ret.add(transform(i));\r
+ }\r
+ return ret;\r
+ }\r
+\r
+ private static class TransformerWithPriority<I, P> implements\r
+ SimpleConditionalTransformer<I, P> {\r
+ final int priority;\r
+ final SimpleConditionalTransformer<I, P> transformer;\r
+ \r
+ public TransformerWithPriority(\r
+ SimpleConditionalTransformer<I, P> transformer, int priority) {\r
+ this.priority = priority;\r
+ this.transformer = transformer;\r
+ }\r
+ \r
+ @Override\r
+ public int hashCode() {\r
+ final int prime = 31;\r
+ int result = 1;\r
+ result = prime * result\r
+ + ((transformer == null) ? 0 : transformer.hashCode());\r
+ return result;\r
+ }\r
+ \r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (this == obj)\r
+ return true;\r
+ if (obj == null)\r
+ return false;\r
+ if (getClass() != obj.getClass())\r
+ return false;\r
+ TransformerWithPriority<?,?> other = (TransformerWithPriority<?,?>) obj;\r
+ if (transformer == null) {\r
+ if (other.transformer != null)\r
+ return false;\r
+ } else if (!transformer.equals(other.transformer))\r
+ return false;\r
+ return true;\r
+ }\r
+ \r
+ @Override\r
+ public boolean isAcceptable(I input) {\r
+ return transformer.isAcceptable(input);\r
+ }\r
+ \r
+ @Override\r
+ public P transform(I input) {\r
+ return transformer.transform(input);\r
+ }\r
+ \r
+ \r
+ \r
+ \r
+ \r
+ }\r
+}\r