f2402270efeaa409102c3ceffa3553f50e5d515e
[yangtools.git] / concepts / src / main / java / org / opendaylight / yangtools / concepts / util / ClassLoaderUtils.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.concepts.util;
9
10 import java.lang.reflect.ParameterizedType;
11 import java.lang.reflect.Type;
12 import java.util.concurrent.Callable;
13 import java.util.concurrent.locks.Lock;
14
15
16 public final class ClassLoaderUtils {
17
18     private ClassLoaderUtils() {
19         throw new UnsupportedOperationException("Utility class");
20     }
21
22     public static <V> V withClassLoader(ClassLoader cls, Callable<V> function) throws Exception {
23         return withClassLoaderAndLock(cls, null, function);
24     }
25
26     public static <V> V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable<V> function) throws Exception {
27         if (cls == null) {
28             throw new IllegalArgumentException("Classloader should not be null");
29         }
30         if (function == null) {
31             throw new IllegalArgumentException("Function should not be null");
32         }
33
34         if (lock != null) {
35             lock.lock();
36         }
37         ClassLoader oldCls = Thread.currentThread().getContextClassLoader();
38         try {
39             Thread.currentThread().setContextClassLoader(cls);
40             return function.call();
41         } finally {
42             Thread.currentThread().setContextClassLoader(oldCls);
43             if (lock != null) {
44                 lock.unlock();
45             }
46         }
47     }
48
49     public static ParameterizedType findParameterizedType(Class<?> subclass, Class<?> genericType) {
50         if(subclass == null || genericType == null) {
51             throw new IllegalArgumentException("Class was not specified.");
52         }
53         for (Type type : subclass.getGenericInterfaces()) {
54             if (type instanceof ParameterizedType && genericType.equals(((ParameterizedType) type).getRawType())) {
55                 return (ParameterizedType) type;
56             }
57         }
58         return null;
59     }
60
61     public static <S,G,P> Class<P> findFirstGenericArgument(final Class<S> scannedClass, final Class<G> genericType) {
62         try {
63             return withClassLoader(scannedClass.getClassLoader(), ClassLoaderUtils.<S,G,P>findFirstGenericArgumentTask(scannedClass, genericType));
64         } catch (Exception e) {
65             return null;
66         }
67     }
68     
69     private static <S,G,P> Callable<Class<P>> findFirstGenericArgumentTask(final Class<S> scannedClass, final Class<G> genericType) {
70         return new Callable<Class<P>>() {
71             @Override
72             @SuppressWarnings("unchecked")
73             public Class<P> call() throws Exception {
74                 final ParameterizedType augmentationGeneric = findParameterizedType(scannedClass,
75                         genericType);
76                 if (augmentationGeneric == null) {
77                     return null;
78                 }
79                 return (Class<P>) augmentationGeneric.getActualTypeArguments()[0];
80             }
81         };
82     }
83
84     public static Type getFirstGenericParameter(Type type) {
85         if(type instanceof ParameterizedType) {
86             return ((ParameterizedType) type).getActualTypeArguments()[0];
87         }
88         return null;
89     }
90
91 }