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

org.eclipse.persistence.jaxb.javamodel.oxm.OXMJavaClassImpl Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * 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 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 thisClass = PrivilegedAccessHelper.getClassForName(thisJavaName); Class argClass = PrivilegedAccessHelper.getClassForName(argJavaName); return thisClass.isAssignableFrom(argClass); } catch (Exception e) { return false; } } else { return thisJavaName.equals(argJavaName); } } /** * Indicates if this JavaClass is an enum. * * @return true if this JavaClass is an enum, otherwise false. */ @Override public boolean isEnum() { return this.enumValues != null; } /** * Indicates if this JavaClass is final. * * @return true if this JavaClass is final, otherwise false. */ @Override public boolean isFinal() { return false; } /** * Indicates if this JavaClass is an interface. * * @return true if this JavaClass is an interface, otherwise false. */ @Override public boolean isInterface() { return false; } /** * Indicates if this JavaClass is an inner Class. * * @return true if this JavaClass is an inner Class, otherwise false. */ @Override public boolean isMemberClass() { return false; } /** * Indicates if this JavaClass represents a primitive type. * * @return true if this JavaClass represents a primitive type, otherwise false. */ @Override public boolean isPrimitive() { return false; } /** * Indicates if this JavaClass is private. * * @return true if this JavaClass is private, otherwise false. */ @Override public boolean isPrivate() { return false; } /** * Indicates if this JavaClass is protected. * * @return true if this JavaClass is protected, otherwise false. */ @Override public boolean isProtected() { return false; } /** * Indicates if this JavaClass is public. * * @return true if this JavaClass is public, otherwise false. */ @Override public boolean isPublic() { return false; } /** * Indicates if this JavaClass is static. * * @return true if this JavaClass is static, otherwise false. */ @Override public boolean isStatic() { return false; } /** * Not supported. */ @Override public boolean isSynthetic() { throw new UnsupportedOperationException("isSynthetic"); } @Override public JavaClassInstanceOf instanceOf() { return JavaClassInstanceOf.OXM_JAVA_CLASS_IMPL; } /** * If this JavaClass is annotated with an Annotation matching aClass, * return its JavaAnnotation representation. * * @param aClass a JavaClass representing the Annotation to look for. * * @return always returns null, as JavaTypes do not have Annotations. */ @Override public JavaAnnotation getAnnotation(JavaClass aClass) { return null; } /** * Return all of the Annotations for this JavaClass. * * @return always returns an empty ArrayList, as JavaTypes do not have Annotations. */ @Override public Collection getAnnotations() { return new ArrayList<>(); } /** * If this JavaClass declares an Annotation matching aClass, * return its JavaAnnotation representation. * * @param arg0 a JavaClass representing the Annotation to look for. * * @return always returns null, as JavaTypes do not have Annotations. */ @Override public JavaAnnotation getDeclaredAnnotation(JavaClass arg0) { return null; } /** * Return all of the declared Annotations for this JavaClass. * * @return always returns an empty ArrayList, as JavaTypes do not have Annotations. */ @Override public Collection getDeclaredAnnotations() { return new ArrayList<>(); } /** * Set this JavaClass' JavaModel. * * @param model The JavaModel to set. */ public void setJavaModel(JavaModel model) { this.javaModel = model; } /** * Get this JavaClass' JavaModel. * * @return The JavaModel associated with this JavaClass. */ public JavaModel getJavaModel() { return this.javaModel; } // ======================================================================== private static String EMPTY_STRING = ""; private static String JAVA = "java"; private static String DOT = "."; private static String JAVA_LANG_OBJECT = "java.lang.Object"; private static String JAVA_UTIL_MAP = "java.util.Map"; }