org.eclipse.persistence.jaxb.javamodel.oxm.OXMJavaClassImpl 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, 2024 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.2 - Initial implementation
package org.eclipse.persistence.jaxb.javamodel.oxm;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import jakarta.xml.bind.JAXBElement;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.jaxb.compiler.XMLProcessor;
import org.eclipse.persistence.jaxb.javamodel.JavaAnnotation;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;
import org.eclipse.persistence.jaxb.javamodel.JavaClassInstanceOf;
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 org.eclipse.persistence.jaxb.xmlmodel.JavaAttribute;
import org.eclipse.persistence.jaxb.xmlmodel.JavaType;
import org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAnyAttribute;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAnyElement;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAttribute;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElement;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElementRef;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElements;
import org.eclipse.persistence.jaxb.xmlmodel.XmlInverseReference;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJoinNodes;
import org.eclipse.persistence.jaxb.xmlmodel.XmlValue;
/**
* INTERNAL:
*
* Purpose: JavaClass
implementation wrapping MOXy's xmlmodel.JavaType
.
* Used when bootstrapping a DynamicJAXBContext
from XML Bindings.
*
*
*
* Responsibilities:
*
*
* - Provide Class information from the underlying
JavaType
.
*
*
* @since EclipseLink 2.2
*
* @see org.eclipse.persistence.jaxb.javamodel.JavaClass
* @see org.eclipse.persistence.jaxb.xmlmodel.JavaType
*/
public class OXMJavaClassImpl implements JavaClass {
private JavaType javaType;
private String javaName;
private List enumValues;
private JavaModel javaModel;
/**
* Construct a new instance of OXMJavaClassImpl
.
*
* @param aJavaType - the XJC JavaType
to be wrapped.
*/
public OXMJavaClassImpl(JavaType aJavaType) {
this.javaType = aJavaType;
}
/**
* Construct a new instance of OXMJavaClassImpl
.
*
* @param aJavaTypeName - the name of the JavaType to create.
*/
public OXMJavaClassImpl(String aJavaTypeName) {
this.javaName = aJavaTypeName;
}
/**
* Construct a new instance of OXMJavaClassImpl
* representing a Java enum
.
*
* @param aJavaTypeName - the name of the JavaType to create.
* @param enumValues - the list of values for this enum
.
*/
public OXMJavaClassImpl(String aJavaTypeName, List enumValues) {
this.javaName = aJavaTypeName;
this.enumValues = enumValues;
}
// ========================================================================
/**
* Return the "actual" type from a parameterized type. For example, if this
* JavaClass
represents List<Employee
, this method will return the
* Employee
JavaClass
.
*
* @return a Collection
containing the actual type's JavaClass
.
*/
@Override
public Collection getActualTypeArguments() {
Object jType = null;
if (this.javaType != null) {
jType = this.javaType;
} else {
try {
Class> jTypeClass = PrivilegedAccessHelper.getClassForName(this.javaName);
jType = PrivilegedAccessHelper.newInstanceFromClass(jTypeClass);
} catch (Exception e) {
return new ArrayList<>();
}
}
ArrayList argCollection = new ArrayList<>();
if (jType instanceof ParameterizedType pType) {
Type[] params = pType.getActualTypeArguments();
for (Type type : params) {
if (type instanceof ParameterizedType pt) {
argCollection.add(this.javaModel.getClass(pt.getRawType().getClass()));
} else if (type instanceof WildcardType) {
Type[] upperTypes = ((WildcardType) type).getUpperBounds();
if (upperTypes.length >0) {
Type upperType = upperTypes[0];
if (upperType instanceof Class>) {
argCollection.add(this.javaModel.getClass(upperType.getClass()));
}
}
} else if (type instanceof Class>) {
argCollection.add(this.javaModel.getClass(type.getClass()));
} else if (type instanceof GenericArrayType) {
Class> genericTypeClass = (Class>) ((GenericArrayType) type).getGenericComponentType();
genericTypeClass = java.lang.reflect.Array.newInstance(genericTypeClass, 0).getClass();
argCollection.add(this.javaModel.getClass(genericTypeClass.getClass()));
}
}
}
return argCollection;
}
/**
* If this JavaClass
is an array type, return the type of the
* array components.
*
* @return always returns null
, as JavaTypes
do not represent arrays.
*/
@Override
public JavaClass getComponentType() {
return null;
}
/**
* Return the JavaConstructor
for this JavaClass
that has the
* provided parameter types.
*
* @param parameterTypes the parameter list used to identify the constructor.
*
* @return the JavaConstructor
with the signature matching parameterTypes.
*/
@Override
public JavaConstructor getConstructor(JavaClass[] parameterTypes) {
return new OXMJavaConstructorImpl(this);
}
/**
* Return all of the JavaConstructors
for this JavaClass.
*
* @return A Collection
containing this JavaClass'
JavaConstructors
.
*/
@Override
public Collection getConstructors() {
ArrayList constructors = new ArrayList<>(1);
constructors.add(new OXMJavaConstructorImpl(this));
return constructors;
}
/**
* Return this JavaClass'
inner classes.
*
* @return always returns an empty ArrayList
as JavaTypes
do not represent inner classes.
*/
@Override
public Collection getDeclaredClasses() {
return new ArrayList<>();
}
/**
* Return the declared JavaConstructor
for this JavaClass
.
*
* @return the JavaConstructor
for this JavaClass
.
*/
@Override
public JavaConstructor getDeclaredConstructor(JavaClass[] parameterTypes) {
return new OXMJavaConstructorImpl(this);
}
/**
* Return all of the declared JavaConstructors
for this JavaClass
.
*
* @return A Collection
containing this JavaClass'
JavaConstructors
.
*/
@Override
public Collection getDeclaredConstructors() {
ArrayList constructors = new ArrayList<>(1);
constructors.add(new OXMJavaConstructorImpl(this));
return constructors;
}
/**
* Return the declared JavaField
for this JavaClass
, identified
* by fieldName
.
*
* @param name the name of the JavaField
to return.
*
* @return the JavaField
named fieldName
from this JavaClass
.
*/
@Override
public JavaField getDeclaredField(String name) {
Collection allFields = getDeclaredFields();
for (Iterator iterator = allFields.iterator(); iterator.hasNext();) {
JavaField field = iterator.next();
if (field.getName().equals(name)) {
return field;
}
}
return null;
}
/**
* Return all of the declared JavaFields
for this JavaClass
.
*
* @return A Collection
containing this JavaClass'
JavaFields
.
*/
@Override
public Collection getDeclaredFields() {
List fieldsToReturn = new ArrayList<>();
if (this.enumValues != null) {
for (Iterator iterator = this.enumValues.iterator(); iterator.hasNext();) {
fieldsToReturn.add(new OXMJavaFieldImpl(iterator.next(), JAVA_LANG_OBJECT, this));
}
} else {
JavaAttributes javaAttributes = this.javaType.getJavaAttributes();
if(null != javaAttributes) {
List> fields = javaAttributes.getJavaAttribute();
for (Iterator> iterator = fields.iterator(); iterator.hasNext();) {
JAXBElement extends JavaAttribute> jaxbElement = iterator.next();
JavaAttribute att = jaxbElement.getValue();
if (att instanceof XmlElement xme) {
String fieldName = xme.getJavaAttribute();
String fieldType = xme.getType();
fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
} else if (att instanceof XmlElements xmes) {
String fieldName = xmes.getJavaAttribute();
String fieldType = JAVA_LANG_OBJECT;
fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
} else if (att instanceof XmlElementRef xmer) {
String fieldName = xmer.getJavaAttribute();
String fieldType = xmer.getType();
fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
} else if (att instanceof XmlAttribute xma) {
String fieldName = xma.getJavaAttribute();
String fieldType = xma.getType();
fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
} else if (att instanceof XmlValue xmv) {
String fieldName = xmv.getJavaAttribute();
String fieldType = xmv.getType();
fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
} else if (att instanceof XmlAnyElement xmae) {
String fieldName = xmae.getJavaAttribute();
String fieldType = JAVA_LANG_OBJECT;
fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
} else if (att instanceof XmlAnyAttribute xmaa) {
String fieldName = xmaa.getJavaAttribute();
String fieldType = JAVA_UTIL_MAP;
fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
} else if (att instanceof XmlJoinNodes xmjn) {
String fieldName = xmjn.getJavaAttribute();
String fieldType = xmjn.getType();
fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
} else if (att instanceof XmlInverseReference xmir) {
String fieldName = xmir.getJavaAttribute();
String fieldType = xmir.getType();
fieldsToReturn.add(new OXMJavaFieldImpl(fieldName, fieldType, this));
}
}
}
}
return fieldsToReturn;
}
/**
* Return the declared JavaMethod
for this JavaClass
,
* identified by name
, with the signature matching args
.
*
* @param name the name of the JavaMethod
to return.
* @param args the parameter list used to identify the method.
*
* @return always returns null
, as JavaTypes
do not have methods.
*/
@Override
public JavaMethod getDeclaredMethod(String name, JavaClass[] args) {
return null;
}
/**
* Return all of the declared JavaMethods
for this JavaClass
.
*
* @return always returns an empty ArrayList
, as JavaTypes
do not have methods.
*/
@Override
public Collection getDeclaredMethods() {
return new ArrayList<>();
}
/**
* Return the JavaMethod
for this JavaClass
,
* identified by name
, with the signature matching args
.
*
* @param name the name of the JavaMethod
to return.
* @param args the parameter list used to identify the method.
*
* @return always returns null
, as JavaTypes
do not have methods.
*/
@Override
public JavaMethod getMethod(String name, JavaClass[] args) {
return null;
}
/**
* Return all of the JavaMethods
for this JavaClass
.
*
* @return always returns an empty ArrayList
, as JavaTypes
do not have methods.
*/
@Override
public Collection getMethods() {
return new ArrayList<>();
}
/**
* Returns the Java language modifiers for this JavaClass
, encoded in an integer.
*
* @return always returns 0
as JavaTypes
do not have modifiers.
*
* @see java.lang.reflect.Modifier
*/
@Override
public int getModifiers() {
return 0;
}
/**
* Returns the name of this JavaClass
.
*
* @return the String
name of this JavaClass
.
*/
@Override
public String getName() {
if (this.javaType != null) {
return this.javaType.getName();
}
return this.javaName;
}
/**
* Returns the JavaPackage
that this JavaClass
belongs to.
*
* @return the JavaPackage
of this JavaClass
.
*/
@Override
public JavaPackage getPackage() {
return new OXMJavaPackageImpl(getPackageName());
}
/**
* Returns the package name of this JavaClass
.
*
* @return the String
name of this JavaClass'
JavaPackage
.
*/
@Override
public String getPackageName() {
int lastDotIndex = getQualifiedName().lastIndexOf('.');
if (lastDotIndex == -1) {
return EMPTY_STRING;
}
return getQualifiedName().substring(0, lastDotIndex);
}
/**
* Returns the fully-qualified name of this JavaClass
.
*
* @return the String
name of this JavaClass
.
*/
@Override
public String getQualifiedName() {
return getName();
}
/**
* Returns the raw name of this JavaClass
. Array types will
* have "[]" appended to the name.
*
* @return the String
raw name of this JavaClass
.
*/
@Override
public String getRawName() {
return getName();
}
/**
* Returns the super class of this JavaClass
.
*
* @return JavaClass
representing the super class of this JavaClass
.
*/
@Override
public JavaClass getSuperclass() {
if (this.javaModel == null) {
return null;
}
if (this.javaType != null) {
if (!(this.javaType.getSuperType().equals(XMLProcessor.DEFAULT))) {
return this.javaModel.getClass(javaType.getSuperType());
}
}
return this.javaModel.getClass(JAVA_LANG_OBJECT);
}
@Override
public Type[] getGenericInterfaces() {
return new Type[0];
}
@Override
public Type getGenericSuperclass() {
return null;
}
/**
* Indicates if this JavaClass
has actual type arguments, i.e. is a
* parameterized type (for example, List<Employee
).
*
* @return always returns false
as JavaTypes
are not parameterized.
*/
@Override
public boolean hasActualTypeArguments() {
return false;
}
/**
* Indicates if this JavaClass
is abstract
.
*
* @return always returns false
as JavaTypes
are never abstract
.
*/
@Override
public boolean isAbstract() {
return false;
}
/**
* Indicates if this JavaClass
is an Annotation
.
*
* @return always returns false
as JavaTypes
are never Annotations
.
*/
@Override
public boolean isAnnotation() {
return false;
}
/**
* Indicates if this JavaClass
is an Array type.
*
* @return always returns false
, as JavaTypes
do not represent arrays.
*/
@Override
public boolean isArray() {
return false;
}
/**
* Indicates if this JavaClass
is either the same as, or is a superclass of,
* the javaClass
argument.
*
* @param arg0 the Class
to test.
*
* @return true
if this JavaClass
is assignable from
* javaClass
, otherwise false
.
*
* @see java.lang.Class#isAssignableFrom(Class)
*/
@Override
@SuppressWarnings("unchecked")
public boolean isAssignableFrom(JavaClass arg0) {
String thisJavaName = EMPTY_STRING;
String argJavaName = arg0.getName();
if (this.javaName != null) {
thisJavaName = this.javaName;
} else {
thisJavaName = this.javaType.getName();
}
if (thisJavaName.startsWith(JAVA) && argJavaName.startsWith(JAVA)) {
// Only try class lookup if this is a JDK class, because
// we won't ever find classes for dynamically generated types.
try {
Class