2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.binding.util;
10 import java.lang.reflect.Field;
11 import java.util.concurrent.TimeUnit;
13 import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils;
14 import org.opendaylight.yangtools.yang.binding.Augmentable;
15 import org.opendaylight.yangtools.yang.binding.Augmentation;
16 import org.opendaylight.yangtools.yang.binding.BindingMapping;
17 import org.opendaylight.yangtools.yang.binding.ChildOf;
18 import org.opendaylight.yangtools.yang.binding.DataContainer;
19 import org.opendaylight.yangtools.yang.binding.DataObject;
20 import org.opendaylight.yangtools.yang.common.QName;
22 import com.google.common.base.Optional;
23 import com.google.common.cache.CacheBuilder;
24 import com.google.common.cache.CacheLoader;
25 import com.google.common.cache.LoadingCache;
27 public class BindingReflections {
29 private static final long EXPIRATION_TIME = 60;
31 private static final LoadingCache<Class<?>, Optional<QName>> classToQName = CacheBuilder.newBuilder() //
33 .expireAfterAccess(EXPIRATION_TIME, TimeUnit.SECONDS) //
34 .build(new ClassToQNameLoader());
39 * {@link Augmentation} subclass for which we want to determine
40 * augmentation target.
41 * @return Augmentation target - class which augmentation provides
42 * additional extensions.
44 public static Class<? extends Augmentable<?>> findAugmentationTarget(
45 final Class<? extends Augmentation<?>> augmentation) {
46 return ClassLoaderUtils.findFirstGenericArgument(augmentation, Augmentation.class);
52 * {@link Augmentation} subclass for which we want to determine
53 * augmentation target.
54 * @return Augmentation target - class which augmentation provides
55 * additional extensions.
57 public static Class<?> findHierarchicalParent(final Class<? extends ChildOf<?>> childClass) {
58 return ClassLoaderUtils.findFirstGenericArgument(childClass, ChildOf.class);
64 * {@link Augmentation} subclass for which we want to determine
65 * augmentation target.
66 * @return Augmentation target - class which augmentation provides
67 * additional extensions.
69 public static Class<?> findHierarchicalParent(DataObject childClass) {
70 if (childClass instanceof ChildOf) {
71 return ClassLoaderUtils.findFirstGenericArgument(childClass.getImplementedInterface(), ChildOf.class);
76 public static final QName findQName(Class<? extends DataContainer> dataType) {
77 return classToQName.getUnchecked(dataType).orNull();
80 private static class ClassToQNameLoader extends CacheLoader<Class<?>, Optional<QName>> {
83 public Optional<QName> load(Class<?> key) throws Exception {
85 Field field = key.getField(BindingMapping.QNAME_STATIC_FIELD_NAME);
86 Object obj = field.get(null);
87 if (obj instanceof QName) {
88 return Optional.of((QName) obj);
90 } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
93 return Optional.absent();