blob: c5cc7ed7eb1297446a4569a10fab1353cbfa20bd [file] [log] [blame]
/*
* Copyright (c) 2011, 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:
// Rick Barkhouse - 2.2 - Initial implementation
package org.eclipse.persistence.jaxb.javamodel.oxm;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.persistence.internal.jaxb.JaxbClassLoader;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;
import org.eclipse.persistence.jaxb.javamodel.JavaModel;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaClassImpl;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaModelImpl;
/**
* INTERNAL:
* <p>
* <b>Purpose:</b> <code>JavaModel</code> implementation backed by a collection of MOXY's
* <code>xmlmodel.JavaClasses</code>. Used when bootstrapping a <code>DynamicJAXBContext</code>
* from XML Bindings.
* </p>
*
* <p>
* <b>Responsibilities:</b>
* </p>
* <ul>
* <li>Return a <code>JavaClass</code> based on a <code>Class</code> or <code>Class</code> name.</li>
* </ul>
*
* @since EclipseLink 2.2
*
* @see org.eclipse.persistence.jaxb.javamodel.JavaModel
*/
public class OXMJavaModelImpl extends JavaModelImpl implements JavaModel {
private Map<String, JavaClass> javaModelClasses = new HashMap<String, JavaClass>();
/**
* Construct a new instance of <code>OXMJavaModelImpl</code>.
*
* @param loader - the <code>ClassLoader</code> used to bootstrap the <code>DynamicJAXBContext</code>.
* @param javaClasses - an array of <code>JavaClasses</code> for which to generate mappings.
*
*/
public OXMJavaModelImpl(ClassLoader loader, JavaClass[] javaClasses) {
super(loader);
for (int i = 0; i < javaClasses.length; i++) {
this.javaModelClasses.put(javaClasses[i].getQualifiedName(), javaClasses[i]);
}
}
/**
* Obtain the <code>JavaClass</code> given the corresponding Java <code>Class</code>.
*
* @param jClass - the Java <code>Class</code> to search for.
*
* @return the <code>JavaClass</code> corresponding to <code>jClass</code>.
*/
@Override
public JavaClass getClass(Class<?> jClass) {
if (jClass == null) {
return null;
}
String className = jClass.getCanonicalName();
JavaClass cachedClass = this.javaModelClasses.get(className);
if (cachedClass != null) {
return cachedClass;
}
// try actually finding the class, might be concrete
try {
if (jClass.isArray()) {
className = jClass.getName();
}
Class<?> realClass = PrivilegedAccessHelper.getClassForName(className, true, classLoader);
if (realClass != null) {
JavaModelImpl jm = new JavaModelImpl(classLoader);
JavaClassImpl jc = new JavaClassImpl(realClass, jm);
return jc;
}
} catch (Exception e) {
}
return new OXMJavaClassImpl(jClass.getCanonicalName());
}
/**
* Obtain the <code>JavaClass</code> given the corresponding Java <code>Class'</code> name.
*
* @param className - the name of the Java <code>Class</code> to search for.
*
* @return the <code>JavaClass</code> corresponding to <code>className</code>.
*/
@Override
public JavaClass getClass(String className) {
if (className == null) {
return null;
}
// jakarta.xml.bind.annotation.XmlElement.DEFAULT
if (className.contains(DEFAULT)) {
return getClass(JAVA_LANG_OBJECT);
}
JavaClass cachedClass = this.javaModelClasses.get(className);
if (cachedClass != null) {
return cachedClass;
}
// try actually finding the class, might be concrete
try {
Class<?> realClass = PrivilegedAccessHelper.getClassForName(className, true, classLoader);
if (realClass != null) {
JavaModelImpl jm = new JavaModelImpl(this.classLoader);
JavaClassImpl jc = new JavaClassImpl(realClass, jm);
return jc;
}
} catch (Exception e) {
}
return new OXMJavaClassImpl(className);
}
/**
* Returns this <code>JavaModel's</code> <code>ClassLoader</code>.
*
* @return the <code>ClassLoader</code> used by this <code>JavaModel</code>.
*/
@Override
public ClassLoader getClassLoader() {
return this.classLoader;
}
/**
* Returns this <code>JavaModel's</code> <code>JaxbClassLoader</code>, which
* should be the parent <code>ClassLoader</code>.
*
* @return the <code>JaxbClassLoader</code> used by this <code>JavaModel</code>.
*/
public JaxbClassLoader getJaxbClassLoader() {
ClassLoader parent = getClassLoader().getParent();
if (parent instanceof JaxbClassLoader) {
return (JaxbClassLoader) parent;
}
return null;
}
// ========================================================================
private static String DEFAULT = "DEFAULT";
private static String JAVA_LANG_OBJECT = "java.lang.Object";
}