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