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.common;
12 import java.util.Objects;
13 import java.util.Optional;
14 import java.util.concurrent.ConcurrentHashMap;
15 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
16 import org.opendaylight.yangtools.yang.binding.DataContainer;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
21 * Processes source and return result based on convertor cases added to this processor.
23 * @param <FROM> the source type
24 * @param <TO> the result type
25 * @param <DATA> the type of convertor data
27 public class ConvertorProcessor<FROM extends DataContainer, TO, DATA extends ConvertorData> {
28 private static final short OFP_VERSION_ALL = 0x00;
29 private static final Logger LOG = LoggerFactory.getLogger(ConvertorProcessor.class);
31 private final Map<Short, Map<Class<?>, ConvertorCase<?, TO, DATA>>> conversions = new ConcurrentHashMap<>();
32 private ConvertorCase<?, TO, DATA> defaultCase;
35 * Add convertor processor case.
37 * @param processorCase the processor case
38 * @return the convertor processor
40 public ConvertorProcessor<FROM, TO, DATA> addCase(final ConvertorCase<?, TO, DATA> processorCase) {
41 if (processorCase.getSupportedVersions().isEmpty()) {
42 getCasesForVersion(OFP_VERSION_ALL).putIfAbsent(processorCase.getType(), processorCase);
44 for (short supportedVersion : processorCase.getSupportedVersions()) {
45 getCasesForVersion(supportedVersion).putIfAbsent(processorCase.getType(), processorCase);
53 * Process source and return result based on convertor cases, or empty if no match is found.
55 * @param source the source
56 * @param convertorExecutor convertor executor
57 * @return the optional
59 public Optional<TO> process(final FROM source, final ConvertorExecutor convertorExecutor) {
60 return process(source, null, convertorExecutor);
64 * Process source and return result based on convertor cases, or empty if no match is found.
66 * @param source the source
67 * @param data the data
68 * @param convertorExecutor convertor executor
69 * @return the optional
71 public Optional<TO> process(final FROM source, final DATA data, final ConvertorExecutor convertorExecutor) {
72 Optional<TO> result = Optional.empty();
73 final short version = data != null ? data.getVersion() : OFP_VERSION_ALL;
75 if (Objects.isNull(source)) {
76 LOG.trace("Failed to convert null for version {}", version);
80 final Class<?> clazz = source.getImplementedInterface();
81 final Optional<ConvertorCase<?, TO, DATA>> caseOptional = Optional
82 .ofNullable(getCasesForVersion(version).get(clazz));
84 final ConvertorCase<?, TO, DATA> processorCase = caseOptional.orElse(defaultCase);
86 if (Objects.nonNull(processorCase)) {
87 result = processorCase.processRaw(source, data, convertorExecutor);
89 if (processorCase.isErrorOnEmpty() && !result.isPresent()) {
90 LOG.warn("Failed to process {} for version {}", clazz, version);
93 LOG.trace("Failed to process {} for version {}", clazz, version);
100 * Sets default case, what will be used when we do not find any matching convertor case for source.
102 * @param defaultCase the default case
103 * @return the default case
105 public ConvertorProcessor<FROM, TO, DATA> setDefaultCase(final ConvertorCase<?, TO, DATA> defaultCase) {
106 this.defaultCase = defaultCase;
110 private Map<Class<?>, ConvertorCase<?, TO, DATA>> getCasesForVersion(final short version) {
111 final Map<Class<?>, ConvertorCase<?, TO, DATA>> casesForVersion =
112 conversions.getOrDefault(version, new ConcurrentHashMap<>());
114 conversions.putIfAbsent(version, casesForVersion);
116 return casesForVersion;