Added headers to the concepts bundles 56/3656/1
authorTony Tkacik <ttkacik@cisco.com>
Thu, 12 Dec 2013 00:37:36 +0000 (01:37 +0100)
committerTony Tkacik <ttkacik@cisco.com>
Thu, 12 Dec 2013 00:37:36 +0000 (01:37 +0100)
  Extracted some of utility code and constants to the concepts and
  yang-binding where it respectivelly belong.

Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
21 files changed:
concepts/src/main/java/org/opendaylight/yangtools/concepts/AbstractListenerRegistration.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/AbstractObjectRegistration.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/AbstractRegistration.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/ClassBasedPropertyBuilder.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/Codec.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/CompositeObjectRegistration.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/Delegator.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/Deserializer.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/InvertibleTransformator.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/Namespace.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/OrderedSet.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/Serializer.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/Transformator.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/util/ClassLoaderUtils.java [new file with mode: 0644]
concepts/src/main/java/org/opendaylight/yangtools/concepts/util/ListenerRegistry.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingCodec.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingDeserializer.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingMapping.java [new file with mode: 0644]
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingSerializer.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/BindingReflections.java [new file with mode: 0644]

index eec6d16ca5214cc915f396c42407e62c909ca723..7bc17a07cdb082efa4f2930ad43ccabd31e875f4 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 import java.util.EventListener;
index 69dddd6ba7f8eb6a29ebced6f29bd837ef359cdc..03ae939a7b430c11d484af230aba72abcea205ca 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.yangtools.concepts;\r
 \r
 /**\r
index 541686cecf728e7de949f094ff098f4fd3cb472b..9f68d0fd7d6792a3c1dc6eef3080f91cf1dc633a 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 /**
index a4055385657e36f5dd95e4723a8972891b7947e1..35187ba167ab9ad9ff0b11965ec6f68fa8f7f5c1 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 public interface ClassBasedPropertyBuilder<P,T extends ClassBasedPropertyBuilder<P,T>> extends Builder<P> {
index 0cde6caeee90f834ffed898ed36d2731ec48fa4d..64c24bf74e7bef244e3f179f1adf1f29fde959ec 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 public interface Codec<P,I> extends Serializer<P, I>, Deserializer<I, P> {
index 2856d6acf8971d2cadbe95f482af1c86c669b63d..c51a53dbf3bdf1990bac260901cfc7abff4886b5 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 import java.util.Collection;
index eb800b3d0f29d25d26589ce6410f512ded51a96f..be799d7fc05dc680999b814cb15c41b987f3aa53 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 /**
index f7aa872298a3d2ab6e3c9d02aeec40f1dad99b65..77034b8b2578eb437667c1a07d584be74f5e10d3 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 public interface Deserializer<P,I> {
index d04774793097255fc8b6095db2aa280ed59621c0..31ca3b5ca741b9e70182c4639686b2fff450b616 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 public interface InvertibleTransformator<P, I> extends Transformator<P, I>{
index b66c1c3397f63766bdd1273843978845bfb97848..b351fa6a3c93e325f3c788aa2ec9fe5c670c2670 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.yangtools.concepts;\r
 \r
 import java.util.Set;\r
index af5c094e054d2356d980b087822f554701c4b632..d6747749dc2f28522b64d2d2f70992e181bd330b 100644 (file)
@@ -1,3 +1,10 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
 package org.opendaylight.yangtools.concepts;\r
 import java.util.List;\r
 import java.util.Set;\r
index ea89231752ff873353265d961d4c03c6f7e0bfc6..24ef67c59b09d79af9a39d603bdf939fce7d9f0d 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 public interface Serializer<P,I> {
index 7c4cc718c2870afcdf452da58dea10e80ce44dd3..c1a70a77dcf13c1cfee8347eb02222d9defb33a6 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts;
 
 public interface Transformator<P,I> {
diff --git a/concepts/src/main/java/org/opendaylight/yangtools/concepts/util/ClassLoaderUtils.java b/concepts/src/main/java/org/opendaylight/yangtools/concepts/util/ClassLoaderUtils.java
new file mode 100644 (file)
index 0000000..480cd57
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts.util;
+
+import static org.opendaylight.yangtools.concepts.util.ClassLoaderUtils.findParameterizedType;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.concurrent.Callable;
+import java.util.concurrent.locks.Lock;
+
+
+public final class ClassLoaderUtils {
+
+    private ClassLoaderUtils() {
+        throw new UnsupportedOperationException("Utility class");
+    }
+
+    public static <V> V withClassLoader(ClassLoader cls, Callable<V> function) throws Exception {
+        return withClassLoaderAndLock(cls, null, function);
+    }
+
+    public static <V> V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable<V> function) throws Exception {
+        if (cls == null) {
+            throw new IllegalArgumentException("Classloader should not be null");
+        }
+        if (function == null) {
+            throw new IllegalArgumentException("Function should not be null");
+        }
+
+        if (lock != null) {
+            lock.lock();
+        }
+        ClassLoader oldCls = Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(cls);
+            return function.call();
+        } finally {
+            Thread.currentThread().setContextClassLoader(oldCls);
+            if (lock != null) {
+                lock.unlock();
+            }
+        }
+    }
+
+    public static ParameterizedType findParameterizedType(Class<?> subclass, Class<?> genericType) {
+        if(subclass == null || genericType == null) {
+            throw new IllegalArgumentException("Class was not specified.");
+        }
+        for (Type type : subclass.getGenericInterfaces()) {
+            if (type instanceof ParameterizedType && genericType.equals(((ParameterizedType) type).getRawType())) {
+                return (ParameterizedType) type;
+            }
+        }
+        return null;
+    }
+
+    public static <S,G,P> Class<P> findFirstGenericArgument(final Class<S> scannedClass, final Class<G> genericType) {
+        try {
+            return withClassLoader(scannedClass.getClassLoader(), ClassLoaderUtils.<S,G,P>findFirstGenericArgumentTask(scannedClass, genericType));
+        } catch (Exception e) {
+            return null;
+        }
+    }
+    
+    private static <S,G,P> Callable<Class<P>> findFirstGenericArgumentTask(final Class<S> scannedClass, final Class<G> genericType) {
+        return new Callable<Class<P>>() {
+            @Override
+            @SuppressWarnings("unchecked")
+            public Class<P> call() throws Exception {
+                final ParameterizedType augmentationGeneric = findParameterizedType(scannedClass,
+                        genericType);
+                if (augmentationGeneric == null) {
+                    return null;
+                }
+                return (Class<P>) augmentationGeneric.getActualTypeArguments()[0];
+            }
+        };
+    }
+
+}
\ No newline at end of file
index 458c54d806ce330c6116f3d75dd58d38b85f03bf..0cde6aa59f6e8f7e29640dca2e003c2d66014315 100644 (file)
@@ -1,5 +1,13 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.concepts.util;
 
+import java.lang.reflect.Proxy;
 import java.util.Collections;
 import java.util.EventListener;
 import java.util.Set;
@@ -10,23 +18,28 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration;
 
 public class ListenerRegistry<T extends EventListener> implements Iterable<ListenerRegistration<T>> {
 
-    final ConcurrentHashMap<ListenerRegistration<T>,ListenerRegistration<T>> listeners;
+    private final ConcurrentHashMap<ListenerRegistration<? extends T>,ListenerRegistration<? extends T>> listeners;
     final Set<ListenerRegistration<T>> unmodifiableView;
+    private T invoker;
 
+    @SuppressWarnings("unchecked")
     public ListenerRegistry() {
         listeners = new ConcurrentHashMap<>();
-        unmodifiableView = Collections.unmodifiableSet(listeners.keySet());
+        // This conversion is known to be safe.
+        @SuppressWarnings("rawtypes")
+        final Set rawSet = Collections.unmodifiableSet(listeners.keySet());
+        unmodifiableView = rawSet;
     }
 
     public Iterable<ListenerRegistration<T>> getListeners() {
         return unmodifiableView;
     }
 
-    public ListenerRegistration<T> register(T listener) {
+    public <F extends T> ListenerRegistration<F> register(F listener) {
         if (listener == null) {
             throw new IllegalArgumentException("Listener should not be null.");
         }
-        ListenerRegistrationImpl<T> ret = new ListenerRegistrationImpl<T>(listener);
+        ListenerRegistrationImpl<F> ret = new ListenerRegistrationImpl<F>(listener);
         listeners.put(ret,ret);
         return ret;
     }
index f8bb91b736819ea5a0993d74b473734f70a43d84..00c14594eef1b0988679d75a9fc7b40a7533fa80 100644 (file)
@@ -1,10 +1,22 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.yang.binding;
 
-public interface BindingCodec<P,I>  extends BindingSerializer<P, I>, BindingDeserializer<I, P> {
+import org.opendaylight.yangtools.concepts.Codec;
+
+public interface BindingCodec<P, I> extends //
+        BindingSerializer<P, I>, //
+        BindingDeserializer<I, P>, //
+        Codec<P, I> {
 
     @Override
     public P serialize(I input);
-    
+
     @Override
     public I deserialize(P input);
 }
index cc97a956221e5e6afc9bd98d0d997667be2ca211..dea3d992db99f03e07b70df229654dcd848554e9 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.yang.binding;
 
 public interface BindingDeserializer<P,I> {
diff --git a/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingMapping.java b/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingMapping.java
new file mode 100644 (file)
index 0000000..00a36d9
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.yang.binding;
+
+import java.util.Set;
+
+import org.opendaylight.yangtools.yang.common.QName;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import static com.google.common.base.Preconditions.*;
+
+public final class BindingMapping {
+
+    public static final String VERSION = "0.6";
+
+    public static final Set<String> JAVA_RESERVED_WORDS = ImmutableSet.of("abstract", "assert", "boolean", "break",
+            "byte", "case", "catch", "char", "class", "const", "continue", "default", "double", "do", "else", "enum",
+            "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof",
+            "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return",
+            "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient",
+            "true", "try", "void", "volatile", "while");
+
+    public static final String DATA_ROOT_SUFFIX = "Data";
+    public static final String RPC_SERVICE_SUFFIX = "Service";
+    public static final String NOTIFICATION_LISTENER_SUFFIX = "Listener";
+    public static final String QNAME_STATIC_FIELD_NAME = "QNAME";
+
+    private static final Splitter SPACE_SPLITTER = Splitter.on(" ").omitEmptyStrings().trimResults();
+
+    public static final String getMethodName(QName name) {
+        checkArgument(name != null, "Name should not be null.");
+        return toFirstLower(toCamelCase(name.getLocalName()));
+    }
+
+    public static final String getClassName(String localName) {
+        return toFirstUpper(toCamelCase(localName));
+    }
+
+    public static final String getClassName(QName name) {
+        checkArgument(name != null, "Name should not be null.");
+        return toFirstUpper(toCamelCase(name.getLocalName()));
+    }
+
+    private static final String toCamelCase(String rawString) {
+        checkArgument(rawString != null, "String should not be null");
+        Iterable<String> components = SPACE_SPLITTER.split(rawString.replace('-', ' ').replace('_', ' '));
+        StringBuilder builder = new StringBuilder();
+        for (String comp : components) {
+            builder.append(toFirstUpper(comp));
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Returns the {@link String} {@code s} with an
+     * {@link Character#isUpperCase(char) upper case} first character. This
+     * function is null-safe.
+     * 
+     * @param s
+     *            the string that should get an upper case first character. May
+     *            be <code>null</code>.
+     * @return the {@link String} {@code s} with an upper case first character
+     *         or <code>null</code> if the input {@link String} {@code s} was
+     *         <code>null</code>.
+     */
+    private static String toFirstUpper(String s) {
+        if (s == null || s.length() == 0)
+            return s;
+        if (Character.isUpperCase(s.charAt(0)))
+            return s;
+        if (s.length() == 1)
+            return s.toUpperCase();
+        return s.substring(0, 1).toUpperCase() + s.substring(1);
+    }
+
+    /**
+     * Returns the {@link String} {@code s} with an
+     * {@link Character#isLowerCase(char) lower case} first character. This
+     * function is null-safe.
+     * 
+     * @param s
+     *            the string that should get an lower case first character. May
+     *            be <code>null</code>.
+     * @return the {@link String} {@code s} with an lower case first character
+     *         or <code>null</code> if the input {@link String} {@code s} was
+     *         <code>null</code>.
+     */
+    private static String toFirstLower(String s) {
+        if (s == null || s.length() == 0)
+            return s;
+        if (Character.isLowerCase(s.charAt(0)))
+            return s;
+        if (s.length() == 1)
+            return s.toLowerCase();
+        return s.substring(0, 1).toLowerCase() + s.substring(1);
+    }
+}
index a0e355b693447b401552eb3f00cbdfea087c930e..fb85eae9f783f3f9ed19cb2c2120946792b4f5bb 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.yang.binding;
 
 public interface BindingSerializer<P,I> {
index 16a06e139f70c89c4daa361b9e0a5c47af3cd5b8..09f0dc13c35cfcbe40f5729f67d06ffc71d352ea 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.concepts.Path;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
 /**
@@ -34,7 +35,7 @@ public final class InstanceIdentifier<T extends DataObject> implements Path<Inst
     }
 
     public InstanceIdentifier(List<PathArgument> path, Class<T> type) {
-        this.path = Collections.<PathArgument> unmodifiableList(new ArrayList<>(path));
+        this.path = ImmutableList.copyOf(path);
         this.targetType = type;
     }
 
diff --git a/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/BindingReflections.java b/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/BindingReflections.java
new file mode 100644 (file)
index 0000000..3e1e7b8
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.yang.binding.util;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.TimeUnit;
+
+import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils;
+import org.opendaylight.yangtools.yang.binding.Augmentable;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
+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.common.QName;
+
+import com.google.common.base.Optional;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+public class BindingReflections {
+
+    private static final long EXPIRATION_TIME = 60;
+
+    private static final LoadingCache<Class<?>, Optional<QName>> classToQName = CacheBuilder.newBuilder() //
+            .weakKeys() //
+            .expireAfterAccess(EXPIRATION_TIME, TimeUnit.SECONDS) //
+            .build(new ClassToQNameLoader());
+
+    /**
+     * 
+     * @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<? extends Augmentable<?>> findAugmentationTarget(
+            final Class<? extends Augmentation<?>> augmentation) {
+        return ClassLoaderUtils.findFirstGenericArgument(augmentation, Augmentation.class);
+    }
+
+    /**
+     * 
+     * @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<?> findHierarchicalParent(final Class<? extends ChildOf<?>> childClass) {
+        return ClassLoaderUtils.findFirstGenericArgument(childClass, ChildOf.class);
+    }
+
+    /**
+     * 
+     * @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<?> findHierarchicalParent(DataObject childClass) {
+        if (childClass instanceof ChildOf) {
+            return ClassLoaderUtils.findFirstGenericArgument(childClass.getImplementedInterface(), ChildOf.class);
+        }
+        return null;
+    }
+
+    public static final QName findQName(Class<? extends DataContainer> dataType) {
+        return classToQName.getUnchecked(dataType).orNull();
+    }
+
+    private static class ClassToQNameLoader extends CacheLoader<Class<?>, Optional<QName>> {
+
+        @Override
+        public Optional<QName> load(Class<?> key) throws Exception {
+            try {
+                Field field = key.getField(BindingMapping.QNAME_STATIC_FIELD_NAME);
+                Object obj = field.get(null);
+                if (obj instanceof QName) {
+                    return Optional.of((QName) obj);
+                }
+            } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+                // NOOP
+            }
+            return Optional.absent();
+        }
+    }
+
+}