return root.getNotification(notification);
}
- ContainerNodeCodecContext<?> getRpcDataContext(final SchemaPath path) {
+ RpcInputCodec<?> getRpcInputCodec(final SchemaPath path) {
return root.getRpc(path);
}
LOG.error("Unexpected failure while serializing path {} data {}", path, data, e);
throw new IllegalStateException("Failed to create normalized node", e);
}
- return new SimpleEntry<YangInstanceIdentifier,NormalizedNode<?,?>>(writeCtx.getKey(),result.getResult());
+ return new SimpleEntry<>(writeCtx.getKey(),result.getResult());
}
@Override
final DataObject lazyObj = codec.deserialize(data);
final InstanceIdentifier<?> bindingPath = InstanceIdentifier.create(builder);
- return new SimpleEntry<InstanceIdentifier<?>, DataObject>(bindingPath, lazyObj);
+ return new SimpleEntry<>(bindingPath, lazyObj);
}
@Override
@Override
public DataObject fromNormalizedNodeRpcData(final SchemaPath path, final ContainerNode data) {
- final ContainerNodeCodecContext<?> codec = codecContext.getRpcDataContext(path);
+ final RpcInputCodec<?> codec = codecContext.getRpcInputCodec(path);
return codec.deserialize(data);
}
public <T extends DataObject> Function<Optional<NormalizedNode<?, ?>>, Optional<T>> deserializeFunction(final InstanceIdentifier<T> path) {
final DataObjectCodecContext<?,?> ctx = (DataObjectCodecContext<?,?>) codecContext.getCodecContextNode(path, null);
- return new DeserializeFunction<T>(ctx);
+ return new DeserializeFunction<>(ctx);
}
@Override
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-final class ContainerNodeCodecContext<D extends DataObject> extends DataObjectCodecContext<D, ContainerSchemaNode> {
+final class ContainerNodeCodecContext<D extends DataObject> extends DataObjectCodecContext<D, ContainerSchemaNode>
+ implements RpcInputCodec<D> {
ContainerNodeCodecContext(final DataContainerCodecPrototype<ContainerSchemaNode> prototype) {
super(prototype);
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.binding.data.codec.impl;
+
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeCodec;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Marker interface for codecs dealing with RPC input being potentially unmapped. We use this interface to mark both
+ * {@link UnmappedRpcInputCodec} and {@link ContainerNodeCodecContext}, which results in bimorphic invocation in
+ * {@link BindingNormalizedNodeCodecRegistry#fromNormalizedNodeRpcData()}.
+ *
+ * Without this interface we could end up with megamorphic invocation, as the two implementations cannot share class
+ * hierarchy.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Binding representation of data
+ */
+interface RpcInputCodec<D extends DataObject> extends BindingNormalizedNodeCodec<D> {
+
+}
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
public DataContainerCodecContext<?,?> load(final Class<?> key) {
return createDataTreeChildContext(key);
}
-
});
private final LoadingCache<Class<?>, ContainerNodeCodecContext<?>> rpcDataByClass = CacheBuilder.newBuilder().build(
@SuppressWarnings("rawtypes")
final Class childCls = factory().getRuntimeContext().getClassForSchema(childSchema);
return streamChild(childCls);
- } else {
- throw new UnsupportedOperationException("Unsupported child type " + childSchema.getClass());
}
+
+ throw new UnsupportedOperationException("Unsupported child type " + childSchema.getClass());
}
});
- private final LoadingCache<SchemaPath, ContainerNodeCodecContext<?>> rpcDataByPath = CacheBuilder.newBuilder().build(
- new CacheLoader<SchemaPath, ContainerNodeCodecContext<?>>() {
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override
- public ContainerNodeCodecContext load(final SchemaPath key) {
- final ContainerSchemaNode schema = SchemaContextUtil.getRpcDataSchema(getSchema(), key);
- final Class cls = factory().getRuntimeContext().getClassForSchema(schema);
- return getRpc(cls);
+ private final LoadingCache<SchemaPath, RpcInputCodec<?>> rpcDataByPath = CacheBuilder.newBuilder().build(
+ new CacheLoader<SchemaPath, RpcInputCodec<?>>() {
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ public RpcInputCodec load(final SchemaPath key) {
+ final ContainerSchemaNode schema = SchemaContextUtil.getRpcDataSchema(getSchema(), key);
+ if (schema instanceof EffectiveStatement &&
+ ((EffectiveStatement) schema).getDeclared().getStatementSource() != StatementSource.DECLARATION) {
+ // This is an implicitly-defined input or output statement. We do not have a corresponding
+ // data representation, so we hard-wire it to null.
+ return UnmappedRpcInputCodec.getInstance();
}
- });
+
+ final Class cls = factory().getRuntimeContext().getClassForSchema(schema);
+ return getRpc(cls);
+ }
+ });
private final LoadingCache<SchemaPath, NotificationCodecContext<?>> notificationsByPath = CacheBuilder.newBuilder()
.build(new CacheLoader<SchemaPath, NotificationCodecContext<?>>() {
return getOrRethrow(notificationsByPath, notification);
}
- ContainerNodeCodecContext<?> getRpc(final SchemaPath notification) {
+ RpcInputCodec<?> getRpc(final SchemaPath notification) {
return getOrRethrow(rpcDataByPath, notification);
}
for (final RpcDefinition potential : getSchema().getOperations()) {
final QName potentialQName = potential.getQName();
/*
- *
* Check if rpc and class represents data from same module and then
* checks if rpc local name produces same class name as class name
* appended with Input/Output based on QName associated with bidning
return cache.getUnchecked(key);
} catch (final UncheckedExecutionException e) {
final Throwable cause = e.getCause();
- if(cause != null) {
+ if (cause != null) {
Throwables.propagateIfPossible(cause);
}
throw e;
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.binding.data.codec.impl;
+
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Singleton codec for translating RPCs with implicit input statements, which are not mapped by binding spec v1. Since
+ * there is no equivalent, we always return null.
+ *
+ * @author Robert Varga
+ *
+ * @param <D> Data object type
+ */
+final class UnmappedRpcInputCodec<D extends DataObject> implements RpcInputCodec<D> {
+ private static final UnmappedRpcInputCodec<?> INSTANCE = new UnmappedRpcInputCodec<>();
+
+ private UnmappedRpcInputCodec() {
+
+ }
+
+ @SuppressWarnings("unchecked")
+ static <D extends DataObject> UnmappedRpcInputCodec<D> getInstance() {
+ return (UnmappedRpcInputCodec<D>) INSTANCE;
+ }
+
+ @Override
+ public D deserialize(final NormalizedNode<?, ?> data) {
+ return null;
+ }
+
+ @Override
+ public NormalizedNode<?, ?> serialize(final D data) {
+ throw new UnsupportedOperationException("Serialization of " + data + " not supported");
+ }
+}