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

org.eclipse.persistence.jaxb.compiler.MappingsGenerator Maven / Gradle / Ivy

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

import java.awt.Image;
import java.beans.Introspector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableSet;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TreeSet;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlMixed;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlValue;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.NormalizedStringAdapter;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;

import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.core.descriptors.CoreDescriptor;
import org.eclipse.persistence.core.mappings.CoreMapping;
import org.eclipse.persistence.core.mappings.converters.CoreConverter;
import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.core.sessions.CoreProject;
import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.JAXBException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.InstantiationPolicy;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.VirtualAttributeAccessor;
import org.eclipse.persistence.internal.jaxb.AccessorFactoryWrapper;
import org.eclipse.persistence.internal.jaxb.CustomAccessorAttributeAccessor;
import org.eclipse.persistence.internal.jaxb.DefaultElementConverter;
import org.eclipse.persistence.internal.jaxb.DomHandlerConverter;
import org.eclipse.persistence.internal.jaxb.JAXBElementConverter;
import org.eclipse.persistence.internal.jaxb.JAXBElementRootConverter;
import org.eclipse.persistence.internal.jaxb.JAXBSetMethodAttributeAccessor;
import org.eclipse.persistence.internal.jaxb.JaxbClassLoader;
import org.eclipse.persistence.internal.jaxb.MultiArgInstantiationPolicy;
import org.eclipse.persistence.internal.jaxb.WrappedValue;
import org.eclipse.persistence.internal.jaxb.XMLJavaTypeConverter;
import org.eclipse.persistence.internal.jaxb.many.JAXBArrayAttributeAccessor;
import org.eclipse.persistence.internal.jaxb.many.ManyValue;
import org.eclipse.persistence.internal.jaxb.many.MapValue;
import org.eclipse.persistence.internal.jaxb.many.MapValueAttributeAccessor;
import org.eclipse.persistence.internal.libraries.asm.EclipseLinkASMClassWriter;
import org.eclipse.persistence.internal.libraries.asm.MethodVisitor;
import org.eclipse.persistence.internal.libraries.asm.Opcodes;
import org.eclipse.persistence.internal.libraries.asm.Type;
import org.eclipse.persistence.internal.localization.JAXBLocalization;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.mappings.AnyAttributeMapping;
import org.eclipse.persistence.internal.oxm.mappings.AnyCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.AnyObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataMapping;
import org.eclipse.persistence.internal.oxm.mappings.ChoiceCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.ChoiceObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.CollectionReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.CompositeCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.CompositeObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.DirectCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.DirectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.InverseReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.mappings.ObjectReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.TransformationMapping;
import org.eclipse.persistence.internal.oxm.mappings.VariableXPathCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.VariableXPathObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.XMLContainerMapping;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.jaxb.JAXBEnumTypeConverter;
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.xmlmodel.XmlAbstractNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElementWrapper;
import org.eclipse.persistence.jaxb.xmlmodel.XmlIsSetNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJoinNodes.XmlJoinNode;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNamedAttributeNode;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNamedObjectGraph;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNamedSubgraph;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlTransformation;
import org.eclipse.persistence.jaxb.xmlmodel.XmlTransformation.XmlReadTransformer;
import org.eclipse.persistence.jaxb.xmlmodel.XmlTransformation.XmlWriteTransformer;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.FixedMimeTypePolicy;
import org.eclipse.persistence.oxm.mappings.UnmarshalKeepAsElementPolicy;
import org.eclipse.persistence.oxm.mappings.XMLAnyAttributeMapping;
import org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLAnyObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLBinaryDataCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping;
import org.eclipse.persistence.oxm.mappings.XMLChoiceCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLChoiceObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLCollectionReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.XMLInverseReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLMapping;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLTransformationMapping;
import org.eclipse.persistence.oxm.mappings.XMLVariableXPathCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLVariableXPathObjectMapping;
import org.eclipse.persistence.oxm.mappings.converters.XMLListConverter;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.IsSetNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.NullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;
import org.eclipse.persistence.oxm.schema.XMLSchemaClassPathReference;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.sessions.Project;

