org.eclipse.persistence.jaxb.compiler.MappingsGenerator Maven / Gradle / Ivy
Show all versions of eclipselink Show documentation
/*
* 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