]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils/src/org/simantics/utils/ReflectionUtils.java
b9d794e4043d2fc73346fd77049fcf7fc67cbe06
[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         if(t instanceof Class<?>) {
62             throw new UnsupportedOperationException("Missing parameter type for input class '" + clazz.getCanonicalName() + "'");
63         } else if (t instanceof ParameterizedType) {
64             ParameterizedType type = (ParameterizedType)t;
65             Type argType = type.getActualTypeArguments()[0];
66             if (argType instanceof Class<?>) {
67                 return (Class<T>) argType;
68             } else if (argType instanceof ParameterizedType) {
69                 // This happens if the input class X<T>
70                 // parameter T is also parameterized.
71                 ParameterizedType pargType = (ParameterizedType) argType;
72                 return (Class<T>) pargType.getRawType();
73             } else {
74                 throw new UnsupportedOperationException("Unsupported parameter type in class '" + clazz.getCanonicalName() + "': " + argType);
75             }
76         } else {
77             throw new UnsupportedOperationException("Unknown case in class '" + clazz.getCanonicalName() + "'");
78         }
79
80     }
81
82 }