
org.eclipse.persistence.jaxb.javamodel.xjc.XJCJavaClassImpl Maven / Gradle / Ivy
/******************************************************************************* * Copyright (c) 2011, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * 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.Type; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.persistence.dynamic.DynamicClassLoader; import org.eclipse.persistence.exceptions.JAXBException; import org.eclipse.persistence.internal.helper.ClassConstants; import org.eclipse.persistence.internal.helper.ConversionManager; 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.JavaConstructor; import org.eclipse.persistence.jaxb.javamodel.JavaField; import org.eclipse.persistence.jaxb.javamodel.JavaMethod; import org.eclipse.persistence.jaxb.javamodel.JavaModel; import org.eclipse.persistence.jaxb.javamodel.JavaPackage; import com.sun.codemodel.ClassType; import com.sun.codemodel.JAnnotationUse; import com.sun.codemodel.JClass; import com.sun.codemodel.JCodeModel; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JFieldVar; import com.sun.codemodel.JMethod; import com.sun.codemodel.JMods; import com.sun.codemodel.JPrimitiveType; import com.sun.codemodel.JType; import com.sun.codemodel.JTypeVar; /** * INTERNAL: *
Class, otherwise* Purpose:
* *JavaClass
implementation wrapping XJC'sJDefinedClass
. * Used when bootstrapping aDynamicJAXBContext
from an XML Schema. ** Responsibilities: *
*
* * * @since EclipseLink 2.1 * * @see org.eclipse.persistence.jaxb.javamodel.JavaClass */ public class XJCJavaClassImpl implements JavaClass { private JDefinedClass xjcClass; private JCodeModel jCodeModel; private JavaModel javaModel; private boolean isArray; private boolean isPrimitive; private JavaClass arg; private DynamicClassLoader dynamicClassLoader; private static Field JDEFINEDCLASS_ANNOTATIONS = null; private static Field JDEFINEDCLASS_MODS = null; private static Field JDEFINEDCLASS_SUPERCLASS = null; private static Field JTYPEVAR_BOUND = null; private static final Map- Provide Class information from the underlying
*JDefinedClass
.jPrimitiveTypes = new HashMap (); static { JCodeModel tempCodeModel = new JCodeModel(); jPrimitiveTypes.put("java.lang.Boolean", tempCodeModel.BOOLEAN); jPrimitiveTypes.put("java.lang.Byte", tempCodeModel.BYTE); jPrimitiveTypes.put("java.lang.Character", tempCodeModel.CHAR); jPrimitiveTypes.put("java.lang.Double", tempCodeModel.DOUBLE); jPrimitiveTypes.put("java.lang.Float", tempCodeModel.FLOAT); jPrimitiveTypes.put("java.lang.Integer", tempCodeModel.INT); jPrimitiveTypes.put("java.lang.Long", tempCodeModel.LONG); jPrimitiveTypes.put("java.lang.Short", tempCodeModel.SHORT); try { JDEFINEDCLASS_ANNOTATIONS = PrivilegedAccessHelper.getDeclaredField(JDefinedClass.class, "annotations", true); JDEFINEDCLASS_MODS = PrivilegedAccessHelper.getDeclaredField(JDefinedClass.class, "mods", true); JDEFINEDCLASS_SUPERCLASS = PrivilegedAccessHelper.getDeclaredField(JDefinedClass.class, "superClass", true); JTYPEVAR_BOUND = PrivilegedAccessHelper.getDeclaredField(JTypeVar.class, "bound", true); } catch (Exception e) { throw JAXBException.errorCreatingDynamicJAXBContext(e); } } /** * Construct a new instance of XJCJavaClassImpl
. * * @param jDefinedClass - the XJCJDefinedClass
to be wrapped. * @param codeModel - the XJCJCodeModel
this class belongs to. * @param loader - theClassLoader
used to bootstrap theDynamicJAXBContext
. */ public XJCJavaClassImpl(JDefinedClass jDefinedClass, JCodeModel codeModel, DynamicClassLoader loader) { this(jDefinedClass, codeModel, loader, false, false); } /** * Construct a new instance ofXJCJavaClassImpl
. * * @param jDefinedClass - the XJCJDefinedClass
to be wrapped. * @param codeModel - the XJCJCodeModel
this class belongs to. * @param loader - theClassLoader
used to bootstrap theDynamicJAXBContext
. * @param isArray - indicates that this class is an array type. * @param isPrimitive - indicates that this class is a primitive type. */ public XJCJavaClassImpl(JDefinedClass jDefinedClass, JCodeModel codeModel, DynamicClassLoader loader, boolean isArray, boolean isPrimitive) { this.xjcClass = jDefinedClass; this.jCodeModel = codeModel; this.dynamicClassLoader = loader; this.isArray = isArray; this.isPrimitive = isPrimitive; } // ======================================================================== public void setActualTypeArgument(JavaClass javaClass){ arg = javaClass; } /** * Return the "actual" type from a parameterized type. For example, if this *JavaClass
representsList<Employee
, this method will return the *Employee
JavaClass
. * * @return aCollection
containing the actual type'sJavaClass
. */ public CollectiongetActualTypeArguments() { JTypeVar[] typeParams = xjcClass.typeParams(); if (null == typeParams || 0 == typeParams.length ) { if(arg != null){ java.util.List theList = new ArrayList (1); theList.add(arg); return theList; }else{ return new ArrayList (0); } } try { ArrayList typeArguments = new ArrayList (1); JTypeVar var = typeParams[typeParams.length - 1]; JClass xjcBoundClass = (JClass) PrivilegedAccessHelper.getValueFromField(JTYPEVAR_BOUND, var); JType basis = null; try { // Check to see if this type has a 'basis' field. // This would indicate it is a "parameterized type" (e.g. List ). // Cannot cache this field because JNarrowedClass is a protected class. Field basisField = PrivilegedAccessHelper.getDeclaredField(xjcBoundClass.getClass(), "basis", true); basis = (JClass) PrivilegedAccessHelper.getValueFromField(basisField, xjcBoundClass); } catch (Exception e) { // "basis" field not found } JavaClass boundClass; if (basis != null) { boundClass = this.javaModel.getClass(basis.fullName()); } else if (javaModel != null) { boundClass = this.javaModel.getClass(xjcBoundClass.fullName()); } else { JDefinedClass c = jCodeModel._getClass(xjcBoundClass.fullName()); boundClass = new XJCJavaClassImpl(c, jCodeModel, dynamicClassLoader); } typeArguments.add(boundClass); return typeArguments; } catch (Exception e) { return new ArrayList (0); } } /** * If this JavaClass
is an array type, return the type of the * array components. * * @returnJavaClass
of this array's component type, ornull
if * this is not an array type. */ public JavaClass getComponentType() { if (!isArray()) { return null; } return javaModel.getClass(this.xjcClass.fullName()); } /** * Return theJavaConstructor
for thisJavaClass
that has the * provided parameter types. * * @param parameterTypes the parameter list used to identify the constructor. * * @return theJavaConstructor
with the signature matching parameterTypes. */ public JavaConstructor getConstructor(JavaClass[] parameterTypes) { JType[] xjcParameterTypes = new JType[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { JavaClass pType = parameterTypes[i]; String className = pType.getQualifiedName(); JType xjcType = null; if (pType.isPrimitive()) { xjcType = jPrimitiveTypes.get(className); } else { xjcType = jCodeModel._getClass(className); } xjcParameterTypes[i] = xjcType; } JMethod constructor = xjcClass.getConstructor(xjcParameterTypes); return new XJCJavaConstructorImpl(constructor, jCodeModel, dynamicClassLoader, this); } /** * Return all of theJavaConstructors
for thisJavaClass
. * * @return ACollection
containing thisJavaClass'
JavaConstructors
. */ @SuppressWarnings("unchecked") public CollectiongetConstructors() { ArrayList constructors = new ArrayList (); Iterator it = xjcClass.constructors(); while (it.hasNext()) { constructors.add(new XJCJavaConstructorImpl(it.next(), jCodeModel, dynamicClassLoader, this)); } return constructors; } /** * Return this JavaClass'
inner classes. * * @return ACollection<JavaClass>
containing thisJavaClass'
inner classes. */ public CollectiongetDeclaredClasses() { ArrayList declaredClasses = new ArrayList (); Iterator it = xjcClass.classes(); while (it.hasNext()) { XJCJavaClassImpl dc; if (javaModel != null) { dc = (XJCJavaClassImpl) this.javaModel.getClass(it.next().fullName()); } else { dc = new XJCJavaClassImpl(it.next(), jCodeModel, dynamicClassLoader); } declaredClasses.add(dc); } return declaredClasses; } /** * Return the declared JavaConstructor
for thisJavaClass
that has the * provided parameter types. * * @param parameterTypes the parameter list used to identify the constructor. * * @return theJavaConstructor
with the signature matchingparameterTypes
. */ public JavaConstructor getDeclaredConstructor(JavaClass[] parameterTypes) { return getConstructor(parameterTypes); } /** * Return all of the declaredJavaConstructors
for thisJavaClass
. * * @return ACollection
containing thisJavaClass'
JavaConstructors
. */ public CollectiongetDeclaredConstructors() { return getConstructors(); } /** * Return the declared JavaField
for thisJavaClass
, identified * byfieldName
. * * @param fieldName the name of theJavaField
to return. * * @return theJavaField
namedfieldName
from thisJavaClass
. */ public JavaField getDeclaredField(String fieldName) { JFieldVar xjcField = xjcClass.fields().get(fieldName); return new XJCJavaFieldImpl(xjcField, jCodeModel, dynamicClassLoader, this); } /** * Return all of the declaredJavaFields
for thisJavaClass
. * * @return ACollection
containing thisJavaClass'
JavaFields
. */ public CollectiongetDeclaredFields() { Collection xjcFields = xjcClass.fields().values(); ArrayList fields = new ArrayList (xjcFields.size()); for (JFieldVar jField : xjcFields) { fields.add(new XJCJavaFieldImpl(jField, jCodeModel, dynamicClassLoader, this)); } return fields; } /** * Return the declared JavaMethod
for thisJavaClass
, * identified byname
, with the signature matchingargs
. * * @param name the name of theJavaMethod
to return. * @param args the parameter list used to identify the method. * * @return the matchingJavaMethod
from thisJavaClass
. */ public JavaMethod getDeclaredMethod(String name, JavaClass[] args) { return getMethod(name, args); } /** * Return all of the declaredJavaMethods
for thisJavaClass
. * * @return ACollection
containing thisJavaClass'
JavaMethods
. */ public CollectiongetDeclaredMethods() { return getMethods(); } /** * Return the JavaMethod
for thisJavaClass
, identified * byname
, with the signature matchingargs
. * * @param name the name of theJavaMethod
to return. * @param args the parameter list used to identify the method. * * @return the matchingJavaMethod
from thisJavaClass
. */ public JavaMethod getMethod(String name, JavaClass[] args) { CollectionxjcMethods = xjcClass.methods(); for (JMethod xjcMethod : xjcMethods) { JType[] params = xjcMethod.listParamTypes(); boolean argsAreEqual = argsAreEqual(args, params); if (xjcMethod.name().equals(name) && argsAreEqual) { return new XJCJavaMethodImpl(xjcMethod, jCodeModel, dynamicClassLoader, this); } } return null; } private boolean argsAreEqual(JavaClass[] elinkArgs, JType[] xjcArgs) { if (elinkArgs == null && xjcArgs == null) { return true; } if (elinkArgs != null && xjcArgs == null) { return false; } if (elinkArgs == null && xjcArgs != null) { return false; } if (elinkArgs.length != xjcArgs.length) { return false; } for (int i = 0; i < elinkArgs.length; i++) { JavaClass elinkClass = elinkArgs[i]; JType xjcClass = xjcArgs[i]; if (!elinkClass.getQualifiedName().equals(xjcClass.fullName())) { return false; } } return true; } /** * Return all of the JavaMethods
for thisJavaClass
. * * @return ACollection
containing thisJavaClass'
JavaMethods
. */ public CollectiongetMethods() { Collection xjcMethods = xjcClass.methods(); ArrayList elinkMethods = new ArrayList (xjcMethods.size()); for (JMethod xjcMethod : xjcMethods) { elinkMethods.add(new XJCJavaMethodImpl(xjcMethod, jCodeModel, dynamicClassLoader, this)); } return elinkMethods; } /** * Returns the Java language modifiers for this JavaClass
, encoded in an integer. * * @return theint
representing the modifiers for this class. * * @see java.lang.reflect.Modifier */ public int getModifiers() { JMods xjcMods = null; try { xjcMods = (JMods) PrivilegedAccessHelper.getValueFromField(JDEFINEDCLASS_MODS, xjcClass); } catch (Exception e) { return 0; } return xjcMods.getValue(); } /** * Returns the name of thisJavaClass
. * * @return theString
name of thisJavaClass
. */ public String getName() { return getQualifiedName(); } /** * Returns theJavaPackage
that thisJavaClass
belongs to. * * @return theJavaPackage
of thisJavaClass
. */ public JavaPackage getPackage() { return new XJCJavaPackageImpl(xjcClass.getPackage(), dynamicClassLoader); } /** * Returns the package name of thisJavaClass
. * * @return theString
name of thisJavaClass'
JavaPackage
. */ public String getPackageName() { return xjcClass._package().name(); } /** * Returns the fully-qualified name of thisJavaClass
. * * @return theString
name of thisJavaClass
. */ public String getQualifiedName() { if(isArray) { if(this.isPrimitive) { return getPrimitiveArrayNameFor(xjcClass.fullName()); } return "[L" + xjcClass.fullName(); } return xjcClass.fullName(); } private String getPrimitiveArrayNameFor(String fullName) { Class> componentClass = ConversionManager.getPrimitiveClass(fullName); if(componentClass != null) { if(componentClass == ClassConstants.PBYTE) { return ClassConstants.APBYTE.getName(); } if(componentClass == ClassConstants.PCHAR) { return ClassConstants.APCHAR.getName(); } if(componentClass == ClassConstants.PBOOLEAN) { return boolean[].class.getName(); } if(componentClass == ClassConstants.PDOUBLE) { return double[].class.getName(); } if(componentClass == ClassConstants.PFLOAT) { return float[].class.getName(); } if(componentClass == ClassConstants.PINT) { return int[].class.getName(); } if(componentClass == ClassConstants.PLONG) { return long[].class.getName(); } if(componentClass == ClassConstants.PSHORT) { return short[].class.getName(); } } return fullName; } /** * Returns the raw name of thisJavaClass
. Array types will * have "[]" appended to the name. * * @return theString
raw name of thisJavaClass
. */ public String getRawName() { if(isArray) { return xjcClass.fullName() + "[]"; } return xjcClass.fullName(); } /** * Returns the super class of thisJavaClass
. * * @returnJavaClass
representing the super class of thisJavaClass
. */ public JavaClass getSuperclass() { try { JClass superClass = (JClass) PrivilegedAccessHelper.getValueFromField(JDEFINEDCLASS_SUPERCLASS, xjcClass); if (superClass instanceof JDefinedClass) { if (javaModel != null) { return this.javaModel.getClass(superClass.fullName()); } return new XJCJavaClassImpl((JDefinedClass) superClass, jCodeModel, dynamicClassLoader); } else { if (javaModel != null) { return this.javaModel.getClass(superClass.fullName()); } return new XJCJavaClassImpl((JDefinedClass) superClass, jCodeModel, dynamicClassLoader); } } catch (Exception e) { return null; } } public Type getGenericSuperclass() { return null; } /** * Indicates if thisJavaClass
has actual type arguments, i.e. is a * parameterized type (for example,List<Employee
). * * @returntrue
if thisJavaClass
is parameterized, otherwisefalse
. */ public boolean hasActualTypeArguments() { return xjcClass.typeParams().length > 0; } /** * Indicates if thisJavaClass
isabstract
. * * @returntrue
if thisJavaClass
isabstract
, otherwisefalse
. */ public boolean isAbstract() { return xjcClass.isAbstract(); } /** * Indicates if thisJavaClass
is anAnnotation
. * * @returntrue
if thisJavaClass
is anAnnotation
, otherwisefalse
. */ public boolean isAnnotation() { return xjcClass.isAnnotationTypeDeclaration(); } /** * Indicates if thisJavaClass
is an Array type. * * @returntrue
if thisJavaClass
is an Array type, otherwisefalse
. */ public boolean isArray() { if (this.isArray) { return true; } return this.xjcClass.isArray(); } /** * Indicates if thisJavaClass
is either the same as, or is a superclass of, * thejavaClass
argument. * * @param javaClass theClass
to test. * * @returntrue
if thisJavaClass
is assignable from *javaClass
, otherwisefalse
. * * @see java.lang.Class#isAssignableFrom(Class) */ public boolean isAssignableFrom(JavaClass javaClass) { if (javaClass == null) { return false; } XJCJavaClassImpl javaClassImpl = (XJCJavaClassImpl) javaClass; JClass someClass = javaClassImpl.xjcClass; return xjcClass.isAssignableFrom(someClass); } /** * Indicates if thisJavaClass
is anenum
. * * @returntrue
if thisJavaClass
is anenum
, otherwisefalse
. */ public boolean isEnum() { return xjcClass.getClassType().equals(ClassType.ENUM); } /** * Indicates if thisJavaClass
isfinal
. * * @returntrue
if thisJavaClass
isfinal
, otherwisefalse
. */ public boolean isFinal() { return Modifier.isFinal(getModifiers()); } /** * Indicates if thisJavaClass
is aninterface
. * * @returntrue
if thisJavaClass
is aninterface
, otherwisefalse
. */ public boolean isInterface() { return xjcClass.isInterface(); } /** * Indicates if thisJavaClass
is an innerClass
. * * @returntrue
if thisJavaClass
is an innerfalse
. */ public boolean isMemberClass() { return this.xjcClass.outer() != null; } /** * Indicates if thisJavaClass
represents a primitive type. * * @returntrue
if thisJavaClass
represents a primitive type, otherwisefalse
. */ public boolean isPrimitive() { return false; } /** * Indicates if thisJavaClass
isprivate
. * * @returntrue
if thisJavaClass
isprivate
, otherwisefalse
. */ public boolean isPrivate() { return Modifier.isPrivate(getModifiers()); } /** * Indicates if thisJavaClass
isprotected
. * * @returntrue
if thisJavaClass
isprotected
, otherwisefalse
. */ public boolean isProtected() { return Modifier.isProtected(getModifiers()); } /** * Indicates if thisJavaClass
ispublic
. * * @returntrue
if thisJavaClass
ispublic
, otherwisefalse
. */ public boolean isPublic() { return Modifier.isPublic(getModifiers()); } /** * Indicates if thisJavaClass
isstatic
. * * @returntrue
if thisJavaClass
isstatic
, otherwisefalse
. */ public boolean isStatic() { return Modifier.isStatic(getModifiers()); } /** * Not supported. */ public boolean isSynthetic() { throw new UnsupportedOperationException("isSynthetic"); } /** * If thisJavaClass
is annotated with anAnnotation
matchingaClass
, * return itsJavaAnnotation
representation. * * @param aClass aJavaClass
representing theAnnotation
to look for. * * @return theJavaAnnotation
represented byaClass
, if one exists, otherwise returnnull
. */ @SuppressWarnings("unchecked") public JavaAnnotation getAnnotation(JavaClass aClass) { if (aClass != null) { Collectionannotations = null; try { annotations = (Collection ) PrivilegedAccessHelper.getValueFromField(JDEFINEDCLASS_ANNOTATIONS, xjcClass); } catch (Exception e) { } if (annotations == null) { return null; } for (JAnnotationUse annotationUse : annotations) { XJCJavaAnnotationImpl xjcAnnotation = new XJCJavaAnnotationImpl(annotationUse, dynamicClassLoader); String myAnnotationClass = xjcAnnotation.getJavaAnnotationClass().getCanonicalName(); String annotationClass = aClass.getQualifiedName(); if (myAnnotationClass.equals(annotationClass)) { 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 thisJavaClass
. * * @return ACollection
containing thisJavaClass'
JavaAnnotations
. */ @SuppressWarnings("unchecked") public CollectiongetAnnotations() { ArrayList annotationsList = new ArrayList (); Collection annotations = null; try { annotations = (Collection ) PrivilegedAccessHelper.getValueFromField(JDEFINEDCLASS_ANNOTATIONS, xjcClass); } catch (Exception e) { } if (annotations == null) { return annotationsList; } for (JAnnotationUse annotationUse : annotations) { XJCJavaAnnotationImpl xjcAnnotation = new XJCJavaAnnotationImpl(annotationUse, dynamicClassLoader); annotationsList.add(xjcAnnotation); } return annotationsList; } /** * Not supported. */ public JavaAnnotation getDeclaredAnnotation(JavaClass arg0) { return getAnnotation(arg0); } /** * Not supported. */ public Collection getDeclaredAnnotations() { return getAnnotations(); } /** * Get this JavaClass'
JavaModel
. * * @return TheJavaModel
associated with thisJavaClass
. */ public JavaModel getJavaModel() { return javaModel; } /** * Set this
JavaClass'
JavaModel
. * * @param javaModel TheJavaModel
to set. */ public void setJavaModel(JavaModel javaModel) { this.javaModel = javaModel; } }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy