org.eclipse.persistence.jaxb.javamodel.xjc.XJCJavaMethodImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Rick Barkhouse - 2.1 - Initial implementation
package org.eclipse.persistence.jaxb.javamodel.xjc;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.exceptions.JAXBException;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.jaxb.javamodel.JavaAnnotation;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;
import org.eclipse.persistence.jaxb.javamodel.JavaMethod;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JType;
/**
* INTERNAL:
*
* Purpose: JavaMethod
implementation wrapping XJC's JMethod
. Used when
* bootstrapping a DynamicJAXBContext
from an XML Schema.
*
*
*
* Responsibilities:
*
*
* - Provide
Method
information from the underlying JMethod
.
*
*
* @since EclipseLink 2.1
*
* @see org.eclipse.persistence.jaxb.javamodel.JavaMethod
*/
public class XJCJavaMethodImpl implements JavaMethod {
private JMethod xjcMethod;
private JCodeModel jCodeModel;
private DynamicClassLoader dynamicClassLoader;
private JavaClass owningClass;
private static Field JMETHOD_ANNOTATIONS = null;
static {
try {
JMETHOD_ANNOTATIONS = PrivilegedAccessHelper.getDeclaredField(JMethod.class, "annotations", true);
} catch (Exception e) {
throw JAXBException.errorCreatingDynamicJAXBContext(e);
}
}
/**
* Construct a new instance of XJCJavaMethodImpl
.
*
* @param javaMethod - the XJC JMethod
to be wrapped.
* @param codeModel - the XJC JCodeModel
this method belongs to.
* @param loader - the ClassLoader
used to bootstrap the DynamicJAXBContext
.
* @param owner - the JavaClass
this method belongs to.
*/
public XJCJavaMethodImpl(JMethod javaMethod, JCodeModel codeModel, DynamicClassLoader loader, JavaClass owner) {
this.xjcMethod = javaMethod;
this.jCodeModel = codeModel;
this.dynamicClassLoader = loader;
this.owningClass = owner;
}
/**
* If this JavaMethod
is annotated with an Annotation
matching aClass
,
* return its JavaAnnotation
representation.
*
* @param aClass a JavaClass
representing the Annotation
to look for.
*
* @return the JavaAnnotation
represented by aClass
, if one exists, otherwise return null
.
*/
@Override
@SuppressWarnings("unchecked")
public JavaAnnotation getAnnotation(JavaClass aClass) {
if (aClass != null) {
Collection annotations = null;
try {
annotations = (Collection) PrivilegedAccessHelper.getValueFromField(JMETHOD_ANNOTATIONS, xjcMethod);
} catch (Exception e) {
}
if (annotations == null) {
return null;
}
for (JAnnotationUse annotationUse : annotations) {
XJCJavaAnnotationImpl xjcAnnotation = new XJCJavaAnnotationImpl(annotationUse, dynamicClassLoader);
if (xjcAnnotation.getJavaAnnotationClass().getCanonicalName().equals(aClass.getQualifiedName())) {
return xjcAnnotation;
}
}
// Didn't find annotation so return null
return null;
}
// aClass was null so return null
return null;
}
/**
* Return all of the Annotations
for this JavaMethod
.
*
* @return A Collection
containing this JavaMethod's
JavaAnnotations
.
*/
@Override
@SuppressWarnings("unchecked")
public Collection getAnnotations() {
ArrayList annotationsList = new ArrayList();
Collection annotations = null;
try {
annotations = (Collection) PrivilegedAccessHelper.getValueFromField(JMETHOD_ANNOTATIONS, xjcMethod);
} catch (Exception e) {
}
if (annotations == null) {
return annotationsList;
}
for (JAnnotationUse annotationUse : annotations) {
XJCJavaAnnotationImpl xjcAnnotation = new XJCJavaAnnotationImpl(annotationUse, dynamicClassLoader);
annotationsList.add(xjcAnnotation);
}
return annotationsList;
}
/**
* Returns the name of this JavaMethod
.
*
* @return the String
name of this JavaMethod
.
*/
@Override
public String getName() {
return xjcMethod.name();
}
/**
* Returns the array of parameters for this JavaMethod
.
*
* @return a JavaClass[]
representing the argument types for this method.
*/
@Override
public JavaClass[] getParameterTypes() {
JType[] params = xjcMethod.listParamTypes();
JavaClass[] paramArray = new JavaClass[params.length];
for (int i = 0; i < params.length; i++) {
if (((XJCJavaClassImpl) getOwningClass()).getJavaModel() != null) {
paramArray[i] = ((XJCJavaClassImpl) getOwningClass()).getJavaModel().getClass(params[i].fullName());
} else {
paramArray[i] = new XJCJavaClassImpl((JDefinedClass) params[i], jCodeModel, dynamicClassLoader);
}
}
return paramArray;
}
/**
* Returns this JavaMethod's
return type.
*
* @return a JavaClass
representing the return type of this method.
*/
public JavaClass getResolvedType() {
if (((XJCJavaClassImpl) getOwningClass()).getJavaModel() != null) {
return ((XJCJavaClassImpl) getOwningClass()).getJavaModel().getClass(xjcMethod.type().fullName());
}
try {
return new XJCJavaClassImpl(jCodeModel._class(xjcMethod.type().fullName()), jCodeModel, dynamicClassLoader);
} catch (JClassAlreadyExistsException ex) {
return new XJCJavaClassImpl(jCodeModel._getClass(xjcMethod.type().fullName()), jCodeModel, dynamicClassLoader);
}
}
/**
* Returns this JavaMethod's
return type.
*
* @return a JavaClass
representing the return type of this method.
*/
@Override
@SuppressWarnings("unchecked")
public JavaClass getReturnType() {
JType type = xjcMethod.type();
JavaClass returnClass = null;
JClass arg = null;
try {
Field argsField = PrivilegedAccessHelper.getDeclaredField(type.getClass(), "args", true);
List args = (List) PrivilegedAccessHelper.getValueFromField(argsField, type);
arg = args.get(0);
} catch (Exception e) {
}
if (((XJCJavaClassImpl) getOwningClass()).getJavaModel() != null) {
returnClass =((XJCJavaClassImpl) getOwningClass()).getJavaModel().getClass(type.fullName());
}
else {
try {
returnClass = new XJCJavaClassImpl(jCodeModel._class(type.fullName()), jCodeModel, dynamicClassLoader);
} catch (JClassAlreadyExistsException ex) {
returnClass = new XJCJavaClassImpl(jCodeModel._getClass(type.fullName()), jCodeModel, dynamicClassLoader);
}
}
if(arg != null){
JavaClass argClass = ((XJCJavaClassImpl) getOwningClass()).getJavaModel().getClass(arg.fullName());
((XJCJavaClassImpl)returnClass).setActualTypeArgument(argClass);
}
return returnClass;
}
/**
* Indicates if this JavaMethod
has actual type arguments, i.e. is a
* parameterized type (for example, List<Employee
).
*
* @return true
if this JavaClass
is parameterized, otherwise false
.
*/
public boolean hasActualTypeArguments() {
try {
JavaClass[] allParams = getParameterTypes();
for (JavaClass type : allParams) {
Class> paramClass = Class.forName(type.getPackageName() + "." + type.getName());
if (paramClass.getConstructor().newInstance() instanceof ParameterizedType) {
return true;
}
}
return false;
} catch (Exception e) {
return false;
}
}
/**
* Not supported.
*/
public Collection