/**
 * INTERNAL:
 * 

Purpose:To generate a TopLink OXM Project based on Java Class and TypeInfo information *

Responsibilities:

    *
  • Generate a XMLDescriptor for each TypeInfo object
  • *
  • Generate a mapping for each TypeProperty object
  • *
  • Determine the correct mapping type based on the type of each property
  • *
  • Set up Converters on mappings for XmlAdapters or JDK 1.5 Enumeration types.
  • *
*

This class is invoked by a Generator in order to create a TopLink Project. * This is generally used by JAXBContextFactory to create the runtime project. A Descriptor will * be generated for each TypeInfo and Mappings generated for each Property. In the case that a * non-transient property's type is a user defined class, a Descriptor and Mappings will be generated * for that class as well. * @see org.eclipse.persistence.jaxb.compiler.Generator * @see org.eclipse.persistence.jaxb.compiler.TypeInfo * @see org.eclipse.persistence.jaxb.compiler.Property * @author mmacivor * @since Oracle TopLink 11.1.1.0.0 * */ public class MappingsGenerator { private static final String ATT = "@"; private static final String TXT = "/text()"; private static String OBJECT_CLASS_NAME = "java.lang.Object"; public static final QName RESERVED_QNAME = new QName("urn:ECLIPSELINK_RESERVEDURI", "RESERVEDNAME"); String outputDir = "."; private Map userDefinedSchemaTypes; private Helper helper; private JavaClass jotArrayList; private JavaClass jotHashSet; private JavaClass jotHashMap; private JavaClass jotLinkedList; private JavaClass jotTreeSet; private Map packageToPackageInfoMappings; private Map typeInfo; private Map qNamesToGeneratedClasses; private Map classToGeneratedClasses; private Map qNamesToDeclaredClasses; private Map globalElements; private List localElements; private Map typeMappingInfoToGeneratedClasses; private Map generatedMapEntryClasses; private CoreProject project; private org.eclipse.persistence.oxm.NamespaceResolver globalNamespaceResolver; private boolean isDefaultNamespaceAllowed; private MaptypeMappingInfoToAdapterClasses; public MappingsGenerator(Helper helper) { this.helper = helper; jotArrayList = helper.getJavaClass(ArrayList.class); jotHashSet = helper.getJavaClass(HashSet.class); jotHashMap = helper.getJavaClass(HashMap.class); jotLinkedList = helper.getJavaClass(LinkedList.class); jotTreeSet = helper.getJavaClass(TreeSet.class); qNamesToGeneratedClasses = new HashMap(); qNamesToDeclaredClasses = new HashMap(); classToGeneratedClasses = new HashMap(); globalNamespaceResolver = new org.eclipse.persistence.oxm.NamespaceResolver(); isDefaultNamespaceAllowed = true; } public CoreProject generateProject(List typeInfoClasses, Map typeInfo, Map userDefinedSchemaTypes, Map packageToPackageInfoMappings, Map globalElements, List localElements, Map typeMappingInfoToGeneratedClass, Map typeMappingInfoToAdapterClasses, boolean isDefaultNamespaceAllowed) throws Exception { this.typeInfo = typeInfo; this.userDefinedSchemaTypes = userDefinedSchemaTypes; this.packageToPackageInfoMappings = packageToPackageInfoMappings; this.isDefaultNamespaceAllowed = isDefaultNamespaceAllowed; this.globalElements = globalElements; this.localElements = localElements; this.typeMappingInfoToGeneratedClasses = typeMappingInfoToGeneratedClass; this.typeMappingInfoToAdapterClasses = typeMappingInfoToAdapterClasses; project = new Project(); processDefaultNamespacePreferences(packageToPackageInfoMappings.values()); // Generate descriptors for (JavaClass next : typeInfoClasses) { if (!next.isEnum()) { generateDescriptor(next, project); } } // Setup inheritance for (JavaClass next : typeInfoClasses) { if (!next.isEnum()) { setupInheritance(next); } } // Now create mappings generateMappings(); // Setup AttributeGroups for(JavaClass next : typeInfoClasses) { setupAttributeGroups(next); } // apply customizers if necessary Set> entrySet = this.typeInfo.entrySet(); for (Entry entry : entrySet) { TypeInfo tInfo = entry.getValue(); if (tInfo.getXmlCustomizer() != null) { String customizerClassName = tInfo.getXmlCustomizer(); try { Class customizerClass = PrivilegedAccessHelper.getClassForName(customizerClassName, true, helper.getClassLoader()); DescriptorCustomizer descriptorCustomizer = (DescriptorCustomizer) PrivilegedAccessHelper.newInstanceFromClass(customizerClass); descriptorCustomizer.customize((XMLDescriptor)tInfo.getDescriptor()); } catch (IllegalAccessException iae) { throw JAXBException.couldNotCreateCustomizerInstance(iae, customizerClassName); } catch (InstantiationException ie) { throw JAXBException.couldNotCreateCustomizerInstance(ie, customizerClassName); } catch (ClassCastException cce) { throw JAXBException.invalidCustomizerClass(cce, customizerClassName); } catch (ClassNotFoundException cnfe) { throw JAXBException.couldNotCreateCustomizerInstance(cnfe, customizerClassName); } } } processGlobalElements(project); return project; } private void setupAttributeGroups(JavaClass javaClass) { TypeInfo info = this.typeInfo.get(javaClass.getQualifiedName()); XMLDescriptor descriptor = (XMLDescriptor)info.getDescriptor(); if(!info.getObjectGraphs().isEmpty()) { for(XmlNamedObjectGraph next:info.getObjectGraphs()) { AttributeGroup group = descriptor.getAttributeGroup(next.getName()); Map> subgraphs = processSubgraphs(next.getXmlNamedSubgraph()); for(XmlNamedAttributeNode nextAttributeNode:next.getXmlNamedAttributeNode()) { if(nextAttributeNode.getSubgraph() == null || nextAttributeNode.getSubgraph().length() == 0) { group.addAttribute(nextAttributeNode.getName()); } else { List nestedGroups = subgraphs.get(nextAttributeNode.getSubgraph()); if(nestedGroups == null || nestedGroups.isEmpty()) { Property property = info.getProperties().get(nextAttributeNode.getName()); if(property == null) { //if there's no property associated with the attributeNode, just ignore it continue; } JavaClass cls = property.getActualType(); TypeInfo referenceType = typeInfo.get(cls.getQualifiedName()); if(referenceType != null) { AttributeGroup targetGroup = (AttributeGroup)referenceType.getDescriptor().getAttributeGroup(nextAttributeNode.getSubgraph()); group.addAttribute(nextAttributeNode.getName(), targetGroup); } else { //TODO: Exception } } else { if(nestedGroups.size() == 1) { group.addAttribute(nextAttributeNode.getName(), nestedGroups.get(0)); } else { group.addAttribute(nextAttributeNode.getName(), nestedGroups); } } } } for(XmlNamedSubgraph nextSubclass:next.getXmlNamedSubclassGraph()) { AttributeGroup subclassGroup = new AttributeGroup(next.getName(), nextSubclass.getType(), true); group.getSubClassGroups().put(nextSubclass.getType(), subclassGroup); for(XmlNamedAttributeNode nextAttributeNode:nextSubclass.getXmlNamedAttributeNode()) { if(nextAttributeNode.getSubgraph() == null || nextAttributeNode.getSubgraph().length() == 0) { subclassGroup.addAttribute(nextAttributeNode.getName()); } else { List nestedGroups = subgraphs.get(nextAttributeNode.getSubgraph()); if(nestedGroups == null || nestedGroups.isEmpty()) { Property property = info.getProperties().get(nextAttributeNode.getName()); JavaClass cls = property.getActualType(); TypeInfo referenceType = typeInfo.get(cls.getQualifiedName()); if(referenceType != null) { AttributeGroup targetGroup = (AttributeGroup)referenceType.getDescriptor().getAttributeGroup(nextAttributeNode.getSubgraph()); subclassGroup.addAttribute(nextAttributeNode.getName(), targetGroup); } else { //TODO: Exception } } else { if(nestedGroups.size() == 1) { subclassGroup.addAttribute(nextAttributeNode.getName(), nestedGroups.get(0)); } else { subclassGroup.addAttribute(nextAttributeNode.getName(), nestedGroups); } } } } } } } } private Map> processSubgraphs(List subgraphs) { Map> subgroups = new HashMap>(); //Iterate through once and create all the AttributeGroups for(XmlNamedSubgraph next: subgraphs) { String type = next.getType(); if(type == null) { type = "java.lang.Object"; } AttributeGroup group = new AttributeGroup(next.getName(), type, false); if(subgroups.containsKey(group.getName())) { List groups = subgroups.get(group.getName()); groups.add(group); } else { List groups = new ArrayList(1); groups.add(group); subgroups.put(group.getName(), groups); } } //Iterate through a second time to populate the groups and set up links. for(XmlNamedSubgraph next:subgraphs) { List attributeNodes = next.getXmlNamedAttributeNode(); List attributeGroups = subgroups.get(next.getName()); if(attributeGroups != null) { for(CoreAttributeGroup group:attributeGroups) { String typeName = next.getType(); if(typeName == null) { typeName = "java.lang.Object"; } if(group.getTypeName().equals(typeName)) { for(XmlNamedAttributeNode attributeNode:attributeNodes) { if(attributeNode.getSubgraph() == null || attributeNode.getSubgraph().length() == 0) { group.addAttribute(attributeNode.getName()); } else { List nestedGroups = subgroups.get(attributeNode.getSubgraph()); if(nestedGroups == null || nestedGroups.size() == 0) { //TODO: Exception or check for root level ones on target class } else { group.addAttribute(attributeNode.getName(), nestedGroups.get(0)); } } } } } } } return subgroups; } public void generateDescriptor(JavaClass javaClass, CoreProject project) { String jClassName = javaClass.getQualifiedName(); TypeInfo info = typeInfo.get(jClassName); if (info.isTransient()){ return; } NamespaceInfo namespaceInfo = this.packageToPackageInfoMappings.get(javaClass.getPackageName()).getNamespaceInfo(); String packageNamespace = namespaceInfo.getNamespace(); String elementName; String namespace; if (javaClass.getSuperclass() != null && javaClass.getSuperclass().getName().equals("javax.xml.bind.JAXBElement")) { generateDescriptorForJAXBElementSubclass(javaClass, project, getNamespaceResolverForDescriptor(namespaceInfo)); return; } Descriptor descriptor = new XMLDescriptor(); org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement rootElem = info.getXmlRootElement(); if (rootElem == null) { try{ elementName = info.getXmlNameTransformer().transformRootElementName(javaClass.getName()); }catch (Exception ex){ throw org.eclipse.persistence.exceptions.JAXBException.exceptionDuringNameTransformation(javaClass.getName(), info.getXmlNameTransformer().getClass().getName(), ex); } namespace = packageNamespace; } else { elementName = rootElem.getName(); if (elementName.equals(XMLProcessor.DEFAULT)) { try{ elementName = info.getXmlNameTransformer().transformRootElementName(javaClass.getName()); }catch (Exception ex){ throw org.eclipse.persistence.exceptions.JAXBException.exceptionDuringNameTransformation(javaClass.getName(), info.getXmlNameTransformer().getClass().getName(), ex); } } namespace = rootElem.getNamespace(); } descriptor.setJavaClassName(jClassName); if (info.getFactoryMethodName() != null) { descriptor.getInstantiationPolicy().useFactoryInstantiationPolicy(info.getObjectFactoryClassName(), info.getFactoryMethodName()); } if (namespace.equals(XMLProcessor.DEFAULT)) { namespace = namespaceInfo.getNamespace(); } NamespaceResolver resolverForDescriptor = getNamespaceResolverForDescriptor(namespaceInfo); JavaClass manyValueJavaClass = helper.getJavaClass(ManyValue.class); if (!manyValueJavaClass.isAssignableFrom(javaClass)){ if(isDefaultNamespaceAllowed && namespace.length() != 0 && globalNamespaceResolver.getDefaultNamespaceURI() == null && !resolverForDescriptor.getPrefixesToNamespaces().containsValue(namespace)) { globalNamespaceResolver.setDefaultNamespaceURI(namespace); resolverForDescriptor.setDefaultNamespaceURI(namespace); } if (rootElem == null) { descriptor.setDefaultRootElement(""); } else { if (namespace.length() == 0) { descriptor.setDefaultRootElement(elementName); } else { descriptor.setDefaultRootElement(getQualifiedString(getPrefixForNamespace(namespace, resolverForDescriptor), elementName)); } } } descriptor.setNamespaceResolver(resolverForDescriptor); setSchemaContext(descriptor, info); // set the ClassExtractor class name if necessary if (info.isSetClassExtractorName()) { descriptor.getInheritancePolicy().setClassExtractorName(info.getClassExtractorName()); } // set any user-defined properties if (info.getUserProperties() != null) { descriptor.setProperties(info.getUserProperties()); } if (info.isLocationAware()) { Property locProp = null; Iterator i = info.getPropertyList().iterator(); while (i.hasNext()) { Property p = i.next(); if (p.getType().getName().equals(Constants.LOCATOR_CLASS_NAME)) { locProp = p; } } if (locProp != null && locProp.isTransient()) { // build accessor // don't make a mapping if (locProp.isMethodProperty()) { MethodAttributeAccessor aa = new MethodAttributeAccessor(); aa.setAttributeName(locProp.getPropertyName()); aa.setSetMethodName(locProp.getSetMethodName()); aa.setGetMethodName(locProp.getGetMethodName()); descriptor.setLocationAccessor(aa); } else { // instance variable property InstanceVariableAttributeAccessor aa = new InstanceVariableAttributeAccessor(); aa.setAttributeName(locProp.getPropertyName()); descriptor.setLocationAccessor(aa); } } } if(!info.getObjectGraphs().isEmpty()) { //create attribute groups for each object graph. //these will be populated later to allow for linking for(XmlNamedObjectGraph next:info.getObjectGraphs()) { AttributeGroup attributeGroup = new AttributeGroup(next.getName(), info.getJavaClassName(), false); ((XMLDescriptor)descriptor).addAttributeGroup(attributeGroup); //process subclass graphs for inheritance //for(NamedSubgraph nextSubclass:next.getNamedSubclassGraph()) { //attributeGroup.insertSubClass(new AttributeGroup(next.getName(), nextSubclass.getType())); //} } } project.addDescriptor((CoreDescriptor)descriptor); info.setDescriptor(descriptor); } public void generateDescriptorForJAXBElementSubclass(JavaClass javaClass, CoreProject project, NamespaceResolver nsr) { String jClassName = javaClass.getQualifiedName(); TypeInfo info = typeInfo.get(jClassName); Descriptor xmlDescriptor = new XMLDescriptor(); xmlDescriptor.setJavaClassName(jClassName); String[] factoryMethodParamTypes = info.getFactoryMethodParamTypes(); MultiArgInstantiationPolicy policy = new MultiArgInstantiationPolicy(); policy.useFactoryInstantiationPolicy(info.getObjectFactoryClassName(), info.getFactoryMethodName()); policy.setParameterTypeNames(factoryMethodParamTypes); policy.setDefaultValues(new String[]{null}); xmlDescriptor.setInstantiationPolicy(policy); JavaClass paramClass = helper.getJavaClass(factoryMethodParamTypes[0]); boolean isObject = paramClass.getName().equals("java.lang.Object"); if(helper.isBuiltInJavaType(paramClass) && !isObject ){ if(isBinaryData(paramClass)){ BinaryDataMapping mapping = new XMLBinaryDataMapping(); mapping.setAttributeName("value"); mapping.setXPath("."); ((Field)mapping.getField()).setSchemaType(Constants.BASE_64_BINARY_QNAME); mapping.setSetMethodName("setValue"); mapping.setGetMethodName("getValue"); Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(factoryMethodParamTypes[0], helper.getClassLoader()); mapping.setAttributeClassification(attributeClassification); mapping.getNullPolicy().setNullRepresentedByEmptyNode(false); mapping.setShouldInlineBinaryData(false); if(mapping.getMimeType() == null) { if(areEquals(paramClass, javax.xml.transform.Source.class)) { mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/xml")); } else { mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/octet-stream")); } } xmlDescriptor.addMapping((CoreMapping)mapping); } else { DirectMapping mapping = new XMLDirectMapping(); mapping.setNullValueMarshalled(true); mapping.setAttributeName("value"); mapping.setGetMethodName("getValue"); mapping.setSetMethodName("setValue"); mapping.setXPath("text()"); Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(factoryMethodParamTypes[0], helper.getClassLoader()); mapping.setAttributeClassification(attributeClassification); xmlDescriptor.addMapping((CoreMapping)mapping); } }else if(paramClass.isEnum()){ EnumTypeInfo enumInfo = (EnumTypeInfo)typeInfo.get(paramClass.getQualifiedName()); DirectMapping mapping = new XMLDirectMapping(); mapping.setConverter(buildJAXBEnumTypeConverter(mapping, enumInfo)); mapping.setNullValueMarshalled(true); mapping.setAttributeName("value"); mapping.setGetMethodName("getValue"); mapping.setSetMethodName("setValue"); mapping.setXPath("text()"); Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(factoryMethodParamTypes[0], helper.getClassLoader()); mapping.setAttributeClassification(attributeClassification); xmlDescriptor.addMapping((CoreMapping)mapping); }else{ CompositeObjectMapping mapping = new XMLCompositeObjectMapping(); mapping.setAttributeName("value"); mapping.setGetMethodName("getValue"); mapping.setSetMethodName("setValue"); mapping.setXPath("."); if(isObject){ mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); }else{ mapping.setReferenceClassName(factoryMethodParamTypes[0]); } xmlDescriptor.addMapping((CoreMapping)mapping); } xmlDescriptor.setNamespaceResolver(nsr); setSchemaContext(xmlDescriptor, info); project.addDescriptor((CoreDescriptor)xmlDescriptor); info.setDescriptor(xmlDescriptor); } private void setSchemaContext(Descriptor desc, TypeInfo info) { XMLSchemaClassPathReference schemaRef = new XMLSchemaClassPathReference(); if (info.getClassNamespace() == null || info.getClassNamespace().equals("")) { schemaRef.setSchemaContext("/" + info.getSchemaTypeName()); schemaRef.setSchemaContextAsQName(new QName(info.getSchemaTypeName())); } else { String prefix = desc.getNonNullNamespaceResolver().resolveNamespaceURI(info.getClassNamespace()); if (prefix != null && !prefix.equals("")) { schemaRef.setSchemaContext("/" + prefix + ":" + info.getSchemaTypeName()); schemaRef.setSchemaContextAsQName(new QName(info.getClassNamespace(), info.getSchemaTypeName(), prefix)); } else { String generatedPrefix =getPrefixForNamespace(info.getClassNamespace(), desc.getNonNullNamespaceResolver(), false); schemaRef.setSchemaContext("/" + getQualifiedString(generatedPrefix, info.getSchemaTypeName())); if(generatedPrefix == null || generatedPrefix.equals(Constants.EMPTY_STRING)){ schemaRef.setSchemaContextAsQName(new QName(info.getClassNamespace(), info.getSchemaTypeName())); }else{ schemaRef.setSchemaContextAsQName(new QName(info.getClassNamespace(), info.getSchemaTypeName(), generatedPrefix)); } } } // the default type is complex; need to check for simple type case if (info.isEnumerationType() || (info.getPropertyNames().size() == 1 && helper.isAnnotationPresent(info.getProperties().get(info.getPropertyNames().get(0)).getElement(), XmlValue.class))) { schemaRef.setType(XMLSchemaReference.SIMPLE_TYPE); } desc.setSchemaReference(schemaRef); } /** * Generate a mapping for a given Property. * * @param property * @param descriptor * @param namespaceInfo * @return newly created mapping */ public Mapping generateMapping(Property property, Descriptor descriptor, JavaClass descriptorJavaClass, NamespaceInfo namespaceInfo) { if (property.isSetXmlJavaTypeAdapter()) { // if we are dealing with a reference, generate mapping and return if (property.isReference()) { return generateMappingForReferenceProperty(property, descriptor, namespaceInfo); } XmlJavaTypeAdapter xja = property.getXmlJavaTypeAdapter(); JavaClass adapterClass = helper.getJavaClass(xja.getValue()); JavaClass valueType = null; String sValType = xja.getValueType(); if (sValType.equals("javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT")) { valueType = property.getActualType(); } else { valueType = helper.getJavaClass(xja.getValueType()); } Mapping mapping; boolean isArray = property.getType().isArray() && !property.getType().getRawName().equals("byte[]"); // if the value type is something we have a descriptor for, create // a composite mapping if(property.isChoice()) { if(helper.isCollectionType(property.getType()) || property.getType().isArray()) { mapping = generateChoiceCollectionMapping(property, descriptor, namespaceInfo); ((ChoiceCollectionMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } else { mapping = generateChoiceMapping(property, descriptor, namespaceInfo); ((ChoiceObjectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } } else if (typeInfo.containsKey(valueType.getQualifiedName())) { TypeInfo reference = typeInfo.get(valueType.getQualifiedName()); if (helper.isCollectionType(property.getType())) { if (reference.isEnumerationType()) { mapping = generateEnumCollectionMapping(property, descriptor, namespaceInfo, (EnumTypeInfo) reference); XMLJavaTypeConverter converter = new XMLJavaTypeConverter(adapterClass.getQualifiedName()); converter.setNestedConverter(((DirectCollectionMapping)mapping).getValueConverter()); ((DirectCollectionMapping)mapping).setValueConverter(converter); } else { if(property.getVariableAttributeName() !=null){ mapping = generateVariableXPathCollectionMapping(property, descriptor, namespaceInfo, valueType); ((VariableXPathCollectionMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); }else{ mapping = generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, valueType.getQualifiedName()); ((CompositeCollectionMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } } } else { if (reference.isEnumerationType()) { mapping = generateDirectEnumerationMapping(property, descriptor, namespaceInfo, (EnumTypeInfo) reference); XMLJavaTypeConverter converter = new XMLJavaTypeConverter(adapterClass.getQualifiedName()); converter.setNestedConverter(((DirectMapping)mapping).getConverter()); ((DirectMapping)mapping).setConverter(converter); } else if (property.isInverseReference()) { mapping = generateInverseReferenceMapping(property, descriptor, namespaceInfo); } else { if(property.getVariableAttributeName() !=null){ mapping = generateVariableXPathObjectMapping(property, descriptor, namespaceInfo, valueType); ((VariableXPathObjectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); }else{ mapping = generateCompositeObjectMapping(property, descriptor, namespaceInfo, valueType.getQualifiedName()); ((CompositeObjectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } } } } else { // no descriptor for value type if (property.isAny()) { if (helper.isCollectionType(property.getType())){ mapping = generateAnyCollectionMapping(property, descriptor, namespaceInfo, property.isMixedContent()); ((AnyCollectionMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } else { mapping = generateAnyObjectMapping(property, descriptor, namespaceInfo); ((AnyObjectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } } else if (helper.isCollectionType(property.getType()) || isArray) { if (property.isSwaAttachmentRef() || property.isMtomAttachment()) { mapping = generateBinaryDataCollectionMapping(property, descriptor, namespaceInfo); ((BinaryDataCollectionMapping) mapping).setValueConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } else{ mapping = generateDirectCollectionMapping(property, descriptor, namespaceInfo); if(adapterClass.getQualifiedName().equals(CollapsedStringAdapter.class.getName())) { ((DirectCollectionMapping)mapping).setCollapsingStringValues(true); } else if(adapterClass.getQualifiedName().equals(NormalizedStringAdapter.class.getName())) { ((DirectCollectionMapping)mapping).setNormalizingStringValues(true); } else { ((DirectCollectionMapping) mapping).setValueConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } } } else if (property.isSwaAttachmentRef() || property.isMtomAttachment()) { mapping = generateBinaryMapping(property, descriptor, namespaceInfo); ((BinaryDataMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } else { if (!property.isAttribute() && areEquals(valueType, Object.class) || property.isTyped()){ mapping = generateCompositeObjectMapping(property, descriptor, namespaceInfo, null); ((CompositeObjectMapping)mapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); ((CompositeObjectMapping)mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); return mapping; } mapping = generateDirectMapping(property, descriptor, namespaceInfo); if(adapterClass.getQualifiedName().equals(CollapsedStringAdapter.class.getName())) { ((DirectMapping)mapping).setCollapsingStringValues(true); } else if(adapterClass.getQualifiedName().equals(NormalizedStringAdapter.class.getName())) { ((DirectMapping)mapping).setNormalizingStringValues(true); } else { ((DirectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } } } return mapping; } if (property.getVariableAttributeName() != null){ if (helper.isCollectionType(property.getType()) || property.getType().isArray() || property.isMap()){ return generateVariableXPathCollectionMapping(property, descriptor, namespaceInfo, property.getActualType()); }else{ return generateVariableXPathObjectMapping(property, descriptor, namespaceInfo, property.getActualType()); } } if (property.isSetXmlJoinNodes()) { if (helper.isCollectionType(property.getType())) { return generateXMLCollectionReferenceMapping(property, descriptor, namespaceInfo, property.getActualType()); } return generateXMLObjectReferenceMapping(property, descriptor, namespaceInfo, property.getType()); } if (property.isXmlTransformation()) { return generateTransformationMapping(property, descriptor, namespaceInfo); } if (property.isChoice()) { if (helper.isCollectionType(property.getType()) || property.getType().isArray()) { return generateChoiceCollectionMapping(property, descriptor, namespaceInfo); } return generateChoiceMapping(property, descriptor, namespaceInfo); } if (property.isInverseReference()) { return generateInverseReferenceMapping(property, descriptor, namespaceInfo); } if (property.isReference()) { return generateMappingForReferenceProperty(property, descriptor, namespaceInfo); } if (property.isAny()) { if (helper.isCollectionType(property.getType()) || property.getType().isArray()){ return generateAnyCollectionMapping(property, descriptor, namespaceInfo, property.isMixedContent()); } return generateAnyObjectMapping(property, descriptor, namespaceInfo); } if (property.isMap()){ if (property.isAnyAttribute()) { return generateAnyAttributeMapping(property, descriptor, namespaceInfo); } return generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, null); } if (helper.isCollectionType(property.getType())) { return generateCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo); } JavaClass referenceClass = property.getType(); String referenceClassName = referenceClass.getRawName(); if (referenceClass.isArray() && !referenceClassName.equals("byte[]")){ JavaClass componentType = referenceClass.getComponentType(); TypeInfo reference = typeInfo.get(componentType.getName()); if (reference != null && reference.isEnumerationType()) { return generateEnumCollectionMapping(property, descriptor, namespaceInfo,(EnumTypeInfo) reference); } if (areEquals(componentType, Object.class)){ CompositeCollectionMapping mapping = generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, null); mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); return mapping; } if (reference != null || componentType.isArray()){ if (property.isXmlIdRef() || property.isSetXmlJoinNodes()) { return generateXMLCollectionReferenceMapping(property, descriptor, namespaceInfo, componentType); } return generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, componentType.getQualifiedName()); } return generateDirectCollectionMapping(property, descriptor, namespaceInfo); } if (property.isXmlIdRef()) { return generateXMLObjectReferenceMapping(property, descriptor, namespaceInfo, referenceClass); } TypeInfo reference = typeInfo.get(referenceClass.getQualifiedName()); if (reference != null) { if (reference.isEnumerationType()) { return generateDirectEnumerationMapping(property, descriptor, namespaceInfo, (EnumTypeInfo) reference); } if (property.isXmlLocation()) { CompositeObjectMapping locationMapping = generateCompositeObjectMapping(property, descriptor, namespaceInfo, referenceClass.getQualifiedName()); reference.getDescriptor().setInstantiationPolicy(new NullInstantiationPolicy()); descriptor.setLocationAccessor(locationMapping.getAttributeAccessor()); return locationMapping; } else { return generateCompositeObjectMapping(property, descriptor, namespaceInfo, referenceClass.getQualifiedName()); } } if (property.isSwaAttachmentRef() || property.isMtomAttachment()) { return generateBinaryMapping(property, descriptor, namespaceInfo); } if (referenceClass.getQualifiedName().equals(OBJECT_CLASS_NAME) && !property.isAttribute() || property.isTyped() ) { CompositeObjectMapping coMapping = generateCompositeObjectMapping(property, descriptor, namespaceInfo, null); coMapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); return coMapping; } if (property.isXmlLocation()) { return null; } return generateDirectMapping(property, descriptor, namespaceInfo); } private Mapping generateVariableXPathCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, JavaClass actualType) { XMLVariableXPathCollectionMapping mapping = new XMLVariableXPathCollectionMapping(); mapping.setAttributeName(property.getPropertyName()); if(property.isMap()){ actualType = property.getValueType(); } initializeXMLContainerMapping(mapping, property.getType().isArray()); initializeXMLMapping(mapping, property); initializeVariableXPathMapping(mapping, property, actualType); if (property.getXmlPath() != null) { mapping.setField(new XMLField(property.getXmlPath())); } else { if (property.isSetXmlElementWrapper()) { mapping.setField((XMLField)getXPathForField(property, namespaceInfo, false, true)); } } if (property.isSetXmlElementWrapper()) { mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property)); } JavaClass collectionType = property.getType(); if (collectionType.isArray()){ JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader()); JavaClass componentType = collectionType.getComponentType(); if(componentType.isArray()) { JavaClass baseComponentType = getBaseComponentType(componentType); if (baseComponentType.isPrimitive()){ Class primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName()); accessor.setComponentClass(primitiveClass); } else { accessor.setComponentClassName(baseComponentType.getQualifiedName()); } } else { accessor.setComponentClassName(componentType.getQualifiedName()); } mapping.setAttributeAccessor(accessor); } if(property.isMap()){ JavaClass mapType = property.getType(); if(mapType.isInterface()){ mapping.useMapClass("java.util.HashMap"); }else{ mapping.useMapClass(property.getType().getName()); } }else{ collectionType = containerClassImpl(collectionType); mapping.useCollectionClass(helper.getClassForJavaClass(collectionType)); } return mapping; } private Mapping generateVariableXPathObjectMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, JavaClass actualType) { XMLVariableXPathObjectMapping mapping = new XMLVariableXPathObjectMapping(); initializeXMLMapping(mapping, property); initializeVariableXPathMapping(mapping, property, actualType); // handle null policy set via xml metadata if (property.isSetNullPolicy()) { mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo))); } else { NullPolicy nullPolicy = (NullPolicy) mapping.getNullPolicy(); nullPolicy.setSetPerformedForAbsentNode(false); if(property.isNillable()) { nullPolicy.setNullRepresentedByXsiNil(true); nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } } if (property.getXmlPath() != null) { mapping.setField(new XMLField(property.getXmlPath())); } else { if (property.isSetXmlElementWrapper()) { mapping.setField((XMLField)getXPathForField(property, namespaceInfo, false, true)); } } return mapping; } private void initializeVariableXPathMapping(VariableXPathObjectMapping mapping, Property property, JavaClass actualType){ String variableAttributeName = property.getVariableAttributeName(); TypeInfo refInfo = typeInfo.get(actualType.getName()); if(refInfo == null){ throw JAXBException.unknownTypeForVariableNode(actualType.getName()); } Property refProperty = refInfo.getProperties().get(variableAttributeName); while(refProperty == null){ JavaClass superClass = CompilerHelper.getNextMappedSuperClass(actualType, typeInfo, helper); if (superClass != null){ refInfo = typeInfo.get(superClass.getName()); refProperty = refInfo.getProperties().get(variableAttributeName); }else{ break; } } if(refProperty == null){ throw JAXBException.unknownPropertyForVariableNode(variableAttributeName, actualType.getName()); } String refPropertyType = refProperty.getActualType().getQualifiedName(); if(!(refPropertyType.equals("java.lang.String") || refPropertyType.equals("javax.xml.namespace.QName"))){ throw JAXBException.invalidTypeForVariableNode(variableAttributeName, refPropertyType, actualType.getName()); } if (refProperty.isMethodProperty()) { if (refProperty.getGetMethodName() == null) { // handle case of set with no get method String paramTypeAsString = refProperty.getType().getName(); JAXBSetMethodAttributeAccessor accessor = new JAXBSetMethodAttributeAccessor(paramTypeAsString, helper.getClassLoader()); accessor.setIsReadOnly(true); accessor.setSetMethodName(refProperty.getSetMethodName()); mapping.setIsReadOnly(true); accessor.setAttributeName("thingBLAH"); mapping.setVariableAttributeAccessor(accessor); } else if (refProperty.getSetMethodName() == null) { mapping.setVariableGetMethodName(refProperty.getGetMethodName()); } else { mapping.setVariableGetMethodName(refProperty.getGetMethodName()); mapping.setVariableSetMethodName(refProperty.getSetMethodName()); } }else{ mapping.setVariableAttributeName(property.getVariableAttributeName()); } if(property.getVariableClassName() != null){ mapping.setReferenceClassName(property.getVariableClassName()); }else{ mapping.setReferenceClassName(actualType.getQualifiedName()); } mapping.setAttribute(property.isVariableNodeAttribute()); } private InverseReferenceMapping generateInverseReferenceMapping(Property property, Descriptor descriptor, NamespaceInfo namespace) { InverseReferenceMapping invMapping = new XMLInverseReferenceMapping(); boolean isCollection = helper.isCollectionType(property.getType()); if (isCollection) { invMapping.setReferenceClassName(property.getGenericType().getQualifiedName()); } else { invMapping.setReferenceClassName(property.getType().getQualifiedName()); } invMapping.setAttributeName(property.getPropertyName()); String setMethodName = property.getInverseReferencePropertySetMethodName(); String getMethodName = property.getInverseReferencePropertyGetMethodName(); if (setMethodName != null && !setMethodName.equals(Constants.EMPTY_STRING)) { invMapping.setSetMethodName(setMethodName); } if (getMethodName != null && !getMethodName.equals(Constants.EMPTY_STRING)) { invMapping.setGetMethodName(getMethodName); } invMapping.setMappedBy(property.getInverseReferencePropertyName()); if (isCollection) { JavaClass collectionType = property.getType(); collectionType = containerClassImpl(collectionType); invMapping.useCollectionClass(org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(collectionType.getQualifiedName(), helper.getClassLoader())); } if(property.isWriteableInverseReference()){ if(isCollection){ JavaClass descriptorClass = helper.getJavaClass(descriptor.getJavaClassName()); invMapping.setInlineMapping((XMLCompositeCollectionMapping)generateCompositeCollectionMapping(property, descriptor, descriptorClass, namespace, invMapping.getReferenceClassName())); }else{ invMapping.setInlineMapping((XMLCompositeObjectMapping)generateCompositeObjectMapping(property, descriptor, namespace, invMapping.getReferenceClassName())); } } return invMapping; } /** * Generate an XMLTransformationMapping based on a given Property. * * @param property * @param descriptor * @param namespace * @return */ public TransformationMapping generateTransformationMapping(Property property, Descriptor descriptor, NamespaceInfo namespace) { TransformationMapping mapping = new XMLTransformationMapping(); if (property.isMethodProperty()) { if (property.getGetMethodName() == null) { // handle case of set with no get method String paramTypeAsString = property.getType().getName(); mapping.setAttributeAccessor(new JAXBSetMethodAttributeAccessor(paramTypeAsString, helper.getClassLoader())); mapping.setSetMethodName(property.getSetMethodName()); } else if (property.getSetMethodName() == null) { mapping.setGetMethodName(property.getGetMethodName()); } else { mapping.setSetMethodName(property.getSetMethodName()); mapping.setGetMethodName(property.getGetMethodName()); } } // handle transformation if (property.isSetXmlTransformation()) { XmlTransformation xmlTransformation = property.getXmlTransformation(); mapping.setIsOptional(xmlTransformation.isOptional()); // handle transformer(s) if (xmlTransformation.isSetXmlReadTransformer()) { // handle read transformer mapping.setAttributeName(property.getPropertyName()); XmlReadTransformer readTransformer = xmlTransformation.getXmlReadTransformer(); if (readTransformer.isSetTransformerClass()) { mapping.setAttributeTransformerClassName(xmlTransformation.getXmlReadTransformer().getTransformerClass()); } else { mapping.setAttributeTransformation(xmlTransformation.getXmlReadTransformer().getMethod()); } } if (xmlTransformation.isSetXmlWriteTransformers()) { // handle write transformer(s) for (XmlWriteTransformer writeTransformer : xmlTransformation.getXmlWriteTransformer()) { if (writeTransformer.isSetTransformerClass()) { mapping.addFieldTransformerClassName(writeTransformer.getXmlPath(), writeTransformer.getTransformerClass()); } else { mapping.addFieldTransformation(writeTransformer.getXmlPath(), writeTransformer.getMethod()); } } } } return mapping; } public ChoiceObjectMapping generateChoiceMapping(Property property, Descriptor descriptor, NamespaceInfo namespace) { ChoiceObjectMapping mapping = new XMLChoiceObjectMapping(); initializeXMLMapping((XMLChoiceObjectMapping)mapping, property); boolean isIdRef = property.isXmlIdRef(); Iterator choiceProperties = property.getChoiceProperties().iterator(); while (choiceProperties.hasNext()) { Property next = choiceProperties.next(); JavaClass type = next.getType(); JavaClass originalType = next.getType(); Converter converter = null; TypeInfo info = typeInfo.get(type.getName()); if(info != null){ XmlJavaTypeAdapter adapter = info.getXmlJavaTypeAdapter(); if(adapter != null){ String adapterValue = adapter.getValue(); JavaClass adapterClass = helper.getJavaClass(adapterValue); JavaClass theClass = CompilerHelper.getTypeFromAdapterClass(adapterClass, helper); type = theClass; converter = new XMLJavaTypeConverter(adapterClass.getQualifiedName()); } } if (next.getXmlJoinNodes() != null) { // handle XmlJoinNodes List srcFlds = new ArrayList(); List tgtFlds = new ArrayList(); for (XmlJoinNode xmlJoinNode: next.getXmlJoinNodes().getXmlJoinNode()) { srcFlds.add(new XMLField(xmlJoinNode.getXmlPath())); tgtFlds.add(new XMLField(xmlJoinNode.getReferencedXmlPath())); } mapping.addChoiceElement(srcFlds, type.getQualifiedName(), tgtFlds); } else if (isIdRef) { // handle IDREF String tgtXPath = null; TypeInfo referenceType = typeInfo.get(type.getQualifiedName()); if (null != referenceType && referenceType.isIDSet()) { Property prop = referenceType.getIDProperty(); tgtXPath = getXPathForField(prop, namespace, !prop.isAttribute(), false).getXPath(); } // if the XPath is set (via xml-path) use it, otherwise figure it out Field srcXPath; if (next.getXmlPath() != null) { srcXPath = new XMLField(next.getXmlPath()); } else { srcXPath = getXPathForField(next, namespace, true, false); } mapping.addChoiceElement(srcXPath.getXPath(), type.getQualifiedName(), tgtXPath); } else { Field xpath; if (next.getXmlPath() != null) { xpath = new XMLField(next.getXmlPath()); } else { xpath = getXPathForField(next, namespace, (!(this.typeInfo.containsKey(type.getQualifiedName()))) || next.isMtomAttachment() || type.isEnum(), false); } mapping.addChoiceElement(xpath, type.getQualifiedName()); if(!originalType.getQualifiedName().equals(type.getQualifiedName())) { if(mapping.getClassNameToFieldMappings().get(originalType.getQualifiedName()) == null) { mapping.getClassNameToFieldMappings().put(originalType.getQualifiedName(), xpath); } mapping.addConverter(xpath, converter); } Mapping nestedMapping = (Mapping) mapping.getChoiceElementMappings().get(xpath); if(nestedMapping instanceof BinaryDataMapping){ ((BinaryDataMapping)nestedMapping).getNullPolicy().setNullRepresentedByEmptyNode(false); } if (type.isEnum()) { if(nestedMapping.isAbstractDirectMapping()) { ((DirectMapping)nestedMapping).setConverter(buildJAXBEnumTypeConverter(nestedMapping, (EnumTypeInfo)info)); } } } } return mapping; } public ChoiceCollectionMapping generateChoiceCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespace) { ChoiceCollectionMapping mapping = new XMLChoiceCollectionMapping(); initializeXMLContainerMapping(mapping, property.getType().isArray()); initializeXMLMapping((XMLChoiceCollectionMapping)mapping, property); JavaClass collectionType = property.getType(); if (collectionType.isArray()){ JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader()); JavaClass componentType = collectionType.getComponentType(); if(componentType.isArray()) { JavaClass baseComponentType = getBaseComponentType(componentType); if (baseComponentType.isPrimitive()){ Class primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName()); accessor.setComponentClass(primitiveClass); } else { accessor.setComponentClassName(baseComponentType.getQualifiedName()); } } else { accessor.setComponentClassName(componentType.getQualifiedName()); } mapping.setAttributeAccessor(accessor); } collectionType = containerClassImpl(collectionType); mapping.useCollectionClassName(collectionType.getRawName()); if (property.isSetXmlElementWrapper()) { mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property)); } boolean isIdRef = property.isXmlIdRef(); Iterator choiceProperties = property.getChoiceProperties().iterator(); while (choiceProperties.hasNext()) { Property next = choiceProperties.next(); JavaClass type = next.getType(); JavaClass originalType = next.getType(); Converter converter = null; Field xmlField = null; TypeInfo info = typeInfo.get(type.getName()); if(info != null){ XmlJavaTypeAdapter adapter = info.getXmlJavaTypeAdapter(); if(adapter != null){ String adapterValue = adapter.getValue(); JavaClass adapterClass = helper.getJavaClass(adapterValue); JavaClass theClass = CompilerHelper.getTypeFromAdapterClass(adapterClass, helper); type = theClass; converter = new XMLJavaTypeConverter(adapterClass.getQualifiedName()); } } if (next.getXmlJoinNodes() != null) { // handle XmlJoinNodes List srcFlds = new ArrayList(); List tgtFlds = new ArrayList(); for (XmlJoinNode xmlJoinNode: next.getXmlJoinNodes().getXmlJoinNode()) { srcFlds.add(new XMLField(xmlJoinNode.getXmlPath())); tgtFlds.add(new XMLField(xmlJoinNode.getReferencedXmlPath())); } mapping.addChoiceElement(srcFlds, type.getQualifiedName(), tgtFlds); } else if (isIdRef) { // handle IDREF String tgtXPath = null; TypeInfo referenceType = typeInfo.get(type.getQualifiedName()); if (null != referenceType && referenceType.isIDSet()) { Property prop = referenceType.getIDProperty(); tgtXPath = getXPathForField(prop, namespace, !prop.isAttribute(), false).getXPath(); } // if the XPath is set (via xml-path) use it, otherwise figure it out Field srcXPath; if (next.getXmlPath() != null) { srcXPath = new XMLField(next.getXmlPath()); } else { srcXPath = getXPathForField(next, namespace, true, false); } mapping.addChoiceElement(srcXPath.getXPath(), type.getQualifiedName(), tgtXPath); } else { Field xpath; if (next.getXmlPath() != null) { xpath = new XMLField(next.getXmlPath()); } else { xpath = getXPathForField(next, namespace, (!(this.typeInfo.containsKey(type.getQualifiedName()))) || type.isEnum(), false); } xmlField = xpath; mapping.addChoiceElement(xpath.getName(), type.getQualifiedName()); if(!originalType.getQualifiedName().equals(type.getQualifiedName())) { if(mapping.getClassNameToFieldMappings().get(originalType.getQualifiedName()) == null) { mapping.getClassNameToFieldMappings().put(originalType.getQualifiedName(), xpath); } mapping.addConverter(xpath, converter); } } if(xmlField !=null){ Mapping nestedMapping = (Mapping) mapping.getChoiceElementMappings().get(xmlField); if(nestedMapping.isAbstractCompositeCollectionMapping()){ //handle null policy set via xml metadata if (property.isSetNullPolicy()) { ((CompositeCollectionMapping)nestedMapping).setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespace))); } else if (next.isNillable() && property.isNillable()){ ((CompositeCollectionMapping)nestedMapping).getNullPolicy().setNullRepresentedByXsiNil(true); ((CompositeCollectionMapping)nestedMapping).getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } } else if(nestedMapping.isAbstractCompositeDirectCollectionMapping()){ if (next.isSetNullPolicy()) { ((DirectCollectionMapping)nestedMapping).setNullPolicy(getNullPolicyFromProperty(next, getNamespaceResolverForDescriptor(namespace))); } else if (next.isNillable() && property.isNillable()){ ((DirectCollectionMapping)nestedMapping).getNullPolicy().setNullRepresentedByXsiNil(true); ((DirectCollectionMapping)nestedMapping).getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } ((DirectCollectionMapping)nestedMapping).getNullPolicy().setNullRepresentedByEmptyNode(false); if (type.isEnum()) { ((DirectCollectionMapping)nestedMapping).setValueConverter(buildJAXBEnumTypeConverter(nestedMapping, (EnumTypeInfo)info)); } } else if(nestedMapping instanceof BinaryDataCollectionMapping){ if (next.isSetNullPolicy()) { ((BinaryDataCollectionMapping)nestedMapping).setNullPolicy(getNullPolicyFromProperty(next, getNamespaceResolverForDescriptor(namespace))); } else if (next.isNillable() && property.isNillable()){ ((BinaryDataCollectionMapping)nestedMapping).getNullPolicy().setNullRepresentedByXsiNil(true); ((BinaryDataCollectionMapping)nestedMapping).getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } } } } return mapping; } public Mapping generateMappingForReferenceProperty(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) { boolean isCollection = helper.isCollectionType(property.getType()) || property.getType().isArray(); Mapping mapping; if (isCollection) { mapping = new XMLChoiceCollectionMapping(); initializeXMLContainerMapping((ChoiceCollectionMapping) mapping, property.getType().isArray()); JavaClass collectionType = property.getType(); collectionType = containerClassImpl(collectionType); ((ChoiceCollectionMapping) mapping).useCollectionClassName(collectionType.getRawName()); JAXBElementRootConverter jaxbERConverter = new JAXBElementRootConverter(Object.class); if (property.isSetXmlJavaTypeAdapter()) { JavaClass adapterClass = helper.getJavaClass(property.getXmlJavaTypeAdapter().getValue()); jaxbERConverter.setNestedConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } ((ChoiceCollectionMapping) mapping).setConverter(jaxbERConverter); if (property.isSetWriteOnly()) { ((ChoiceCollectionMapping) mapping).setIsWriteOnly(property.isWriteOnly()); } if (property.isSetXmlElementWrapper()) { ((ChoiceCollectionMapping) mapping).setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property)); } } else { mapping = new XMLChoiceObjectMapping(); JAXBElementRootConverter jaxbERConverter = new JAXBElementRootConverter(Object.class); if (property.isSetXmlJavaTypeAdapter()) { JavaClass adapterClass = helper.getJavaClass(property.getXmlJavaTypeAdapter().getValue()); jaxbERConverter.setNestedConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName())); } ((ChoiceObjectMapping) mapping).setConverter(jaxbERConverter); if (property.isSetWriteOnly()) { ((ChoiceObjectMapping) mapping).setIsWriteOnly(property.isWriteOnly()); } } initializeXMLMapping((XMLMapping)mapping, property); List referencedElements = property.getReferencedElements(); JavaClass propertyType = property.getType(); if (propertyType.isArray()) { JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader()); accessor.setComponentClassName(property.getType().getComponentType().getQualifiedName()); JavaClass componentType = propertyType.getComponentType(); if(componentType.isArray()) { Class adaptedClass = classToGeneratedClasses.get(componentType.getQualifiedName()); accessor.setAdaptedClassName(adaptedClass.getName()); } mapping.setAttributeAccessor(accessor); } String wrapperXPath = ""; // handle XmlElementWrapper if (property.isSetXmlElementWrapper()) { XmlElementWrapper wrapper = property.getXmlElementWrapper(); String namespace = wrapper.getNamespace(); if (namespace.equals(XMLProcessor.DEFAULT)) { if (namespaceInfo.isElementFormQualified()) { namespace = namespaceInfo.getNamespace(); } else { namespace = ""; } } if (namespace.equals("")) { wrapperXPath += (wrapper.getName() + "/"); } else { String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(namespaceInfo)); wrapperXPath += getQualifiedString(prefix, wrapper.getName() + "/"); } } if(property.isMixedContent() && isCollection) { if(wrapperXPath.length() == 0) { ((ChoiceCollectionMapping)mapping).setMixedContent(true); } else { ((ChoiceCollectionMapping)mapping).setMixedContent(wrapperXPath.substring(0, wrapperXPath.length() - 1)); } } for (ElementDeclaration element:referencedElements) { QName elementName = element.getElementName(); JavaClass pType = element.getJavaType(); String pTypeName = element.getJavaTypeName(); boolean isBinaryType = (areEquals(pType, AnnotationsProcessor.JAVAX_ACTIVATION_DATAHANDLER) || areEquals(pType, byte[].class) || areEquals(pType, Image.class) || areEquals(pType, Source.class) || areEquals(pType, AnnotationsProcessor.JAVAX_MAIL_INTERNET_MIMEMULTIPART)); boolean isText = pType.isEnum() || (!isBinaryType && !(this.typeInfo.containsKey(element.getJavaTypeName())) && !(element.getJavaTypeName().equals(OBJECT_CLASS_NAME))); String xPath = wrapperXPath; Field xmlField = this.getXPathForElement(xPath, elementName, namespaceInfo, isText); //ensure byte[] goes to base64 instead of the default hex. if(helper.getXMLToJavaTypeMap().get(pType.getRawName()) == Constants.BASE_64_BINARY_QNAME) { xmlField.setSchemaType(Constants.BASE_64_BINARY_QNAME); } if(areEquals(pType, Object.class)) { setTypedTextField(xmlField); } Mapping nestedMapping; AbstractNullPolicy nullPolicy = null; if(isCollection){ ChoiceCollectionMapping xmlChoiceCollectionMapping = (ChoiceCollectionMapping) mapping; xmlChoiceCollectionMapping.addChoiceElement(xmlField, pTypeName); nestedMapping = (Mapping) xmlChoiceCollectionMapping.getChoiceElementMappings().get(xmlField); if(nestedMapping.isAbstractCompositeCollectionMapping()){ ((CompositeCollectionMapping)nestedMapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); nullPolicy = ((CompositeCollectionMapping)nestedMapping).getNullPolicy(); } if (nestedMapping.isAbstractCompositeDirectCollectionMapping()) { DirectCollectionMapping nestedCompositeDirectCollectionMapping = (DirectCollectionMapping) nestedMapping; nullPolicy = nestedCompositeDirectCollectionMapping.getNullPolicy(); if(pType.isEnum()) { TypeInfo enumTypeInfo = typeInfo.get(pType.getQualifiedName()); nestedCompositeDirectCollectionMapping.setValueConverter(buildJAXBEnumTypeConverter(nestedCompositeDirectCollectionMapping, (EnumTypeInfo) enumTypeInfo)); } if(element.isList()){ XMLListConverter listConverter = new XMLListConverter(); listConverter.setObjectClassName(pType.getQualifiedName()); ((DirectCollectionMapping)nestedMapping).setValueConverter(listConverter); } }else if(nestedMapping instanceof BinaryDataCollectionMapping){ nullPolicy = ((BinaryDataCollectionMapping)nestedMapping).getNullPolicy(); if(element.isList()){ ((XMLField)((BinaryDataCollectionMapping)nestedMapping).getField()).setUsesSingleNode(true); } } } else { ChoiceObjectMapping xmlChoiceObjectMapping = (ChoiceObjectMapping) mapping; xmlChoiceObjectMapping.addChoiceElement(xmlField, pTypeName); nestedMapping = (Mapping) xmlChoiceObjectMapping.getChoiceElementMappings().get(xmlField); if(pType.isEnum()) { TypeInfo enumTypeInfo = typeInfo.get(pType.getQualifiedName()); ((DirectMapping)nestedMapping).setConverter(buildJAXBEnumTypeConverter(nestedMapping, (EnumTypeInfo) enumTypeInfo)); } if(nestedMapping.isAbstractCompositeObjectMapping()){ ((CompositeObjectMapping)nestedMapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); nullPolicy = ((CompositeObjectMapping)nestedMapping).getNullPolicy(); }else if(nestedMapping instanceof BinaryDataMapping){ nullPolicy = ((BinaryDataMapping)nestedMapping).getNullPolicy(); }else if(nestedMapping instanceof DirectMapping){ nullPolicy = ((DirectMapping)nestedMapping).getNullPolicy(); } } if(nullPolicy != null){ nullPolicy.setNullRepresentedByEmptyNode(false); nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); nullPolicy.setNullRepresentedByXsiNil(true); nullPolicy.setIgnoreAttributesForNil(false); } if (!element.isXmlRootElement()) { Class scopeClass = element.getScopeClass(); if (scopeClass == javax.xml.bind.annotation.XmlElementDecl.GLOBAL.class){ scopeClass = JAXBElement.GlobalScope.class; } Class declaredType = null; if(element.getAdaptedJavaType() != null){ declaredType = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(element.getAdaptedJavaType().getQualifiedName(), helper.getClassLoader()); }else{ declaredType = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(pType.getQualifiedName(), helper.getClassLoader()); } JAXBElementConverter converter = new JAXBElementConverter(xmlField, declaredType, scopeClass); if (isCollection){ ChoiceCollectionMapping xmlChoiceCollectionMapping = (ChoiceCollectionMapping) mapping; if(element.getJavaTypeAdapterClass() != null){ converter.setNestedConverter(new XMLJavaTypeConverter(element.getJavaTypeAdapterClass().getName())); }else{ CoreConverter originalConverter = xmlChoiceCollectionMapping.getConverter(xmlField); converter.setNestedConverter(originalConverter); } xmlChoiceCollectionMapping.addConverter(xmlField, converter); } else { ChoiceObjectMapping xmlChoiceObjectMapping = (ChoiceObjectMapping) mapping; if(element.getJavaTypeAdapterClass() != null){ converter.setNestedConverter(new XMLJavaTypeConverter(element.getJavaTypeAdapterClass().getName())); }else{ CoreConverter originalConverter = xmlChoiceObjectMapping.getConverter(xmlField); converter.setNestedConverter(originalConverter); } xmlChoiceObjectMapping.addConverter(xmlField, converter); } } } if(property.isAny()){ if(isCollection){ XMLChoiceCollectionMapping xmlChoiceCollectionMapping = (XMLChoiceCollectionMapping) mapping; xmlChoiceCollectionMapping.setIsAny(true); } } return mapping; } private void setTypedTextField(Field field){ field.setIsTypedTextField(true); if(field.getSchemaType() == null){ field.setSchemaType(Constants.ANY_TYPE_QNAME); } ((XMLField)field).addXMLConversion(Constants.DATE_TIME_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR); ((XMLField)field).addXMLConversion(Constants.DATE_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR); ((XMLField)field).addXMLConversion(Constants.TIME_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR); ((XMLField)field).addJavaConversion(CoreClassConstants.APBYTE, Constants.BASE_64_BINARY_QNAME); ((XMLField)field).addJavaConversion(CoreClassConstants.ABYTE, Constants.BASE_64_BINARY_QNAME); } public AnyCollectionMapping generateAnyCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, boolean isMixed) { AnyCollectionMapping mapping = new XMLAnyCollectionMapping(); initializeXMLContainerMapping(mapping, property.getType().isArray()); initializeXMLMapping((XMLMapping)mapping, property); // if the XPath is set (via xml-path) use it if (property.getXmlPath() != null) { mapping.setField(new XMLField(property.getXmlPath())); } else { if (property.isSetXmlElementWrapper()) { mapping.setField(getXPathForField(property, namespaceInfo, false, true)); } } if (property.isSetXmlElementWrapper()) { mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property)); } Class declaredType = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(property.getActualType().getQualifiedName(), helper.getClassLoader()); JAXBElementRootConverter jaxbElementRootConverter = new JAXBElementRootConverter(declaredType); mapping.setConverter(jaxbElementRootConverter); if (property.getDomHandlerClassName() != null) { jaxbElementRootConverter.setNestedConverter(new DomHandlerConverter(property.getDomHandlerClassName())); } if (property.isLax() || property.isReference()) { mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); } else { if (property.isAny()) { mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT); } else { mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_NONE_AS_ELEMENT); } } mapping.setMixedContent(isMixed); if (isMixed) { mapping.setPreserveWhitespaceForMixedContent(true); } if (property.isAny()) { mapping.setUseXMLRoot(true); } JavaClass collectionType = property.getType(); if (collectionType.isArray()){ JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader()); JavaClass componentType = collectionType.getComponentType(); if(componentType.isArray()) { JavaClass baseComponentType = getBaseComponentType(componentType); if (baseComponentType.isPrimitive()){ Class primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName()); accessor.setComponentClass(primitiveClass); } else { accessor.setComponentClassName(baseComponentType.getQualifiedName()); } } else { accessor.setComponentClassName(componentType.getQualifiedName()); } mapping.setAttributeAccessor(accessor); } collectionType = containerClassImpl(collectionType); mapping.useCollectionClass(helper.getClassForJavaClass(collectionType)); return mapping; } public CompositeObjectMapping generateCompositeObjectMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, String referenceClassName) { CompositeObjectMapping mapping = new XMLCompositeObjectMapping(); initializeXMLMapping((XMLMapping)mapping, property); // if the XPath is set (via xml-path) use it; otherwise figure it out mapping.setField(getXPathForField(property, namespaceInfo, false, false)); // handle null policy set via xml metadata if (property.isSetNullPolicy()) { mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo))); } else { NullPolicy nullPolicy = (NullPolicy) mapping.getNullPolicy(); nullPolicy.setSetPerformedForAbsentNode(false); if(property.isNillable()) { nullPolicy.setNullRepresentedByXsiNil(true); nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } } if (referenceClassName == null){ setTypedTextField((Field)mapping.getField()); String defaultValue = property.getDefaultValue(); if (null != defaultValue) { mapping.setConverter(new DefaultElementConverter(defaultValue)); } } else { mapping.setReferenceClassName(referenceClassName); } if(property.isTransientType()){ mapping.setReferenceClassName(Constants.UNKNOWN_OR_TRANSIENT_CLASS); } if (property.isRequired()) { ((Field) mapping.getField()).setRequired(true); } return mapping; } public DirectMapping generateDirectMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) { DirectMapping mapping = new XMLDirectMapping(); mapping.setNullValueMarshalled(true); String fixedValue = property.getFixedValue(); if (fixedValue != null) { mapping.setIsWriteOnly(true); } initializeXMLMapping((XMLMapping)mapping, property); // if the XPath is set (via xml-path) use it; otherwise figure it out Field xmlField = getXPathForField(property, namespaceInfo, true, false); mapping.setField(xmlField); if (property.getDefaultValue() != null) { mapping.setNullValue(property.getDefaultValue()); } if (property.isXmlId()) { mapping.setCollapsingStringValues(true); } // handle null policy set via xml metadata if (property.isSetNullPolicy()) { mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo))); } else { if (property.isNillable()){ mapping.getNullPolicy().setNullRepresentedByXsiNil(true); mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } mapping.getNullPolicy().setNullRepresentedByEmptyNode(false); if (!mapping.getXPath().equals("text()")) { ((NullPolicy) mapping.getNullPolicy()).setSetPerformedForAbsentNode(false); } } if (property.isRequired()) { ((Field) mapping.getField()).setRequired(true); } if (property.getType() != null) { String theClass = null; String targetClass = null; if (property.isSetXmlJavaTypeAdapter()) { theClass = property.getOriginalType().getQualifiedName(); targetClass = property.getType().getQualifiedName(); } else { theClass = property.getType().getQualifiedName(); } // Try to get the actual Class try { JavaClass actualJavaClass = helper.getJavaClass(theClass); Class actualClass = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(actualJavaClass.getQualifiedName(), helper.getClassLoader()); mapping.setAttributeClassification(actualClass); if(targetClass != null) { Class fieldClass = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(targetClass, helper.getClassLoader()); mapping.getField().setType(fieldClass); } } catch (Exception e) { // Couldn't find Class (Dynamic?), so set class name instead. mapping.setAttributeClassificationName(theClass); } } if (Constants.QNAME_QNAME.equals(property.getSchemaType())){ ((Field) mapping.getField()).setSchemaType(Constants.QNAME_QNAME); } // handle cdata set via metadata if (property.isSetCdata()) { mapping.setIsCDATA(property.isCdata()); } return mapping; } public BinaryDataMapping generateBinaryMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) { BinaryDataMapping mapping = new XMLBinaryDataMapping(); initializeXMLMapping((XMLMapping)mapping, property); // if the XPath is set (via xml-path) use it mapping.setField(getXPathForField(property, namespaceInfo, false, false)); if (property.isSwaAttachmentRef()) { ((Field) mapping.getField()).setSchemaType(Constants.SWA_REF_QNAME); mapping.setSwaRef(true); } else if (property.isMtomAttachment()) { Field f = ((Field) mapping.getField()); if (!f.getSchemaType().equals(Constants.HEX_BINARY_QNAME)) { f.setSchemaType(Constants.BASE_64_BINARY_QNAME); } } if (property.isInlineBinaryData()) { mapping.setShouldInlineBinaryData(true); } // use a non-dynamic implementation of MimeTypePolicy to wrap the MIME string if (property.getMimeType() != null) { mapping.setMimeTypePolicy(new FixedMimeTypePolicy(property.getMimeType(),(DatabaseMapping) mapping)); } else { if(areEquals(property.getType(), javax.xml.transform.Source.class)) { mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/xml", (DatabaseMapping)mapping)); } else if(areEquals(property.getType(), java.awt.Image.class)) { mapping.setMimeTypePolicy(new FixedMimeTypePolicy("image/png", (DatabaseMapping)mapping)); } else { mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/octet-stream", (DatabaseMapping)mapping)); } } if (property.isSetNullPolicy()) { mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo))); } else { if (property.isNillable()){ mapping.getNullPolicy().setNullRepresentedByXsiNil(true); mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } mapping.getNullPolicy().setNullRepresentedByEmptyNode(false); if (!mapping.getXPath().equals("text()")) { ((NullPolicy) mapping.getNullPolicy()).setSetPerformedForAbsentNode(false); } } mapping.setAttributeClassificationName(property.getActualType().getQualifiedName()); return mapping; } public BinaryDataCollectionMapping generateBinaryDataCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) { BinaryDataCollectionMapping mapping = new XMLBinaryDataCollectionMapping(); initializeXMLMapping((XMLMapping)mapping, property); initializeXMLContainerMapping(mapping, property.getType().isArray()); if (property.isSetXmlElementWrapper()) { mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property)); } // handle null policy set via xml metadata if (property.isSetNullPolicy()) { mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo))); } else if (property.isNillable()){ mapping.getNullPolicy().setNullRepresentedByXsiNil(true); mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } // if the XPath is set (via xml-path) use it mapping.setField(getXPathForField(property, namespaceInfo, false, false)); if (property.isSwaAttachmentRef()) { ((Field) mapping.getField()).setSchemaType(Constants.SWA_REF_QNAME); mapping.setSwaRef(true); } else if (property.isMtomAttachment()) { Field f = (Field) mapping.getField(); if (!f.getSchemaType().equals(Constants.HEX_BINARY_QNAME)) { f.setSchemaType(Constants.BASE_64_BINARY_QNAME); } } if (property.isInlineBinaryData()) { mapping.setShouldInlineBinaryData(true); } // use a non-dynamic implementation of MimeTypePolicy to wrap the MIME string if (property.getMimeType() != null) { mapping.setMimeTypePolicy(new FixedMimeTypePolicy(property.getMimeType())); } else { if(areEquals(property.getType(), javax.xml.transform.Source.class)) { mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/xml")); } else { mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/octet-stream")); } } JavaClass collectionType = property.getType(); JavaClass itemType = property.getActualType(); if(collectionType != null && helper.isCollectionType(collectionType)){ try{ Class declaredClass = PrivilegedAccessHelper.getClassForName(itemType.getQualifiedName(), false, helper.getClassLoader()); mapping.setAttributeElementClass(declaredClass); }catch (Exception e) { } } collectionType = containerClassImpl(collectionType); mapping.useCollectionClassName(collectionType.getRawName()); return mapping; } public DirectMapping generateDirectEnumerationMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, EnumTypeInfo enumInfo) { DirectMapping mapping = new XMLDirectMapping(); initializeXMLMapping((XMLMapping)mapping, property); mapping.setNullValueMarshalled(true); mapping.setConverter(buildJAXBEnumTypeConverter(mapping, enumInfo)); // handle null policy set via xml metadata if (property.isSetNullPolicy()) { mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo))); } else if (property.isNillable()) { mapping.getNullPolicy().setNullRepresentedByXsiNil(true); mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } mapping.setField(getXPathForField(property, namespaceInfo, true, false)); if (!mapping.getXPath().equals("text()")) { ((NullPolicy) mapping.getNullPolicy()).setSetPerformedForAbsentNode(false); } return mapping; } private JAXBEnumTypeConverter buildJAXBEnumTypeConverter(Mapping mapping, EnumTypeInfo enumInfo){ JAXBEnumTypeConverter converter = new JAXBEnumTypeConverter(mapping, enumInfo.getClassName(), false); List fieldNames = enumInfo.getFieldNames(); List xmlEnumValues = enumInfo.getXmlEnumValues(); for (int i=0; i< fieldNames.size(); i++) { converter.addConversionValue(xmlEnumValues.get(i), fieldNames.get(i)); } return converter; } public Mapping generateCollectionMapping(Property property, Descriptor descriptor, JavaClass descriptorJavaClass, NamespaceInfo namespaceInfo) { // check to see if this should be a composite or direct mapping JavaClass javaClass = property.getActualType(); if (property.isMixedContent()) { return generateAnyCollectionMapping(property, descriptor, namespaceInfo, true); } if (property.isXmlIdRef() || property.isSetXmlJoinNodes()) { return generateXMLCollectionReferenceMapping(property, descriptor, namespaceInfo, javaClass); } if (javaClass != null && typeInfo.get(javaClass.getQualifiedName()) != null) { TypeInfo referenceInfo = typeInfo.get(javaClass.getQualifiedName()); if (referenceInfo.isEnumerationType()) { return generateEnumCollectionMapping(property, descriptor, namespaceInfo,(EnumTypeInfo) referenceInfo); } return generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, javaClass.getQualifiedName()); } if (!property.isAttribute() && javaClass != null && javaClass.getQualifiedName().equals(OBJECT_CLASS_NAME)){ CompositeCollectionMapping ccMapping = generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, null); ccMapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); return ccMapping; } if(isBinaryData(javaClass)){ return generateBinaryDataCollectionMapping(property, descriptor, namespaceInfo); } return generateDirectCollectionMapping(property, descriptor, namespaceInfo); } public DirectCollectionMapping generateEnumCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, EnumTypeInfo info) { DirectCollectionMapping mapping = generateDirectCollectionMapping(property, descriptor, namespaceInfo); mapping.setValueConverter(buildJAXBEnumTypeConverter(mapping, info)); return mapping; } public AnyAttributeMapping generateAnyAttributeMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) { AnyAttributeMapping mapping = new XMLAnyAttributeMapping(); initializeXMLMapping((XMLAnyAttributeMapping)mapping, property); initializeXMLContainerMapping(mapping, property.getType().isArray()); // if the XPath is set (via xml-path) use it if (property.getXmlPath() != null) { mapping.setField(new XMLField(property.getXmlPath())); } mapping.setSchemaInstanceIncluded(false); mapping.setNamespaceDeclarationIncluded(false); JavaClass mapType = property.getType(); if (areEquals(mapType, Map.class)) { mapType = jotHashMap; } mapping.useMapClassName(mapType.getRawName()); return mapping; } public AnyObjectMapping generateAnyObjectMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) { AnyObjectMapping mapping = new XMLAnyObjectMapping(); initializeXMLMapping((XMLMapping)mapping, property); // if the XPath is set (via xml-path) use it if (property.getXmlPath() != null) { mapping.setField(new XMLField(property.getXmlPath())); } Class declaredType = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(property.getActualType().getQualifiedName(), helper.getClassLoader()); JAXBElementRootConverter jaxbElementRootConverter = new JAXBElementRootConverter(declaredType); mapping.setConverter(jaxbElementRootConverter); if (property.getDomHandlerClassName() != null) { jaxbElementRootConverter.setNestedConverter(new DomHandlerConverter(property.getDomHandlerClassName())); } if (property.isLax()) { mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); } else { mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT); } if (property.isMixedContent()) { mapping.setMixedContent(true); } else { mapping.setUseXMLRoot(true); } return mapping; } protected boolean areEquals(JavaClass src, Class tgt) { if (src == null || tgt == null) { return false; } return src.getRawName().equals(tgt.getCanonicalName()); } /** * Compares a JavaModel JavaClass to a Class. Equality is based on * the raw name of the JavaClass compared to the canonical * name of the Class. * * @param src * @param tgtCanonicalName * @return */ protected boolean areEquals(JavaClass src, String tgtCanonicalName) { if (src == null || tgtCanonicalName == null) { return false; } return src.getRawName().equals(tgtCanonicalName); } private Class generateMapEntryClassAndDescriptor(Property property, NamespaceResolver nr){ JavaClass keyType = property.getKeyType(); JavaClass valueType = property.getValueType(); if(keyType == null){ keyType = helper.getJavaClass("java.lang.Object"); } if(valueType == null){ valueType = helper.getJavaClass("java.lang.Object"); } String mapEntryClassName = getJaxbClassLoader().nextAvailableGeneratedClassName(); MapEntryGeneratedKey mapKey = new MapEntryGeneratedKey(keyType.getQualifiedName(),valueType.getQualifiedName()); Class generatedClass = getGeneratedMapEntryClasses().get(mapKey); if(generatedClass == null){ generatedClass = generateMapEntryClass(mapEntryClassName, keyType.getQualifiedName(), valueType.getQualifiedName()); getGeneratedMapEntryClasses().put(mapKey, generatedClass); Descriptor desc = new XMLDescriptor(); desc.setJavaClass(generatedClass); desc.addMapping((CoreMapping)generateMappingForType(keyType, Property.DEFAULT_KEY_NAME)); desc.addMapping((CoreMapping)generateMappingForType(valueType, Property.DEFAULT_VALUE_NAME)); desc.setNamespaceResolver(nr); project.addDescriptor((CoreDescriptor)desc); } return generatedClass; } private Class generateMapEntryClass(String className, String keyType, String valueType){ EclipseLinkASMClassWriter cw = new EclipseLinkASMClassWriter(); String qualifiedInternalClassName = className.replace('.', '/'); String qualifiedInternalKeyClassName = keyType.replace('.', '/'); String qualifiedInternalValueClassName = valueType.replace('.', '/'); String valuePrefix = "L"; // non-array type if (qualifiedInternalValueClassName.startsWith("[L") && qualifiedInternalValueClassName.endsWith(";")) { valuePrefix = "[L"; // array type qualifiedInternalValueClassName = qualifiedInternalValueClassName.substring(2, qualifiedInternalValueClassName.length() - 1); } String sig = "Ljava/lang/Object;Lorg/eclipse/persistence/internal/jaxb/many/MapEntry;"; cw.visit(Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, qualifiedInternalClassName, sig, "java/lang/Object", new String[] { "org/eclipse/persistence/internal/jaxb/many/MapEntry" }); cw.visitField(Opcodes.ACC_PRIVATE, "key", "L"+qualifiedInternalKeyClassName+";", null, null); cw.visitField(Opcodes.ACC_PRIVATE, "value", valuePrefix + qualifiedInternalValueClassName+";", null, null); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getKey", "()L"+qualifiedInternalKeyClassName+";", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, qualifiedInternalClassName, "key", "L"+qualifiedInternalKeyClassName+";"); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setKey", "(L"+qualifiedInternalKeyClassName+";)V", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitFieldInsn(Opcodes.PUTFIELD, qualifiedInternalClassName, "key", "L"+qualifiedInternalKeyClassName+";"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getValue", "()" + valuePrefix + qualifiedInternalValueClassName+";", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, qualifiedInternalClassName, "value", valuePrefix + qualifiedInternalValueClassName+";"); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setValue", "(" + valuePrefix + qualifiedInternalValueClassName+";)V", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitFieldInsn(Opcodes.PUTFIELD, qualifiedInternalClassName, "value", valuePrefix + qualifiedInternalValueClassName+";"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); if(!qualifiedInternalValueClassName.equals("java/lang/Object")){ mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "getValue", "()Ljava/lang/Object;", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, qualifiedInternalClassName, "getValue", "()" + valuePrefix + qualifiedInternalValueClassName+";", false); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "setValue", "(Ljava/lang/Object;)V", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); // CHECKCAST is slightly different for array types if (valuePrefix.equals("[L")) { mv.visitTypeInsn(Opcodes.CHECKCAST, valuePrefix + qualifiedInternalValueClassName + ";"); } else { mv.visitTypeInsn(Opcodes.CHECKCAST, qualifiedInternalValueClassName); } mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, qualifiedInternalClassName, "setValue", "(" + valuePrefix + qualifiedInternalValueClassName+";)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } if(!qualifiedInternalKeyClassName.equals("java/lang/Object")){ mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "getKey", "()Ljava/lang/Object;", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,qualifiedInternalClassName, "getKey", "()L"+qualifiedInternalKeyClassName+";", false); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "setKey", "(Ljava/lang/Object;)V", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitTypeInsn(Opcodes.CHECKCAST, qualifiedInternalKeyClassName); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, qualifiedInternalClassName, "setKey", "(L"+qualifiedInternalKeyClassName+";)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); byte[] classBytes =cw.toByteArray(); Class generatedClass = getJaxbClassLoader().generateClass(className, classBytes); return generatedClass; } private Mapping generateMappingForType(JavaClass theType, String attributeName){ Mapping mapping; boolean typeIsObject = theType.getRawName().equals(OBJECT_CLASS_NAME); TypeInfo info = typeInfo.get(theType.getQualifiedName()); if ((info != null && !(info.isEnumerationType())) || typeIsObject) { mapping = new XMLCompositeObjectMapping(); mapping.setAttributeName(attributeName); ((CompositeObjectMapping)mapping).setXPath(attributeName); if(typeIsObject){ ((CompositeObjectMapping)mapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); setTypedTextField((Field)((CompositeObjectMapping)mapping).getField()); }else{ ((CompositeObjectMapping)mapping).setReferenceClassName(theType.getQualifiedName()); } } else if (theType.isArray() || helper.isCollectionType(theType)) { DirectCollectionMapping directCollectionMapping; mapping = directCollectionMapping = new XMLCompositeDirectCollectionMapping(); initializeXMLContainerMapping(directCollectionMapping, theType.isArray()); directCollectionMapping.setAttributeName(attributeName); if (theType.isArray()) { JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(directCollectionMapping.getAttributeAccessor(), directCollectionMapping.getContainerPolicy(), helper.getClassLoader()); String componentClassName = theType.getComponentType().getQualifiedName(); if (theType.getComponentType().isPrimitive()){ Class primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(componentClassName); accessor.setComponentClass(primitiveClass); directCollectionMapping.setAttributeAccessor(accessor); Class declaredClass = XMLConversionManager.getDefaultManager().getObjectClass(primitiveClass); directCollectionMapping.setAttributeElementClass(declaredClass); } else { accessor.setComponentClassName(componentClassName); directCollectionMapping.setAttributeAccessor(accessor); JavaClass componentType = theType.getComponentType(); Class declaredClass = PrivilegedAccessHelper.callDoPrivilegedWithException( () -> PrivilegedAccessHelper.getClassForName(componentType.getRawName(), false, helper.getClassLoader()), (ex) -> JAXBException.classNotFoundException(componentType.getRawName()) ); directCollectionMapping.setAttributeElementClass(declaredClass); } } else if (helper.isCollectionType(theType)) { Collection args = theType.getActualTypeArguments(); if (args.size() > 0) { JavaClass itemType = (JavaClass) args.iterator().next(); Class declaredClass = PrivilegedAccessHelper.callDoPrivilegedWithException( () -> PrivilegedAccessHelper.getClassForName(itemType.getRawName(), false, helper.getClassLoader()), (ex) -> JAXBException.classNotFoundException(itemType.getRawName()) ); if (declaredClass != String.class) { directCollectionMapping.setAttributeElementClass(declaredClass); } } } theType = containerClassImpl(theType); directCollectionMapping.useCollectionClassName(theType.getRawName()); directCollectionMapping.setXPath(attributeName + TXT); } else { mapping = new XMLDirectMapping(); mapping.setAttributeName(attributeName); ((DirectMapping)mapping).setNullValueMarshalled(true); ((DirectMapping)mapping).setXPath(attributeName + TXT); QName schemaType = userDefinedSchemaTypes.get(theType.getQualifiedName()); if (schemaType == null) { schemaType = (QName) helper.getXMLToJavaTypeMap().get(theType); } ((Field)((DirectMapping)mapping).getField()).setSchemaType(schemaType); if(info != null && info.isEnumerationType()) { ((DirectMapping)mapping).setConverter(buildJAXBEnumTypeConverter(mapping, (EnumTypeInfo)info)); } } return mapping; } public CompositeCollectionMapping generateCompositeCollectionMapping(Property property, Descriptor descriptor, JavaClass javaClass, NamespaceInfo namespaceInfo, String referenceClassName) { boolean nestedArray = false; CompositeCollectionMapping mapping = new XMLCompositeCollectionMapping(); initializeXMLMapping((XMLMapping)mapping, property); initializeXMLContainerMapping(mapping, property.getType().isArray()); JavaClass manyValueJavaClass = helper.getJavaClass(ManyValue.class); if (manyValueJavaClass.isAssignableFrom(javaClass)){ mapping.setReuseContainer(false); } // handle null policy set via xml metadata if (property.isSetNullPolicy()) { mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo))); } else if (property.isNillable()){ mapping.getNullPolicy().setNullRepresentedByXsiNil(true); mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } if (property.isSetXmlElementWrapper()) { mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property)); } JavaClass collectionType = property.getType(); if (collectionType.isArray()){ JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader()); JavaClass componentType = collectionType.getComponentType(); if(componentType.isArray()) { Class adaptedClass = classToGeneratedClasses.get(componentType.getName()); referenceClassName = adaptedClass.getName(); accessor.setAdaptedClassName(referenceClassName); JavaClass baseComponentType = getBaseComponentType(componentType); if (baseComponentType.isPrimitive()){ Class primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName()); accessor.setComponentClass(primitiveClass); } else { accessor.setComponentClassName(baseComponentType.getQualifiedName()); } } else { accessor.setComponentClassName(componentType.getQualifiedName()); } mapping.setAttributeAccessor(accessor); }else if (helper.isMapType(property.getType())){ Class generatedClass = generateMapEntryClassAndDescriptor(property, descriptor.getNonNullNamespaceResolver()); referenceClassName = generatedClass.getName(); String mapClassName = property.getType().getRawName(); mapping.setAttributeAccessor(new MapValueAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), generatedClass, mapClassName, helper.getClassLoader())); } //Nested array check (used in JSON marshalling) if (collectionType.getComponentType() == null) { if ((collectionType.isArray() || helper.isCollectionType(collectionType)) && (referenceClassName != null && referenceClassName.contains(AnnotationsProcessor.ARRAY_PACKAGE_NAME))) { nestedArray = true; } } else if ((collectionType.isArray() || helper.isCollectionType(collectionType)) && (collectionType.getComponentType().isArray() || helper.isCollectionType(collectionType.getComponentType()))) { nestedArray = true; } collectionType = containerClassImpl(collectionType); mapping.useCollectionClassName(collectionType.getRawName()); // if the XPath is set (via xml-path) use it; otherwise figure it out Field xmlField = getXPathForField(property, namespaceInfo, false, false); if(helper.isMapType(property.getType())){ JavaClass mapValueClass = helper.getJavaClass(MapValue.class); if(mapValueClass.isAssignableFrom(javaClass)){ mapping.setXPath("entry"); }else{ mapping.setXPath(xmlField.getXPath() + "/entry"); } }else{ mapping.setXPath(xmlField.getXPath()); } if (referenceClassName == null){ setTypedTextField((Field)mapping.getField()); } else { mapping.setReferenceClassName(referenceClassName); } if(property.isTransientType()){ mapping.setReferenceClassName(Constants.UNKNOWN_OR_TRANSIENT_CLASS); } if (property.isRequired()) { ((Field) mapping.getField()).setRequired(true); } ((Field) mapping.getField()).setNestedArray(nestedArray); return mapping; } public DirectCollectionMapping generateDirectCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) { DirectCollectionMapping mapping = new XMLCompositeDirectCollectionMapping(); initializeXMLMapping((XMLMapping)mapping, property); initializeXMLContainerMapping(mapping, property.getType().isArray()); JavaClass collectionType = property.getType(); if (collectionType.isArray()){ JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader()); String componentClassName = collectionType.getComponentType().getQualifiedName(); if (collectionType.getComponentType().isPrimitive()){ Class primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(componentClassName); accessor.setComponentClass(primitiveClass); mapping.setAttributeAccessor(accessor); Class declaredClass = XMLConversionManager.getDefaultManager().getObjectClass(primitiveClass); mapping.setAttributeElementClass(declaredClass); } else { accessor.setComponentClassName(componentClassName); mapping.setAttributeAccessor(accessor); JavaClass componentType = collectionType.getComponentType(); try{ Class declaredClass = PrivilegedAccessHelper.getClassForName(componentType.getRawName(), false, helper.getClassLoader()); mapping.setAttributeElementClass(declaredClass); }catch (Exception e) {} } } else if (helper.isCollectionType(collectionType)){ Collection args = collectionType.getActualTypeArguments(); if (args.size() >0){ JavaClass itemType = (JavaClass)args.iterator().next(); try { Class declaredClass = PrivilegedAccessHelper.getClassForName(itemType.getRawName(), false, helper.getClassLoader()); if(declaredClass != String.class){ mapping.setAttributeElementClass(declaredClass); } } catch (Exception e) {} } } collectionType = containerClassImpl(collectionType); mapping.useCollectionClassName(collectionType.getRawName()); if (property.getDefaultValue() != null) { mapping.setNullValue(property.getDefaultValue()); } // if the XPath is set (via xml-path) use it; otherwise figure it out Field xmlField = getXPathForField(property, namespaceInfo, true, false); mapping.setField(xmlField); if (helper.isAnnotationPresent(property.getElement(), XmlMixed.class)) { xmlField.setXPath("text()"); } if (Constants.QNAME_QNAME.equals(property.getSchemaType())){ ((Field) mapping.getField()).setSchemaType(Constants.QNAME_QNAME); } // handle null policy set via xml metadata if (property.isSetNullPolicy()) { mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo))); } else if (property.isNillable()){ mapping.getNullPolicy().setNullRepresentedByXsiNil(true); mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); } mapping.getNullPolicy().setNullRepresentedByEmptyNode(false); if (property.isSetXmlElementWrapper()) { mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property)); } if (property.isRequired()) { ((Field) mapping.getField()).setRequired(true); } if (property.isXmlElementType() && property.getGenericType()!=null ){ Class theClass = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(property.getGenericType().getQualifiedName(), helper.getClassLoader()); mapping.setAttributeElementClass(theClass); } if (xmlField.getXPathFragment().isAttribute() || property.isXmlList() || xmlField.getXPathFragment().nameIsText()){ mapping.setUsesSingleNode(true); } // handle cdata set via metadata if (property.isSetCdata()) { mapping.setIsCDATA(property.isCdata()); } return mapping; } public String getPrefixForNamespace(String URI, NamespaceResolver namespaceResolver) { return getPrefixForNamespace(URI, namespaceResolver, true); } public String getPrefixForNamespace(String URI, NamespaceResolver namespaceResolver, boolean addPrefixToNR) { String defaultNS = namespaceResolver.getDefaultNamespaceURI(); if(defaultNS != null && URI.equals(defaultNS)){ return null; } String prefix = namespaceResolver.resolveNamespaceURI(URI); if (prefix != null) { return prefix; } prefix = globalNamespaceResolver.resolveNamespaceURI(URI); if(prefix == null){ if(URI.equals(globalNamespaceResolver.getDefaultNamespaceURI())) { namespaceResolver.setDefaultNamespaceURI(URI); return null; } else { //Bug 400536 before generating a new one check other resolvers String suggestedPrefix = null; NamespaceInfo refInfo = getNamespaceInfoForURI(URI); if(refInfo != null && refInfo.getNamespaceResolver() !=null){ suggestedPrefix = refInfo.getNamespaceResolver().resolveNamespaceURI(URI); } if(suggestedPrefix != null){ prefix = globalNamespaceResolver.generatePrefix(suggestedPrefix); } else{ prefix = globalNamespaceResolver.generatePrefix(); } } } String nrUri = namespaceResolver.resolveNamespacePrefix(prefix); while(null != nrUri && !URI.equals(nrUri)){ prefix = globalNamespaceResolver.generatePrefix(); nrUri = namespaceResolver.resolveNamespacePrefix(prefix); } if(addPrefixToNR){ namespaceResolver.put(prefix, URI); } globalNamespaceResolver.put(prefix, URI); return prefix; } /** * Setup inheritance for abstract superclass. * * NOTE: We currently only handle one level of inheritance in this case. * For multiple levels the code will need to be modified. The logic in * generateMappings() that determines when to copy down inherited * methods from the parent class will need to be changed as well. * * @param jClass */ private void setupInheritance(JavaClass jClass) { TypeInfo tInfo = typeInfo.get(jClass.getName()); Descriptor descriptor = tInfo.getDescriptor(); if (descriptor == null) { return; } JavaClass superClass = CompilerHelper.getNextMappedSuperClass(jClass, typeInfo, helper); if (superClass == null){ return; } TypeInfo superTypeInfo = typeInfo.get(superClass.getName()); if (superTypeInfo == null){ return; } Descriptor superDescriptor = superTypeInfo.getDescriptor(); if (superDescriptor != null) { XMLSchemaReference sRef = descriptor.getSchemaReference(); if (sRef == null || sRef.getSchemaContext() == null) { return; } JavaClass rootMappedSuperClass = getRootMappedSuperClass(superClass); TypeInfo rootTypeInfo = typeInfo.get(rootMappedSuperClass.getName()); Descriptor rootDescriptor = rootTypeInfo.getDescriptor(); if (rootDescriptor.getNamespaceResolver() == null) { rootDescriptor.setNamespaceResolver(new org.eclipse.persistence.oxm.NamespaceResolver()); } if (rootDescriptor.getInheritancePolicy().getClassIndicatorField() == null) { Field classIndicatorField; if (rootTypeInfo.isSetXmlDiscriminatorNode()) { classIndicatorField = new XMLField(rootTypeInfo.getXmlDiscriminatorNode()); } else { classIndicatorField = XMLConstants.DEFAULT_XML_TYPE_ATTRIBUTE; classIndicatorField.getXPathFragment().setNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); } rootDescriptor.getInheritancePolicy().setClassIndicatorField(classIndicatorField); } Object sCtx = null; //TypeInfo tInfo = typeInfo.get(jClass.getName()); if (tInfo.isSetXmlDiscriminatorValue()) { sCtx = tInfo.getXmlDiscriminatorValue(); } else if(!tInfo.isAnonymousComplexType()){ sCtx = sRef.getSchemaContextAsQName(); } if(sCtx != null) { descriptor.getInheritancePolicy().setParentClassName(superClass.getName()); rootDescriptor.getInheritancePolicy().addClassNameIndicator(jClass.getName(), sCtx); } Object value = rootDescriptor.getInheritancePolicy().getClassNameIndicatorMapping().get(rootDescriptor.getJavaClassName()); if (value == null){ if (rootTypeInfo.isSetXmlDiscriminatorValue()) { rootDescriptor.getInheritancePolicy().addClassNameIndicator(rootDescriptor.getJavaClassName(), rootTypeInfo.getXmlDiscriminatorValue()); } else { XMLSchemaReference rootSRef = rootDescriptor.getSchemaReference(); if (rootSRef != null && rootSRef.getSchemaContext() != null) { QName rootSCtx = rootSRef.getSchemaContextAsQName(); rootDescriptor.getInheritancePolicy().addClassNameIndicator(rootDescriptor.getJavaClassName(), rootSCtx); } } } rootDescriptor.getInheritancePolicy().setShouldReadSubclasses(true); //Check for attributeGroups Map childGroups = ((XMLDescriptor)descriptor).getAttributeGroups(); Map parentGroups = ((XMLDescriptor)rootDescriptor).getAttributeGroups(); if(childGroups != null && !(childGroups.isEmpty()) && parentGroups != null && !(parentGroups.isEmpty())) { for(String nextKey:childGroups.keySet()) { AttributeGroup parentGroup = parentGroups.get(nextKey); if(parentGroup != null) { AttributeGroup childGroup = childGroups.get(nextKey); parentGroup.getSubClassGroups().put(descriptor.getJavaClassName(), childGroup); } } } } } private JavaClass getRootMappedSuperClass(JavaClass javaClass){ JavaClass rootMappedSuperClass = javaClass; JavaClass nextMappedSuperClass = rootMappedSuperClass; while(nextMappedSuperClass != null){ nextMappedSuperClass = CompilerHelper.getNextMappedSuperClass(nextMappedSuperClass, this.typeInfo, helper); if(nextMappedSuperClass == null){ return rootMappedSuperClass; } rootMappedSuperClass = nextMappedSuperClass; } return rootMappedSuperClass; } public void generateMappings() { Iterator javaClasses = this.typeInfo.keySet().iterator(); while (javaClasses.hasNext()) { String next = (String)javaClasses.next(); JavaClass javaClass = helper.getJavaClass(next); TypeInfo info = this.typeInfo.get(next); if (info.isEnumerationType()) { continue; } NamespaceInfo namespaceInfo = this.packageToPackageInfoMappings.get(javaClass.getPackageName()).getNamespaceInfo(); Descriptor descriptor = info.getDescriptor(); if (descriptor != null) { generateMappings(info, descriptor, javaClass, namespaceInfo); // set primary key fields (if necessary) CoreMapping mapping; // handle XmlID if (info.isIDSet()) { mapping = descriptor.getMappingForAttributeName(info.getIDProperty().getPropertyName()); if (mapping != null) { descriptor.addPrimaryKeyField(mapping.getField()); } } // handle XmlKey if (info.hasXmlKeyProperties()) { for (Property keyProp : info.getXmlKeyProperties()) { mapping = descriptor.getMappingForAttributeName(keyProp.getPropertyName()); if (mapping != null) { descriptor.addPrimaryKeyField(mapping.getField()); } } } } info.postInitialize(); if (descriptor != null) { logMappingGeneration(descriptor); } } } /** * Generate mappings for a given TypeInfo. * * @param info * @param descriptor * @param namespaceInfo */ public void generateMappings(TypeInfo info, Descriptor descriptor, JavaClass descriptorJavaClass, NamespaceInfo namespaceInfo) { if(info.isAnonymousComplexType()) { //may need to generate inherited mappings generateInheritedMappingsForAnonymousType(info, descriptor, descriptorJavaClass, namespaceInfo); } List propertiesInOrder = info.getNonTransientPropertiesInPropOrder(); for (int i = 0; i < propertiesInOrder.size(); i++) { Property next = propertiesInOrder.get(i); if (next != null && (!next.isTransient() || (next.isTransient() && next.isXmlLocation()))) { Mapping mapping = generateMapping(next, descriptor, descriptorJavaClass, namespaceInfo); if (next.isVirtual()) { VirtualAttributeAccessor accessor = new VirtualAttributeAccessor(); accessor.setAttributeName(mapping.getAttributeName()); String getMethod = info.getXmlVirtualAccessMethods().getGetMethod(); String setMethod = info.getXmlVirtualAccessMethods().getSetMethod(); // Check to see if get/set were overridden in the mapping if (mapping.getAttributeAccessor().isMethodAttributeAccessor()) { getMethod = ((MethodAttributeAccessor) mapping.getAttributeAccessor()).getGetMethodName(); setMethod = ((MethodAttributeAccessor) mapping.getAttributeAccessor()).getSetMethodName(); accessor.setValueType(mapping.getAttributeClassification()); } accessor.setGetMethodName(getMethod); accessor.setSetMethodName(setMethod); if (mapping.getAttributeAccessor() instanceof JAXBArrayAttributeAccessor) { JAXBArrayAttributeAccessor jaa = (JAXBArrayAttributeAccessor) mapping.getAttributeAccessor(); jaa.setNestedAccessor(accessor); } else { mapping.setAttributeAccessor(accessor); } } if (mapping != null) { descriptor.addMapping((CoreMapping)mapping); } // set user-defined properties if necessary if (next.isSetUserProperties()) { mapping.setProperties(next.getUserProperties()); } //get package info AccessorFactoryWrapper accessorFactory = info.getXmlAccessorFactory(); if(accessorFactory == null) { accessorFactory = info.getPackageLevelXmlAccessorFactory(); } if(accessorFactory != null) { try { Object accessor = CompilerHelper.createAccessorFor(descriptorJavaClass, next, helper, accessorFactory); if(accessor != null) { CustomAccessorAttributeAccessor attributeAccessor = new CustomAccessorAttributeAccessor(accessor); mapping.setAttributeAccessor(attributeAccessor); } } catch(Exception ex) {} } } next.postInitialize(); } } private void generateInheritedMappingsForAnonymousType(TypeInfo info, Descriptor descriptor, JavaClass descriptorJavaClass, NamespaceInfo namespaceInfo) { List mappedParents = new ArrayList(); JavaClass next = CompilerHelper.getNextMappedSuperClass(descriptorJavaClass, typeInfo, helper); while(next != null) { TypeInfo nextInfo = this.typeInfo.get(next.getName()); mappedParents.add(0, nextInfo); next = CompilerHelper.getNextMappedSuperClass(helper.getJavaClass(nextInfo.getJavaClassName()), typeInfo, helper); } for(TypeInfo nextInfo:mappedParents) { List propertiesInOrder = nextInfo.getNonTransientPropertiesInPropOrder(); for (int i = 0; i < propertiesInOrder.size(); i++) { Property nextProp = propertiesInOrder.get(i); if (nextProp != null){ Mapping mapping = generateMapping(nextProp, descriptor, descriptorJavaClass, namespaceInfo); descriptor.addMapping((CoreMapping)mapping); // set user-defined properties if necessary if (nextProp.isSetUserProperties()) { mapping.setProperties(nextProp.getUserProperties()); } } } } } /** * Create an XMLCollectionReferenceMapping and add it to the descriptor. * * @param property * @param descriptor * @param namespaceInfo * @param referenceClass */ public CollectionReferenceMapping generateXMLCollectionReferenceMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, JavaClass referenceClass) { CollectionReferenceMapping mapping = new XMLCollectionReferenceMapping(); initializeXMLMapping((XMLMapping)mapping, property); initializeXMLContainerMapping(mapping, property.getType().isArray()); mapping.setUsesSingleNode(property.isXmlList() || (property.isAttribute() && (property.getXmlPath() == null || !property.getXmlPath().contains("/")))); String referenceClassName = referenceClass.getQualifiedName(); JavaClass collectionType = property.getType(); if (collectionType.isArray()){ JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader()); JavaClass componentType = collectionType.getComponentType(); if(componentType.isArray()) { Class adaptedClass = classToGeneratedClasses.get(componentType.getName()); referenceClassName = adaptedClass.getName(); accessor.setAdaptedClassName(referenceClassName); JavaClass baseComponentType = getBaseComponentType(componentType); if (baseComponentType.isPrimitive()){ Class primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName()); accessor.setComponentClass(primitiveClass); } else { accessor.setComponentClassName(baseComponentType.getQualifiedName()); } } else { accessor.setComponentClassName(componentType.getQualifiedName()); } mapping.setAttributeAccessor(accessor); } collectionType = containerClassImpl(collectionType); mapping.useCollectionClassName(collectionType.getRawName()); mapping.setReferenceClassName(referenceClassName); // here we need to setup source/target key field associations if (property.isSetXmlJoinNodes()) { for (XmlJoinNode xmlJoinNode: property.getXmlJoinNodes().getXmlJoinNode()) { validateJoinNode(descriptor.getJavaClassName(), property, xmlJoinNode.getReferencedXmlPath(), referenceClass); mapping.addSourceToTargetKeyFieldAssociation(xmlJoinNode.getXmlPath(), xmlJoinNode.getReferencedXmlPath()); } } else { // here we need to setup source/target key field associations TypeInfo referenceType = typeInfo.get(referenceClass.getQualifiedName()); String tgtXPath = null; if (null != referenceType && referenceType.isIDSet()) { Property prop = referenceType.getIDProperty(); tgtXPath = getXPathForField(prop, namespaceInfo, !prop.isAttribute(), false).getXPath(); } // if the XPath is set (via xml-path) use it Field srcXPath; if (property.getXmlPath() != null) { srcXPath = new XMLField(property.getXmlPath()); } else { srcXPath = getXPathForField(property, namespaceInfo, true, false); } mapping.addSourceToTargetKeyFieldAssociation(srcXPath.getXPath(), tgtXPath); } if (property.getInverseReferencePropertyName() != null) { mapping.getInverseReferenceMapping().setAttributeName(property.getInverseReferencePropertyName()); JavaClass backPointerPropertyType = null; if (property.getInverseReferencePropertyGetMethodName() != null && property.getInverseReferencePropertySetMethodName() != null && !property.getInverseReferencePropertyGetMethodName().equals("") && !property.getInverseReferencePropertySetMethodName().equals("")) { mapping.getInverseReferenceMapping().setGetMethodName(property.getInverseReferencePropertySetMethodName()); mapping.getInverseReferenceMapping().setSetMethodName(property.getInverseReferencePropertySetMethodName()); JavaMethod getMethod = referenceClass.getDeclaredMethod(mapping.getInverseReferenceMapping().getGetMethodName(), new JavaClass[]{}); if (getMethod != null) { backPointerPropertyType = getMethod.getReturnType(); } } else { JavaField backpointerField = referenceClass.getDeclaredField(property.getInverseReferencePropertyName()); if (backpointerField != null) { backPointerPropertyType = backpointerField.getResolvedType(); } } if (helper.isCollectionType(backPointerPropertyType)) { mapping.getInverseReferenceMapping().setContainerPolicy(ContainerPolicy.buildDefaultPolicy()); } } return mapping; } /** * Create an XMLObjectReferenceMapping and add it to the descriptor. * * @param property * @param descriptor * @param namespaceInfo * @param referenceClass */ public ObjectReferenceMapping generateXMLObjectReferenceMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, JavaClass referenceClass) { ObjectReferenceMapping mapping = new XMLObjectReferenceMapping(); initializeXMLMapping((XMLMapping)mapping, property); mapping.setReferenceClassName(referenceClass.getQualifiedName()); // here we need to setup source/target key field associations if (property.isSetXmlJoinNodes()) { for (XmlJoinNode xmlJoinNode: property.getXmlJoinNodes().getXmlJoinNode()) { validateJoinNode(descriptor.getJavaClassName(), property, xmlJoinNode.getReferencedXmlPath(), referenceClass); mapping.addSourceToTargetKeyFieldAssociation(xmlJoinNode.getXmlPath(), xmlJoinNode.getReferencedXmlPath()); } } else { String tgtXPath = null; TypeInfo referenceType = typeInfo.get(referenceClass.getQualifiedName()); if (null != referenceType && referenceType.isIDSet()) { Property prop = referenceType.getIDProperty(); tgtXPath = getXPathForField(prop, namespaceInfo, !prop.isAttribute(), false).getXPath(); } // if the XPath is set (via xml-path) use it, otherwise figure it out Field srcXPath; if (property.getXmlPath() != null) { srcXPath = new XMLField(property.getXmlPath()); } else { srcXPath = getXPathForField(property, namespaceInfo, true, false); } mapping.addSourceToTargetKeyFieldAssociation(srcXPath.getXPath(), tgtXPath); } if (property.getInverseReferencePropertyName() != null) { mapping.getInverseReferenceMapping().setAttributeName(property.getInverseReferencePropertyName()); JavaClass backPointerPropertyType = null; if (property.getInverseReferencePropertyGetMethodName() != null && property.getInverseReferencePropertySetMethodName() != null && !property.getInverseReferencePropertyGetMethodName().equals("") && !property.getInverseReferencePropertySetMethodName().equals("")) { mapping.getInverseReferenceMapping().setGetMethodName(property.getInverseReferencePropertySetMethodName()); mapping.getInverseReferenceMapping().setSetMethodName(property.getInverseReferencePropertySetMethodName()); JavaMethod getMethod = referenceClass.getDeclaredMethod(mapping.getInverseReferenceMapping().getGetMethodName(), new JavaClass[]{}); if (getMethod != null) { backPointerPropertyType = getMethod.getReturnType(); } } else { JavaField backpointerField = referenceClass.getDeclaredField(property.getInverseReferencePropertyName()); if (backpointerField != null) { backPointerPropertyType = backpointerField.getResolvedType(); } } if (helper.isCollectionType(backPointerPropertyType)) { mapping.getInverseReferenceMapping().setContainerPolicy(ContainerPolicy.buildDefaultPolicy()); } } return mapping; } private void validateJoinNode(String className, Property property, String referencedXmlPath, JavaClass referenceClass) { TypeInfo targetInfo = this.typeInfo.get(referenceClass.getQualifiedName()); NamespaceInfo namespaceInfo = this.packageToPackageInfoMappings.get(referenceClass.getPackageName()).getNamespaceInfo(); Property idProp = targetInfo.getIDProperty(); if(idProp != null) { String idXpath = idProp.getXmlPath(); if(idXpath == null) { idXpath = this.getXPathForField(idProp, namespaceInfo, !idProp.isAttribute(), false).getXPath(); } if (referencedXmlPath.equals(idXpath)) { return; } } boolean matched = false; if (targetInfo.getXmlKeyProperties() != null) { for (Property xmlkeyProperty : targetInfo.getXmlKeyProperties()) { String keyXpath = xmlkeyProperty.getXmlPath(); if(keyXpath == null) { keyXpath = this.getXPathForField(xmlkeyProperty, namespaceInfo, !xmlkeyProperty.isAttribute(), false).getXPath(); } if (referencedXmlPath.equals(keyXpath)) { matched = true; break; } } } if (!matched) { throw JAXBException.invalidReferencedXmlPathOnJoin(className, property.getPropertyName(), referenceClass.getQualifiedName(), referencedXmlPath); } } private String prefixCustomXPath(String unprefixedXPath, Property property, NamespaceInfo nsInfo) { StringBuilder newXPath = new StringBuilder(32); QName schemaName = property.getSchemaName(); String namespace = schemaName.getNamespaceURI(); if (null == namespace || namespace.equals(Constants.EMPTY_STRING)) { return unprefixedXPath; } String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(nsInfo)); if (null == prefix) { return unprefixedXPath; } StringTokenizer st = new StringTokenizer(unprefixedXPath, Constants.XPATH_SEPARATOR); while (st.hasMoreTokens()) { String nextToken = st.nextToken(); if (st.hasMoreTokens()) { if (nextToken.lastIndexOf(Constants.COLON) != -1) { // Token already has a user-supplied prefix newXPath.append(nextToken); } else { newXPath.append(prefix).append(Constants.COLON).append(nextToken); } newXPath.append(Constants.XPATH_SEPARATOR); } else { // Last token is text() newXPath.append(nextToken); } } return newXPath.toString(); } public Field getXPathForField(Property property, NamespaceInfo namespaceInfo, boolean isTextMapping, boolean isAny) { Field xmlField = null; String xPath = property.getXmlPath(); if (null != xPath) { String newXPath = prefixCustomXPath(xPath, property, namespaceInfo); xmlField = new XMLField(newXPath); } else { StringBuilder xPathBuilder = new StringBuilder(); if (property.isSetXmlElementWrapper()) { XmlElementWrapper wrapper = property.getXmlElementWrapper(); String namespace = wrapper.getNamespace(); if (namespace.equals(XMLProcessor.DEFAULT)) { if (namespaceInfo.isElementFormQualified()) { namespace = namespaceInfo.getNamespace(); } else { namespace = ""; } } if (namespace.equals("")) { xPathBuilder.append(wrapper.getName()).append("/"); } else { String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(namespaceInfo)); xPathBuilder.append(getQualifiedString(prefix, wrapper.getName() + "/")); } if (isAny || property.isMap()) { xmlField = new XMLField(xPathBuilder.toString()); return xmlField; } } if (property.isAttribute()) { if (property.isSetXmlPath()) { xPathBuilder.append(property.getXmlPath()); } else { QName name = property.getSchemaName(); String namespace = name.getNamespaceURI(); if (namespace.equals("")) { xPathBuilder.append(ATT).append(name.getLocalPart()); } else { String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(namespaceInfo)); xPathBuilder.append(ATT).append(getQualifiedString(prefix, name.getLocalPart())); } } xmlField = new XMLField(xPathBuilder.toString()); } else if (property.isXmlValue()) { if(isBinaryData(property.getActualType())){ xmlField = new XMLField("."); }else{ xmlField = new XMLField("text()"); } } else { QName elementName = property.getSchemaName(); xmlField = getXPathForElement(xPathBuilder.toString(), elementName, namespaceInfo, isTextMapping); } } QName schemaType = userDefinedSchemaTypes.get(property.getActualType().getQualifiedName()); if (property.getSchemaType() != null) { schemaType = property.getSchemaType(); } if (schemaType == null) { String propertyActualTypeRawName = property.getActualType().getRawName(); if(QName.class.getCanonicalName().equals(propertyActualTypeRawName)) { schemaType = (QName) helper.getXMLToJavaTypeMap().get(propertyActualTypeRawName); } } if(schemaType !=null && !schemaType.equals (Constants.NORMALIZEDSTRING_QNAME)){ xmlField.setSchemaType(schemaType); } return xmlField; } public Field getXPathForElement(String path, QName elementName, NamespaceInfo namespaceInfo, boolean isText) { String namespace = ""; if (!elementName.getNamespaceURI().equals(Constants.EMPTY_STRING)) { namespace = elementName.getNamespaceURI(); } if (namespace.equals(Constants.EMPTY_STRING)) { path += elementName.getLocalPart(); if (isText) { path += TXT; } } else { String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(namespaceInfo)); path += getQualifiedString(prefix, elementName.getLocalPart()); if (isText) { path += TXT; } } return new XMLField(path); } public Property getXmlValueFieldForSimpleContent(ArrayList properties) { boolean foundValue = false; boolean foundNonAttribute = false; Property valueField = null; for (Property prop : properties) { if (helper.isAnnotationPresent(prop.getElement(), XmlValue.class)) { foundValue = true; valueField = prop; } else if (!helper.isAnnotationPresent(prop.getElement(), XmlAttribute.class) && !helper.isAnnotationPresent(prop.getElement(), XmlTransient.class) && !prop.isAnyAttribute()) { foundNonAttribute = true; } } if (foundValue && !foundNonAttribute) { return valueField; } return null; } public String getSchemaTypeNameForClassName(String className) { String typeName = Introspector.decapitalize(className.substring(className.lastIndexOf('.') + 1)); return typeName; } public void processGlobalElements(CoreProject project) { //Find any global elements for classes we've generated descriptors for, and add them as possible //root elements. if(this.globalElements == null && this.localElements == null) { return; } List elements = new ArrayList(); elements.addAll(this.localElements); elements.addAll(this.globalElements.values()); for(ElementDeclaration nextElement:elements) { QName next = nextElement.getElementName(); String nextClassName = nextElement.getJavaTypeName(); TypeInfo type = this.typeInfo.get(nextClassName); if(helper.isBuiltInJavaType(nextElement.getJavaType()) || (type !=null && type.isEnumerationType())){ //generate a class/descriptor for this element String attributeTypeName = nextClassName; if(nextElement.getJavaType().isPrimitive()) { attributeTypeName = helper.getClassForJavaClass(nextElement.getJavaType()).getName(); } if (nextElement.getAdaptedJavaTypeName() != null) { attributeTypeName = nextElement.getAdaptedJavaTypeName(); } if(next == null){ if(isBinaryData(nextElement.getJavaType())){ Class generatedClass = addByteArrayWrapperAndDescriptor(type, nextElement.getJavaType().getRawName(), nextElement,nextClassName, attributeTypeName); this.qNamesToGeneratedClasses.put(next, generatedClass); if(nextElement.getTypeMappingInfo() != null) { typeMappingInfoToGeneratedClasses.put(nextElement.getTypeMappingInfo(), generatedClass); } try{ Class declaredClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader()); this.qNamesToDeclaredClasses.put(next, declaredClass); }catch(Exception e){ } } if(nextElement.getJavaType().isEnum()) { if(!(helper.getClassLoader() instanceof DynamicClassLoader)) { // Only generate enum wrappers in non-dynamic case. Class generatedClass = addEnumerationWrapperAndDescriptor(type, nextElement.getJavaType().getRawName(), nextElement, nextClassName, attributeTypeName); this.qNamesToGeneratedClasses.put(next, generatedClass); if(nextElement.getTypeMappingInfo() != null) { typeMappingInfoToGeneratedClasses.put(nextElement.getTypeMappingInfo(), generatedClass); } try{ Class declaredClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader()); this.qNamesToDeclaredClasses.put(next, declaredClass); }catch(Exception ex) { } } } continue; } Class generatedClass = generateWrapperClassAndDescriptor(type, next, nextElement, nextClassName, attributeTypeName); this.qNamesToGeneratedClasses.put(next, generatedClass); if(type != null && type.isEnumerationType() && nextElement.isXmlRootElement()) { this.classToGeneratedClasses.put(type.getJavaClassName(), generatedClass); } try{ Class declaredClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader()); this.qNamesToDeclaredClasses.put(next, declaredClass); }catch(Exception e){ } }else if(type != null && !type.isTransient()){ if(next.getNamespaceURI() == null || next.getNamespaceURI().equals("")) { type.getDescriptor().addRootElement(next.getLocalPart()); } else { Descriptor descriptor = type.getDescriptor(); String uri = next.getNamespaceURI(); String prefix = getPrefixForNamespace(uri, descriptor.getNamespaceResolver()); descriptor.addRootElement(getQualifiedString(prefix, next.getLocalPart())); } } } } private Class addByteArrayWrapperAndDescriptor(TypeInfo type , String javaClassName, ElementDeclaration nextElement, String nextClassName, String attributeTypeName){ Class generatedClass = classToGeneratedClasses.get(javaClassName); if(generatedClass == null){ generatedClass = generateWrapperClassAndDescriptor(type, null, nextElement, nextClassName, attributeTypeName); classToGeneratedClasses.put(javaClassName, generatedClass); } return generatedClass; } private Class addEnumerationWrapperAndDescriptor(TypeInfo type, String javaClassName, ElementDeclaration nextElement, String nextClassName, String attributeTypeName) { Class generatedClass = classToGeneratedClasses.get(javaClassName); if(generatedClass == null){ generatedClass = generateWrapperClassAndDescriptor(type, nextElement.getElementName(), nextElement, nextClassName, attributeTypeName); classToGeneratedClasses.put(javaClassName, generatedClass); } return generatedClass; } private Class generateWrapperClassAndDescriptor(TypeInfo type, QName next, ElementDeclaration nextElement, String nextClassName, String attributeTypeName){ String namespaceUri = null; if(next!= null){ //generate a class/descriptor for this element namespaceUri = next.getNamespaceURI(); if (namespaceUri == null || namespaceUri.equals(XMLProcessor.DEFAULT)) { namespaceUri = ""; } } TypeMappingInfo tmi = nextElement.getTypeMappingInfo(); Class generatedClass = null; JaxbClassLoader loader = getJaxbClassLoader(); if(tmi != null){ generatedClass = CompilerHelper.getExisitingGeneratedClass(tmi, typeMappingInfoToGeneratedClasses, typeMappingInfoToAdapterClasses, helper.getClassLoader()); if(generatedClass == null){ generatedClass = this.generateWrapperClass(loader.nextAvailableGeneratedClassName(), attributeTypeName, nextElement.isList(), next); } typeMappingInfoToGeneratedClasses.put(tmi, generatedClass); }else{ generatedClass = this.generateWrapperClass(loader.nextAvailableGeneratedClassName(), attributeTypeName, nextElement.isList(), next); } this.qNamesToGeneratedClasses.put(next, generatedClass); try{ Class declaredClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader()); this.qNamesToDeclaredClasses.put(next, declaredClass); }catch(Exception e){ } Descriptor desc = (Descriptor)project.getDescriptor(generatedClass); if(desc == null){ desc = new XMLDescriptor(); desc.setJavaClass(generatedClass); if(nextElement.isList()){ DirectCollectionMapping mapping = new XMLCompositeDirectCollectionMapping(); mapping.setAttributeName("value"); mapping.setXPath("text()"); mapping.setUsesSingleNode(true); mapping.setReuseContainer(true); if(type != null && type.isEnumerationType()){ mapping.setValueConverter(buildJAXBEnumTypeConverter(mapping, (EnumTypeInfo)type)); }else{ try{ Class fieldElementClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader()); mapping.setFieldElementClass(fieldElementClass); }catch(ClassNotFoundException e){ } } if(nextClassName.equals("[B") || nextClassName.equals("[Ljava.lang.Byte;")) { ((Field)mapping.getField()).setSchemaType(Constants.BASE_64_BINARY_QNAME); } else if(nextClassName.equals("javax.xml.namespace.QName")){ ((Field)mapping.getField()).setSchemaType(Constants.QNAME_QNAME); } desc.addMapping((CoreMapping)mapping); } else{ if(nextElement.getJavaTypeName().equals(OBJECT_CLASS_NAME)){ CompositeObjectMapping mapping = new XMLCompositeObjectMapping(); mapping.setAttributeName("value"); mapping.setSetMethodName("setValue"); mapping.setGetMethodName("getValue"); mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); mapping.setXPath("."); setTypedTextField((Field)mapping.getField()); desc.addMapping((CoreMapping)mapping); }else if(isBinaryData(nextElement.getJavaType())){ BinaryDataMapping mapping = new XMLBinaryDataMapping(); mapping.setAttributeName("value"); mapping.setXPath("."); ((Field)mapping.getField()).setSchemaType(Constants.BASE_64_BINARY_QNAME); mapping.setSetMethodName("setValue"); mapping.setGetMethodName("getValue"); mapping.getNullPolicy().setNullRepresentedByXsiNil(true); mapping.getNullPolicy().setNullRepresentedByEmptyNode(false); Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(attributeTypeName, helper.getClassLoader()); mapping.setAttributeClassification(attributeClassification); mapping.setShouldInlineBinaryData(false); //if(nextElement.getTypeMappingInfo() != null) { mapping.setSwaRef(nextElement.isXmlAttachmentRef()); mapping.setMimeType(nextElement.getXmlMimeType()); //} desc.addMapping((CoreMapping)mapping); }else{ DirectMapping mapping = new XMLDirectMapping(); mapping.setNullValueMarshalled(true); mapping.setAttributeName("value"); mapping.setXPath("text()"); mapping.setSetMethodName("setValue"); mapping.setGetMethodName("getValue"); if(nextElement.getDefaultValue() != null) { mapping.setNullValue(nextElement.getDefaultValue()); mapping.getNullPolicy().setNullRepresentedByXsiNil(true); } if(helper.isBuiltInJavaType(nextElement.getJavaType())){ Class attributeClassification = null; if(nextElement.getJavaType().isPrimitive()) { attributeClassification = XMLConversionManager.getDefaultManager().convertClassNameToClass(attributeTypeName); } else { attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(attributeTypeName, helper.getClassLoader()); } mapping.setAttributeClassification(attributeClassification); } IsSetNullPolicy nullPolicy = new IsSetNullPolicy("isSetValue", false, true, XMLNullRepresentationType.ABSENT_NODE); //nullPolicy.setNullRepresentedByEmptyNode(true); mapping.setNullPolicy(nullPolicy); if(type != null && type.isEnumerationType()){ mapping.setConverter(buildJAXBEnumTypeConverter(mapping, (EnumTypeInfo)type)); } if(nextClassName.equals("[B") || nextClassName.equals("[Ljava.lang.Byte;")) { ((Field)mapping.getField()).setSchemaType(Constants.BASE_64_BINARY_QNAME); } else if(nextClassName.equals("javax.xml.namespace.QName")){ ((Field)mapping.getField()).setSchemaType(Constants.QNAME_QNAME); } if (nextElement.getJavaTypeAdapterClass() != null) { mapping.setConverter(new XMLJavaTypeConverter(nextElement.getJavaTypeAdapterClass())); } desc.addMapping((CoreMapping)mapping); } } if(next != null){ NamespaceInfo info = getNamespaceInfoForURI(namespaceUri); if(info != null) { NamespaceResolver resolver = getNamespaceResolverForDescriptor(info); String prefix = null; if(namespaceUri != Constants.EMPTY_STRING){ prefix = resolver.resolveNamespaceURI(namespaceUri); if(prefix == null){ prefix = getPrefixForNamespace(namespaceUri, resolver); } } desc.setNamespaceResolver(resolver); if(nextElement.isXmlRootElement()) { desc.setDefaultRootElement(getQualifiedString(prefix, next.getLocalPart())); } else { desc.setDefaultRootElement(""); desc.addRootElement(getQualifiedString(prefix, next.getLocalPart())); desc.setResultAlwaysXMLRoot(true); } } else { if(namespaceUri.equals("")) { desc.setDefaultRootElement(next.getLocalPart()); } else { NamespaceResolver resolver = new org.eclipse.persistence.oxm.NamespaceResolver(); String prefix = getPrefixForNamespace(namespaceUri, resolver); desc.setNamespaceResolver(resolver); if(nextElement.isXmlRootElement()) { desc.setDefaultRootElement(getQualifiedString(prefix, next.getLocalPart())); } else { desc.setDefaultRootElement(""); desc.addRootElement(getQualifiedString(prefix, next.getLocalPart())); desc.setResultAlwaysXMLRoot(true); } } } } project.addDescriptor((CoreDescriptor)desc); } return generatedClass; } private String getQualifiedString(String prefix, String localPart){ if(prefix == null){ return localPart; } return prefix + Constants.COLON + localPart; } private NamespaceInfo getNamespaceInfoForURI(String namespaceUri) { Iterator namespaces = this.packageToPackageInfoMappings.values().iterator(); while(namespaces.hasNext()) { NamespaceInfo next = namespaces.next().getNamespaceInfo(); if(next.getNamespace().equals(namespaceUri)) { return next; } } return null; } @SuppressWarnings("unused") private String getPackageNameForURI(String namespaceUri) { for(String next:this.packageToPackageInfoMappings.keySet()) { if(packageToPackageInfoMappings.get(next).getNamespace().equals(namespaceUri)) { return next; } } return null; } public Class generateWrapperClass(String className, String attributeType, boolean isList, QName theQName) { EclipseLinkASMClassWriter cw = new EclipseLinkASMClassWriter(); String sig = null; cw.visit(Opcodes.ACC_PUBLIC, className.replace(".", "/"), sig, Type.getType(WrappedValue.class).getInternalName(), null); String fieldType = null; if(isList){ fieldType ="Ljava/util/List;"; }else{ fieldType = attributeType.replace(".", "/"); if(!(fieldType.startsWith("["))) { fieldType = "L" + fieldType + ";"; } } if(theQName == null){ theQName = RESERVED_QNAME; } MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName"); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn(theQName.getNamespaceURI()); mv.visitLdcInsn(theQName.getLocalPart()); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName", "", "(Ljava/lang/String;Ljava/lang/String;)V", false); mv.visitLdcInsn(Type.getType(fieldType)); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "org/eclipse/persistence/internal/jaxb/WrappedValue", "", "(Ljavax/xml/namespace/QName;Ljava/lang/Class;Ljava/lang/Object;)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(5, 1); mv.visitEnd(); cw.visitEnd(); byte[] classBytes = cw.toByteArray(); //byte[] classBytes = new byte[]{}; Class generatedClass = getJaxbClassLoader().generateClass(className, classBytes); return generatedClass; } public Map getQNamesToGeneratedClasses() { return qNamesToGeneratedClasses; } public Map getClassToGeneratedClasses() { return classToGeneratedClasses; } public Map getQNamesToDeclaredClasses() { return qNamesToDeclaredClasses; } private Map getGeneratedMapEntryClasses() { if(generatedMapEntryClasses == null){ generatedMapEntryClasses = new HashMap(); } return generatedMapEntryClasses; } // Made static final for performance reasons. private static final class MapEntryGeneratedKey { @SuppressWarnings("unused") String keyClassName; @SuppressWarnings("unused") String valueClassName; public MapEntryGeneratedKey(String keyClass, String valueClass){ keyClassName = keyClass; valueClassName = valueClass; } } private AbstractNullPolicy getWrapperNullPolicyFromProperty(Property property) { NullPolicy nullPolicy = null; if (property.isSetXmlElementWrapper()) { nullPolicy = new NullPolicy(); nullPolicy.setNullRepresentedByEmptyNode(false); nullPolicy.setSetPerformedForAbsentNode(false); if (property.getXmlElementWrapper().isNillable()) { nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); nullPolicy.setNullRepresentedByXsiNil(true); } else { nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.ABSENT_NODE); nullPolicy.setNullRepresentedByXsiNil(false); } } return nullPolicy; } /** * Convenience method which returns an AbstractNullPolicy built from an XmlAbstractNullPolicy. * * @param property * @param nsr if 'NullRepresentedByXsiNil' is true, this is the resolver * that we will add the schema instance prefix/uri pair to * @return * @see org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy * @see org.eclipse.persistence.jaxb.xmlmodel.XmlAbstractNullPolicy */ private AbstractNullPolicy getNullPolicyFromProperty(Property property, NamespaceResolver nsr) { AbstractNullPolicy absNullPolicy = null; XmlAbstractNullPolicy xmlAbsNullPolicy = property.getNullPolicy(); // policy is assumed to be one of XmlNullPolicy or XmlIsSetNullPolicy if (xmlAbsNullPolicy instanceof XmlNullPolicy) { XmlNullPolicy xmlNullPolicy = (XmlNullPolicy) xmlAbsNullPolicy; NullPolicy nullPolicy = new NullPolicy(); nullPolicy.setSetPerformedForAbsentNode(xmlNullPolicy.isIsSetPerformedForAbsentNode()); absNullPolicy = nullPolicy; } else { XmlIsSetNullPolicy xmlIsSetNullPolicy = (XmlIsSetNullPolicy) xmlAbsNullPolicy; IsSetNullPolicy isSetNullPolicy = new IsSetNullPolicy(); isSetNullPolicy.setIsSetMethodName(xmlIsSetNullPolicy.getIsSetMethodName()); // handle isSetParams ArrayList parameters = new ArrayList(); ArrayList parameterTypes = new ArrayList(); List params = xmlIsSetNullPolicy.getIsSetParameter(); for (XmlIsSetNullPolicy.IsSetParameter param : params) { String valueStr = param.getValue(); String typeStr = param.getType(); // create a conversion manager instance with the helper's loader XMLConversionManager mgr = new XMLConversionManager(); mgr.setLoader(helper.getClassLoader()); // handle parameter type Class typeClass = mgr.convertClassNameToClass(typeStr); // handle parameter value Object parameterValue = mgr.convertObject(valueStr, typeClass); parameters.add(parameterValue); parameterTypes.add(typeClass); } isSetNullPolicy.setIsSetParameters(parameters.toArray()); isSetNullPolicy.setIsSetParameterTypes(parameterTypes.toArray(new Class[parameterTypes.size()])); absNullPolicy = isSetNullPolicy; } // handle commmon settings absNullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.valueOf(xmlAbsNullPolicy.getNullRepresentationForXml().name())); absNullPolicy.setNullRepresentedByEmptyNode(xmlAbsNullPolicy.isEmptyNodeRepresentsNull()); boolean xsiRepresentsNull = xmlAbsNullPolicy.isXsiNilRepresentsNull(); if (xsiRepresentsNull) { absNullPolicy.setNullRepresentedByXsiNil(true); } return absNullPolicy; } /** * Return the base component type for a class. For example, the base * component type for Integer, Integer[], and Integer[][] are all Integer. */ private JavaClass getBaseComponentType(JavaClass javaClass) { JavaClass componentType = javaClass.getComponentType(); if(null == componentType) { return javaClass; } if(!componentType.isArray()) { return componentType; } return getBaseComponentType(componentType); } public JaxbClassLoader getJaxbClassLoader() { if (helper.getClassLoader() instanceof DynamicClassLoader) { return (JaxbClassLoader) helper.getClassLoader().getParent(); } else { return (JaxbClassLoader) helper.getClassLoader(); } } private boolean isBinaryData(JavaClass type){ return areEquals(type, CoreClassConstants.APBYTE) ||areEquals(type, "javax.activation.DataHandler") || areEquals(type, "java.awt.Image") || areEquals(type, "javax.xml.transform.Source") || areEquals(type, "javax.mail.internet.MimeMultipart"); } // Made static final for performance reasons. /** *

An InstantiationPolicy that does not construct any objects (and therefore * will not throw validation errors caused by a lack of a no-arg constructor).

* *

This is used by @XmlLocation, where we want to have a real mapping created * (so we can later set its value through the mapping), but where we will never * instantiate a Locator from XML (the Locator will be built internally during parsing).

* * @see org.eclipse.persistence.internal.descriptors.InstantiationPolicy * @see org.xml.sax.Locator */ private static final class NullInstantiationPolicy extends InstantiationPolicy { /** * Returns a new instance of this InstantiationPolicy's Descriptor's class. * * In this case, do nothing and return null. */ @Override public Object buildNewInstance() throws DescriptorException { return null; } } private void initializeXMLContainerMapping(XMLContainerMapping xmlContainerMapping, boolean isArray) { xmlContainerMapping.setReuseContainer(!isArray); xmlContainerMapping.setDefaultEmptyContainer(false); } private void initializeXMLMapping(XMLMapping mapping, Property property){ mapping.setAttributeName(property.getPropertyName()); // handle read-only set via metadata if (property.isSetReadOnly()) { mapping.setIsReadOnly(property.isReadOnly()); } // handle write-only set via metadata if (property.isSetWriteOnly()) { mapping.setIsWriteOnly(property.isWriteOnly()); } if (property.isMethodProperty()) { if (property.getGetMethodName() == null) { // handle case of set with no get method String paramTypeAsString = property.getType().getName(); mapping.setAttributeAccessor(new JAXBSetMethodAttributeAccessor(paramTypeAsString, helper.getClassLoader())); mapping.setIsReadOnly(true); mapping.setSetMethodName(property.getSetMethodName()); } else if (property.getSetMethodName() == null) { mapping.setGetMethodName(property.getGetMethodName()); mapping.setIsWriteOnly(true); } else { mapping.setSetMethodName(property.getSetMethodName()); mapping.setGetMethodName(property.getGetMethodName()); } } } private JavaClass containerClassImpl(JavaClass collectionType) { if (areEquals(collectionType, List.class) || areEquals(collectionType, Collection.class) || collectionType.isArray() || helper.isMapType(collectionType) ) { return jotArrayList; } else if (areEquals(collectionType, Set.class)) { return jotHashSet; } else if (areEquals(collectionType, Deque.class) || areEquals(collectionType, Queue.class)) { return jotLinkedList; } else if (areEquals(collectionType, NavigableSet.class) || areEquals(collectionType, SortedSet.class)) { return jotTreeSet; } else { return collectionType; } } private void processDefaultNamespacePreferences(Collection packageInfos) { if (isDefaultNamespaceAllowed && globalNamespaceResolver.getDefaultNamespaceURI() == null) { for (PackageInfo packageInfo : packageInfos) { NamespaceResolver resolver = packageInfo.getNamespaceInfo().getNamespaceResolver(); String defaultNS = resolver.getDefaultNamespaceURI(); if (defaultNS != null) { globalNamespaceResolver.setDefaultNamespaceURI(defaultNS); break; } } } } private NamespaceResolver getNamespaceResolverForDescriptor(NamespaceInfo info) { return info.getNamespaceResolverForDescriptor(globalNamespaceResolver, isDefaultNamespaceAllowed); } private void logMappingGeneration(Descriptor xmlDescriptor) { String i18nmsg = JAXBLocalization.buildMessage("create_mappings", new Object[] { xmlDescriptor.getJavaClassName() }); AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.MOXY, i18nmsg, new Object[0], false); Iterator mappingIterator = xmlDescriptor.getMappings().iterator(); Mapping xmlMapping; while (mappingIterator.hasNext()) { xmlMapping = (Mapping) mappingIterator.next(); AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.MOXY, xmlMapping.toString(), new Object[0], false); } } }