Bug 4202: Migrate also toaster to use mdsal project
[controller.git] / opendaylight / commons / concepts / src / main / java / org / opendaylight / controller / concepts / transform / CompositeClassBasedTransformer.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.concepts.transform;
10
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Map;
14 import java.util.concurrent.ConcurrentHashMap;
15
16
17 /**
18  * Transformer which aggregates multiple implementations of
19  * {@link InputClassBasedTransformer}.
20  *
21  * The transformation process is driven by {@link Class} of input. The selection
22  * of used {@link InputClassBasedTransformer} is done by using the {@link Class}
23  * of input as a key to select the transformer.
24  *
25  * This approach provides quick resolution of transformer, but does not support
26  * registering a super type of input to provide transformation support for all
27  * subclasses, one must register a new instance of transformer for each valid
28  * input class.
29  *
30  * If you need more flexible selection of transformation consider using
31  * {@link CompositeConditionalTransformer} which is slower but most flexible or
32  * {@link RuleBasedTransformer} which provides declarative approach for
33  * transformation.
34  *
35  * See {@link #transform(Object)} for more information about tranformation
36  * process.
37  *
38  * @author Tony Tkacik <ttkacik@cisco.com>
39  *
40  * @param <I>
41  *            Input super-type
42  * @param <P>
43  *            Product
44  */
45 public abstract class CompositeClassBasedTransformer<I, P> implements
46         InputClassBasedTransformer<I, I, P>,
47         AggregateTransformer<I, P> {
48
49     private Map<Class<? extends I>, InputClassBasedTransformer<I, ? extends I, P>> transformers = new ConcurrentHashMap<Class<? extends I>, InputClassBasedTransformer<I, ? extends I, P>>();
50
51     /**
52      * Transforms an input into instance of Product class.
53      *
54      * The final registered transformer is the one which match following
55      * condition:
56      *
57      * <code>input.getClass() == transformer.getInputClass()</code>
58      *
59      * This means that transformers are not resolved by class hierarchy, only
60      * selected based on final class of the input. If you need more flexible
61      * selection of transformation consider using
62      * {@link CompositeConditionalTransformer} which is slower but more
63      * flexible.
64      *
65      */
66     @Override
67     public P transform(I input) {
68         @SuppressWarnings("unchecked")
69         InputClassBasedTransformer<I, I, P> transformer = (InputClassBasedTransformer<I, I, P>) transformers
70                 .get(input.getClass());
71         if (transformer == null)
72             throw new IllegalArgumentException("Transformation of: " + input
73                     + " is not supported");
74         return transformer.transform(input);
75     }
76
77     /**
78      * Registers a new transformer.
79      *
80      * The transformer is registered for class returned by
81      * {@link InputClassBasedTransformer#getInputClass()}. Only one transformer
82      * can be registered for particular input class.
83      *
84      */
85     public void addTransformer(
86             InputClassBasedTransformer<I, ? extends I, P> transformer)
87             throws IllegalStateException {
88         if (transformer == null)
89             throw new IllegalArgumentException("Transformer should not be null");
90         if (transformer.getInputClass() == null)
91             throw new IllegalArgumentException(
92                     "Transformer should specify input class.");
93         transformers.put(transformer.getInputClass(), transformer);
94     }
95
96     /**
97      * Removes an registered transformer.
98      *
99      * Note: Removal is currently unsupported.
100      *
101      * @param transformer
102      *            Tranformer to be removed.
103      * @throws IllegalArgumentException
104      *             If the provided transformer is null or is not registered.
105      */
106     public void removeTransformer(
107             InputClassBasedTransformer<I, ? extends I, P> transformer)
108             throws IllegalArgumentException {
109         throw new UnsupportedOperationException("Not implemented yet");
110     }
111
112     @Override
113     public Collection<P> transformAll(Collection<? extends I> inputs) {
114         Collection<P> ret = new ArrayList<P>();
115         for (I i : inputs) {
116             ret.add(transform(i));
117         }
118         return ret;
119     }
120
121 }