--- /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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.Future;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Beta
+abstract class AbstractMappedOperationInvoker<T> extends OperationServiceInvoker {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractMappedOperationInvoker.class);
+ private final Map<T, OperationMethodInvoker> map;
+
+ protected AbstractMappedOperationInvoker(final Map<T, Method> map) {
+ final Builder<T, OperationMethodInvoker> b = ImmutableMap.builder();
+
+ for (final Entry<T, Method> e : map.entrySet()) {
+ if (BindingReflections.isOperationMethod(e.getValue())) {
+ b.put(e.getKey(), OperationMethodInvoker.from(e.getValue()));
+ } else {
+ LOG.debug("Method {} is not an operation method, ignoring it", e.getValue());
+ }
+ }
+
+ this.map = b.build();
+ }
+
+ protected abstract T qnameToKey(QName qname);
+
+ @Override
+ public final <I extends Operation> Future<RpcResult<?>> invoke(@Nonnull final I impl,
+ @Nonnull final QName operationName, @Nullable final Instantiable<?> input) {
+
+ Preconditions.checkNotNull(impl, "Implementation must be supplied");
+
+ final OperationMethodInvoker invoker = map.get(qnameToKey(operationName));
+ Preconditions.checkArgument(invoker != null, "Supplied operation is not valid for implementation %s", impl);
+ return invoker.invokeOn(impl, input);
+ }
+}
--- /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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
+import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.yangtools.yang.common.QName;
+
+@Beta
+final class ClassBasedOperationServiceInvoker extends AbstractMappedOperationInvoker<String> {
+
+ private static final LoadingCache<Class<? extends Operation>, OperationServiceInvoker> INVOKERS = CacheBuilder
+ .newBuilder().weakKeys().build(new CacheLoader<Class<? extends Operation>, OperationServiceInvoker>() {
+ @Nonnull
+ @Override
+ public OperationServiceInvoker load(@Nonnull final Class<? extends Operation> key) {
+ final Map<String, Method> ret = new HashMap<>();
+ for (final Method m : key.getMethods()) {
+ ret.put(m.getName(), m);
+ }
+
+ return new ClassBasedOperationServiceInvoker(ret);
+ }
+ });
+
+ ClassBasedOperationServiceInvoker(final Map<String, Method> ret) {
+ super(ret);
+ }
+
+ @Override
+ protected String qnameToKey(final QName qname) {
+ return JavaIdentifierNormalizer.normalizeSpecificIdentifier(qname.getLocalName(), JavaIdentifier.METHOD);
+ }
+
+ static OperationServiceInvoker instanceFor(final Class<? extends Operation> type) {
+ Preconditions.checkArgument(type.isInterface());
+ Preconditions.checkArgument(BindingReflections.isBindingClass(type));
+ return INVOKERS.getUnchecked(type);
+ }
+}
\ No newline at end of file
--- /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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+
+@Beta
+final class LocalNameOperationServiceInvoker extends AbstractMappedOperationInvoker<String> {
+ private final QNameModule module;
+
+ private LocalNameOperationServiceInvoker(final QNameModule module, final Map<String, Method> map) {
+ super(map);
+ this.module = Preconditions.checkNotNull(module);
+ }
+
+ static OperationServiceInvoker instanceFor(final QNameModule module, final Map<QName, Method> qnameToMethod) {
+ final Map<String, Method> map = new HashMap<>();
+ for (final Entry<QName, Method> e : qnameToMethod.entrySet()) {
+ map.put(e.getKey().getLocalName(), e.getValue());
+ }
+ return new LocalNameOperationServiceInvoker(module, map);
+ }
+
+ @Override
+ protected String qnameToKey(final QName qname) {
+ if (module.equals(qname.getModule())) {
+ return qname.getLocalName();
+ } else {
+ return null;
+ }
+ }
+}
+
--- /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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.base.Throwables;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.reflect.Method;
+import java.util.concurrent.Future;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+@Beta
+abstract class OperationMethodInvoker {
+
+ private static final Lookup LOOKUP = MethodHandles.publicLookup();
+
+ protected abstract <T extends Operation> Future<RpcResult<?>> invokeOn(T impl, Instantiable<?> input);
+
+ protected static OperationMethodInvoker from(final Method method) {
+ final Optional<Class<? extends Instantiable<?>>> input = BindingReflections.resolveOperationInputClass(method);
+ try {
+ final MethodHandle methodHandle = LOOKUP.unreflect(method);
+ if (input.isPresent()) {
+ return new OperationMethodInvokerWithInput(methodHandle);
+ }
+ return new OperationMethodInvokerWithoutInput(methodHandle);
+ } catch (final IllegalAccessException e) {
+ throw new IllegalStateException("Lookup on public method failed.", e);
+ }
+ }
+
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ protected Future<RpcResult<?>> invoking(final MethodHandle handle, final Object... args) {
+ try {
+ return (Future<RpcResult<?>>) handle.invokeExact(args);
+ } catch (final Throwable e) {
+ throw Throwables.propagate(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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.Future;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.ListAction;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+@Beta
+class OperationMethodInvokerWithInput extends OperationMethodInvoker {
+
+ private static final MethodType INVOCATION_SIGNATURE =
+ MethodType.methodType(Future.class, Rpc.class, Action.class, ListAction.class, Instantiable.class);
+
+ private final MethodHandle handle;
+
+ OperationMethodInvokerWithInput(final MethodHandle methodHandle) {
+ this.handle = methodHandle.asType(INVOCATION_SIGNATURE);
+ }
+
+ @Override
+ public <T extends Operation> Future<RpcResult<?>> invokeOn(final T impl, final Instantiable<?> input) {
+ return invoking(handle, impl, input);
+ }
+}
--- /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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.Future;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.ListAction;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+@Beta
+class OperationMethodInvokerWithoutInput extends OperationMethodInvoker {
+
+ private static final MethodType INVOCATION_SIGNATURE =
+ MethodType.methodType(Future.class, Rpc.class, Action.class, ListAction.class);
+
+ private final MethodHandle handle;
+
+ OperationMethodInvokerWithoutInput(final MethodHandle methodHandle) {
+ this.handle = methodHandle.asType(INVOCATION_SIGNATURE);
+ }
+
+ @Override
+ public <T extends Operation> Future<RpcResult<?>> invokeOn(final T impl, final Instantiable<?> input) {
+ return invoking(handle, impl);
+ }
+}
--- /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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.Future;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides single method invocation of operations on supplied instance.
+ *
+ * <p>
+ * Operation Service invoker provides common invocation interface for any subtype of operation. via
+ * {@link #invoke(Operation, QName, Instantiable)} method.
+ */
+@Beta
+public abstract class OperationServiceInvoker {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OperationServiceInvoker.class);
+
+ /**
+ * Creates OperationServiceInvoker for specified operation type.
+ *
+ * @param type
+ * operation interface, which was generated from model.
+ * @return Cached instance of {@link OperationServiceInvoker} for supplied operation type.
+ *
+ */
+ public static OperationServiceInvoker from(final Class<? extends Operation> type) {
+ return ClassBasedOperationServiceInvoker.instanceFor(type);
+ }
+
+ /**
+ * Creates an OperationServiceInvoker for specified QName-<Method mapping.
+ *
+ * @param qnameToMethod
+ * translation mapping, must not be null nor empty.
+ * @return An {@link OperationMethodInvoker} instance.
+ */
+ public static OperationServiceInvoker from(final Map<QName, Method> qnameToMethod) {
+ Preconditions.checkArgument(!qnameToMethod.isEmpty());
+ QNameModule module = null;
+
+ for (final QName qname : qnameToMethod.keySet()) {
+ if (module != null) {
+ if (!module.equals(qname.getModule())) {
+ LOG.debug("QNames from different modules {} and {}, falling back to QName map", module,
+ qname.getModule());
+ return QNameOperationServiceInvoker.instanceFor(qnameToMethod);
+ }
+ } else {
+ module = qname.getModule();
+ }
+ }
+
+ // All module are equal, which means we can use localName only
+ return LocalNameOperationServiceInvoker.instanceFor(module, qnameToMethod);
+ }
+
+ /**
+ * Invokes supplied operation on provided implementation of Operation Service.
+ *
+ * @param <T>
+ * - operation type
+ * @param impl
+ * Implementation on which operation should be invoked.
+ * @param operationName
+ * Name of operation to be invoked.
+ * @param input
+ * Input data for operation.
+ * @return Future which will complete once operation processing is finished.
+ */
+ public abstract <T extends Operation> Future<RpcResult<?>> invoke(@Nonnull T impl, @Nonnull QName operationName,
+ @Nullable Instantiable<?> input);
+}
--- /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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import java.lang.reflect.Method;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
+
+@Beta
+final class QNameOperationServiceInvoker extends AbstractMappedOperationInvoker<QName> {
+
+ private QNameOperationServiceInvoker(final Map<QName, Method> qnameToMethod) {
+ super(qnameToMethod);
+ }
+
+ static OperationServiceInvoker instanceFor(final Map<QName, Method> qnameToMethod) {
+ return new QNameOperationServiceInvoker(qnameToMethod);
+ }
+
+ @Override
+ protected QName qnameToKey(final QName qname) {
+ return qname;
+ }
+}
\ No newline at end of file
package org.opendaylight.mdsal.binding.javav2.dom.adapter.registration;
import com.google.common.annotations.Beta;
-import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
-import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationRegistration;
import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
/**
- * Registration of Binding - DOM Action adapter.
+ * Registration of Binding - DOM Operation adapter.
*
* @param <T>
- * - {@link Action} type
+ * - {@link Operation} type
*/
@Beta
-public class BindingDOMActionAdapterRegistration<T extends Action<? extends TreeNode, ?, ?>>
- extends AbstractObjectRegistration<T> {
+public class BindingDOMOperationAdapterRegistration<T extends Operation> extends AbstractObjectRegistration<T> {
private final DOMRpcImplementationRegistration<?> reg;
// FIXME : DOM part doesn't work with Yang 1.1 - Action registration isn't implemented yet.
- public BindingDOMActionAdapterRegistration(final T instance, final DOMRpcImplementationRegistration<?> reg) {
+ public BindingDOMOperationAdapterRegistration(final T instance, final DOMRpcImplementationRegistration<?> reg) {
super(instance);
this.reg = reg;
}
protected void removeRegistration() {
reg.close();
}
-}
+}
\ No newline at end of file
+++ /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.mdsal.binding.javav2.dom.adapter.registration;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementationRegistration;
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
-
-/**
- * Registration of Binding - DOM RPC adapter.
- *
- * @param <T>
- * - {@link Rpc} type
- */
-@Beta
-public class BindingDOMRpcAdapterRegistration<T extends Rpc<?, ?>> extends AbstractObjectRegistration<T> {
-
- private final DOMRpcImplementationRegistration<?> reg;
-
- public BindingDOMRpcAdapterRegistration(final T instance, final DOMRpcImplementationRegistration<?> reg) {
- super(instance);
- this.reg = reg;
- }
-
- @Override
- protected void removeRegistration() {
- reg.close();
- }
-}
\ No newline at end of file
Optional<DataNodeContainer> currentContainer = Optional.absent();
if (BindingReflections.isNotification(currentArg.getType())) {
currentContainer = findNotification(ctx, currentQName);
- } else if (BindingReflections.isRpcOrActionType(currentArg.getType())) {
+ } else if (BindingReflections.isOperationType(currentArg.getType())) {
currentContainer = findFirstDataNodeContainerInRpcOrAction(ctx, currentArg.getType());
if(currentQName == null && currentContainer.isPresent()) {
currentQName = ((DataSchemaNode) currentContainer.get()).getQName();
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
-
import com.google.common.annotations.Beta;
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
-import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
import org.opendaylight.mdsal.binding.javav2.spec.base.BaseIdentity;
import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
import org.opendaylight.mdsal.binding.javav2.spec.base.Notification;
-import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
import org.opendaylight.mdsal.binding.javav2.spec.runtime.YangModelBindingProvider;
import org.opendaylight.mdsal.binding.javav2.spec.runtime.YangModuleInfo;
private static final long EXPIRATION_TIME = 60;
private static final String QNAME_STATIC_FIELD_NAME = "QNAME";
- private static final String RPC_ACTION_OUTPUT_SUFFIX = "Output";
+ private static final String OPERATION_ACTION_OUTPUT_SUFFIX = "Output";
private static final String MODULE_INFO_CLASS_NAME = "$YangModuleInfoImpl";
private static final String PACKAGE_PREFIX = "org.opendaylight.mdsal.gen.javav2";
private static final String ROOT_PACKAGE_PATTERN_STRING =
* - method to check
* @return true if method is RPC or Action invocation, false otherwise.
*/
- public static boolean isRpcOrActionMethod(final Method possibleMethod) {
- return possibleMethod != null && (Rpc.class.isAssignableFrom(possibleMethod.getDeclaringClass())
- || Action.class.isAssignableFrom(possibleMethod.getDeclaringClass()))
+ public static boolean isOperationMethod(final Method possibleMethod) {
+ return possibleMethod != null && Operation.class.isAssignableFrom(possibleMethod.getDeclaringClass())
&& Future.class.isAssignableFrom(possibleMethod.getReturnType())
- // length <= 2: it seemed to be impossible to get correct RpcMethodInvoker because of
- // resolveRpcInputClass() check.While RpcMethodInvoker counts with one argument for
- // non input type and two arguments for input type, resolveRpcInputClass() counting
+ // length <= 2: it seemed to be impossible to get correct OperationMethodInvoker because of
+ // resolveOperationInputClass() check.While OperationMethodInvoker counts with one argument
+ // for
+ // non input type and two arguments for input type, resolveOperationInputClass() counting
// with zero for non input and one for input type
&& possibleMethod.getParameterTypes().length <= 2;
}
* is Void.
*/
@SuppressWarnings("rawtypes")
- public static Optional<Class<?>> resolveRpcOutputClass(final Method targetMethod) {
- checkState(isRpcOrActionMethod(targetMethod), "Supplied method is not a RPC or Action invocation method");
+ public static Optional<Class<?>> resolveOperationOutputClass(final Method targetMethod) {
+ checkState(isOperationMethod(targetMethod), "Supplied method is not a RPC or Action invocation method");
final Type futureType = targetMethod.getGenericReturnType();
- final Type rpcResultType = ClassLoaderUtils.getFirstGenericParameter(futureType);
- final Type rpcResultArgument = ClassLoaderUtils.getFirstGenericParameter(rpcResultType);
- if (rpcResultArgument instanceof Class && !Void.class.equals(rpcResultArgument)) {
- return Optional.of((Class) rpcResultArgument);
+ final Type operationResultType = ClassLoaderUtils.getFirstGenericParameter(futureType);
+ final Type operationResultArgument = ClassLoaderUtils.getFirstGenericParameter(operationResultType);
+ if (operationResultArgument instanceof Class && !Void.class.equals(operationResultArgument)) {
+ return Optional.of((Class) operationResultArgument);
}
return Optional.absent();
}
* otherwise.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
- public static Optional<Class<? extends Instantiable<?>>> resolveRpcInputClass(final Method targetMethod) {
+ public static Optional<Class<? extends Instantiable<?>>> resolveOperationInputClass(final Method targetMethod) {
for (final Class clazz : targetMethod.getParameterTypes()) {
if (Instantiable.class.isAssignableFrom(clazz)) {
return Optional.of(clazz);
* - class to be checked
* @return true if class represents RPC or Action input/output class
*/
- public static boolean isRpcOrActionType(final Class<? extends TreeNode> targetType) {
+ public static boolean isOperationType(final Class<? extends TreeNode> targetType) {
return Instantiable.class.isAssignableFrom(targetType) && !TreeChildNode.class.isAssignableFrom(targetType)
&& !Notification.class.isAssignableFrom(targetType)
&& (targetType.getName().endsWith("Input") || targetType.getName().endsWith("Output"));
final QName module = getModuleQName(moduleInfo).intern();
if (Augmentation.class.isAssignableFrom(key)) {
return module;
- } else if (isRpcOrActionType(key)) {
+ } else if (isOperationType(key)) {
final String className = key.getSimpleName();
- if (className.endsWith(RPC_ACTION_OUTPUT_SUFFIX)) {
+ if (className.endsWith(OPERATION_ACTION_OUTPUT_SUFFIX)) {
return QName.create(module, "output").intern();
} else {
return QName.create(module, "input").intern();
assertEquals("ModuleInfoClassName should be equal to string", "test.$YangModuleInfoImpl",
BindingReflections.getModuleInfoClassName("test"));
assertEquals("Module info should be empty Set", Collections.EMPTY_SET, BindingReflections.loadModuleInfos());
- assertFalse("Should not be RpcType", BindingReflections.isRpcOrActionType(TreeNode.class));
+ assertFalse("Should not be RpcType", BindingReflections.isOperationType(TreeNode.class));
assertFalse("Should not be AugmentationChild", BindingReflections.isAugmentationChild(TreeNode.class));
assertTrue("Should be BindingClass", BindingReflections.isBindingClass(TreeNode.class));
assertFalse("Should not be Notification", BindingReflections.isNotification(TreeNode.class));
assertEquals(GroupingFoo.class, BindingReflections.findHierarchicalParent(FooChild.class));
- assertTrue(BindingReflections.isRpcOrActionMethod(TestImplementation.class.getDeclaredMethod("rpcMethodTest")));
+ assertTrue(BindingReflections.isOperationMethod(TestImplementation.class.getDeclaredMethod("rpcMethodTest")));
assertEquals(TestImplementation.class, BindingReflections.findAugmentationTarget(TestImplementation.class));
assertEquals(Object.class, BindingReflections
- .resolveRpcOutputClass(TestImplementation.class.getDeclaredMethod("rpcMethodTest")).get());
+ .resolveOperationOutputClass(TestImplementation.class.getDeclaredMethod("rpcMethodTest")).get());
assertFalse(BindingReflections
- .resolveRpcOutputClass(TestImplementation.class.getDeclaredMethod("rpcMethodTest2")).isPresent());
+ .resolveOperationOutputClass(TestImplementation.class.getDeclaredMethod("rpcMethodTest2")).isPresent());
assertTrue(BindingReflections.getQName(TestImplementation.class).toString().equals("test"));
}
*
*/
@FunctionalInterface
-public interface Action<P extends TreeNode, I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>> {
+public interface Action<P extends TreeNode, I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>>
+ extends Operation {
/**
* @param input Action input schema node
*
*/
@FunctionalInterface
-public interface ListAction<P extends TreeNode, I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>> {
+public interface ListAction<P extends TreeNode, I extends Input<I> & Instantiable<I>,
+ O extends Output<O> & Instantiable<O>> extends Operation {
/**
* @param input Action input schema node
--- /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.mdsal.binding.javav2.spec.base;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Marker interface for tagging operations - RPC, Action and ListAction.
+ */
+@Beta
+public interface Operation {
+
+}
*
*/
@FunctionalInterface
-public interface Rpc<I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>> {
+public interface Rpc<I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>> extends Operation {
/**
* @param input Rpc input schema node