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.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
26 * Manages various convertors and allows to use them all in one generic way
28 public class ConvertorManager {
29 private static final Logger LOG = LoggerFactory.getLogger(ConvertorManager.class);
30 private static ConvertorManager INSTANCE;
33 INSTANCE = new ConvertorManager();
34 // All convertors are registered here
35 INSTANCE.registerConvertor(new TableFeaturesConvertor());
36 INSTANCE.registerConvertor(new TableFeaturesResponseConvertor());
37 INSTANCE.registerConvertor(new MeterConvertor());
38 INSTANCE.registerConvertor(new MeterStatsResponseConvertor());
39 INSTANCE.registerConvertor(new MeterConfigStatsResponseConvertor());
42 // Actual convertor keys
43 private List<Class<?>> convertorKeys = new ArrayList<>();
44 private List<Class<?>> parametrizedConvertorKeys = new ArrayList<>();
46 // Cache, that holds all registered convertors, but they can have multiple keys,
47 // based on instanceof checks in the convert method
48 private Map<Class<?>, Convertor> convertors = new HashMap<>();
49 private Map<Class<?>, ParametrizedConvertor> parametrizedConvertors = new HashMap<>();
51 private ConvertorManager() {
52 // Hiding implicit constructor
56 * Gets instance of Convertor Manager.
58 * @return the instance
60 public static ConvertorManager getInstance() {
67 * @param convertor the convertor
68 * @return if registration was successful
70 public boolean registerConvertor(final Convertor convertor) {
71 final Class<?> type = convertor.getType();
73 if (convertors.containsKey(type)) {
74 LOG.warn("Convertor for type {} is already registered", type);
78 convertorKeys.add(type);
79 convertors.put(type, convertor);
80 LOG.debug("{} is now converted by {}", type, convertor);
87 * @param convertor the convertor
88 * @return if registration was successful
90 public boolean registerConvertor(final ParametrizedConvertor convertor) {
91 final Class<?> type = convertor.getType();
93 if (parametrizedConvertors.containsKey(type)) {
94 LOG.warn("Convertor for type {} is already registered", type);
98 parametrizedConvertorKeys.add(type);
99 parametrizedConvertors.put(type, convertor);
100 LOG.debug("{} is now converted by {}", type, convertor);
105 * Lookup and use convertor by specified type, then converts source and returns converted result
107 * @param <FROM> the source type
108 * @param <TO> the result type
109 * @param source the source
110 * @return the result (can be empty, if no convertor was found)
112 @SuppressWarnings("unchecked")
113 public <FROM, TO> Optional<TO> convert(final FROM source) {
114 if (Objects.isNull(source)) {
115 LOG.trace("Cannot convert source, because it is null");
116 return Optional.empty();
119 Class<?> type = source.getClass();
121 if (source instanceof Collection) {
122 final Iterator it = ((Collection) source).iterator();
129 if (Objects.isNull(next)) {
130 LOG.trace("Cannot convert {}, because it is empty collection", type);
131 return Optional.empty();
134 type = next.getClass();
137 Convertor convertor = null;
139 if (!convertors.containsKey(type)) {
140 boolean found = false;
142 for (Class<?> key : convertorKeys) {
143 if (key.isAssignableFrom(type)) {
144 convertor = convertors.get(key);
145 convertors.put(type, convertor);
146 LOG.debug("{} is now converted by {}", type, convertor);
153 LOG.error("Convertor for {} not found", type);
154 return Optional.empty();
158 if (Objects.isNull(convertor)) {
159 convertor = convertors.get(type);
162 final Object result = convertor.convert(source);
163 return Optional.of((TO) result);
167 * Lookup and use convertor by specified type, then converts source and returns converted result
169 * @param <FROM> the source type
170 * @param <TO> the result type
171 * @param <DATA> the data type
172 * @param source the source
173 * @param data convertor data
174 * @return the result (can be empty, if no convertor was found)
176 @SuppressWarnings("unchecked")
177 public <FROM, TO, DATA extends ConvertorData> Optional<TO> convert(final FROM source, final DATA data) {
178 if (Objects.isNull(source)) {
179 LOG.trace("Cannot convert source, because it is null");
180 return Optional.empty();
183 Class<?> type = source.getClass();
185 if (source instanceof Collection) {
186 final Iterator it = ((Collection) source).iterator();
193 if (Objects.isNull(next)) {
194 LOG.trace("Cannot convert {}, because it is empty collection", type);
195 return Optional.empty();
198 type = next.getClass();
201 ParametrizedConvertor convertor = null;
203 if (!parametrizedConvertors.containsKey(type)) {
204 boolean found = false;
206 for (Class<?> key : parametrizedConvertorKeys) {
207 if (key.isAssignableFrom(type)) {
208 convertor = parametrizedConvertors.get(key);
209 parametrizedConvertors.put(type, convertor);
210 LOG.debug("{} is now converted by {}", type, convertor);
217 LOG.error("Convertor for {} not found", type);
218 return Optional.empty();
222 if (Objects.isNull(convertor)) {
223 convertor = parametrizedConvertors.get(type);
226 final Object result = convertor.convert(source, data);
227 return Optional.of((TO) result);