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

org.eclipse.persistence.jaxb.javamodel.xjc.XJCJavaAnnotationImpl Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 2011, 2021 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.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jakarta.xml.bind.annotation.XmlEnum;

import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.jaxb.javamodel.AnnotationProxy;
import org.eclipse.persistence.jaxb.javamodel.JavaAnnotation;

import com.sun.codemodel.JAnnotationArrayMember;
import com.sun.codemodel.JAnnotationClassValue;
import com.sun.codemodel.JAnnotationStringValue;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JAnnotationValue;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JType;

/**
 * INTERNAL:
 * 

* Purpose: JavaAnnotation implementation wrapping XJC's JAnnotationUse. Used when * bootstrapping a DynamicJAXBContext from an XML Schema. *

* *

* Responsibilities: *

*
    *
  • Provide Annotation information from the underlying JAnnotationUse.
  • *
* * @since EclipseLink 2.1 * * @see org.eclipse.persistence.jaxb.javamodel.JavaAnnotation */ public class XJCJavaAnnotationImpl implements JavaAnnotation { private JAnnotationUse xjcAnnotation; private DynamicClassLoader dynamicClassLoader; /** * Construct a new instance of XJCJavaAnnotationImpl. * * @param annotation - the XJC JAnnotationUse to be wrapped. * @param loader - the ClassLoader used to bootstrap the DynamicJAXBContext. */ public XJCJavaAnnotationImpl(JAnnotationUse annotation, DynamicClassLoader loader) { this.xjcAnnotation = annotation; this.dynamicClassLoader = loader; } /** * Return a Java Annotation representation of this JavaAnnotation. * * @return a Java Annotation representation of this JavaAnnotation. */ @SuppressWarnings("unchecked") public Annotation getJavaAnnotation() { try { Map components = new HashMap<>(); // First, get all the default values for this annotation class. Class annotationClass = (Class) getJavaAnnotationClass(); Method[] methods = annotationClass.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { components.put(methods[i].getName(), methods[i].getDefaultValue()); } // Get the property values for this annotation instance. Map memberValues = xjcAnnotation.getAnnotationMembers(); if (memberValues == null) { // Return an annotation with just the defaults set. return AnnotationProxy.getProxy(components, annotationClass, dynamicClassLoader, XMLConversionManager.getDefaultManager()); } boolean isXmlEnum = annotationClass.equals(XmlEnum.class); // Now overwrite the default values with anything we find in the XJC annotation instance. for (String key : memberValues.keySet()) { JAnnotationValue xjcValue = memberValues.get(key); if (xjcValue instanceof JAnnotationArrayMember) { Collection values = ((JAnnotationArrayMember) xjcValue).annotations2(); List valuesArray = new ArrayList<>(values.size()); for (JAnnotationValue val : values) { if (val instanceof JAnnotationUse) { JAnnotationUse xjcAnno = (JAnnotationUse) val; XJCJavaAnnotationImpl anno = new XJCJavaAnnotationImpl(xjcAnno, dynamicClassLoader); valuesArray.add(anno.getJavaAnnotation()); } else if (val instanceof JAnnotationStringValue) { JAnnotationStringValue value = (JAnnotationStringValue) val; valuesArray.add(value.toString()); } else if (val instanceof JAnnotationClassValue) { JAnnotationClassValue cval = (JAnnotationClassValue) val; valuesArray.add(getValueFromClsValue(cval, isXmlEnum)); } else { throw new RuntimeException("got " + val.getClass().getName()); } } components.put(key, valuesArray.toArray(new Object[valuesArray.size()])); } else if (xjcValue instanceof JAnnotationStringValue) { JAnnotationStringValue value = (JAnnotationStringValue) xjcValue; components.put(key, value.toString()); } else if (xjcValue instanceof JAnnotationClassValue) { JAnnotationClassValue cval = (JAnnotationClassValue) xjcValue; components.put(key, getValueFromClsValue(cval, isXmlEnum)); } else { throw new RuntimeException("got " + xjcValue.getClass().getName()); } } return AnnotationProxy.getProxy(components, annotationClass, dynamicClassLoader, XMLConversionManager.getDefaultManager()); } catch (Exception e) { return null; } } /** * Return the Java Class of the Annotation represented by this JavaAnnotation. * * @return the Java Class of this JavaAnnotation's Annotation. */ public Class getJavaAnnotationClass() { try { return Class.forName(getName()); } catch (ClassNotFoundException e) { return null; } } /** * Not supported. */ @Override public Map getComponents() { throw new UnsupportedOperationException("getComponents"); } @Override @SuppressWarnings("unchecked") public String getName() { return xjcAnnotation.getAnnotationClass().binaryName(); } private Object getValueFromClsValue(JAnnotationClassValue value, boolean isXmlEnum) { JClass cls = value.type(); for (JType param : cls.getTypeParameters()) { String name = param.boxify().fullName(); getTempClass(name, isXmlEnum); } Class tempDynClass = getTempClass(cls.fullName(), isXmlEnum); if (tempDynClass.isEnum() && !isXmlEnum) { return Enum.valueOf(tempDynClass.asSubclass(Enum.class), value.value()); } return tempDynClass; } private Class getTempClass(String name, boolean isXmlEnum) { Class tempDynClass; try { // Attempt to look up the class normally tempDynClass = Class.forName(name); } catch (ClassNotFoundException e) { if (isXmlEnum) { tempDynClass = String.class; } else { tempDynClass = dynamicClassLoader.createDynamicClass(name); } } return tempDynClass; } }