All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.jaxb.javamodel.xjc.XJCJavaMethodImpl Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * 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 getActualTypeArguments() { throw new UnsupportedOperationException("getActualTypeArguments"); } /** * Returns the Java language modifiers for this JavaMethod, encoded in an integer. * * @return the int representing the modifiers for this method. * * @see java.lang.reflect.Modifier */ @Override public int getModifiers() { return xjcMethod.mods().getValue(); } /** * Indicates if this JavaMethod is abstract. * * @return true if this JavaMethod is abstract, otherwise false. */ @Override public boolean isAbstract() { return Modifier.isAbstract(getModifiers()); } /** * Indicates if this JavaMethod is private. * * @return true if this JavaMethod is private, otherwise false. */ @Override public boolean isPrivate() { return Modifier.isPrivate(getModifiers()); } /** * Indicates if this JavaMethod is protected. * * @return true if this JavaMethod is protected, otherwise false. */ @Override public boolean isProtected() { return Modifier.isProtected(getModifiers()); } /** * Indicates if this JavaMethod is public. * * @return true if this JavaMethod is public, otherwise false. */ @Override public boolean isPublic() { return Modifier.isPublic(getModifiers()); } /** * Indicates if this JavaMethod is static. * * @return true if this JavaMethod is static, otherwise false. */ @Override public boolean isStatic() { return Modifier.isStatic(getModifiers()); } /** * Indicates if this JavaMethod is final. * * @return true if this JavaMethod is final, otherwise false. */ @Override public boolean isFinal() { return Modifier.isFinal(getModifiers()); } /** * Not supported. */ @Override public boolean isSynthetic() { return false; } /** * Not supported. */ @Override public JavaAnnotation getDeclaredAnnotation(JavaClass arg0) { throw new UnsupportedOperationException("getDeclaredAnnotation"); } /** * Not supported. */ @Override public Collection getDeclaredAnnotations() { throw new UnsupportedOperationException("getDeclaredAnnotations"); } /** * Returns the JavaClass which contains this method. * * @return JavaClass representing the owner of this JavaMethod. */ @Override public JavaClass getOwningClass() { return owningClass; } /** * Set the JavaClass which contains this method. * * @param owningClass the JavaClass representing the owner of this JavaMethod. */ public void setOwningClass(JavaClass owningClass) { this.owningClass = owningClass; } /** * Not supported. */ @Override public boolean isBridge() { return false; } }