org.eclipse.persistence.jaxb.javamodel.xjc.XJCJavaFieldImpl 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, 2018 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.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.JavaField;
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.JFieldVar;
import com.sun.codemodel.JPrimitiveType;
import com.sun.codemodel.JType;
import com.sun.codemodel.JVar;
/**
* INTERNAL:
*
* Purpose: JavaField
implementation wrapping XJC's JFieldVar
. Used when
* bootstrapping a DynamicJAXBContext
from an XML Schema.
*
*
*
* Responsibilities:
*
*
* - Provide
Field
information from the underlying JFieldVar
.
*
*
* @since EclipseLink 2.1
*
* @see org.eclipse.persistence.jaxb.javamodel.JavaField
*/
public class XJCJavaFieldImpl implements JavaField {
private JFieldVar xjcField;
private JCodeModel jCodeModel;
private DynamicClassLoader dynamicClassLoader;
private JavaClass owningClass;
private static Field JVAR_ANNOTATIONS = null;
private static Field JARRAYCLASS_COMPONENTTYPE = null;
static {
try {
JVAR_ANNOTATIONS = PrivilegedAccessHelper.getDeclaredField(JVar.class, "annotations", true);
Class> c = Class.forName("com.sun.codemodel.JArrayClass");
JARRAYCLASS_COMPONENTTYPE = PrivilegedAccessHelper.getDeclaredField(c, "componentType", true);
} catch (Exception e) {
throw JAXBException.errorCreatingDynamicJAXBContext(e);
}
}
/**
* Construct a new instance of XJCJavaFieldImpl
.
*
* @param javaField - the XJC JFieldVar
to be wrapped.
* @param codeModel - the XJC JCodeModel
this field belongs to.
* @param loader - the ClassLoader
used to bootstrap the DynamicJAXBContext
.
* @param owner - the JavaClass
this field belongs to.
*/
public XJCJavaFieldImpl(JFieldVar javaField, JCodeModel codeModel, DynamicClassLoader loader, JavaClass owner) {
this.xjcField = javaField;
this.jCodeModel = codeModel;
this.dynamicClassLoader = loader;
this.owningClass = owner;
}
/**
* If this JavaField
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
.
*/
@SuppressWarnings("unchecked")
public JavaAnnotation getAnnotation(JavaClass aClass) {
if (aClass != null) {
Collection annotations = null;
try {
annotations = (Collection) PrivilegedAccessHelper.getValueFromField(JVAR_ANNOTATIONS, xjcField);
} 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 JavaField
.
*
* @return A Collection
containing this JavaField's
JavaAnnotations
.
*/
@SuppressWarnings("unchecked")
public Collection getAnnotations() {
ArrayList annotationsList = new ArrayList();
Collection annotations = null;
try {
annotations = (Collection) PrivilegedAccessHelper.getValueFromField(JVAR_ANNOTATIONS, xjcField);
} catch (Exception e) {
}
if (annotations != null) {
for (JAnnotationUse annotationUse : annotations) {
XJCJavaAnnotationImpl xjcAnnotation = new XJCJavaAnnotationImpl(annotationUse, dynamicClassLoader);
annotationsList.add(xjcAnnotation);
}
}
return annotationsList;
}
/**
* Returns the Java language modifiers for this JavaField
, encoded in an integer.
*
* @return the int
representing the modifiers for this field.
*
* @see java.lang.reflect.Modifier
*/
public int getModifiers() {
return xjcField.mods().getValue();
}
/**
* Returns the name of this JavaField
.
*
* @return the String
name of this JavaField
.
*/
public String getName() {
return xjcField.name();
}
/**
* Returns the JavaClass
representing the type of this JavaField
.
*
* @return the type of this JavaField
as a JavaClass
.
*/
@SuppressWarnings("unchecked")
public JavaClass getResolvedType() {
JType type = xjcField.type();
JType basis = null;
boolean isArray = false;
boolean isPrimitive = false;
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(type.getClass(), "basis", true);
basis = (JClass) PrivilegedAccessHelper.getValueFromField(basisField, type);
} catch (Exception e) {
// "basis" field not found
}
JClass classToReturn = null;
if (type.isPrimitive()) {
JPrimitiveType pType = (JPrimitiveType) type;
classToReturn = pType.boxify();
} else if (type.getClass().getName().contains("JArrayClass")) {
isArray = true;
classToReturn = (JClass) type;
try {
JType componentType = (JType) PrivilegedAccessHelper.getValueFromField(JARRAYCLASS_COMPONENTTYPE, type);
if (componentType.isPrimitive()) {
isPrimitive = true;
}
} catch (Exception e) {
throw JAXBException.errorCreatingDynamicJAXBContext(e);
}
} else {
try {
classToReturn = jCodeModel._class(basis != null ? basis.fullName() : type.fullName());
} catch (JClassAlreadyExistsException ex) {
classToReturn = jCodeModel._getClass(basis != null ? basis.fullName() : type.fullName());
}
}
if (basis != null) {
try {
// Cannot cache this field because JNarrowedClass is a protected class.
Field argsField = PrivilegedAccessHelper.getDeclaredField(type.getClass(), "args", true);
List args = (List) PrivilegedAccessHelper.getValueFromField(argsField, type);
for (JClass jClass : args) {
((JDefinedClass) classToReturn).generify("param", jClass);
}
} catch (Exception e) {
throw JAXBException.errorCreatingDynamicJAXBContext(e);
}
}
String className = classToReturn.fullName();
if (isArray) {
className += "[]";
}
if (((XJCJavaClassImpl) getOwningClass()).getJavaModel() != null) {
return ((XJCJavaClassImpl) getOwningClass()).getJavaModel().getClass(className);
}
return new XJCJavaClassImpl((JDefinedClass) classToReturn, jCodeModel, dynamicClassLoader, isArray, isPrimitive);
}
/**
* Indicates if this JavaField
is final
.
*
* @return true
if this JavaField
is final
, otherwise false
.
*/
public boolean isFinal() {
return Modifier.isFinal(getModifiers());
}
/**
* Indicates if this JavaField
is abstract
.
*
* @return true
if this JavaField
is abstract
, otherwise false
.
*/
public boolean isAbstract() {
return Modifier.isAbstract(getModifiers());
}
/**
* Indicates if this JavaField
is private
.
*
* @return true
if this JavaField
is private
, otherwise false
.
*/
public boolean isPrivate() {
return Modifier.isPrivate(getModifiers());
}
/**
* Indicates if this JavaField
is protected
.
*
* @return true
if this JavaField
is protected
, otherwise false
.
*/
public boolean isProtected() {
return Modifier.isProtected(getModifiers());
}
/**
* Indicates if this JavaField
is public
.
*
* @return true
if this JavaField
is public
, otherwise false
.
*/
public boolean isPublic() {
return Modifier.isPublic(getModifiers());
}
/**
* Indicates if this JavaField
is static
.
*
* @return true
if this JavaField
is static
, otherwise false
.
*/
public boolean isStatic() {
return Modifier.isStatic(getModifiers());
}
/**
* Not supported.
*/
public boolean isSynthetic() {
throw new UnsupportedOperationException("isSynthetic");
}
/**
* Indicates if this JavaField
is an enum
constant - i.e. its owner is an enum
.
*
* @return true
if this JavaField
is an enum
constant.
*/
public boolean isEnumConstant() {
return getOwningClass().isEnum();
}
/**
* If this JavaField
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
.
*/
public JavaAnnotation getDeclaredAnnotation(JavaClass aClass) {
return getAnnotation(aClass);
}
/**
* Return all of the Annotations
for this JavaField
.
*
* @return A Collection
containing this JavaField's
JavaAnnotations
.
*/
public Collection getDeclaredAnnotations() {
return getAnnotations();
}
/**
* Set the JavaClass
which contains this field.
*
* @param owningClass the JavaClass
representing the owner of this JavaField
.
*/
public void setOwningClass(JavaClass owningClass) {
this.owningClass = owningClass;
}
/**
* Returns the JavaClass
which contains this field.
*
* @return JavaClass
representing the owner of this JavaField
.
*/
public JavaClass getOwningClass() {
return this.owningClass;
}
}