X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-spec-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fspec%2Freflect%2FBindingReflections.java;h=623385d8658c51906a30874e5fce2b83b639e9d2;hb=5bc3681743c768aa4cb74b0c58b525779ba7963c;hp=847ca2d97b52c3cad91a23ddd3999f4a63ed7b8d;hpb=9e8f577a837b3f8d7d29bbb37717208d420e61f2;p=mdsal.git diff --git a/binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java b/binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java index 847ca2d97b..623385d865 100644 --- a/binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java +++ b/binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java @@ -10,34 +10,22 @@ package org.opendaylight.mdsal.binding.spec.reflect; 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.annotations.VisibleForTesting; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSet.Builder; -import com.google.common.util.concurrent.ListenableFuture; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Optional; -import java.util.ServiceLoader; import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.yangtools.util.ClassLoaderUtils; import org.opendaylight.yangtools.yang.binding.Action; -import org.opendaylight.yangtools.yang.binding.Augmentable; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.BaseIdentity; -import org.opendaylight.yangtools.yang.binding.BindingContract; import org.opendaylight.yangtools.yang.binding.ChildOf; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.Notification; -import org.opendaylight.yangtools.yang.binding.Rpc; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider; import org.opendaylight.yangtools.yang.binding.YangModuleInfo; import org.opendaylight.yangtools.yang.binding.contract.Naming; import org.opendaylight.yangtools.yang.common.QName; @@ -52,35 +40,11 @@ public final class BindingReflections { .weakKeys() .expireAfterAccess(60, TimeUnit.SECONDS) .build(new ClassToQNameLoader()); - private static final LoadingCache> MODULE_INFO_CACHE = - CacheBuilder.newBuilder().weakKeys().weakValues().build( - new CacheLoader>() { - @Override - public ImmutableSet load(final ClassLoader key) { - return loadModuleInfos(key); - } - }); private BindingReflections() { // Hidden on purpose } - /** - * Find augmentation target class from concrete Augmentation class. This method uses first generic argument of - * implemented {@link Augmentation} interface. - * - * @param augmentation - * {@link Augmentation} subclass for which we want to determine - * augmentation target. - * @return Augmentation target - class which augmentation provides additional extensions. - */ - public static Class> findAugmentationTarget( - final Class> augmentation) { - final Optional>> opt = ClassLoaderUtils.findFirstGenericArgument(augmentation, - Augmentation.class); - return opt.orElse(null); - } - /** * Returns a QName associated to supplied type. * @@ -93,58 +57,9 @@ public final class BindingReflections { return CLASS_TO_QNAME.getUnchecked(dataType).orElse(null); } - /** - * Checks if method is RPC invocation. - * - * @param possibleMethod - * Method to check - * @return true if method is RPC invocation, false otherwise. - */ - public static boolean isRpcMethod(final Method possibleMethod) { - return possibleMethod != null && RpcService.class.isAssignableFrom(possibleMethod.getDeclaringClass()) - && ListenableFuture.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 - // with zero for non input and one for input type - && possibleMethod.getParameterCount() <= 2; - } - public static @NonNull QName getQName(final BaseIdentity identity) { - return getContractQName(identity); - } - - public static @NonNull QName getQName(final Rpc rpc) { - return getContractQName(rpc); - } - - private static @NonNull QName getContractQName(final BindingContract contract) { - return CLASS_TO_QNAME.getUnchecked(contract.implementedInterface()) - .orElseThrow(() -> new IllegalStateException("Failed to resolve QName of " + contract)); - } - - /** - * Returns root package name for supplied package. - * - * @param pkg Package for which find model root package. - * @deprecated Use {@link Naming#getModelRootPackageName(String)} instead. - */ - @Deprecated(since = "11.0.3", forRemoval = true) - public static String getModelRootPackageName(final Package pkg) { - return getModelRootPackageName(pkg.getName()); - } - - /** - * Returns root package name for supplied package name. - * - * @param name Package for which find model root package. - * @return Package of model root. - * @deprecated Use {@link Naming#getModelRootPackageName(String)} instead. - */ - @Deprecated(since = "11.0.3", forRemoval = true) - public static String getModelRootPackageName(final String name) { - checkArgument(name != null, "Package name should not be null."); - return Naming.getModelRootPackageName(name); + return CLASS_TO_QNAME.getUnchecked(identity.implementedInterface()) + .orElseThrow(() -> new IllegalStateException("Failed to resolve QName of " + identity)); } public static QNameModule getQNameModule(final Class clz) { @@ -162,9 +77,9 @@ public final class BindingReflections { * @param cls data object class * @return Instance of {@link YangModuleInfo} associated with model, from which this class was derived. */ - public static @NonNull YangModuleInfo getModuleInfo(final Class cls) { - final String packageName = Naming.getModelRootPackageName(cls.getPackage().getName()); - final String potentialClassName = getModuleInfoClassName(packageName); + private static @NonNull YangModuleInfo getModuleInfo(final Class cls) { + final String potentialClassName = Naming.getModelRootPackageName(cls.getPackage().getName()) + "." + + Naming.MODULE_INFO_CLASS_NAME; final Class moduleInfoClass; try { moduleInfoClass = cls.getClassLoader().loadClass(potentialClassName); @@ -183,10 +98,6 @@ public final class BindingReflections { return (YangModuleInfo) infoInstance; } - public static @NonNull String getModuleInfoClassName(final String packageName) { - return packageName + "." + Naming.MODULE_INFO_CLASS_NAME; - } - /** * Check if supplied class is derived from YANG model. * @@ -201,95 +112,6 @@ public final class BindingReflections { return cls.getName().startsWith(Naming.PACKAGE_PREFIX); } - /** - * Checks if supplied method is callback for notifications. - * - * @param method method to check - * @return true if method is notification callback. - */ - public static boolean isNotificationCallback(final Method method) { - checkArgument(method != null); - if (method.getName().startsWith("on") && method.getParameterCount() == 1) { - Class potentialNotification = method.getParameterTypes()[0]; - if (isNotification(potentialNotification) - && method.getName().equals("on" + potentialNotification.getSimpleName())) { - return true; - } - } - return false; - } - - /** - * Checks is supplied class is a {@link Notification}. - * - * @param potentialNotification class to examine - * @return True if the class represents a Notification. - */ - @VisibleForTesting - static boolean isNotification(final Class potentialNotification) { - checkArgument(potentialNotification != null, "potentialNotification must not be null."); - return Notification.class.isAssignableFrom(potentialNotification); - } - - /** - * Loads {@link YangModuleInfo} infos available on supplied classloader. - * - *

- * {@link YangModuleInfo} are discovered using {@link ServiceLoader} for {@link YangModelBindingProvider}. - * {@link YangModelBindingProvider} are simple classes which holds only pointers to actual instance - * {@link YangModuleInfo}. - * - *

- * When {@link YangModuleInfo} is available, all dependencies are recursively collected into returning set by - * collecting results of {@link YangModuleInfo#getImportedModules()}. - * - *

- * Consider using {@link #cacheModuleInfos(ClassLoader)} if the classloader is known to be immutable. - * - * @param loader Classloader for which {@link YangModuleInfo} should be retrieved. - * @return Set of {@link YangModuleInfo} available for supplied classloader. - */ - public static @NonNull ImmutableSet loadModuleInfos(final ClassLoader loader) { - Builder moduleInfoSet = ImmutableSet.builder(); - ServiceLoader serviceLoader = ServiceLoader.load(YangModelBindingProvider.class, - loader); - for (YangModelBindingProvider bindingProvider : serviceLoader) { - YangModuleInfo moduleInfo = bindingProvider.getModuleInfo(); - checkState(moduleInfo != null, "Module Info for %s is not available.", bindingProvider.getClass()); - collectYangModuleInfo(bindingProvider.getModuleInfo(), moduleInfoSet); - } - return moduleInfoSet.build(); - } - - /** - * Loads {@link YangModuleInfo} instances available on supplied {@link ClassLoader}, assuming the set of available - * information does not change. Subsequent accesses may return cached values. - * - *

- * {@link YangModuleInfo} are discovered using {@link ServiceLoader} for {@link YangModelBindingProvider}. - * {@link YangModelBindingProvider} are simple classes which holds only pointers to actual instance - * {@link YangModuleInfo}. - * - *

- * When {@link YangModuleInfo} is available, all dependencies are recursively collected into returning set by - * collecting results of {@link YangModuleInfo#getImportedModules()}. - * - * @param loader Class loader for which {@link YangModuleInfo} should be retrieved. - * @return Set of {@link YangModuleInfo} available for supplied classloader. - */ - @Beta - public static @NonNull ImmutableSet cacheModuleInfos(final ClassLoader loader) { - return MODULE_INFO_CACHE.getUnchecked(loader); - } - - private static void collectYangModuleInfo(final YangModuleInfo moduleInfo, - final Builder moduleInfoSet) { - moduleInfoSet.add(moduleInfo); - for (YangModuleInfo dependency : moduleInfo.getImportedModules()) { - collectYangModuleInfo(dependency, moduleInfoSet); - } - } - /** * Checks if supplied class represents RPC Input / RPC Output. * @@ -297,14 +119,15 @@ public final class BindingReflections { * Class to be checked * @return true if class represents RPC Input or RPC Output class. */ - public static boolean isRpcType(final Class targetType) { + @VisibleForTesting + static boolean isRpcType(final Class targetType) { return DataContainer.class.isAssignableFrom(targetType) && !ChildOf.class.isAssignableFrom(targetType) && !Notification.class.isAssignableFrom(targetType) && (targetType.getName().endsWith("Input") || targetType.getName().endsWith("Output")); } - private static class ClassToQNameLoader extends CacheLoader, Optional> { + private static final class ClassToQNameLoader extends CacheLoader, Optional> { @Override public Optional load(@SuppressWarnings("NullableProblems") final Class key) throws Exception {