| /* |
| * 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: |
| // Denise Smith - January, 2010 - 2.0.1 |
| package org.eclipse.persistence.jaxb.compiler; |
| |
| import java.lang.reflect.Field; |
| import java.lang.reflect.GenericArrayType; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.ParameterizedType; |
| import java.lang.reflect.Type; |
| import java.lang.reflect.WildcardType; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import jakarta.xml.bind.JAXBElement; |
| import jakarta.xml.bind.JAXBException; |
| import jakarta.xml.bind.Unmarshaller; |
| import jakarta.xml.bind.annotation.XmlElement; |
| import jakarta.xml.bind.annotation.XmlList; |
| import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; |
| |
| import org.eclipse.persistence.internal.jaxb.AccessorFactoryWrapper; |
| import org.eclipse.persistence.internal.jaxb.JaxbClassLoader; |
| import org.eclipse.persistence.internal.security.PrivilegedAccessHelper; |
| import org.eclipse.persistence.jaxb.JAXBContextFactory; |
| import org.eclipse.persistence.jaxb.JAXBContext; |
| import org.eclipse.persistence.jaxb.TypeMappingInfo; |
| import org.eclipse.persistence.jaxb.javamodel.Helper; |
| import org.eclipse.persistence.jaxb.javamodel.JavaClass; |
| import org.eclipse.persistence.jaxb.javamodel.JavaField; |
| import org.eclipse.persistence.jaxb.javamodel.JavaMethod; |
| import org.eclipse.persistence.jaxb.javamodel.reflection.JavaClassImpl; |
| import org.eclipse.persistence.jaxb.xmlmodel.XmlJoinNodes; |
| |
| /** |
| * Helper class for code that needs to be shared between AnnotationsProcessor, |
| * MappingsGenerator, SchemaGenerator |
| */ |
| public class CompilerHelper { |
| |
| public static final String XML_LOCATION_ANNOTATION_NAME = "org.glassfish.jaxb.core.annotation.XmlLocation"; |
| public static final String OLD_XML_LOCATION_ANNOTATION_NAME = "com.sun.xml.bind.annotation.XmlLocation"; |
| public static final String INTERNAL_XML_LOCATION_ANNOTATION_NAME = "com.sun.xml.internal.bind.annotation.XmlLocation"; |
| |
| private static final String XML_ACCESSOR_FACTORY_ANNOTATION_NAME = "org.glassfish.jaxb.runtime.XmlAccessorFactory"; |
| private static final String OLD_ACCESSOR_FACTORY_ANNOTATION_NAME = "com.sun.xml.bind.XmlAccessorFactory"; |
| private static final String INTERNAL_ACCESSOR_FACTORY_ANNOTATION_NAME = "com.sun.xml.internal.bind.XmlAccessorFactory"; |
| private static final String METADATA_MODEL_PACKAGE = "org.eclipse.persistence.jaxb.xmlmodel"; |
| |
| public static Class ACCESSOR_FACTORY_ANNOTATION_CLASS = null; |
| public static Method ACCESSOR_FACTORY_VALUE_METHOD = null; |
| public static Class OLD_ACCESSOR_FACTORY_ANNOTATION_CLASS = null; |
| public static Method OLD_ACCESSOR_FACTORY_VALUE_METHOD = null; |
| public static Class INTERNAL_ACCESSOR_FACTORY_ANNOTATION_CLASS = null; |
| public static Method INTERNAL_ACCESSOR_FACTORY_VALUE_METHOD = null; |
| public static Class XML_LOCATION_ANNOTATION_CLASS = null; |
| public static Class OLD_XML_LOCATION_ANNOTATION_CLASS = null; |
| public static Class INTERNAL_XML_LOCATION_ANNOTATION_CLASS = null; |
| |
| private static JAXBContext xmlBindingsModelContext; |
| |
| static { |
| try { |
| ACCESSOR_FACTORY_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(XML_ACCESSOR_FACTORY_ANNOTATION_NAME, true, CompilerHelper.class.getClassLoader()); |
| ACCESSOR_FACTORY_VALUE_METHOD = PrivilegedAccessHelper.getDeclaredMethod(ACCESSOR_FACTORY_ANNOTATION_CLASS, "value", new Class[]{}); |
| } catch (Exception ex) { |
| } |
| |
| try { |
| XML_LOCATION_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(XML_LOCATION_ANNOTATION_NAME, true, CompilerHelper.class.getClassLoader()); |
| } catch (Exception ex) { |
| } |
| |
| try { |
| OLD_XML_LOCATION_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(OLD_XML_LOCATION_ANNOTATION_NAME, true, CompilerHelper.class.getClassLoader()); |
| } catch (Exception ex) { |
| } |
| |
| try{ |
| OLD_ACCESSOR_FACTORY_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(OLD_ACCESSOR_FACTORY_ANNOTATION_NAME); |
| OLD_ACCESSOR_FACTORY_VALUE_METHOD = PrivilegedAccessHelper.getDeclaredMethod(OLD_ACCESSOR_FACTORY_ANNOTATION_CLASS, "value", new Class[]{}); |
| } catch (Exception ex) { |
| } |
| |
| try{ |
| INTERNAL_ACCESSOR_FACTORY_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(INTERNAL_ACCESSOR_FACTORY_ANNOTATION_NAME); |
| INTERNAL_ACCESSOR_FACTORY_VALUE_METHOD = PrivilegedAccessHelper.getDeclaredMethod(INTERNAL_ACCESSOR_FACTORY_ANNOTATION_CLASS, "value", new Class[]{}); |
| } catch (Exception ex) { |
| } |
| |
| try{ |
| INTERNAL_XML_LOCATION_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(INTERNAL_XML_LOCATION_ANNOTATION_NAME); |
| }catch (Exception ex) { |
| } |
| |
| |
| } |
| |
| /** |
| * If 2 TypeMappingInfo objects would generate the same generated class (and |
| * therefore complex type) then return the existing class otherwise return |
| * null. |
| */ |
| static Class getExisitingGeneratedClass(TypeMappingInfo tmi, Map<TypeMappingInfo, Class> typeMappingInfoToGeneratedClasses, Map<TypeMappingInfo, Class> typeMappingInfoToAdapterClasses, ClassLoader loader) { |
| |
| Iterator<Map.Entry<TypeMappingInfo, Class>> iter = typeMappingInfoToGeneratedClasses.entrySet().iterator(); |
| while (iter.hasNext()) { |
| Map.Entry<TypeMappingInfo, Class> next = iter.next(); |
| TypeMappingInfo nextTMI = next.getKey(); |
| if (CompilerHelper.generatesSameComplexType(tmi, nextTMI, loader)) { |
| return next.getValue(); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Return true if the two TypeMappingInfoObjects should generate the same |
| * complex type in the XSD |
| */ |
| private static boolean generatesSameComplexType(TypeMappingInfo tmi1, TypeMappingInfo tmi2, ClassLoader loader) { |
| |
| org.eclipse.persistence.jaxb.xmlmodel.XmlElement element1 = null; |
| org.eclipse.persistence.jaxb.xmlmodel.XmlElement element2 = null; |
| |
| if (tmi1.getXmlElement() != null) { |
| element1 = getXmlElement(tmi1.getXmlElement(), loader); |
| } |
| |
| if (tmi2.getXmlElement() != null) { |
| element2 = getXmlElement(tmi2.getXmlElement(), loader); |
| } |
| |
| Type actualType1 = getActualType(tmi1, element1); |
| Type actualType2 = getActualType(tmi2, element2); |
| |
| if (!areTypesEqual(actualType1, actualType2)) { |
| return false; |
| } |
| |
| if (!hasSameClassName(tmi1,tmi2)) { |
| return false; |
| } |
| |
| boolean isXmlList1 = isXmlList(tmi1, element1); |
| boolean isXmlList2 = isXmlList(tmi2, element2); |
| |
| if (isXmlList1) { |
| if (!isXmlList2) { |
| return false; |
| } |
| } else if (isXmlList2) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Return true if tmi1 and tmi2 are instances of Class and have same class name. |
| * |
| * @param tmi1 instance of TypeMappingInfo |
| * @param tmi2 instance of typeMappingInfo |
| * @return true if TypeMappingInfos are instances of Class and have same class name |
| */ |
| private static boolean hasSameClassName(TypeMappingInfo tmi1, TypeMappingInfo tmi2) { |
| |
| Type type1 = tmi1.getType(); |
| Type type2 = tmi2.getType(); |
| |
| if (type1 != null && type2 == null) { |
| return false; |
| } else if (type1 == null && type2 != null) { |
| return false; |
| } else if (type1 instanceof Class && type2 instanceof Class){ |
| |
| String typeName1 = ((Class)type1).getName(); |
| String typeName2 = ((Class)type2).getName(); |
| |
| if (!typeName1.equals(typeName2)) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Return if this TypeMappingInfo has an XmlList annotation or is specified |
| * to be an xmlList in an XMLElement override |
| */ |
| private static boolean isXmlList(TypeMappingInfo tmi, org.eclipse.persistence.jaxb.xmlmodel.XmlElement element) { |
| if (element != null && element.isXmlList()) { |
| return true; |
| } |
| |
| if (tmi.getAnnotations() != null) { |
| for (int i = 0; i < tmi.getAnnotations().length; i++) { |
| java.lang.annotation.Annotation nextAnnotation = tmi.getAnnotations()[i]; |
| if (nextAnnotation != null && nextAnnotation instanceof XmlList) { |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Return true if the Types are equal. Accounts for Classes and |
| * Parameterized types or any combintation of the two. |
| */ |
| private static boolean areTypesEqual(java.lang.reflect.Type type, java.lang.reflect.Type type2) { |
| // handle null |
| if (type == null) { |
| return type2 == null; |
| } else if (type instanceof Class) { |
| if (type2 instanceof ParameterizedType) { |
| |
| java.lang.reflect.Type rawType = ((ParameterizedType) type2).getRawType(); |
| if (!areTypesEqual(type, rawType)) { |
| return false; |
| } |
| |
| java.lang.reflect.Type[] args = ((ParameterizedType) type2).getActualTypeArguments(); |
| for (int i = 0; i < args.length; i++) { |
| Type argType = getActualArgumentType(args[i]); |
| if (!areTypesEqual(Object.class, argType)) { |
| return false; |
| } |
| } |
| return true; |
| } else if (type2 instanceof Class) { |
| return type.equals(type2); |
| } else { |
| return false; |
| } |
| } else if (type instanceof ParameterizedType) { |
| if (type2 instanceof Class) { |
| |
| java.lang.reflect.Type rawType = ((ParameterizedType) type).getRawType(); |
| if (!areTypesEqual(type2, rawType)) { |
| return false; |
| } |
| |
| java.lang.reflect.Type[] args = ((ParameterizedType) type).getActualTypeArguments(); |
| for (int i = 0; i < args.length; i++) { |
| Type argType = getActualArgumentType(args[i]); |
| if (!areTypesEqual(Object.class, argType)) { |
| return false; |
| } |
| } |
| return true; |
| } else if (type2 instanceof ParameterizedType) { |
| // compare raw type |
| if (!areTypesEqual(((ParameterizedType) type).getRawType(), |
| ((ParameterizedType) type2).getRawType())) { |
| return false; |
| } |
| |
| java.lang.reflect.Type[] ta1 = ((ParameterizedType) type).getActualTypeArguments(); |
| java.lang.reflect.Type[] ta2 = ((ParameterizedType) type2).getActualTypeArguments(); |
| // check array length |
| if (ta1.length != ta2.length) { |
| return false; |
| } |
| for (int i = 0; i < ta1.length; i++) { |
| Type componentType1 = getActualArgumentType(ta1[i]); |
| Type componentType2 = getActualArgumentType(ta2[i]); |
| if (!areTypesEqual(componentType1, componentType2)) { |
| return false; |
| } |
| } |
| return true; |
| } else { |
| return false; |
| } |
| } |
| return false; |
| } |
| |
| private static Type getActualArgumentType(Type argument){ |
| if(argument instanceof WildcardType){ |
| Type[] upperBounds = ((WildcardType)argument).getUpperBounds(); |
| if(upperBounds != null && upperBounds.length >0){ |
| return upperBounds[0]; |
| }else{ |
| return Object.class; |
| } |
| }else if (argument instanceof GenericArrayType){ |
| return ((GenericArrayType)argument).getGenericComponentType(); |
| } |
| return argument; |
| } |
| |
| /** |
| * Convenience method for creating an XmlElement object based on a given |
| * Element. The method will load the eclipselink metadata model and |
| * unmarshal the Element. This assumes that the Element represents an |
| * xml-element to be unmarshalled. |
| * |
| * @param xmlElementNode |
| * @param classLoader |
| * @return |
| */ |
| static org.eclipse.persistence.jaxb.xmlmodel.XmlElement getXmlElement(org.w3c.dom.Element xmlElementNode, ClassLoader classLoader) { |
| try { |
| Unmarshaller unmarshaller = CompilerHelper.getXmlBindingsModelContext().createUnmarshaller(); |
| JAXBElement<org.eclipse.persistence.jaxb.xmlmodel.XmlElement> jelt = unmarshaller.unmarshal(xmlElementNode, org.eclipse.persistence.jaxb.xmlmodel.XmlElement.class); |
| return jelt.getValue(); |
| } catch (jakarta.xml.bind.JAXBException jaxbEx) { |
| throw org.eclipse.persistence.exceptions.JAXBException.couldNotUnmarshalMetadata(jaxbEx); |
| } |
| } |
| |
| /** |
| * If adapter class is null return null If there is a marshal method that |
| * returns something other than Object on the adapter class return the |
| * return type of that method Otherwise return Object.class |
| */ |
| static Class getTypeFromAdapterClass(Class adapterClass) { |
| if (adapterClass != null) { |
| Class declJavaType = Object.class; |
| // look for marshal method |
| Method[] tacMethods = PrivilegedAccessHelper.getMethods(adapterClass); |
| for (int i = 0; i < tacMethods.length; i++) { |
| Method method = tacMethods[i]; |
| if (method.getName().equals("marshal")) { |
| Class returnType = PrivilegedAccessHelper.getMethodReturnType(method); |
| if (!(returnType == declJavaType)) { |
| declJavaType = returnType; |
| return declJavaType; |
| } |
| } |
| } |
| return declJavaType; |
| } |
| return null; |
| |
| } |
| |
| /** |
| * If adapter class is null return null If there is a marshal method that |
| * returns something other than Object on the adapter class return the |
| * return type of that method Otherwise return Object.class |
| */ |
| public static JavaClass getTypeFromAdapterClass(JavaClass adapterClass, Helper helper) { |
| if (adapterClass != null) { |
| //JavaClass declJavaType = Object.class; |
| JavaClass declJavaType = helper.getJavaClass(Object.class); |
| // look for marshal method |
| Object[] tacMethods = adapterClass.getMethods().toArray(); |
| for (int i = 0; i < tacMethods.length; i++) { |
| JavaMethod method = (JavaMethod)tacMethods[i]; |
| if (method.getName().equals("marshal")) { |
| JavaClass returnType = method.getReturnType(); |
| if (!(returnType.getQualifiedName().equals(declJavaType.getQualifiedName()))) { |
| declJavaType = returnType; |
| return declJavaType; |
| } |
| } |
| } |
| return declJavaType; |
| } |
| return null; |
| |
| } |
| |
| /** |
| * Return true if the type is a Collection, List or Set |
| */ |
| private static boolean isCollectionType(Type theType) { |
| if (theType instanceof Class) { |
| if (Collection.class.isAssignableFrom((Class) theType) |
| || List.class.isAssignableFrom((Class) theType) |
| || Set.class.isAssignableFrom((Class) theType)) { |
| return true; |
| } |
| return false; |
| } else if (theType instanceof ParameterizedType) { |
| Type rawType = ((ParameterizedType) theType).getRawType(); |
| return isCollectionType(rawType); |
| } |
| return false; |
| } |
| |
| /** |
| * The actual type accounts for adapter classes or xmlelemnt types specified |
| * in either an annotation or an XML override |
| * |
| */ |
| static Type getActualType(TypeMappingInfo tmi, org.eclipse.persistence.jaxb.xmlmodel.XmlElement element) { |
| try { |
| if (element == null) { |
| if (tmi.getAnnotations() != null) { |
| for (int i = 0; i < tmi.getAnnotations().length; i++) { |
| java.lang.annotation.Annotation nextAnnotation = tmi.getAnnotations()[i]; |
| if (nextAnnotation != null) { |
| if (nextAnnotation instanceof XmlJavaTypeAdapter) { |
| Class typeClass = ((XmlJavaTypeAdapter) nextAnnotation).type(); |
| if (typeClass.getName().equals("jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter$DEFAULT")) { |
| Class adapterClass = ((XmlJavaTypeAdapter) nextAnnotation).value(); |
| return getTypeFromAdapterClass(adapterClass); |
| } |
| return typeClass; |
| } else if (nextAnnotation instanceof XmlElement) { |
| Class typeClass = ((XmlElement) nextAnnotation).type(); |
| if (!typeClass.getName().equals("jakarta.xml.bind.annotation.XmlElement.DEFAULT")) { |
| final Type tmiType = tmi.getType(); |
| if (isCollectionType(tmiType)) { |
| final Class itemType = typeClass; |
| Type parameterizedType = new ParameterizedType() { |
| Type[] typeArgs = { itemType }; |
| |
| @Override |
| public Type[] getActualTypeArguments() { |
| return typeArgs; |
| } |
| |
| @Override |
| public Type getOwnerType() { |
| return null; |
| } |
| |
| @Override |
| public Type getRawType() { |
| return tmiType; |
| } |
| }; |
| return parameterizedType; |
| } else { |
| return typeClass; |
| } |
| } |
| } |
| } |
| |
| } |
| } |
| return tmi.getType(); |
| } else { |
| |
| // if it has an XMLElement specified |
| // Check for an adapater, then check for XMLElement.type |
| if (element.getXmlJavaTypeAdapter() != null) { |
| String actualType = element.getXmlJavaTypeAdapter().getType(); |
| if (actualType != null && !actualType.equals("jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT")) { |
| return PrivilegedAccessHelper.getClassForName(actualType); |
| } else { |
| String adapterClassName = element.getXmlJavaTypeAdapter().getValue(); |
| Class adapterClass = PrivilegedAccessHelper.getClassForName(adapterClassName); |
| return getTypeFromAdapterClass(adapterClass); |
| } |
| } |
| |
| if (!(element.getType().equals("jakarta.xml.bind.annotation.XmlElement.DEFAULT"))) { |
| String actualType = element.getType(); |
| |
| final Type tmiType = tmi.getType(); |
| if (isCollectionType(tmiType)) { |
| final Class itemType = PrivilegedAccessHelper.getClassForName(actualType); |
| Type parameterizedType = new ParameterizedType() { |
| Type[] typeArgs = { itemType }; |
| |
| @Override |
| public Type[] getActualTypeArguments() { |
| return typeArgs; |
| } |
| |
| @Override |
| public Type getOwnerType() { |
| return null; |
| } |
| |
| @Override |
| public Type getRawType() { |
| return tmiType; |
| } |
| }; |
| return parameterizedType; |
| } else { |
| return PrivilegedAccessHelper.getClassForName(actualType); |
| } |
| } |
| return tmi.getType(); |
| } |
| } catch (Exception e) { |
| return tmi.getType(); |
| } |
| } |
| |
| /** |
| * The method will load the eclipselink metadata model and return the |
| * corresponding JAXBContext |
| */ |
| public static JAXBContext getXmlBindingsModelContext() { |
| if (xmlBindingsModelContext == null) { |
| try { |
| xmlBindingsModelContext = (JAXBContext) JAXBContextFactory.createContext(METADATA_MODEL_PACKAGE,CompilerHelper.class.getClassLoader()); |
| } catch (JAXBException e) { |
| throw org.eclipse.persistence.exceptions.JAXBException.couldNotCreateContextForXmlModel(e); |
| } |
| if (xmlBindingsModelContext == null) { |
| throw org.eclipse.persistence.exceptions.JAXBException.couldNotCreateContextForXmlModel(); |
| } |
| } |
| return xmlBindingsModelContext; |
| } |
| |
| public static JavaClass getNextMappedSuperClass(JavaClass cls, Map<String, TypeInfo> typeInfo, Helper helper) { |
| JavaClass superClass = cls.getSuperclass(); |
| |
| if(superClass == null || helper.isBuiltInJavaType(cls) || superClass.getRawName().equals("java.lang.Object")){ |
| return null; |
| } |
| TypeInfo parentTypeInfo = typeInfo.get(superClass.getQualifiedName()); |
| if(parentTypeInfo == null || parentTypeInfo.isTransient()) { |
| return getNextMappedSuperClass(superClass, typeInfo, helper); |
| } |
| |
| return superClass; |
| } |
| |
| public static void addClassToClassLoader(JavaClass cls, ClassLoader loader) { |
| |
| if(loader.getClass() == JaxbClassLoader.class && cls.getClass() == JavaClassImpl.class) { |
| Class wrappedClass = ((JavaClassImpl)cls).getJavaClass(); |
| ((JaxbClassLoader)loader).putClass(wrappedClass.getName(), wrappedClass); |
| } |
| } |
| |
| static boolean hasNonAttributeJoinNodes(Property property) { |
| if(property.isSetXmlJoinNodes()) { |
| for(XmlJoinNodes.XmlJoinNode next: property.getXmlJoinNodes().getXmlJoinNode()) { |
| if(!(next.getXmlPath().startsWith("@"))) { |
| return true; |
| } |
| } |
| } else if(property.isSetXmlJoinNodesList()) { |
| for(XmlJoinNodes nextNodes:property.getXmlJoinNodesList()) { |
| for(XmlJoinNodes.XmlJoinNode next: nextNodes.getXmlJoinNode()) { |
| if(!(next.getXmlPath().startsWith("@"))) { |
| return true; |
| } |
| } |
| } |
| |
| } |
| return false; |
| } |
| |
| public static Object createAccessorFor(JavaClass jClass, Property property, Helper helper, AccessorFactoryWrapper accessorFactory) { |
| if(!(jClass.getClass() == JavaClassImpl.class)) { |
| return null; |
| } |
| Class beanClass = ((JavaClassImpl)jClass).getJavaClass(); |
| if(property.isMethodProperty()) { |
| try { |
| Method getMethod = null; |
| Method setMethod = null; |
| if(property.getGetMethodName() != null) { |
| getMethod = PrivilegedAccessHelper.getMethod(beanClass, property.getGetMethodName(), new Class[]{}, true); |
| } |
| if(property.getSetMethodName() != null) { |
| String setMethodParamTypeName = property.getType().getName(); |
| JavaClassImpl paramType = (JavaClassImpl)helper.getJavaClass(setMethodParamTypeName); |
| Class[] setMethodParams = new Class[]{paramType.getJavaClass()}; |
| setMethod = PrivilegedAccessHelper.getMethod(beanClass, property.getSetMethodName(), setMethodParams, true); |
| } |
| return accessorFactory.createPropertyAccessor(beanClass, getMethod, setMethod); |
| } catch(Exception ex) {} |
| } else { |
| try { |
| Field field = PrivilegedAccessHelper.getField(beanClass, ((JavaField)property.getElement()).getName(), true); |
| return accessorFactory.createFieldAccessor(beanClass, field, property.isReadOnly()); |
| } catch(Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| return null; |
| } |
| |
| public static boolean isSimpleType(TypeInfo info) { |
| if (info.isEnumerationType()) { |
| return true; |
| } |
| Property xmlValueProperty = info.getXmlValueProperty(); |
| |
| boolean hasMappedAttributes = false; |
| |
| for (Property nextProp : info.getPropertyList()) { |
| if (nextProp.isAttribute() && !nextProp.isTransient()) { |
| hasMappedAttributes = true; |
| } |
| } |
| hasMappedAttributes = hasMappedAttributes || info.hasPredicateProperties(); |
| |
| return (xmlValueProperty != null && !hasMappedAttributes); |
| } |
| |
| } |