2 * Copyright (c) 2014 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
8 package org.opendaylight.mdsal.binding.dom.codec.impl;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.collect.ImmutableBiMap;
14 import com.google.common.collect.Maps;
15 import java.util.Arrays;
18 import java.util.concurrent.Callable;
19 import java.util.stream.Collectors;
20 import org.opendaylight.mdsal.binding.dom.codec.impl.ValueTypeCodec.SchemaUnawareCodec;
21 import org.opendaylight.yangtools.yang.binding.Enumeration;
22 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
23 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 final class EnumerationCodec extends ReflectionBasedCodec implements SchemaUnawareCodec {
28 private static final Logger LOG = LoggerFactory.getLogger(EnumerationCodec.class);
30 private final ImmutableBiMap<String, Enum<?>> nameToEnum;
32 EnumerationCodec(final Class<? extends Enum<?>> enumeration, final Map<String, Enum<?>> nameToEnum) {
34 this.nameToEnum = ImmutableBiMap.copyOf(nameToEnum);
37 static Callable<EnumerationCodec> loader(final Class<?> returnType, final EnumTypeDefinition def) {
38 checkArgument(Enum.class.isAssignableFrom(returnType));
39 @SuppressWarnings("unchecked")
40 final Class<? extends Enum<?>> enumType = (Class<? extends Enum<?>>) returnType;
42 final Map<String, Enum<?>> mapping = Maps.uniqueIndex(Arrays.asList(enumType.getEnumConstants()),
44 checkArgument(value instanceof Enumeration,
45 "Enumeration constant %s.%s is not implementing Enumeration", enumType.getName(), value);
46 return ((Enumeration) value).getName();
49 // Check if mapping is a bijection
50 final Set<String> assignedNames = def.getValues().stream().map(EnumPair::getName)
51 .collect(Collectors.toSet());
52 for (String name : assignedNames) {
53 if (!mapping.containsKey(name)) {
54 LOG.warn("Enumeration {} does not contain assigned name '{}' from {}", enumType, name, def);
57 for (String name : mapping.keySet()) {
58 if (!assignedNames.contains(name)) {
59 LOG.warn("Enumeration {} contains assigned name '{}' not covered by {}", enumType, name, def);
63 return new EnumerationCodec(enumType, mapping);
68 public Enum<?> deserialize(final Object input) {
69 checkArgument(input instanceof String, "Input %s is not a String", input);
70 final Enum<?> value = nameToEnum.get(input);
71 checkArgument(value != null, "Invalid enumeration value %s. Valid values are %s", input, nameToEnum.keySet());
76 public String serialize(final Object input) {
77 checkArgument(getTypeClass().isInstance(input), "Input %s is not a instance of %s", input, getTypeClass());
78 return requireNonNull(nameToEnum.inverse().get(input));