X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=restconf%2Frestconf-nb-rfc8040%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Frestconf%2Fnb%2Frfc8040%2Fcodecs%2FRestCodec.java;h=d455e813f15c198faf8af5b187914388092e0401;hb=4f8fe6ca68115fecdb9ce43573af5a2e26c50b50;hp=4d9ee346e26740674d53e37a25c6397fd1623dae;hpb=a01dad851768102b3182033c10d860f5245d7d26;p=netconf.git diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/codecs/RestCodec.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/codecs/RestCodec.java index 4d9ee346e2..d455e813f1 100644 --- a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/codecs/RestCodec.java +++ b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/codecs/RestCodec.java @@ -7,22 +7,27 @@ */ package org.opendaylight.restconf.nb.rfc8040.codecs; -import com.google.common.base.Preconditions; +import static java.util.Objects.requireNonNull; + import com.google.common.collect.Iterables; -import java.net.URI; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; +import java.util.Optional; +import java.util.Set; +import org.opendaylight.mdsal.dom.api.DOMMountPoint; +import org.opendaylight.mdsal.dom.api.DOMSchemaService; import org.opendaylight.restconf.common.util.IdentityValuesDTO; import org.opendaylight.restconf.common.util.IdentityValuesDTO.IdentityValue; import org.opendaylight.restconf.common.util.IdentityValuesDTO.Predicate; import org.opendaylight.restconf.common.util.RestUtil; -import org.opendaylight.yangtools.concepts.Codec; +import org.opendaylight.yangtools.concepts.IllegalArgumentCodec; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.XMLNamespace; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; @@ -32,12 +37,13 @@ import org.opendaylight.yangtools.yang.data.api.codec.IdentityrefCodec; import org.opendaylight.yangtools.yang.data.api.codec.InstanceIdentifierCodec; import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec; import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec; -import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode; import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; @@ -57,26 +63,27 @@ public final class RestCodec { private RestCodec() { } - public static Codec from(final TypeDefinition typeDefinition, - final DOMMountPoint mountPoint, final SchemaContext schemaContext) { + // FIXME: IllegalArgumentCodec is not quite accurate + public static IllegalArgumentCodec from(final TypeDefinition typeDefinition, + final DOMMountPoint mountPoint, final EffectiveModelContext schemaContext) { return new ObjectCodec(typeDefinition, mountPoint, schemaContext); } @SuppressWarnings("rawtypes") - public static final class ObjectCodec implements Codec { + public static final class ObjectCodec implements IllegalArgumentCodec { private static final Logger LOG = LoggerFactory.getLogger(ObjectCodec.class); - public static final Codec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl(); - private final Codec instanceIdentifier; - private final Codec identityrefCodec; + public static final IllegalArgumentCodec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl(); + private final IllegalArgumentCodec instanceIdentifier; + private final IllegalArgumentCodec identityrefCodec; private final TypeDefinition type; - private final SchemaContext schemaContext; + private final EffectiveModelContext schemaContext; private ObjectCodec(final TypeDefinition typeDefinition, final DOMMountPoint mountPoint, - final SchemaContext schemaContext) { + final EffectiveModelContext schemaContext) { this.schemaContext = schemaContext; this.type = RestUtil.resolveBaseTypeFrom(typeDefinition); if (this.type instanceof IdentityrefTypeDefinition) { @@ -102,7 +109,7 @@ public final class RestCodec { if (LOG.isDebugEnabled()) { LOG.debug( "Value is not instance of IdentityrefTypeDefinition but is {}. " - + "Therefore NULL is used as translation of - {}", + + "Therefore NULL is used as translation of - {}", input == null ? "null" : input.getClass(), String.valueOf(input)); } return null; @@ -123,15 +130,12 @@ public final class RestCodec { } return typeAwarecodec.deserialize(String.valueOf(input)); } else { - LOG.debug("Codec for type \"" + this.type.getQName().getLocalName() - + "\" is not implemented yet."); + LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName().getLocalName()); return null; } } } catch (final ClassCastException e) { // TODO remove this catch when everyone use codecs - LOG.error( - "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), - e); + LOG.error("ClassCastException was thrown when codec is invoked with parameter {}", input, e); return null; } } @@ -153,20 +157,16 @@ public final class RestCodec { return typeAwarecodec.serialize(input); } else { if (LOG.isDebugEnabled()) { - LOG.debug("Codec for type \"" + this.type.getQName().getLocalName() - + "\" is not implemented yet."); + LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName().getLocalName()); } return null; } } } catch (final ClassCastException e) { // TODO remove this catch when everyone use codecs - LOG.error( - "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), - e); + LOG.error("ClassCastException was thrown when codec is invoked with parameter {}", input, e); return input; } } - } public static class IdentityrefCodecImpl implements IdentityrefCodec { @@ -234,11 +234,11 @@ public final class RestCodec { final IdentityValue identityValue = qNameToIdentityValue(pathArgument.getNodeType()); if (pathArgument instanceof NodeIdentifierWithPredicates && identityValue != null) { final List predicates = - keyValuesToPredicateList(((NodeIdentifierWithPredicates) pathArgument).getKeyValues()); + keyValuesToPredicateList(((NodeIdentifierWithPredicates) pathArgument).entrySet()); identityValue.setPredicates(predicates); } else if (pathArgument instanceof NodeWithValue && identityValue != null) { final List predicates = new ArrayList<>(); - final String value = String.valueOf(((NodeWithValue) pathArgument).getValue()); + final String value = String.valueOf(((NodeWithValue) pathArgument).getValue()); predicates.add(new Predicate(null, value)); identityValue.setPredicates(predicates); } @@ -247,6 +247,10 @@ public final class RestCodec { return identityValuesDTO; } + @SuppressFBWarnings(value = { + "NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE", + "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" + }, justification = "Unrecognised NullableDecl") @Override public YangInstanceIdentifier deserialize(final IdentityValuesDTO data) { final List result = new ArrayList<>(); @@ -265,7 +269,7 @@ public final class RestCodec { final List identities = data.getValuesWithNamespaces(); for (int i = 0; i < identities.size(); i++) { final IdentityValue identityValue = identities.get(i); - URI validNamespace = + XMLNamespace validNamespace = resolveValidNamespace(identityValue.getNamespace(), this.mountPoint, schemaContext); final DataSchemaNode node = findInstanceDataChildByNameAndNamespace( parentContainer, identityValue.getValue(), validNamespace); @@ -299,7 +303,7 @@ public final class RestCodec { predicate.getName().getValue(), validNamespace); predicatesMap.put(listKey.getQName(), predicate.getValue()); } - pathArgument = new NodeIdentifierWithPredicates(qName, predicatesMap); + pathArgument = NodeIdentifierWithPredicates.of(qName, predicatesMap); } else { LOG.info("Node {} is not List or Leaf-list.", node); LOG.info("Instance-identifier will be translated as NULL for data - {}", @@ -324,9 +328,9 @@ public final class RestCodec { return result.isEmpty() ? null : YangInstanceIdentifier.create(result); } - private static List keyValuesToPredicateList(final Map keyValues) { + private static List keyValuesToPredicateList(final Set> keyValues) { final List result = new ArrayList<>(); - for (final Entry entry : keyValues.entrySet()) { + for (final Entry entry : keyValues) { final QName qualifiedName = entry.getKey(); final Object value = entry.getValue(); result.add(new Predicate(qNameToIdentityValue(qualifiedName), String.valueOf(value))); @@ -342,38 +346,40 @@ public final class RestCodec { } } + @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", + justification = "https://github.com/spotbugs/spotbugs/issues/811") private static Module getModuleByNamespace(final String namespace, final DOMMountPoint mountPoint, final SchemaContext schemaContext) { - final URI validNamespace = resolveValidNamespace(namespace, mountPoint, schemaContext); + final XMLNamespace validNamespace = resolveValidNamespace(namespace, mountPoint, schemaContext); Module module = null; if (mountPoint != null) { - module = mountPoint.getSchemaContext().findModules(validNamespace).iterator().next(); + module = modelContext(mountPoint).findModules(validNamespace).iterator().next(); } else { module = schemaContext.findModules(validNamespace).iterator().next(); } if (module == null) { - LOG.info("Module for namespace " + validNamespace + " wasn't found."); + LOG.info("Module for namespace {} was not found.", validNamespace); return null; } return module; } - private static URI resolveValidNamespace(final String namespace, final DOMMountPoint mountPoint, + private static XMLNamespace resolveValidNamespace(final String namespace, final DOMMountPoint mountPoint, final SchemaContext schemaContext) { - URI validNamespace; + XMLNamespace validNamespace; if (mountPoint != null) { - validNamespace = findFirstModuleByName(mountPoint.getSchemaContext(), namespace); + validNamespace = findFirstModuleByName(modelContext(mountPoint), namespace); } else { validNamespace = findFirstModuleByName(schemaContext, namespace); } if (validNamespace == null) { - validNamespace = URI.create(namespace); + validNamespace = XMLNamespace.of(namespace); } return validNamespace; } - private static URI findFirstModuleByName(final SchemaContext schemaContext, final String name) { + private static XMLNamespace findFirstModuleByName(final SchemaContext schemaContext, final String name) { for (final Module module : schemaContext.getModules()) { if (module.getName().equals(name)) { return module.getNamespace(); @@ -382,9 +388,11 @@ public final class RestCodec { return null; } + @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", + justification = "https://github.com/spotbugs/spotbugs/issues/811") private static DataSchemaNode findInstanceDataChildByNameAndNamespace(final DataNodeContainer container, - final String name, final URI namespace) { - Preconditions.checkNotNull(namespace); + final String name, final XMLNamespace namespace) { + requireNonNull(namespace); final Iterable result = Iterables.filter(findInstanceDataChildrenByName(container, name), node -> namespace.equals(node.getQName().getNamespace())); @@ -393,18 +401,16 @@ public final class RestCodec { private static List findInstanceDataChildrenByName(final DataNodeContainer container, final String name) { - Preconditions.checkNotNull(container); - Preconditions.checkNotNull(name); - final List instantiatedDataNodeContainers = new ArrayList<>(); - collectInstanceDataNodeContainers(instantiatedDataNodeContainers, container, name); + collectInstanceDataNodeContainers(instantiatedDataNodeContainers, requireNonNull(container), + requireNonNull(name)); return instantiatedDataNodeContainers; } private static void collectInstanceDataNodeContainers(final List potentialSchemaNodes, final DataNodeContainer container, final String name) { - final Iterable nodes = + final Iterable nodes = Iterables.filter(container.getChildNodes(), node -> name.equals(node.getQName().getLocalName())); // Can't combine this loop with the filter above because the filter is @@ -417,8 +423,8 @@ public final class RestCodec { final Iterable choiceNodes = Iterables.filter(container.getChildNodes(), ChoiceSchemaNode.class); - final Iterable> map = Iterables.transform(choiceNodes, - choice -> choice.getCases().values()); + final Iterable> map = Iterables.transform(choiceNodes, + ChoiceSchemaNode::getCases); for (final CaseSchemaNode caze : Iterables.concat(map)) { collectInstanceDataNodeContainers(potentialSchemaNodes, caze, name); } @@ -427,6 +433,12 @@ public final class RestCodec { private static boolean isInstantiatedDataSchema(final DataSchemaNode node) { return node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode || node instanceof ContainerSchemaNode || node instanceof ListSchemaNode - || node instanceof AnyXmlSchemaNode; + || node instanceof AnyxmlSchemaNode; + } + + private static EffectiveModelContext modelContext(final DOMMountPoint mountPoint) { + return mountPoint.getService(DOMSchemaService.class) + .flatMap(svc -> Optional.ofNullable(svc.getGlobalContext())) + .orElse(null); } }