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());
40 // Actual convertor keys
41 private List<Class<?>> convertorKeys = new ArrayList<>();
42 private List<Class<?>> parametrizedConvertorKeys = new ArrayList<>();
44 // Cache, that holds all registered convertors, but they can have multiple keys,
45 // based on instanceof checks in the convert method
46 private Map<Class<?>, Convertor> convertors = new HashMap<>();
47 private Map<Class<?>, ParametrizedConvertor> parametrizedConvertors = new HashMap<>();
49 private ConvertorManager() {
50 // Hiding implicit constructor
54 * Gets instance of Convertor Manager.
56 * @return the instance
58 public static ConvertorManager getInstance() {
65 * @param convertor the convertor
66 * @return if registration was successful
68 public boolean registerConvertor(final Convertor convertor) {
69 final Class<?> type = convertor.getType();
71 if (convertors.containsKey(type)) {
72 LOG.warn("Convertor for type {} is already registered", type);
76 convertorKeys.add(type);
77 convertors.put(type, convertor);
78 LOG.debug("{} is now converted by {}", type, convertor);
85 * @param convertor the convertor
86 * @return if registration was successful
88 public boolean registerConvertor(final ParametrizedConvertor convertor) {
89 final Class<?> type = convertor.getType();
91 if (parametrizedConvertors.containsKey(type)) {
92 LOG.warn("Convertor for type {} is already registered", type);
96 parametrizedConvertorKeys.add(type);
97 parametrizedConvertors.put(type, convertor);
98 LOG.debug("{} is now converted by {}", type, convertor);
103 * Lookup and use convertor by specified type, then converts source and returns converted result
105 * @param <FROM> the source type
106 * @param <TO> the result type
107 * @param source the source
108 * @return the result (can be empty, if no convertor was found)
110 @SuppressWarnings("unchecked")
111 public <FROM, TO> Optional<TO> convert(final FROM source) {
112 if (Objects.isNull(source)) {
113 LOG.trace("Cannot convert source, because it is null");
114 return Optional.empty();
117 Class<?> type = source.getClass();
119 if (source instanceof Collection) {
120 final Iterator it = ((Collection) source).iterator();
127 if (Objects.isNull(next)) {
128 LOG.trace("Cannot convert {}, because it is empty collection", type);
129 return Optional.empty();
132 type = next.getClass();
135 Convertor convertor = null;
137 if (!convertors.containsKey(type)) {
138 boolean found = false;
140 for (Class<?> key : convertorKeys) {
141 if (key.isAssignableFrom(type)) {
142 convertor = convertors.get(key);
143 convertors.put(type, convertor);
144 LOG.debug("{} is now converted by {}", type, convertor);
151 LOG.error("Convertor for {} not found", type);
152 return Optional.empty();
156 if (Objects.isNull(convertor)) {
157 convertor = convertors.get(type);
160 final Object result = convertor.convert(source);
161 return Optional.of((TO) result);
165 * Lookup and use convertor by specified type, then converts source and returns converted result
167 * @param <FROM> the source type
168 * @param <TO> the result type
169 * @param <DATA> the data type
170 * @param source the source
171 * @param data convertor data
172 * @return the result (can be empty, if no convertor was found)
174 @SuppressWarnings("unchecked")
175 public <FROM, TO, DATA extends ConvertorData> Optional<TO> convert(final FROM source, final DATA data) {
176 if (Objects.isNull(source)) {
177 LOG.trace("Cannot convert source, because it is null");
178 return Optional.empty();
181 Class<?> type = source.getClass();
183 if (source instanceof Collection) {
184 final Iterator it = ((Collection) source).iterator();
191 if (Objects.isNull(next)) {
192 LOG.trace("Cannot convert {}, because it is empty collection", type);
193 return Optional.empty();
196 type = next.getClass();
199 ParametrizedConvertor convertor = null;
201 if (!parametrizedConvertors.containsKey(type)) {
202 boolean found = false;
204 for (Class<?> key : parametrizedConvertorKeys) {
205 if (key.isAssignableFrom(type)) {
206 convertor = parametrizedConvertors.get(key);
207 parametrizedConvertors.put(type, convertor);
208 LOG.debug("{} is now converted by {}", type, convertor);
215 LOG.error("Convertor for {} not found", type);
216 return Optional.empty();
220 if (Objects.isNull(convertor)) {
221 convertor = parametrizedConvertors.get(type);
224 final Object result = convertor.convert(source, data);
225 return Optional.of((TO) result);