2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.Iterator;
15 import java.util.List;
17 import java.util.Objects;
18 import java.util.Optional;
19 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Convertor;
20 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.ConvertorData;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.ParametrizedConvertor;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchResponseConvertor;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchV10ResponseConvertor;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Manages various convertors and allows to use them all in one generic way
30 public class ConvertorManager {
31 private static final Logger LOG = LoggerFactory.getLogger(ConvertorManager.class);
32 private static ConvertorManager INSTANCE;
35 INSTANCE = new ConvertorManager();
36 // All convertors are registered here
37 INSTANCE.registerConvertor(new TableFeaturesConvertor());
38 INSTANCE.registerConvertor(new TableFeaturesResponseConvertor());
39 INSTANCE.registerConvertor(new MeterConvertor());
40 INSTANCE.registerConvertor(new MeterStatsResponseConvertor());
41 INSTANCE.registerConvertor(new MeterConfigStatsResponseConvertor());
42 INSTANCE.registerConvertor(new PortConvertor());
43 // TODO: Add MatchConvertor
44 INSTANCE.registerConvertor(new MatchResponseConvertor());
45 INSTANCE.registerConvertor(new MatchV10ResponseConvertor());
48 // Actual convertor keys
49 private List<Class<?>> convertorKeys = new ArrayList<>();
50 private List<Class<?>> parametrizedConvertorKeys = new ArrayList<>();
52 // Cache, that holds all registered convertors, but they can have multiple keys,
53 // based on instanceof checks in the convert method
54 private Map<Class<?>, Convertor> convertors = new HashMap<>();
55 private Map<Class<?>, ParametrizedConvertor> parametrizedConvertors = new HashMap<>();
57 private ConvertorManager() {
58 // Hiding implicit constructor
62 * Gets instance of Convertor Manager.
64 * @return the instance
66 public static ConvertorManager getInstance() {
73 * @param convertor the convertor
74 * @return if registration was successful
76 public boolean registerConvertor(final Convertor convertor) {
77 final Class<?> type = convertor.getType();
79 if (convertors.containsKey(type)) {
80 LOG.warn("Convertor for type {} is already registered", type);
84 convertorKeys.add(type);
85 convertors.put(type, convertor);
86 LOG.debug("{} is now converted by {}", type, convertor);
93 * @param convertor the convertor
94 * @return if registration was successful
96 public boolean registerConvertor(final ParametrizedConvertor convertor) {
97 final Class<?> type = convertor.getType();
99 if (parametrizedConvertors.containsKey(type)) {
100 LOG.warn("Convertor for type {} is already registered", type);
104 parametrizedConvertorKeys.add(type);
105 parametrizedConvertors.put(type, convertor);
106 LOG.debug("{} is now converted by {}", type, convertor);
111 * Lookup and use convertor by specified type, then converts source and returns converted result
113 * @param <FROM> the source type
114 * @param <TO> the result type
115 * @param source the source
116 * @return the result (can be empty, if no convertor was found)
118 @SuppressWarnings("unchecked")
119 public <FROM, TO> Optional<TO> convert(final FROM source) {
120 if (Objects.isNull(source)) {
121 LOG.trace("Cannot convert source, because it is null");
122 return Optional.empty();
125 Class<?> type = source.getClass();
127 if (source instanceof Collection) {
128 final Iterator it = ((Collection) source).iterator();
135 if (Objects.isNull(next)) {
136 LOG.trace("Cannot convert {}, because it is empty collection", type);
137 return Optional.empty();
140 type = next.getClass();
143 Convertor convertor = null;
145 if (!convertors.containsKey(type)) {
146 boolean found = false;
148 for (Class<?> key : convertorKeys) {
149 if (key.isAssignableFrom(type)) {
150 convertor = convertors.get(key);
151 convertors.put(type, convertor);
152 LOG.debug("{} is now converted by {}", type, convertor);
159 LOG.error("Convertor for {} not found", type);
160 return Optional.empty();
164 if (Objects.isNull(convertor)) {
165 convertor = convertors.get(type);
168 final Object result = convertor.convert(source);
169 return Optional.of((TO) result);
173 * Lookup and use convertor by specified type, then converts source and returns converted result
175 * @param <FROM> the source type
176 * @param <TO> the result type
177 * @param <DATA> the data type
178 * @param source the source
179 * @param data convertor data
180 * @return the result (can be empty, if no convertor was found)
182 @SuppressWarnings("unchecked")
183 public <FROM, TO, DATA extends ConvertorData> Optional<TO> convert(final FROM source, final DATA data) {
184 if (Objects.isNull(source)) {
185 LOG.trace("Cannot convert source, because it is null");
186 return Optional.empty();
189 Class<?> type = source.getClass();
191 if (source instanceof Collection) {
192 final Iterator it = ((Collection) source).iterator();
199 if (Objects.isNull(next)) {
200 LOG.trace("Cannot convert {}, because it is empty collection", type);
201 return Optional.empty();
204 type = next.getClass();
207 ParametrizedConvertor convertor = null;
209 if (!parametrizedConvertors.containsKey(type)) {
210 boolean found = false;
212 for (Class<?> key : parametrizedConvertorKeys) {
213 if (key.isAssignableFrom(type)) {
214 convertor = parametrizedConvertors.get(key);
215 parametrizedConvertors.put(type, convertor);
216 LOG.debug("{} is now converted by {}", type, convertor);
223 LOG.error("Convertor for {} not found", type);
224 return Optional.empty();
228 if (Objects.isNull(convertor)) {
229 convertor = parametrizedConvertors.get(type);
232 final Object result = convertor.convert(source, data);
233 return Optional.of((TO) result);