/*******************************************************************************
* Copyright (c) 2007, 2010 Association for Decentralized Information Management
* in Industry THTH ry.
* 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
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
*******************************************************************************/
package org.simantics.utils;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class ReflectionUtils {
/**
* For a class C extends PC<P>
, where PC
is
* a class, not an interface, retrieves class P
.
*
* @param clazz
* @return
*/
public static Class> getSingleParameterType(Class> clazz) {
Type t = clazz.getGenericSuperclass();
if(t instanceof Class>) {
throw new UnsupportedOperationException("Missing parameter type for input class '" + clazz.getCanonicalName() + "'");
} else if (t instanceof ParameterizedType) {
ParameterizedType type = (ParameterizedType)t;
Type argType = type.getActualTypeArguments()[0];
if (argType instanceof Class>) {
return (Class>) argType;
} else if (argType instanceof ParameterizedType) {
// This happens if the input class X
// parameter T is also parameterized.
ParameterizedType pargType = (ParameterizedType) argType;
return (Class>) pargType.getRawType();
} else {
throw new UnsupportedOperationException("Unsupported parameter type in class '" + clazz.getCanonicalName() + "': " + argType);
}
} else {
throw new UnsupportedOperationException("Unknown case in class '" + clazz.getCanonicalName() + "'");
}
}
/**
* Works like {@link #getSingleParameterType(Class)} assuming the retrieved
* parameter class extends T
.
*
* @param clazz
* @return
*/
@SuppressWarnings("unchecked")
public static Class getSingleParameterTypeExtending(Class> clazz) {
Type t = clazz.getGenericSuperclass();
if(t instanceof Class>) {
throw new UnsupportedOperationException("Missing parameter type for input class '" + clazz.getCanonicalName() + "'");
} else if (t instanceof ParameterizedType) {
ParameterizedType type = (ParameterizedType)t;
Type argType = type.getActualTypeArguments()[0];
if (argType instanceof Class>) {
return (Class) argType;
} else if (argType instanceof ParameterizedType) {
// This happens if the input class X
// parameter T is also parameterized.
ParameterizedType pargType = (ParameterizedType) argType;
return (Class) pargType.getRawType();
} else {
throw new UnsupportedOperationException("Unsupported parameter type in class '" + clazz.getCanonicalName() + "': " + argType);
}
} else {
throw new UnsupportedOperationException("Unknown case in class '" + clazz.getCanonicalName() + "'");
}
}
}