]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils/src/org/simantics/utils/ReflectionUtils.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.utils / src / org / simantics / utils / ReflectionUtils.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.utils;
13
14 import java.lang.reflect.ParameterizedType;
15 import java.lang.reflect.Type;
16
17 public class ReflectionUtils {
18
19     /**
20      * For a class <code>C extends PC&lt;P&gt;</code>, where <code>PC</code> is
21      * a class, not an interface, retrieves class <code>P</code>.
22      * 
23      * @param clazz
24      * @return
25      */
26     public static Class<?> getSingleParameterType(Class<?> clazz) {
27
28         Type t = clazz.getGenericSuperclass();
29         if(t instanceof Class<?>) {
30             throw new UnsupportedOperationException("Missing parameter type for input class '" + clazz.getCanonicalName() + "'");
31         } else if (t instanceof ParameterizedType) {
32             ParameterizedType type = (ParameterizedType)t;
33             Type argType = type.getActualTypeArguments()[0];
34             if (argType instanceof Class<?>) {
35                 return (Class<?>) argType;
36             } else if (argType instanceof ParameterizedType) {
37                 // This happens if the input class X<T>
38                 // parameter T is also parameterized.
39                 ParameterizedType pargType = (ParameterizedType) argType;
40                 return (Class<?>) pargType.getRawType();
41             } else {
42                 throw new UnsupportedOperationException("Unsupported parameter type in class '" + clazz.getCanonicalName() + "': " + argType);
43             }
44         } else {
45             throw new UnsupportedOperationException("Unknown case in class '" + clazz.getCanonicalName() + "'");
46         }
47
48     }
49
50     /**
51      * Works like {@link #getSingleParameterType(Class)} assuming the retrieved
52      * parameter class extends <code>T</code>.
53      * 
54      * @param clazz
55      * @return
56      */
57     @SuppressWarnings("unchecked")
58     public static <T> Class<T> getSingleParameterTypeExtending(Class<?> clazz) {
59
60         Type t = clazz.getGenericSuperclass();
61         while (t instanceof Class<?>) {
62             Class<?> cl = (Class) t;
63             t = cl.getGenericSuperclass();
64             if (t == null) {
65                 // according to javadoc, we have reached java.lang.Object so no can do
66                 break;
67             }
68         }
69         if(t instanceof Class<?>) {
70             throw new UnsupportedOperationException("Missing parameter type for input class '" + clazz.getCanonicalName() + "'");
71         } else if (t instanceof ParameterizedType) {
72             ParameterizedType type = (ParameterizedType)t;
73             Type argType = type.getActualTypeArguments()[0];
74             if (argType instanceof Class<?>) {
75                 return (Class<T>) argType;
76             } else if (argType instanceof ParameterizedType) {
77                 // This happens if the input class X<T>
78                 // parameter T is also parameterized.
79                 ParameterizedType pargType = (ParameterizedType) argType;
80                 return (Class<T>) pargType.getRawType();
81             } else {
82                 throw new UnsupportedOperationException("Unsupported parameter type in class '" + clazz.getCanonicalName() + "': " + argType);
83             }
84         } else {
85             throw new UnsupportedOperationException("Unknown case in class '" + clazz.getCanonicalName() + "'");
86         }
87
88     }
89
90 }