X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fbinding%2Fimpl%2FBindingToNormalizedNodeCodec.java;h=bf3ac3d50d5bbebbf2d50681c513611fa674dd8a;hp=9ad35fcdda85347de6a7680c4f91dabbeed8e2a7;hb=7d9f0a4667c803c7155c8964b41bdf1e6196728a;hpb=be88c930f435d3a5f0f012cb0588022a216237bd diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java index 9ad35fcdda..bf3ac3d50d 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java @@ -9,54 +9,66 @@ package org.opendaylight.controller.md.sal.binding.impl; import com.google.common.base.Function; import com.google.common.base.Optional; - +import com.google.common.collect.ImmutableBiMap; +import java.lang.reflect.Method; import java.util.Iterator; import java.util.Map.Entry; - +import javax.annotation.Nonnull; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer; +import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTree; +import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory; import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy; import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; +import org.opendaylight.yangtools.yang.binding.BindingMapping; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.binding.util.BindingReflections; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; -public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoCloseable { +public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, SchemaContextListener, AutoCloseable { private final BindingIndependentMappingService bindingToLegacy; private final BindingNormalizedNodeCodecRegistry codecRegistry; private DataNormalizer legacyToNormalized; private final GeneratedClassLoadingStrategy classLoadingStrategy; + private BindingRuntimeContext runtimeContext; - public BindingToNormalizedNodeCodec(final GeneratedClassLoadingStrategy classLoadingStrategy, final BindingIndependentMappingService mappingService, final BindingNormalizedNodeCodecRegistry codecRegistry) { - super(); + public BindingToNormalizedNodeCodec(final GeneratedClassLoadingStrategy classLoadingStrategy, + final BindingIndependentMappingService mappingService, + final BindingNormalizedNodeCodecRegistry codecRegistry) { this.bindingToLegacy = mappingService; this.classLoadingStrategy = classLoadingStrategy; this.codecRegistry = codecRegistry; } - public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier toNormalized( - final InstanceIdentifier binding) { + public YangInstanceIdentifier toNormalized(final InstanceIdentifier binding) { return codecRegistry.toYangInstanceIdentifier(binding); } @SuppressWarnings({ "unchecked", "rawtypes" }) - public Entry> toNormalizedNode( + public Entry> toNormalizedNode( final InstanceIdentifier bindingPath, final DataObject bindingObject) { return codecRegistry.toNormalizedNode((InstanceIdentifier) bindingPath, bindingObject); } - public Entry> toNormalizedNode( - final Entry, DataObject> binding) { + public Entry> toNormalizedNode( + final Entry, DataObject> binding) { return toNormalizedNode(binding.getKey(),binding.getValue()); } @@ -69,12 +81,11 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoC * augmentation. * */ - public Optional> toBinding( - final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized) + public Optional> toBinding(final YangInstanceIdentifier normalized) throws DeserializationException { try { - return Optional.>of(codecRegistry.fromYangInstanceIdentifier(normalized)); - } catch (IllegalArgumentException e) { + return Optional.>fromNullable(codecRegistry.fromYangInstanceIdentifier(normalized)); + } catch (final IllegalArgumentException e) { return Optional.absent(); } } @@ -83,23 +94,36 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoC return legacyToNormalized; } - @SuppressWarnings("unchecked") - public Optional, DataObject>> toBinding( - final Entry> normalized) + public Optional, DataObject>> toBinding( + final @Nonnull Entry> normalized) throws DeserializationException { try { - @SuppressWarnings("rawtypes") - Entry binding = codecRegistry.fromNormalizedNode(normalized.getKey(), normalized.getValue()); - return Optional., DataObject>>fromNullable(binding); - } catch (IllegalArgumentException e) { + /* + * This cast is required, due to generics behaviour in openjdk / oracle javac + * + * InstanceIdentifier has definition InstanceIdentifier, + * this means '?' is always  . Eclipse compiler + * is able to determine this relationship and treats + * Entry,DataObject> and Entry + * as assignable. However openjdk / oracle javac treats this two types + * as incompatible and issues a compile error. + * + * It is safe to loose generic information and cast it to other generic signature. + * + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Entry, DataObject> binding = Entry.class.cast(codecRegistry.fromNormalizedNode(normalized.getKey(), normalized.getValue())); + return Optional.fromNullable(binding); + } catch (final IllegalArgumentException e) { return Optional.absent(); } } @Override public void onGlobalContextUpdated(final SchemaContext arg0) { - legacyToNormalized = new DataNormalizer(arg0); - codecRegistry.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(classLoadingStrategy, arg0)); + legacyToNormalized = new DataNormalizer (arg0); + runtimeContext = BindingRuntimeContext.create(classLoadingStrategy, arg0); + codecRegistry.onBindingRuntimeContextUpdated(runtimeContext); } public Function>, Optional> deserializeFunction(final InstanceIdentifier path) { @@ -112,14 +136,14 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoC * @param path DOM Path * @return Node with defaults set on. */ - public NormalizedNode getDefaultNodeFor(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path) { - Iterator iterator = path.getPathArguments().iterator(); + public NormalizedNode getDefaultNodeFor(final YangInstanceIdentifier path) { + final Iterator iterator = path.getPathArguments().iterator(); DataNormalizationOperation currentOp = legacyToNormalized.getRootOperation(); while (iterator.hasNext()) { - PathArgument currentArg = iterator.next(); + final PathArgument currentArg = iterator.next(); try { currentOp = currentOp.getChild(currentArg); - } catch (DataNormalizationException e) { + } catch (final DataNormalizationException e) { throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e); } } @@ -130,8 +154,52 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoC return bindingToLegacy; } + public BindingNormalizedNodeCodecRegistry getCodecRegistry() { + return codecRegistry; + } + @Override - public void close() throws Exception { + public void close() { // NOOP Intentionally } + + public BindingNormalizedNodeCodecRegistry getCodecFactory() { + return codecRegistry; + } + + // FIXME: This should be probably part of Binding Runtime context + public ImmutableBiMap getRpcMethodToSchemaPath(final Class key) { + final QNameModule moduleName = BindingReflections.getQNameModule(key); + final Module module = runtimeContext.getSchemaContext().findModuleByNamespaceAndRevision(moduleName.getNamespace(), moduleName.getRevision()); + final ImmutableBiMap.Builder ret = ImmutableBiMap.builder(); + try { + for (final RpcDefinition rpcDef : module.getRpcs()) { + final Method method = findRpcMethod(key, rpcDef); + ret.put(method, rpcDef.getPath()); + } + } catch (final NoSuchMethodException e) { + throw new IllegalStateException("Rpc defined in model does not have representation in generated class.", e); + } + return ret.build(); + } + + private Method findRpcMethod(final Class key, final RpcDefinition rpcDef) throws NoSuchMethodException { + final String methodName = BindingMapping.getMethodName(rpcDef.getQName()); + if(rpcDef.getInput() != null) { + final Class inputClz = runtimeContext.getClassForSchema(rpcDef.getInput()); + return key.getMethod(methodName, inputClz); + } + return key.getMethod(methodName); + } + + @Override + public BindingCodecTree create(BindingRuntimeContext context) { + return codecRegistry.create(context); + } + + @Override + public BindingCodecTree create(SchemaContext context, Class... bindingClasses) { + return codecRegistry.create(context, bindingClasses); + } + }