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

org.eclipse.persistence.jaxb.javamodel.Helper Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.jaxb.javamodel;

import static org.eclipse.persistence.jaxb.JAXBContextFactory.PKG_SEPARATOR;
import static org.eclipse.persistence.jaxb.compiler.XMLProcessor.DEFAULT;

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.persistence.internal.core.helper.CoreClassConstants;

import jakarta.xml.bind.JAXBElement;

import org.eclipse.persistence.internal.oxm.Constants;

/**
 * INTERNAL:
 * 

Purpose:To provide helper methods and constants to assist * in integrating TopLink JAXB 2.0 Generation with the JDEV JOT APIs. *

Responsibilities: *

    *
  • Make available a map of JOT - XML type pairs
  • *
  • Redirect method calls to the current JavaModel implementation as * required
  • *
  • Provide methods for accessing generics, annotations, etc. on a * given implementaiton's classes
  • *
  • Provide a dynamic proxy instance for a given JavaAnnotation in * the JOT implementation (for reflection a Java SDK annotation is * returned)
  • *
* * @since Oracle TopLink 11.1.1.0.0 * @see JavaModel * @see AnnotationProxy * */ public class Helper { protected ClassLoader loader; protected JavaModel jModel; private HashMap xmlToJavaTypeMap; private boolean facets; public final static String APBYTE = "byte[]"; public final static String BIGDECIMAL = "java.math.BigDecimal"; public final static String BIGINTEGER = "java.math.BigInteger"; public final static String PBOOLEAN = "boolean"; public final static String PBYTE = "byte"; public final static String CALENDAR = "java.util.Calendar"; public final static String CHARACTER = "java.lang.Character"; public final static String CHAR = "char"; public final static String OBJECT = "java.lang.Object"; public final static String CLASS = "java.lang.Class"; public final static String PDOUBLE = "double"; public final static String PFLOAT = "float"; public final static String PINT = "int"; public final static String PLONG = "long"; public final static String PSHORT = "short"; public final static String QNAME_CLASS = "javax.xml.namespace.QName"; public final static String STRING = "java.lang.String"; public final static String ABYTE = "java.lang.Byte[]"; public final static String BOOLEAN = "java.lang.Boolean"; public final static String BYTE = "java.lang.Byte"; public final static String GREGORIAN_CALENDAR = "java.util.GregorianCalendar"; public final static String DOUBLE = "java.lang.Double"; public final static String FLOAT = "java.lang.Float"; public final static String INTEGER = "java.lang.Integer"; public final static String UUID = "java.util.UUID"; public final static String LONG = "java.lang.Long"; public final static String SHORT = "java.lang.Short"; public final static String UTIL_DATE = "java.util.Date"; public final static String SQL_DATE = "java.sql.Date"; public final static String SQL_TIME = "java.sql.Time"; public final static String SQL_TIMESTAMP = "java.sql.Timestamp"; public final static String DURATION = "javax.xml.datatype.Duration"; public final static String XMLGREGORIANCALENDAR = "javax.xml.datatype.XMLGregorianCalendar"; public final static String URI = "java.net.URI"; public final static String URL = "java.net.URL"; protected final static String JAVA_PKG = "java."; protected final static String JAVAX_PKG = "javax."; protected final static String JAKARTA_PKG = "jakarta."; protected final static String JAVAX_WS_PKG = "javax.xml.ws."; protected final static String JAKARTA_WS_PKG = "jakarta.xml.ws."; protected final static String JAVAX_RPC_PKG = "javax.xml.rpc."; protected final static String JAKARTA_RPC_PKG = "jakarta.xml.rpc."; private JavaClass collectionClass; private JavaClass setClass; private JavaClass listClass; private JavaClass mapClass; private JavaClass jaxbElementClass; private JavaClass objectClass; /** * INTERNAL: * This is the preferred constructor. * * This constructor builds the map of XML-Java type pairs, * and sets the JavaModel and ClassLoader. * * @param model */ public Helper(JavaModel model) { xmlToJavaTypeMap = buildXMLToJavaTypeMap(); setJavaModel(model); setClassLoader(model.getClassLoader()); collectionClass = getJavaClass(CoreClassConstants.Collection_Class); listClass = getJavaClass(CoreClassConstants.List_Class); setClass = getJavaClass(CoreClassConstants.Set_Class); mapClass = getJavaClass(CoreClassConstants.Map_Class); jaxbElementClass = getJavaClass(JAXBElement.class); objectClass = getJavaClass(CoreClassConstants.OBJECT); } /** * Builds a map of Java types to XML types. * * @return */ private HashMap buildXMLToJavaTypeMap() { HashMap javaTypes = new HashMap(); // jaxb 2.0 spec pairs javaTypes.put(APBYTE, Constants.BASE_64_BINARY_QNAME); javaTypes.put(BIGDECIMAL, Constants.DECIMAL_QNAME); javaTypes.put(BIGINTEGER, Constants.INTEGER_QNAME); javaTypes.put(PBOOLEAN, Constants.BOOLEAN_QNAME); javaTypes.put(PBYTE, Constants.BYTE_QNAME); javaTypes.put(CALENDAR, Constants.DATE_TIME_QNAME); javaTypes.put(PDOUBLE, Constants.DOUBLE_QNAME); javaTypes.put(PFLOAT, Constants.FLOAT_QNAME); javaTypes.put(PINT, Constants.INT_QNAME); javaTypes.put(PLONG, Constants.LONG_QNAME); javaTypes.put(PSHORT, Constants.SHORT_QNAME); javaTypes.put(QNAME_CLASS, Constants.QNAME_QNAME); javaTypes.put(STRING, Constants.STRING_QNAME); javaTypes.put(CHAR, Constants.STRING_QNAME); javaTypes.put(CHARACTER, Constants.STRING_QNAME); // other pairs javaTypes.put(ABYTE, Constants.BYTE_QNAME); javaTypes.put(BOOLEAN, Constants.BOOLEAN_QNAME); javaTypes.put(BYTE, Constants.BYTE_QNAME); javaTypes.put(CLASS, Constants.STRING_QNAME); javaTypes.put(GREGORIAN_CALENDAR, Constants.DATE_TIME_QNAME); javaTypes.put(DOUBLE, Constants.DOUBLE_QNAME); javaTypes.put(FLOAT, Constants.FLOAT_QNAME); javaTypes.put(INTEGER, Constants.INT_QNAME); javaTypes.put(LONG, Constants.LONG_QNAME); javaTypes.put(OBJECT, Constants.ANY_TYPE_QNAME); javaTypes.put(SHORT, Constants.SHORT_QNAME); javaTypes.put(UTIL_DATE, Constants.DATE_TIME_QNAME); javaTypes.put(SQL_DATE, Constants.DATE_QNAME); javaTypes.put(SQL_TIME, Constants.TIME_QNAME); javaTypes.put(SQL_TIMESTAMP, Constants.DATE_TIME_QNAME); javaTypes.put(DURATION, Constants.DURATION_QNAME); javaTypes.put(UUID, Constants.STRING_QNAME); javaTypes.put(URI, Constants.STRING_QNAME); javaTypes.put(URL, Constants.ANY_URI_QNAME); return javaTypes; } /** * Return a given method's generic return type as a JavaClass. * * @param meth * @return */ public JavaClass getGenericReturnType(JavaMethod meth) { JavaClass result = meth.getReturnType(); JavaClass jClass = null; if (result == null) { return null; } Collection args = result.getActualTypeArguments(); if (args.size() >0) { jClass = (JavaClass) args.iterator().next(); } return jClass; } /** * Return a JavaClass instance created based the provided class. * This assumes that the provided class exists on the classpath * - null is returned otherwise. * * @param javaClass * @return */ public JavaClass getJavaClass(Class javaClass) { return jModel.getClass(javaClass); } /** * Return array of JavaClass instances created based on the provided classes. * This assumes provided classes exist on the classpath. * * @param classes * @return JavaClass array */ public JavaClass[] getJavaClassArray(Class... classes) { if (0 == classes.length) { return new JavaClass[0]; } JavaClass[] result = new JavaClass[classes.length]; int i = 0; for (Class clazz : classes) { result[i++] = getJavaClass(clazz); } return result; } /** * Return a JavaClass instance created based on fully qualified * class name. This assumes that a class with the provided name * exists on the classpath - null is returned otherwise. * * @param javaClassName * @return */ public JavaClass getJavaClass(String javaClassName) { return jModel.getClass(javaClassName); } /** * Return a map of default Java types to XML types. * @return */ public HashMap getXMLToJavaTypeMap() { return xmlToJavaTypeMap; } /** * Returns a either a dynamic proxy instance that allows an element * to be treated as an annotation (for JOT), or a Java annotation * (for Reflection), or null if the specified annotation does not * exist. * Intended to be used in conjunction with isAnnotationPresent. * * @param element * @param annotationClass * @return * @see #isAnnotationPresent */ public Annotation getAnnotation(JavaHasAnnotations element, Class annotationClass) { JavaAnnotation janno = element.getAnnotation(jModel.getClass(annotationClass)); if (janno == null) { return null; } return jModel.getAnnotation(janno, annotationClass); } /** * Returns a JavaClass instance wrapping the provided field's resolved * type. * * @param field * @return */ public JavaClass getType(JavaField field) { JavaClass type = field.getResolvedType(); try { return jModel.getClass(type.getRawName()); } catch (Exception x) {} return null; } /** * Return a JavaClass instance based on the @see jakarta.xml.bind.JAXBElement . * * Replacement of direct access to JAXBELEMENT_CLASS field. * * @return */ public JavaClass getJaxbElementClass() { return jaxbElementClass; } /** * Return a JavaClass instance based on the @see java.lang.Object . * * Replacement of direct access to OBJECT_CLASS field. * * @return */ public JavaClass getObjectClass() { return objectClass; } /** * Indicates if element contains a given annotation. * * @param element * @param annotationClass * @return */ public boolean isAnnotationPresent(JavaHasAnnotations element, Class annotationClass) { if (element == null || annotationClass == null) { return false; } return (element.getAnnotation(jModel.getClass(annotationClass)) != null); } /** * Indicates if a given JavaClass is a built-in Java type. * * A JavaClass is considered to be a built-in type if: * 1 - the XMLToJavaTypeMap map contains a key equal to the provided * JavaClass' raw name * 2 - the provided JavaClass' raw name starts with "java." * 3 - the provided JavaClass' raw name starts with "javax.", with * the exception of "jakarta.xml.ws." and "javax.xml.rpc" * @param jClass * @return */ public boolean isBuiltInJavaType(JavaClass jClass) { String rawName = jClass.getRawName(); if(null == rawName) { return true; } return (getXMLToJavaTypeMap().containsKey(rawName) || rawName.startsWith(JAVA_PKG) || ((rawName.startsWith(JAVAX_PKG) || rawName.startsWith(JAKARTA_PKG)) && !( rawName.startsWith(JAVAX_WS_PKG) || rawName.startsWith(JAVAX_RPC_PKG) || rawName.startsWith(JAKARTA_WS_PKG) || rawName.startsWith(JAKARTA_RPC_PKG) ))); } public void setClassLoader(ClassLoader loader) { this.loader = loader; } public void setJavaModel(JavaModel model) { jModel = model; } public ClassLoader getClassLoader() { return loader; } public Class getClassForJavaClass(JavaClass javaClass){ String javaClassName = javaClass.getRawName(); if (javaClass.isPrimitive() || javaClass.isArray() && javaClass.getComponentType().isPrimitive()){ if (CoreClassConstants.APBYTE.getCanonicalName().equals(javaClassName)){ return Byte[].class; } if (CoreClassConstants.PBYTE.getCanonicalName().equals(javaClassName)){ return Byte.class; } if (CoreClassConstants.PBOOLEAN.getCanonicalName().equals(javaClassName)){ return Boolean.class; } if (CoreClassConstants.PSHORT.getCanonicalName().equals(javaClassName)){ return Short.class; } if (CoreClassConstants.PFLOAT.getCanonicalName().equals(javaClassName)){ return Float.class; } if (CoreClassConstants.PCHAR.getCanonicalName().equals(javaClassName)){ return Character.class; } if (CoreClassConstants.PDOUBLE.getCanonicalName().equals(javaClassName)){ return Double.class; } if (CoreClassConstants.PINT.getCanonicalName().equals(javaClassName)){ return Integer.class; } if (CoreClassConstants.PLONG.getCanonicalName().equals(javaClassName)){ return Long.class; } return null; } return org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(javaClass.getQualifiedName(), loader); } /** * Convenience method to determine if a class exists in a given ArrayList. */ public boolean classExistsInArray(JavaClass theClass, List existingClasses) { for (JavaClass jClass : existingClasses) { if (areClassesEqual(jClass, theClass)) { return true; } } return false; } /** * Convenience method to determine if two JavaClass instances are equal. * * @param classA * @param classB * @return */ private boolean areClassesEqual(JavaClass classA, JavaClass classB) { if (classA == classB) { return true; } if (!(classA.getQualifiedName().equals(classB.getQualifiedName()))) { return false; } Collection classAargs = classA.getActualTypeArguments(); Collection classBargs = classB.getActualTypeArguments(); if (classAargs != null) { if (classBargs == null) { return false; } if (classAargs.size() != classBargs.size()) { return false; } Iterator classAargsIter = classAargs.iterator(); Iterator classBargsIter = classBargs.iterator(); while(classAargsIter.hasNext()){ JavaClass nestedClassA = (JavaClass) classAargsIter.next(); JavaClass nestedClassB = (JavaClass) classBargsIter.next(); if (!areClassesEqual(nestedClassA, nestedClassB)) { return false; } } return true; } if (classBargs == null) { return true; } return false; } /** * Prepends a package name to a given java type name, if it is not already present. * * @param javaTypeName Java type name that may/may not contain 'packageName' * @param packageName package name to prepend to javaTypeName if not already * @return fully qualified java type name */ public static String getQualifiedJavaTypeName(String javaTypeName, String packageName) { // prepend the package name if not already present if (packageName != null && packageName.length() > 0 && !packageName.equals(DEFAULT) && !javaTypeName.contains(PKG_SEPARATOR)) { return packageName + PKG_SEPARATOR + javaTypeName; } return javaTypeName; } public boolean isCollectionType(JavaClass type) { if (collectionClass.isAssignableFrom(type) || listClass.isAssignableFrom(type) || setClass.isAssignableFrom(type)) { return true; } return false; } public boolean isMapType(JavaClass type) { return mapClass.isAssignableFrom(type); } public boolean isFacets() { return facets; } public void setFacets(boolean facets) { this.facets = facets; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy