blob: 668a8967ee8a7350b83c54561db48a74284bcb70 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 1998, 2010 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.jaxb.compiler;
import java.beans.Introspector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlInlineBinaryData;
import javax.xml.bind.annotation.XmlMixed;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlValue;
import javax.xml.namespace.QName;
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.XmlElementWrapper;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter;
import org.eclipse.persistence.jaxb.JAXBEnumTypeConverter;
import org.eclipse.persistence.jaxb.TypeMappingInfo;
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.exceptions.JAXBException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.jaxb.DefaultElementConverter;
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.DomHandlerConverter;
import org.eclipse.persistence.internal.jaxb.MultiArgInstantiationPolicy;
import org.eclipse.persistence.internal.jaxb.WrappedValue;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.oxm.*;
import org.eclipse.persistence.oxm.mappings.*;
import org.eclipse.persistence.oxm.mappings.converters.XMLListConverter;
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.internal.jaxb.XMLJavaTypeConverter;
import org.eclipse.persistence.internal.jaxb.many.JAXBObjectArrayAttributeAccessor;
import org.eclipse.persistence.internal.jaxb.many.JAXBPrimitiveArrayAttributeAccessor;
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.sessions.Project;
import org.eclipse.persistence.internal.libraries.asm.*;
import org.eclipse.persistence.internal.libraries.asm.attrs.SignatureAttribute;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
/**
* INTERNAL:
* <p><b>Purpose:</b>To generate a TopLink OXM Project based on Java Class and TypeInfo information
* <p><b>Responsibilities:</b><ul>
* <li>Generate a XMLDescriptor for each TypeInfo object</li>
* <li>Generate a mapping for each TypeProperty object</li>
* <li>Determine the correct mapping type based on the type of each property</li>
* <li>Set up Converters on mappings for XmlAdapters or JDK 1.5 Enumeration types.</li>
* </ul>
* <p>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 HashMap userDefinedSchemaTypes;
private Helper helper;
private JavaClass jotArrayList;
private JavaClass jotHashSet;
private HashMap<String, NamespaceInfo> packageToNamespaceMappings;
private HashMap<String, TypeInfo> typeInfo;
private HashMap<QName, Class> qNamesToGeneratedClasses;
private HashMap<String, Class> classToGeneratedClasses;
private HashMap<QName, Class> qNamesToDeclaredClasses;
private HashMap<QName, ElementDeclaration> globalElements;
private List<ElementDeclaration> localElements;
private Map<TypeMappingInfo, Class> typeMappingInfoToGeneratedClasses;
private Map<MapEntryGeneratedKey, Class> generatedMapEntryClasses;
private Project project;
private NamespaceResolver globalNamespaceResolver;
private boolean isDefaultNamespaceAllowed;
private Map<TypeMappingInfo, Class>typeMappingInfoToAdapterClasses;
public MappingsGenerator(Helper helper) {
this.helper = helper;
jotArrayList = helper.getJavaClass(ArrayList.class);
jotHashSet = helper.getJavaClass(HashSet.class);
qNamesToGeneratedClasses = new HashMap<QName, Class>();
qNamesToDeclaredClasses = new HashMap<QName, Class>();
classToGeneratedClasses = new HashMap<String, Class>();
globalNamespaceResolver = new NamespaceResolver();
isDefaultNamespaceAllowed = true;
}
public Project generateProject(ArrayList<JavaClass> typeInfoClasses, HashMap<String, TypeInfo> typeInfo, HashMap userDefinedSchemaTypes, HashMap<String, NamespaceInfo> packageToNamespaceMappings, HashMap<QName, ElementDeclaration> globalElements, List<ElementDeclaration> localElements, Map<TypeMappingInfo, Class> typeMappingInfoToGeneratedClass, Map<TypeMappingInfo, Class> typeMappingInfoToAdapterClasses, boolean isDefaultNamespaceAllowed) throws Exception {
this.typeInfo = typeInfo;
this.userDefinedSchemaTypes = userDefinedSchemaTypes;
this.packageToNamespaceMappings = packageToNamespaceMappings;
this.isDefaultNamespaceAllowed = isDefaultNamespaceAllowed;
this.globalElements = globalElements;
this.localElements = localElements;
this.typeMappingInfoToGeneratedClasses = typeMappingInfoToGeneratedClass;
this.typeMappingInfoToAdapterClasses = typeMappingInfoToAdapterClasses;
project = new Project();
// 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();
// apply customizers if necessary
Set<Entry<String, TypeInfo>> entrySet = this.typeInfo.entrySet();
for (Entry<String, TypeInfo> 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(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;
}
public void generateDescriptor(JavaClass javaClass, Project project) {
String jClassName = javaClass.getQualifiedName();
TypeInfo info = typeInfo.get(jClassName);
if (info.isTransient()){
return;
}
NamespaceInfo namespaceInfo = this.packageToNamespaceMappings.get(javaClass.getPackageName());
String packageNamespace = namespaceInfo.getNamespace();
String elementName;
String namespace;
if (javaClass.getSuperclass() != null && javaClass.getSuperclass().getName().equals("javax.xml.bind.JAXBElement")) {
generateDescriptorForJAXBElementSubclass(javaClass, project, namespaceInfo.getNamespaceResolverForDescriptor());
return;
}
XMLDescriptor descriptor = new XMLDescriptor();
org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement rootElem = info.getXmlRootElement();
if (rootElem == null) {
elementName = Introspector.decapitalize(javaClass.getRawName().substring(jClassName.lastIndexOf(".") + 1));
namespace = packageNamespace;
descriptor.setResultAlwaysXMLRoot(true);
} else {
elementName = rootElem.getName();
if (elementName.equals("##default")) {
elementName = Introspector.decapitalize(javaClass.getRawName().substring(jClassName.lastIndexOf(".") + 1));
}
namespace = rootElem.getNamespace();
descriptor.setResultAlwaysXMLRoot(false);
}
descriptor.setJavaClassName(jClassName);
if (info.getFactoryMethodName() != null) {
descriptor.getInstantiationPolicy().useFactoryInstantiationPolicy(info.getObjectFactoryClassName(), info.getFactoryMethodName());
}
if (namespace.equals("##default")) {
namespace = namespaceInfo.getNamespace();
}
JavaClass manyValueJavaClass = helper.getJavaClass(ManyValue.class);
if (!manyValueJavaClass.isAssignableFrom(javaClass)){
if(namespace.length() != 0) {
if(isDefaultNamespaceAllowed && globalNamespaceResolver.getDefaultNamespaceURI() == null && namespace.length() != 0) {
globalNamespaceResolver.setDefaultNamespaceURI(namespace);
namespaceInfo.getNamespaceResolverForDescriptor().setDefaultNamespaceURI(namespace);
}
}
if (rootElem == null) {
descriptor.setDefaultRootElement("");
} else {
if (namespace.length() == 0) {
descriptor.setDefaultRootElement(elementName);
} else {
descriptor.setDefaultRootElement(getQualifiedString(getPrefixForNamespace(namespace, namespaceInfo.getNamespaceResolverForDescriptor(), null), elementName));
}
}
}
descriptor.setNamespaceResolver(namespaceInfo.getNamespaceResolverForDescriptor());
setPKField(descriptor, info);
setSchemaContext(descriptor, info);
project.addDescriptor(descriptor);
info.setDescriptor(descriptor);
}
public void generateDescriptorForJAXBElementSubclass(JavaClass javaClass, Project project, NamespaceResolver nsr) {
String jClassName = javaClass.getQualifiedName();
TypeInfo info = typeInfo.get(jClassName);
XMLDescriptor 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]);
if(helper.isBuiltInJavaType(paramClass)){
XMLDirectMapping mapping = new XMLDirectMapping();
mapping.setAttributeName("value");
mapping.setGetMethodName("getValue");
mapping.setSetMethodName("setValue");
mapping.setXPath("text()");
Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(factoryMethodParamTypes[0], getClass().getClassLoader());
mapping.setAttributeClassification(attributeClassification);
xmlDescriptor.addMapping(mapping);
}else{
XMLCompositeObjectMapping mapping = new XMLCompositeObjectMapping();
mapping.setAttributeName("value");
mapping.setGetMethodName("getValue");
mapping.setSetMethodName("setValue");
mapping.setXPath(".");
mapping.setReferenceClassName(factoryMethodParamTypes[0]);
xmlDescriptor.addMapping(mapping);
}
xmlDescriptor.setNamespaceResolver(nsr);
setPKField(xmlDescriptor, info);
setSchemaContext(xmlDescriptor, info);
project.addDescriptor(xmlDescriptor);
info.setDescriptor(xmlDescriptor);
}
private void setSchemaContext(XMLDescriptor desc, TypeInfo info) {
XMLSchemaClassPathReference schemaRef = new XMLSchemaClassPathReference();
if (info.getClassNamespace() == null || info.getClassNamespace().equals("")) {
schemaRef.setSchemaContext("/" + info.getSchemaTypeName());
} else {
String prefix = desc.getNonNullNamespaceResolver().resolveNamespaceURI(info.getClassNamespace());
if (prefix != null && !prefix.equals("")) {
schemaRef.setSchemaContext("/" + prefix + ":" + info.getSchemaTypeName());
} else {
String generatedPrefix =getPrefixForNamespace(info.getClassNamespace(), desc.getNonNullNamespaceResolver(), null);
schemaRef.setSchemaContext("/" + getQualifiedString(generatedPrefix, info.getSchemaTypeName()));
}
schemaRef.setSchemaContextAsQName(new QName(info.getClassNamespace(), info.getSchemaTypeName()));
}
// 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);
}
private void setPKField(XMLDescriptor desc, TypeInfo info) {
// if there is an @XmlID annotation, we need to add
// primary key field names to the descriptor
if (info.isIDSet()) {
String pkFieldName;
String uri = info.getIDProperty().getSchemaName().getNamespaceURI();
String local = info.getIDProperty().getSchemaName().getLocalPart();
String prefix = null;
if(uri != null && uri.length() != 0) {
prefix = desc.getNamespaceResolver().resolveNamespaceURI(uri);
if(prefix == null) {
prefix = getPrefixForNamespace(uri, desc.getNamespaceResolver(), null, true);
}
}
if (prefix == null) {
prefix = "";
} else {
prefix += ":";
}
if (info.getIDProperty().isAttribute()) {
pkFieldName = ATT + prefix + local;
} else { // assume element
pkFieldName = prefix + local + TXT;
}
desc.addPrimaryKeyFieldName(pkFieldName);
}
}
public void generateMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
if (property.isSetXmlJavaTypeAdapter()) {
// need to check the adapter to determine whether we require a
// direct mapping (anything we can create a descriptor for) or
// a composite mapping
XmlJavaTypeAdapter xja = property.getXmlJavaTypeAdapter();
JavaClass adapterClass = helper.getJavaClass(xja.getValue());
JavaClass valueType = property.getActualType();
// if the value type is something we have a descriptor for, create
// a composite object mapping, otherwise create a direct mapping
if (typeInfo.containsKey(valueType.getQualifiedName())) {
if (isCollectionType(property)) {
generateCompositeCollectionMapping(property, descriptor, namespaceInfo, valueType.getQualifiedName()).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
} else {
generateCompositeObjectMapping(property, descriptor, namespaceInfo, valueType.getQualifiedName()).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
}
} else {
if (isCollectionType(property)) {
if(areEquals(valueType, ClassConstants.ABYTE) || areEquals(valueType, ClassConstants.APBYTE) ||areEquals(valueType, "javax.activation.DataHandler") || areEquals(valueType, "java.awt.Image") || areEquals(valueType, "java.xml.transform.Source") || areEquals(valueType, "javax.mail.internet.MimeMultipart")) {
generateBinaryDataCollectionMapping(property, descriptor, namespaceInfo).setValueConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
} else{
generateDirectCollectionMapping(property, descriptor, namespaceInfo).setValueConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
}
} else {
if (property.isSwaAttachmentRef() || property.isMtomAttachment()) {
generateBinaryMapping(property, descriptor, namespaceInfo).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
} else {
generateDirectMapping(property, descriptor, namespaceInfo).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
}
}
}
return;
}
if (property.isChoice()) {
if(this.isCollectionType(property)) {
generateChoiceCollectionMapping(property, descriptor, namespaceInfo);
} else {
generateChoiceMapping(property, descriptor, namespaceInfo);
}
} else if(property.isInverseReference()) {
generateInverseReferenceMapping(property, descriptor, namespaceInfo);
} else if(property.isAny()) {
if(isCollectionType(property)){
generateAnyCollectionMapping(property, descriptor, namespaceInfo, property.isMixedContent());
}else{
generateAnyObjectMapping(property, descriptor, namespaceInfo);
}
} else if(property.isReference()) {
generateMappingForReferenceProperty((ReferenceProperty)property, descriptor, namespaceInfo);
} else if (property.isMap()){
if(property.isAnyAttribute()) {
generateAnyAttributeMapping(property, descriptor, namespaceInfo);
}else{
generateMapMapping(property, descriptor, namespaceInfo);
}
} else if (isCollectionType(property)) {
generateCollectionMapping(property, descriptor, namespaceInfo);
} else {
JavaClass referenceClass = property.getType();
String referenceClassName = referenceClass.getRawName();
if(referenceClass.isArray() && !referenceClassName.equals("byte[]") && !referenceClassName.equals("java.lang.Byte[]")){
JavaClass componentType = referenceClass.getComponentType();
TypeInfo reference = typeInfo.get(componentType.getQualifiedName());
if(reference !=null){
generateCompositeCollectionMapping(property, descriptor, namespaceInfo, componentType.getQualifiedName());
}else{
generateDirectCollectionMapping(property, descriptor, namespaceInfo);
}
}else{
TypeInfo reference = typeInfo.get(referenceClass.getQualifiedName());
if (reference != null) {
if (property.isXmlIdRef()) {
generateXMLObjectReferenceMapping(property, descriptor, namespaceInfo, referenceClass);
} else {
if (reference.isEnumerationType()) {
generateDirectEnumerationMapping(property, descriptor, namespaceInfo, (EnumTypeInfo) reference);
} else {
generateCompositeObjectMapping(property, descriptor, namespaceInfo, referenceClass.getQualifiedName());
}
}
} else {
if (property.isSwaAttachmentRef() || property.isMtomAttachment()) {
generateBinaryMapping(property, descriptor, namespaceInfo);
} else {
if (referenceClass.getQualifiedName().equals(OBJECT_CLASS_NAME)) {
XMLCompositeObjectMapping coMapping = generateCompositeObjectMapping(property, descriptor, namespaceInfo, null);
coMapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
} else {
generateDirectMapping(property, descriptor, namespaceInfo);
}
}
}
}
}
}
private XMLInverseReferenceMapping generateInverseReferenceMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespace) {
XMLInverseReferenceMapping invMapping = new XMLInverseReferenceMapping();
if (isCollectionType(property.getType())) {
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(XMLConstants.EMPTY_STRING)) {
invMapping.setSetMethodName(setMethodName);
}
if (getMethodName != null && !getMethodName.equals(XMLConstants.EMPTY_STRING)) {
invMapping.setGetMethodName(getMethodName);
}
invMapping.setMappedBy(property.getInverseReferencePropertyName());
if (isCollectionType(property.getType())) {
invMapping.setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
}
descriptor.addMapping(invMapping);
return invMapping;
}
public XMLChoiceObjectMapping generateChoiceMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespace) {
ChoiceProperty prop = (ChoiceProperty)property;
XMLChoiceObjectMapping mapping = new XMLChoiceObjectMapping();
mapping.setAttributeName(property.getPropertyName());
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());
}
}
Iterator<Property> choiceProperties = prop.getChoiceProperties().iterator();
while(choiceProperties.hasNext()) {
Property next = choiceProperties.next();
JavaClass type = next.getType();
XMLField xpath = getXPathForField(next, namespace, !(this.typeInfo.containsKey(type.getQualifiedName())));
mapping.addChoiceElement(xpath.getName(), type.getQualifiedName(), false);
}
descriptor.addMapping(mapping);
return mapping;
}
public XMLChoiceCollectionMapping generateChoiceCollectionMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespace) {
ChoiceProperty prop = (ChoiceProperty)property;
XMLChoiceCollectionMapping mapping = new XMLChoiceCollectionMapping();
mapping.setReuseContainer(true);
mapping.setAttributeName(property.getPropertyName());
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());
}
}
JavaClass collectionType = property.getType();
if (areEquals(collectionType, Collection.class) || areEquals(collectionType, List.class)) {
collectionType = jotArrayList;
} else if (areEquals(collectionType, Set.class)) {
collectionType = jotHashSet;
}
mapping.useCollectionClassName(collectionType.getRawName());
Iterator<Property> choiceProperties = prop.getChoiceProperties().iterator();
while(choiceProperties.hasNext()) {
Property next = choiceProperties.next();
JavaClass type = next.getType();
XMLField xpath = getXPathForField(next, namespace, !(this.typeInfo.containsKey(type.getQualifiedName())));
mapping.addChoiceElement(xpath.getName(), type.getQualifiedName());
}
descriptor.addMapping(mapping);
return mapping;
}
public XMLMapping generateMappingForReferenceProperty(ReferenceProperty property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
if(property.isMixedContent()) {
XMLAnyCollectionMapping mapping = generateAnyCollectionMapping(property, descriptor, namespaceInfo, true);
return mapping;
}
boolean isCollection = isCollectionType(property) || property.getType().isArray();
DatabaseMapping mapping;
if(isCollection) {
mapping = new XMLChoiceCollectionMapping();
((XMLChoiceCollectionMapping) mapping).setReuseContainer(true);
((XMLChoiceCollectionMapping) mapping).setConverter(new JAXBElementRootConverter(Object.class));
} else {
mapping = new XMLChoiceObjectMapping();
((XMLChoiceObjectMapping) mapping).setConverter(new JAXBElementRootConverter(Object.class));
}
mapping.setAttributeName(property.getPropertyName());
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());
((XMLMapping)mapping).setIsWriteOnly(true);
} else {
mapping.setSetMethodName(property.getSetMethodName());
mapping.setGetMethodName(property.getGetMethodName());
}
}
List<ElementDeclaration> referencedElements = property.getReferencedElements();
if(property.getType().isArray()) {
JAXBObjectArrayAttributeAccessor accessor = new JAXBObjectArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy());
accessor.setComponentClassName(property.getType().getComponentType().getRawName());
mapping.setAttributeAccessor(accessor);
}
for(ElementDeclaration element:referencedElements) {
QName elementName = element.getElementName();
boolean isText = !(this.typeInfo.containsKey(element.getJavaTypeName())) && !(element.getJavaTypeName().equals(OBJECT_CLASS_NAME));
XMLField xmlField = this.getXPathForElement("", elementName, namespaceInfo, isText);
//ensure byte[] goes to base64 instead of the default hex.
if(helper.getXMLToJavaTypeMap().get(element.getJavaType().getRawName()) == XMLConstants.BASE_64_BINARY_QNAME) {
xmlField.setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);
}
DatabaseMapping nestedMapping;
if(isCollection){
XMLChoiceCollectionMapping xmlChoiceCollectionMapping = (XMLChoiceCollectionMapping) mapping;
xmlChoiceCollectionMapping.addChoiceElement(xmlField, element.getJavaTypeName());
nestedMapping = (DatabaseMapping) xmlChoiceCollectionMapping.getChoiceElementMappings().get(xmlField);
if(nestedMapping.isAbstractCompositeCollectionMapping()){
((XMLCompositeCollectionMapping)nestedMapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
}
if (nestedMapping.isAbstractCompositeDirectCollectionMapping()) {
((XMLCompositeDirectCollectionMapping) nestedMapping).getNullPolicy().setNullRepresentedByEmptyNode(false);
}
if (element.isList() && nestedMapping.isAbstractCompositeDirectCollectionMapping()) {
XMLListConverter listConverter = new XMLListConverter();
listConverter.setObjectClassName(element.getJavaType().getQualifiedName());
((XMLCompositeDirectCollectionMapping)nestedMapping).setValueConverter(listConverter);
}
}else{
XMLChoiceObjectMapping xmlChoiceObjectMapping = (XMLChoiceObjectMapping) mapping;
xmlChoiceObjectMapping.addChoiceElement(xmlField, element.getJavaTypeName());
nestedMapping = (DatabaseMapping) xmlChoiceObjectMapping.getChoiceElementMappings().get(xmlField);
if(nestedMapping.isAbstractCompositeObjectMapping()){
((XMLCompositeObjectMapping)nestedMapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
}
}
if(!element.isXmlRootElement()) {
Class scopeClass = element.getScopeClass();
if(scopeClass == javax.xml.bind.annotation.XmlElementDecl.GLOBAL.class){
scopeClass = JAXBElement.GlobalScope.class;
}
Class declaredType = helper.getClassForJavaClass(element.getJavaType());
JAXBElementConverter converter = new JAXBElementConverter(xmlField, declaredType, scopeClass);
if(isCollection){
XMLChoiceCollectionMapping xmlChoiceCollectionMapping = (XMLChoiceCollectionMapping) mapping;
Converter originalConverter = xmlChoiceCollectionMapping.getConverter(xmlField);
converter.setNestedConverter(originalConverter);
xmlChoiceCollectionMapping.addConverter(xmlField, converter);
}else{
XMLChoiceObjectMapping xmlChoiceObjectMapping = (XMLChoiceObjectMapping) mapping;
Converter originalConverter = xmlChoiceObjectMapping.getConverter(xmlField);
converter.setNestedConverter(originalConverter);
xmlChoiceObjectMapping.addConverter(xmlField, converter);
}
}
}
descriptor.addMapping(mapping);
return (XMLMapping)mapping;
}
public XMLAnyCollectionMapping generateAnyCollectionMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo, boolean isMixed) {
boolean isLax = false;
String domHandlerClassName = null;
if (property.isAny()) {
isLax = property.isLax();
domHandlerClassName = property.getDomHandlerClassName();
}
XMLAnyCollectionMapping mapping = new XMLAnyCollectionMapping();
mapping.setAttributeName(property.getPropertyName());
mapping.setReuseContainer(true);
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());
}
}
if (!isMixed) {
mapping.setUseXMLRoot(true);
}
Class declaredType = helper.getClassForJavaClass(property.getActualType());
JAXBElementRootConverter jaxbElementRootConverter = new JAXBElementRootConverter(declaredType);
mapping.setConverter(jaxbElementRootConverter);
if (isLax) {
mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
} else {
mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT);
}
if (domHandlerClassName != null) {
jaxbElementRootConverter.setNestedConverter(new DomHandlerConverter(domHandlerClassName));
}
descriptor.addMapping(mapping);
mapping.setMixedContent(isMixed);
if (isMixed) {
mapping.setPreserveWhitespaceForMixedContent(true);
}
return mapping;
}
public XMLCompositeObjectMapping generateCompositeObjectMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo, String referenceClassName) {
XMLCompositeObjectMapping mapping = new XMLCompositeObjectMapping();
mapping.setAttributeName(property.getPropertyName());
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());
}
}
if(property.isNillable()){
mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
}
mapping.setXPath(getXPathForField(property, namespaceInfo, false).getXPath());
if(referenceClassName == null){
((XMLField)mapping.getField()).setIsTypedTextField(true);
((XMLField)mapping.getField()).setSchemaType(XMLConstants.ANY_TYPE_QNAME);
String defaultValue = property.getDefaultValue();
if(null != defaultValue) {
mapping.setConverter(new DefaultElementConverter(defaultValue));
}
}else{
mapping.setReferenceClassName(referenceClassName);
}
if(property.getInverseReferencePropertyName() != null) {
mapping.setContainerAttributeName(property.getInverseReferencePropertyName());
JavaClass backPointerPropertyType = null;
JavaClass referenceClass = property.getActualType();
if(property.getInverseReferencePropertyGetMethodName() != null && property.getInverseReferencePropertySetMethodName() != null && !property.getInverseReferencePropertyGetMethodName().equals("") && !property.getInverseReferencePropertySetMethodName().equals("")) {
mapping.setContainerGetMethodName(property.getInverseReferencePropertySetMethodName());
mapping.setContainerSetMethodName(property.getInverseReferencePropertySetMethodName());
JavaMethod getMethod = referenceClass.getDeclaredMethod(mapping.getContainerGetMethodName(), new JavaClass[]{});
if(getMethod != null) {
backPointerPropertyType = getMethod.getReturnType();
}
} else {
JavaField backpointerField = referenceClass.getDeclaredField(property.getInverseReferencePropertyName());
if(backpointerField != null) {
backPointerPropertyType = backpointerField.getResolvedType();
}
}
if(isCollectionType(backPointerPropertyType)) {
mapping.getInverseReferenceMapping().setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
}
}
if (property.isRequired()) {
((XMLField) mapping.getField()).setRequired(true);
}
descriptor.addMapping(mapping);
return mapping;
}
public XMLDirectMapping generateDirectMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
XMLDirectMapping mapping = new XMLDirectMapping();
mapping.setAttributeName(property.getPropertyName());
String fixedValue = property.getFixedValue();
if(fixedValue != null){
mapping.setIsWriteOnly(true);
}
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());
}
}
if(property.isNillable()){
mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
}
mapping.setField(getXPathForField(property, namespaceInfo, true));
mapping.getNullPolicy().setNullRepresentedByEmptyNode(false);
if (property.getType().getRawName().equals("java.lang.String")) {
mapping.setNullValue("");
}
if (!mapping.getXPath().equals("text()")) {
((NullPolicy) mapping.getNullPolicy()).setSetPerformedForAbsentNode(false);
}
if (property.isRequired()) {
((XMLField) mapping.getField()).setRequired(true);
}
if(property.isXmlElementType()){
Class theClass = helper.getClassForJavaClass(property.getType());
mapping.setAttributeClassification(theClass);
}
if(XMLConstants.QNAME_QNAME.equals(property.getSchemaType())){
((XMLField) mapping.getField()).setSchemaType(XMLConstants.QNAME_QNAME);
}
if(property.getDefaultValue() != null) {
mapping.setNullValue(property.getDefaultValue());
}
descriptor.addMapping(mapping);
return mapping;
}
public XMLBinaryDataMapping generateBinaryMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
XMLBinaryDataMapping mapping = new XMLBinaryDataMapping();
mapping.setAttributeName(property.getPropertyName());
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());
}
}
mapping.setField(getXPathForField(property, namespaceInfo, false));
if (property.isSwaAttachmentRef()) {
((XMLField) mapping.getField()).setSchemaType(XMLConstants.SWA_REF_QNAME);
mapping.setSwaRef(true);
} else if (property.isMtomAttachment()) {
((XMLField) mapping.getField()).setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);
}
if (helper.isAnnotationPresent(property.getElement(), XmlInlineBinaryData.class)) {
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"));
}
}
descriptor.addMapping(mapping);
return mapping;
}
public XMLBinaryDataCollectionMapping generateBinaryDataCollectionMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
XMLBinaryDataCollectionMapping mapping = new XMLBinaryDataCollectionMapping();
mapping.setAttributeName(property.getPropertyName());
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());
}
}
mapping.setField(getXPathForField(property, namespaceInfo, false));
if (property.isSwaAttachmentRef()) {
((XMLField) mapping.getField()).setSchemaType(XMLConstants.SWA_REF_QNAME);
mapping.setSwaRef(true);
} else if (property.isMtomAttachment()) {
((XMLField) mapping.getField()).setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);
}
if (helper.isAnnotationPresent(property.getElement(), XmlInlineBinaryData.class)) {
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();
if(collectionType != null && isCollectionType(collectionType)){
if(collectionType.hasActualTypeArguments()){
JavaClass itemType = (JavaClass)collectionType.getActualTypeArguments().toArray()[0];
try{
Class declaredClass = PrivilegedAccessHelper.getClassForName(itemType.getQualifiedName(), false, helper.getClassLoader());
mapping.setAttributeElementClass(declaredClass);
}catch (Exception e) {
}
}
}else{
mapping.setAttributeElementClass(Byte[].class);
}
if (areEquals(collectionType, Collection.class) || areEquals(collectionType, List.class)) {
collectionType = jotArrayList;
} else if (areEquals(collectionType, Set.class)) {
collectionType = jotHashSet;
}
mapping.useCollectionClassName(collectionType.getRawName());
descriptor.addMapping(mapping);
return mapping;
}
public void generateDirectEnumerationMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo, EnumTypeInfo enumInfo) {
XMLDirectMapping mapping = new XMLDirectMapping();
mapping.setConverter(buildJAXBEnumTypeConverter(mapping, enumInfo));
mapping.setAttributeName(property.getPropertyName());
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());
}
}
mapping.setField(getXPathForField(property, namespaceInfo, true));
descriptor.addMapping(mapping);
}
private JAXBEnumTypeConverter buildJAXBEnumTypeConverter(DatabaseMapping mapping, EnumTypeInfo enumInfo){
JAXBEnumTypeConverter converter = new JAXBEnumTypeConverter(mapping, enumInfo.getClassName(), false);
List<Object> objects = enumInfo.getObjectValues();
List<String> fieldValues = enumInfo.getFieldValues();
for (int i=0; i< objects.size(); i++) {
converter.addConversionValue(fieldValues.get(i), objects.get(i));
}
return converter;
}
public void generateCollectionMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
// check to see if this should be a composite or direct mapping
JavaClass javaClass = property.getActualType();
if (property.isMixedContent()) {
generateAnyCollectionMapping(property, descriptor, namespaceInfo, true);
return;
}
if (javaClass != null && typeInfo.get(javaClass.getQualifiedName()) != null) {
TypeInfo referenceInfo = typeInfo.get(javaClass.getQualifiedName());
if (referenceInfo.isEnumerationType()) {
generateEnumCollectionMapping(property, descriptor, namespaceInfo,(EnumTypeInfo) referenceInfo);
} else {
if (property.isXmlIdRef()) {
generateXMLCollectionReferenceMapping(property, descriptor, namespaceInfo, javaClass);
} else {
generateCompositeCollectionMapping(property, descriptor, namespaceInfo, javaClass.getQualifiedName());
}
}
} else if(!property.isAttribute() && javaClass != null && javaClass.getQualifiedName().equals(OBJECT_CLASS_NAME)){
XMLCompositeCollectionMapping ccMapping = generateCompositeCollectionMapping(property, descriptor, namespaceInfo, null);
ccMapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
}else if(areEquals(javaClass, ClassConstants.ABYTE) || areEquals(javaClass, ClassConstants.APBYTE) ||areEquals(javaClass, "javax.activation.DataHandler") || areEquals(javaClass, "java.awt.Image") || areEquals(javaClass, "java.xml.transform.Source") || areEquals(javaClass, "javax.mail.internet.MimeMultipart")) {
generateBinaryDataCollectionMapping(property, descriptor, namespaceInfo);
} else {
generateDirectCollectionMapping(property, descriptor, namespaceInfo);
}
}
public void generateEnumCollectionMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo, EnumTypeInfo info) {
XMLCompositeDirectCollectionMapping mapping = new XMLCompositeDirectCollectionMapping();
mapping.setAttributeName(property.getPropertyName());
mapping.setReuseContainer(true);
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());
}
}
mapping.setValueConverter(buildJAXBEnumTypeConverter(mapping, info));
JavaClass collectionType = property.getType();
if (areEquals(collectionType, Collection.class) || areEquals(collectionType, List.class)) {
collectionType = jotArrayList;
} else if (areEquals(collectionType, Set.class)) {
collectionType = jotHashSet;
}
mapping.useCollectionClassName(collectionType.getRawName());
mapping.setField(getXPathForField(property, namespaceInfo, true));
if (property.isXmlList()) {
mapping.setUsesSingleNode(true);
}
descriptor.addMapping(mapping);
}
public void generateAnyAttributeMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
XMLAnyAttributeMapping mapping = new XMLAnyAttributeMapping();
mapping.setAttributeName(property.getPropertyName());
mapping.setReuseContainer(true);
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());
}
}
mapping.setSchemaInstanceIncluded(false);
mapping.setNamespaceDeclarationIncluded(false);
descriptor.addMapping(mapping);
}
public void generateAnyObjectMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
XMLAnyObjectMapping mapping = new XMLAnyObjectMapping();
mapping.setAttributeName(property.getPropertyName());
mapping.setMixedContent(false);
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());
}
}
if(property.getType().getQualifiedName().equals("org.w3c.dom.Element")){
mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT);
}else{
mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
}
mapping.setUseXMLRoot(true);
Class declaredType = helper.getClassForJavaClass(property.getActualType());
JAXBElementRootConverter jaxbElementRootConverter = new JAXBElementRootConverter(declaredType);
mapping.setConverter(jaxbElementRootConverter);
descriptor.addMapping(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 tgt
* @return
*/
protected boolean areEquals(JavaClass src, String tgtCanonicalName) {
if (src == null || tgtCanonicalName == null) {
return false;
}
return src.getRawName().equals(tgtCanonicalName);
}
public XMLCompositeCollectionMapping generateMapMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
XMLCompositeCollectionMapping mapping = new XMLCompositeCollectionMapping();
mapping.setAttributeName(property.getPropertyName());
mapping.setReuseContainer(true);
XMLField field = getXPathForField(property, namespaceInfo, false);
JavaClass descriptorClass = helper.getJavaClass(descriptor.getJavaClassName());
JavaClass mapValueClass = helper.getJavaClass(MapValue.class);
if(mapValueClass.isAssignableFrom(descriptorClass)){
mapping.setXPath("entry");
}else{
mapping.setXPath(field.getXPath() + "/entry");
}
Class generatedClass = generateMapEntryClassAndDescriptor(property, descriptor.getNonNullNamespaceResolver());
mapping.setReferenceClass(generatedClass);
String mapClassName = property.getType().getRawName();
mapping.useCollectionClass(ArrayList.class);
mapping.setAttributeAccessor(new MapValueAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), generatedClass, mapClassName));
descriptor.addMapping(mapping);
return mapping;
}
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 = ((JaxbClassLoader)helper.getClassLoader()).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);
XMLDescriptor desc = new XMLDescriptor();
desc.setJavaClass(generatedClass);
desc.addMapping(generateMappingForType(keyType, Property.DEFAULT_KEY_NAME));
desc.addMapping(generateMappingForType(valueType, Property.DEFAULT_VALUE_NAME));
NamespaceResolver newNr = new NamespaceResolver();
String prefix = getPrefixForNamespace(XMLConstants.SCHEMA_INSTANCE_URL, nr, XMLConstants.SCHEMA_INSTANCE_PREFIX, false);
if(prefix != null){
newNr.put(prefix, XMLConstants.SCHEMA_INSTANCE_URL);
}
desc.setNamespaceResolver(newNr);
project.addDescriptor(desc);
}
return generatedClass;
}
private Class generateMapEntryClass(String className, String keyType, String valueType){
ClassWriter cw = new ClassWriter(false);
CodeVisitor cv;
String qualifiedInternalClassName = className.replace('.', '/');
String qualifiedInternalKeyClassName = keyType.replace('.', '/');
String qualifiedInternalValueClassName = valueType.replace('.', '/');
cw.visit(Constants.V1_5, Constants.ACC_PUBLIC + Constants.ACC_SUPER, qualifiedInternalClassName, "java/lang/Object", new String[] { "org/eclipse/persistence/internal/jaxb/many/MapEntry" }, className.substring(className.lastIndexOf(".")));
cw.visitField(Constants.ACC_PRIVATE, "key", "L"+qualifiedInternalKeyClassName+";", null, null);
cw.visitField(Constants.ACC_PRIVATE, "value", "L"+qualifiedInternalValueClassName+";", null, null);
cv = cw.visitMethod(Constants.ACC_PUBLIC, "<init>", "()V", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitMethodInsn(Constants.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
cv.visitInsn(Constants.RETURN);
cv.visitMaxs(1, 1);
cv = cw.visitMethod(Constants.ACC_PUBLIC, "getKey", "()L"+qualifiedInternalKeyClassName+";", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitFieldInsn(Constants.GETFIELD, qualifiedInternalClassName, "key", "L"+qualifiedInternalKeyClassName+";");
cv.visitInsn(Constants.ARETURN);
cv.visitMaxs(1, 1);
cv = cw.visitMethod(Constants.ACC_PUBLIC, "setKey", "(L"+qualifiedInternalKeyClassName+";)V", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitVarInsn(Constants.ALOAD, 1);
cv.visitFieldInsn(Constants.PUTFIELD, qualifiedInternalClassName, "key", "L"+qualifiedInternalKeyClassName+";");
cv.visitInsn(Constants.RETURN);
cv.visitMaxs(2, 2);
cv = cw.visitMethod(Constants.ACC_PUBLIC, "getValue", "()L"+qualifiedInternalValueClassName+";", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitFieldInsn(Constants.GETFIELD, qualifiedInternalClassName, "value", "L"+qualifiedInternalValueClassName+";");
cv.visitInsn(Constants.ARETURN);
cv.visitMaxs(1, 1);
cv = cw.visitMethod(Constants.ACC_PUBLIC, "setValue", "(L"+qualifiedInternalValueClassName+";)V", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitVarInsn(Constants.ALOAD, 1);
cv.visitFieldInsn(Constants.PUTFIELD, qualifiedInternalClassName, "value", "L"+qualifiedInternalValueClassName+";");
cv.visitInsn(Constants.RETURN);
cv.visitMaxs(2, 2);
if(!qualifiedInternalValueClassName.equals("java/lang/Object")){
cv = cw.visitMethod(Constants.ACC_PUBLIC + Constants.ACC_BRIDGE + Constants.ACC_SYNTHETIC, "getValue", "()Ljava/lang/Object;", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitMethodInsn(Constants.INVOKEVIRTUAL, qualifiedInternalClassName, "getValue", "()L"+qualifiedInternalValueClassName+";");
cv.visitInsn(Constants.ARETURN);
cv.visitMaxs(1, 1);
cv = cw.visitMethod(Constants.ACC_PUBLIC + Constants.ACC_BRIDGE + Constants.ACC_SYNTHETIC, "setValue", "(Ljava/lang/Object;)V", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitVarInsn(Constants.ALOAD, 1);
cv.visitTypeInsn(Constants.CHECKCAST, qualifiedInternalValueClassName);
cv.visitMethodInsn(Constants.INVOKEVIRTUAL, qualifiedInternalClassName, "setValue", "(L"+qualifiedInternalValueClassName+";)V");
cv.visitInsn(Constants.RETURN);
cv.visitMaxs(2, 2);
}
if(!qualifiedInternalKeyClassName.equals("java/lang/Object")){
cv = cw.visitMethod(Constants.ACC_PUBLIC + Constants.ACC_BRIDGE + Constants.ACC_SYNTHETIC, "getKey", "()Ljava/lang/Object;", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitMethodInsn(Constants.INVOKEVIRTUAL,qualifiedInternalClassName, "getKey", "()L"+qualifiedInternalKeyClassName+";");
cv.visitInsn(Constants.ARETURN);
cv.visitMaxs(1, 1);
cv = cw.visitMethod(Constants.ACC_PUBLIC + Constants.ACC_BRIDGE + Constants.ACC_SYNTHETIC, "setKey", "(Ljava/lang/Object;)V", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitVarInsn(Constants.ALOAD, 1);
cv.visitTypeInsn(Constants.CHECKCAST, qualifiedInternalKeyClassName);
cv.visitMethodInsn(Constants.INVOKEVIRTUAL, qualifiedInternalClassName, "setKey", "(L"+qualifiedInternalKeyClassName+";)V");
cv.visitInsn(Constants.RETURN);
cv.visitMaxs(2, 2);
}
// CLASS ATRIBUTE
SignatureAttribute attr = new SignatureAttribute("Ljava/lang/Object;Lorg/eclipse/persistence/internal/jaxb/many/MapEntry<L"+qualifiedInternalKeyClassName+";L"+qualifiedInternalValueClassName+";>;");
cw.visitAttribute(attr);
cw.visitEnd();
byte[] classBytes =cw.toByteArray();
JaxbClassLoader loader = (JaxbClassLoader)helper.getClassLoader();
Class generatedClass = loader.generateClass(className, classBytes);
return generatedClass;
}
private DatabaseMapping generateMappingForType(JavaClass theType, String attributeName){
DatabaseMapping mapping;
boolean typeIsObject = theType.getRawName().equals(OBJECT_CLASS_NAME);
if (typeInfo.containsKey(theType.getQualifiedName()) || typeIsObject) {
mapping = new XMLCompositeObjectMapping();
mapping.setAttributeName(attributeName);
((XMLCompositeObjectMapping)mapping).setXPath(attributeName);
if(typeIsObject){
((XMLCompositeObjectMapping)mapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
((XMLField)((XMLCompositeObjectMapping)mapping).getField()).setIsTypedTextField(true);
((XMLField)((XMLCompositeObjectMapping)mapping).getField()).setSchemaType(XMLConstants.ANY_TYPE_QNAME);
}else{
((XMLCompositeObjectMapping)mapping).setReferenceClassName(theType.getQualifiedName());
}
} else {
mapping = new XMLDirectMapping();
mapping.setAttributeName(attributeName);
((XMLDirectMapping)mapping).setXPath(attributeName + "/text()");
QName schemaType = (QName) userDefinedSchemaTypes.get(theType);
if (schemaType == null) {
schemaType = (QName) helper.getXMLToJavaTypeMap().get(theType);
}
((XMLField)((XMLDirectMapping)mapping).getField()).setSchemaType(schemaType);
}
return mapping;
}
public XMLCompositeCollectionMapping generateCompositeCollectionMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo, String referenceClassName) {
XMLCompositeCollectionMapping mapping = new XMLCompositeCollectionMapping();
mapping.setAttributeName(property.getPropertyName());
mapping.setReuseContainer(true);
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());
}
}
if(property.isNillable()){
mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
}
JavaClass collectionType = property.getType();
if(collectionType.isArray()){
JAXBObjectArrayAttributeAccessor accessor = new JAXBObjectArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy());
accessor.setComponentClassName(collectionType.getComponentType().getRawName());
mapping.setAttributeAccessor(accessor);
collectionType = jotArrayList;
}else if (areEquals(collectionType, Collection.class) || areEquals(collectionType, List.class)) {
collectionType = jotArrayList;
} else if (areEquals(collectionType, Set.class)) {
collectionType = jotHashSet;
}
mapping.useCollectionClassName(collectionType.getRawName());
XMLField xmlField = getXPathForField(property, namespaceInfo, false);
mapping.setXPath(xmlField.getXPath());
if(referenceClassName == null){
((XMLField)mapping.getField()).setIsTypedTextField(true);
((XMLField)mapping.getField()).setSchemaType(XMLConstants.ANY_TYPE_QNAME);
}else{
mapping.setReferenceClassName(referenceClassName);
}
if (property.isRequired()) {
((XMLField) mapping.getField()).setRequired(true);
}
if(property.getInverseReferencePropertyName() != null) {
mapping.setContainerAttributeName(property.getInverseReferencePropertyName());
JavaClass backPointerPropertyType = null;
JavaClass referenceClass = property.getActualType();
if(property.getInverseReferencePropertyGetMethodName() != null && property.getInverseReferencePropertySetMethodName() != null && !property.getInverseReferencePropertyGetMethodName().equals("") && !property.getInverseReferencePropertySetMethodName().equals("")) {
mapping.setContainerGetMethodName(property.getInverseReferencePropertySetMethodName());
mapping.setContainerSetMethodName(property.getInverseReferencePropertySetMethodName());
JavaMethod getMethod = referenceClass.getDeclaredMethod(mapping.getContainerGetMethodName(), new JavaClass[]{});
if(getMethod != null) {
backPointerPropertyType = getMethod.getReturnType();
}
} else {
JavaField backpointerField = referenceClass.getDeclaredField(property.getInverseReferencePropertyName());
if(backpointerField != null) {
backPointerPropertyType = backpointerField.getResolvedType();
}
}
if(isCollectionType(backPointerPropertyType)) {
mapping.getInverseReferenceMapping().setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
}
}
descriptor.addMapping(mapping);
return mapping;
}
public XMLCompositeDirectCollectionMapping generateDirectCollectionMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
XMLCompositeDirectCollectionMapping mapping = new XMLCompositeDirectCollectionMapping();
mapping.setAttributeName(property.getPropertyName());
mapping.setReuseContainer(true);
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());
}
}
JavaClass collectionType = property.getType();
if(collectionType.isArray()){
if(collectionType.getComponentType().isPrimitive()){
JAXBPrimitiveArrayAttributeAccessor accessor = new JAXBPrimitiveArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy());
String componentClassName = collectionType.getComponentType().getRawName();
Class primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(componentClassName);
accessor.setComponentClass(primitiveClass);
mapping.setAttributeAccessor(accessor);
Class declaredClass = XMLConversionManager.getDefaultManager().getObjectClass(primitiveClass);
mapping.setAttributeElementClass(declaredClass);
}else{
JAXBObjectArrayAttributeAccessor accessor = new JAXBObjectArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy());
String componentClassName = collectionType.getComponentType().getRawName();
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) {}
}
collectionType = jotArrayList;
}
else if(collectionType != null && isCollectionType(collectionType)){
if(collectionType.hasActualTypeArguments()){
JavaClass itemType = (JavaClass)collectionType.getActualTypeArguments().toArray()[0];
try{
Class declaredClass = PrivilegedAccessHelper.getClassForName(itemType.getRawName(), false, helper.getClassLoader());
mapping.setAttributeElementClass(declaredClass);
}catch (Exception e) {
}
}
}
if (areEquals(collectionType, Collection.class) || areEquals(collectionType, List.class)) {
collectionType = jotArrayList;
} else if (areEquals(collectionType, Set.class)) {
collectionType = jotHashSet;
}
mapping.useCollectionClassName(collectionType.getRawName());
XMLField xmlField = getXPathForField(property, namespaceInfo, true);
mapping.setField(xmlField);
if(helper.isAnnotationPresent(property.getElement(), XmlMixed.class)) {
xmlField.setXPath("text()");
}
if(XMLConstants.QNAME_QNAME.equals(property.getSchemaType())){
((XMLField) mapping.getField()).setSchemaType(XMLConstants.QNAME_QNAME);
}
if (property.getActualType() == null || property.getActualType().getRawName().equals("java.lang.String")) {
mapping.getNullPolicy().setNullRepresentedByEmptyNode(false);
}
if (property.isRequired()) {
((XMLField) mapping.getField()).setRequired(true);
}
if(property.isXmlElementType() && property.getGenericType()!=null ){
Class theClass = helper.getClassForJavaClass(property.getGenericType());
mapping.setAttributeElementClass(theClass);
}
if(xmlField.getXPathFragment().isAttribute()){
mapping.setUsesSingleNode(true);
}
if (property.isXmlList()) {
mapping.setUsesSingleNode(true);
}
descriptor.addMapping(mapping);
return mapping;
}
public String getPrefixForNamespace(String URI, org.eclipse.persistence.oxm.NamespaceResolver namespaceResolver, String suggestedPrefix) {
return getPrefixForNamespace(URI, namespaceResolver, suggestedPrefix, true);
}
public String getPrefixForNamespace(String URI, org.eclipse.persistence.oxm.NamespaceResolver namespaceResolver, String suggestedPrefix, boolean addPrefixToNR) {
String defaultNS = namespaceResolver.getDefaultNamespaceURI();
if(defaultNS != null && URI.equals(defaultNS)){
return null;
}
Enumeration keys = namespaceResolver.getPrefixes();
while (keys.hasMoreElements()) {
String next = (String) keys.nextElement();
String nextUri = namespaceResolver.resolveNamespacePrefix(next);
if (nextUri.equals(URI)) {
return next;
}
}
String prefix = null;
if(suggestedPrefix != null){
prefix = globalNamespaceResolver.generatePrefix(suggestedPrefix);
}else{
prefix = globalNamespaceResolver.generatePrefix();
}
while(null != namespaceResolver.resolveNamespacePrefix(prefix)){
prefix = globalNamespaceResolver.generatePrefix();
}
if(addPrefixToNR){
namespaceResolver.put(prefix, URI);
}
return prefix;
}
public boolean isCollectionType(Property field) {
JavaClass type = field.getType();
return isCollectionType(type);
}
public boolean isCollectionType(JavaClass type) {
if (helper.getJavaClass(Collection.class).isAssignableFrom(type)
|| helper.getJavaClass(List.class).isAssignableFrom(type)
|| helper.getJavaClass(Set.class).isAssignableFrom(type)) {
return true;
}
return false;
}
/**
* 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) {
XMLDescriptor descriptor = typeInfo.get(jClass.getName()).getDescriptor();
if (descriptor == null) {
return;
}
JavaClass superClass = helper.getNextMappedSuperClass(jClass);
if(superClass == null){
return;
}
TypeInfo superTypeInfo = typeInfo.get(superClass.getName());
if(superTypeInfo == null){
return;
}
XMLDescriptor 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());
XMLDescriptor rootDescriptor = rootTypeInfo.getDescriptor();
if (rootDescriptor.getNamespaceResolver() == null) {
rootDescriptor.setNamespaceResolver(new NamespaceResolver());
}
if(rootDescriptor.getInheritancePolicy().getClassIndicatorField() == null){
String prefix = getPrefixForNamespace(XMLConstants.SCHEMA_INSTANCE_URL, rootDescriptor.getNamespaceResolver(),XMLConstants.SCHEMA_INSTANCE_PREFIX);
XMLField classIndicatorField = new XMLField("@"+ getQualifiedString(prefix, "type"));
rootDescriptor.getInheritancePolicy().setClassIndicatorField(classIndicatorField);
}
String sCtx = sRef.getSchemaContext();
if (sCtx.length() > 1 && sCtx.startsWith("/")) {
sCtx = sCtx.substring(1);
}
descriptor.getInheritancePolicy().setParentClassName(superClass.getName());
rootDescriptor.getInheritancePolicy().addClassNameIndicator(jClass.getName(), sCtx);
Object value = rootDescriptor.getInheritancePolicy().getClassNameIndicatorMapping().get(rootDescriptor.getJavaClassName());
if(value == null){
XMLSchemaReference rootSRef = rootDescriptor.getSchemaReference();
if (rootSRef != null && rootSRef.getSchemaContext() != null) {
String rootSCtx = rootSRef.getSchemaContext();
if (rootSCtx.length() > 1 && rootSCtx.startsWith("/")) {
rootSCtx = rootSCtx.substring(1);
}
rootDescriptor.getInheritancePolicy().addClassNameIndicator(rootDescriptor.getJavaClassName(), rootSCtx);
}
}
rootDescriptor.getInheritancePolicy().setShouldReadSubclasses(true);
}
}
private JavaClass getRootMappedSuperClass(JavaClass javaClass){
JavaClass rootMappedSuperClass = javaClass;
JavaClass nextMappedSuperClass = rootMappedSuperClass;
while(nextMappedSuperClass != null){
nextMappedSuperClass = helper.getNextMappedSuperClass(nextMappedSuperClass);
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 = (TypeInfo) this.typeInfo.get(next);
NamespaceInfo namespaceInfo = this.packageToNamespaceMappings.get(javaClass.getPackageName());
if (info.isEnumerationType()) {
continue;
}
XMLDescriptor descriptor = info.getDescriptor();
if (descriptor != null) {
generateMappings(info, descriptor, namespaceInfo);
}
}
}
public void generateMappings(TypeInfo info, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) {
List<Property> propertiesInOrder = info.getNonTransientPropertiesInPropOrder();
for (int i = 0; i < propertiesInOrder.size(); i++) {
Property next = propertiesInOrder.get(i);
if(next != null){
generateMapping(next, descriptor, namespaceInfo);
}
}
}
/**
* Create an XMLCollectionReferenceMapping and add it to the descriptor.
*
* @param property
* @param descriptor
* @param namespaceInfo
* @param referenceClass
*/
public void generateXMLCollectionReferenceMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo, JavaClass referenceClass) {
XMLField srcXPath = getXPathForField(property, namespaceInfo, true);
XMLCollectionReferenceMapping mapping = new XMLCollectionReferenceMapping();
mapping.setAttributeName(property.getPropertyName());
mapping.setReuseContainer(true);
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());
}
}
mapping.setReferenceClassName(referenceClass.getQualifiedName());
JavaClass collectionType = property.getType();
if (areEquals(collectionType, Collection.class) || areEquals(collectionType, List.class)) {
collectionType = jotArrayList;
} else if (areEquals(collectionType, Set.class)) {
collectionType = jotHashSet;
}
mapping.useCollectionClassName(collectionType.getRawName());
// here we need to setup source/target key field associations
TypeInfo referenceType = typeInfo.get(referenceClass.getQualifiedName());
if (referenceType.isIDSet()) {
Property prop = referenceType.getIDProperty();
XMLField tgtXPath = getXPathForField(prop, namespaceInfo, !(helper.isAnnotationPresent(prop.getElement(), XmlAttribute.class)));
mapping.addSourceToTargetKeyFieldAssociation(srcXPath.getXPath(), tgtXPath.getXPath());
}
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(isCollectionType(backPointerPropertyType)) {
mapping.getInverseReferenceMapping().setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
}
}
descriptor.addMapping(mapping);
}
/**
* Create an XMLObjectReferenceMapping and add it to the descriptor.
*
* @param property
* @param descriptor
* @param namespaceInfo
* @param referenceClass
*/
public void generateXMLObjectReferenceMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo, JavaClass referenceClass) {
XMLField srcXPath = getXPathForField(property, namespaceInfo, true);
XMLObjectReferenceMapping mapping = new XMLObjectReferenceMapping();
mapping.setAttributeName(property.getPropertyName());
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());
}
}
mapping.setReferenceClassName(referenceClass.getQualifiedName());
// here we need to setup source/target key field associations
TypeInfo referenceType = typeInfo.get(referenceClass.getQualifiedName());
if (referenceType.isIDSet()) {
Property prop = referenceType.getIDProperty();
XMLField tgtXPath = getXPathForField(prop, namespaceInfo, !(helper.isAnnotationPresent(prop.getElement(), XmlAttribute.class)));
mapping.addSourceToTargetKeyFieldAssociation(srcXPath.getXPath(), tgtXPath.getXPath());
}
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(isCollectionType(backPointerPropertyType)) {
mapping.getInverseReferenceMapping().setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
}
}
descriptor.addMapping(mapping);
}
public XMLField getXPathForField(Property property, NamespaceInfo namespaceInfo, boolean isTextMapping) {
String xPath = "";
XMLField xmlField = null;
if (property.isSetXmlElementWrapper()) {
XmlElementWrapper wrapper = property.getXmlElementWrapper();
String namespace = wrapper.getNamespace();
if (namespace.equals("##default")) {
if (namespaceInfo.isElementFormQualified()) {
namespace = namespaceInfo.getNamespace();
} else {
namespace = "";
}
}
if (namespace.equals("")) {
xPath += (wrapper.getName() + "/");
} else {
String prefix = getPrefixForNamespace(namespace, namespaceInfo.getNamespaceResolverForDescriptor(), null);
xPath += getQualifiedString(prefix, wrapper.getName() + "/");
}
}
if (property.isAttribute()) {
QName name = property.getSchemaName();
String namespace = "";
if (namespaceInfo.isAttributeFormQualified()) {
namespace = namespaceInfo.getNamespace();
}
if (!name.getNamespaceURI().equals("")) {
namespace = name.getNamespaceURI();
}
if (namespace.equals("")) {
xPath += ("@" + name.getLocalPart());
} else {
String prefix = getPrefixForNamespace(namespace, namespaceInfo.getNamespaceResolverForDescriptor(), null);
xPath += "@" + getQualifiedString(prefix, name.getLocalPart());
}
QName schemaType = (QName) userDefinedSchemaTypes.get(property.getClass());
if (property.getSchemaType() != null) {
schemaType = property.getSchemaType();
}
if (schemaType == null) {
schemaType = (QName) helper.getXMLToJavaTypeMap().get(property.getType().getRawName());
}
XMLField field = new XMLField(xPath);
field.setSchemaType(schemaType);
return field;
} else if (helper.isAnnotationPresent(property.getElement(), XmlValue.class)) {
xPath = "text()";
XMLField field = new XMLField(xPath);
QName schemaType = (QName) userDefinedSchemaTypes.get(property.getType());
if (property.getSchemaType() != null) {
schemaType = property.getSchemaType();
}
if (schemaType == null) {
schemaType = (QName) helper.getXMLToJavaTypeMap().get(property.getType());
}
field.setSchemaType(schemaType);
return field;
} else {
QName elementName = property.getSchemaName();
xmlField = getXPathForElement(xPath, elementName, namespaceInfo, isTextMapping);
QName schemaType = (QName) userDefinedSchemaTypes.get(property.getType());
if (property.getSchemaType() != null) {
schemaType = property.getSchemaType();
}
if (schemaType == null){
JavaClass propertyType = property.getActualType();
schemaType = (QName) helper.getXMLToJavaTypeMap().get(propertyType.getRawName());
}
xmlField.setSchemaType(schemaType);
}
return xmlField;
}
public XMLField getXPathForElement(String path, QName elementName, NamespaceInfo namespaceInfo, boolean isText) {
String namespace = "";
if (!elementName.getNamespaceURI().equals("")) {
namespace = elementName.getNamespaceURI();
}
if (namespace.equals("")) {
path += elementName.getLocalPart();
if (isText) {
path += "/text()";
}
} else {
String prefix = getPrefixForNamespace(namespace, namespaceInfo.getNamespaceResolverForDescriptor(), null);
path += getQualifiedString(prefix, elementName.getLocalPart());
if (isText) {
path += "/text()";
}
}
XMLField xmlField = new XMLField(path);
return xmlField;
}
public Property getXmlValueFieldForSimpleContent(ArrayList<Property> 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 void processSchemaType(XmlSchemaType type) {
String schemaTypeName = type.name();
Class javaType = type.type();
if (javaType == null) {
return;
}
QName typeQName = new QName(type.namespace(), schemaTypeName);
this.userDefinedSchemaTypes.put(javaType, typeQName);
}
public String getSchemaTypeNameForClassName(String className) {
String typeName = Introspector.decapitalize(className.substring(className.lastIndexOf('.') + 1));
return typeName;
}
public boolean isMapType(Property property) {
JavaClass mapCls = helper.getJavaClass(java.util.Map.class);
return mapCls.isAssignableFrom(property.getType());
}
public void processGlobalElements(Project 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<ElementDeclaration> elements = new ArrayList<ElementDeclaration>();
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(areEquals(nextElement.getJavaType(), ClassConstants.ABYTE) || areEquals(nextElement.getJavaType(), ClassConstants.APBYTE) ||areEquals(nextElement.getJavaType(), "javax.activation.DataHandler") || areEquals(nextElement.getJavaType(), "java.awt.Image") || areEquals(nextElement.getJavaType(), "java.xml.transform.Source") || areEquals(nextElement.getJavaType(), "javax.mail.internet.MimeMultipart")) {
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){
}
return;
}
}
Class generatedClass = generateWrapperClassAndDescriptor(type, next, nextElement, nextClassName, attributeTypeName);
this.qNamesToGeneratedClasses.put(next, 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("")) {
if(type.getDescriptor().getDefaultRootElement() == null){
type.getDescriptor().setDefaultRootElement(next.getLocalPart());
}else{
type.getDescriptor().addRootElement(next.getLocalPart());
}
} else {
XMLDescriptor descriptor = type.getDescriptor();
String uri = next.getNamespaceURI();
String prefix = getPrefixForNamespace(uri, descriptor.getNamespaceResolver(),null);
if(type.getDescriptor().getDefaultRootElement() == null){
descriptor.setDefaultRootElement(getQualifiedString(prefix, next.getLocalPart()));
}else{
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 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("##default")) {
namespaceUri = "";
}
}
TypeMappingInfo tmi = nextElement.getTypeMappingInfo();
Class generatedClass = null;
JaxbClassLoader loader = (JaxbClassLoader)helper.getClassLoader();
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){
}
XMLDescriptor desc = (XMLDescriptor)project.getDescriptor(generatedClass);
if(desc == null){
desc = new XMLDescriptor();
desc.setJavaClass(generatedClass);
if(nextElement.isList()){
XMLCompositeDirectCollectionMapping 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;")) {
((XMLField)mapping.getField()).setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);
}
else if(nextClassName.equals("javax.xml.namespace.QName")){
((XMLField)mapping.getField()).setSchemaType(XMLConstants.QNAME_QNAME);
}
desc.addMapping(mapping);
} else{
if(nextElement.getJavaTypeName().equals(OBJECT_CLASS_NAME)){
XMLCompositeObjectMapping mapping = new XMLCompositeObjectMapping();
mapping.setAttributeName("value");
mapping.setSetMethodName("setValue");
mapping.setGetMethodName("getValue");
mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
mapping.setXPath(".");
((XMLField)mapping.getField()).setIsTypedTextField(true);
((XMLField)mapping.getField()).setSchemaType(XMLConstants.ANY_TYPE_QNAME);
desc.addMapping(mapping);
}else if(areEquals(nextElement.getJavaType(), ClassConstants.ABYTE) || areEquals(nextElement.getJavaType(), ClassConstants.APBYTE)|| areEquals(nextElement.getJavaType(), "javax.activation.DataHandler") || areEquals(nextElement.getJavaType(), "java.awt.Image") || areEquals(nextElement.getJavaType(), "javax.xml.transform.Source")){
XMLBinaryDataMapping mapping = new XMLBinaryDataMapping();
mapping.setAttributeName("value");
mapping.setXPath(".");
((XMLField)mapping.getField()).setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);
mapping.setSetMethodName("setValue");
mapping.setGetMethodName("getValue");
Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(attributeTypeName, getClass().getClassLoader());
mapping.setAttributeClassification(attributeClassification);
mapping.setShouldInlineBinaryData(false);
if(nextElement.getTypeMappingInfo() != null) {
mapping.setSwaRef(nextElement.isXmlAttachmentRef());
mapping.setMimeType(nextElement.getXmlMimeType());
}
desc.addMapping(mapping);
}else{
XMLDirectMapping mapping = new XMLDirectMapping();
mapping.setAttributeName("value");
mapping.setXPath("text()");
mapping.setSetMethodName("setValue");
mapping.setGetMethodName("getValue");
if(nextElement.getDefaultValue() != null) {
mapping.setNullValue(nextElement.getDefaultValue());
}
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, getClass().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;")) {
((XMLField)mapping.getField()).setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);
}
else if(nextClassName.equals("javax.xml.namespace.QName")){
((XMLField)mapping.getField()).setSchemaType(XMLConstants.QNAME_QNAME);
}
if (nextElement.getJavaTypeAdapterClass() != null) {
mapping.setConverter(new XMLJavaTypeConverter(nextElement.getJavaTypeAdapterClass()));
}
desc.addMapping(mapping);
}
}
if(next != null){
NamespaceInfo info = getNamespaceInfoForURI(namespaceUri);
if(info != null) {
NamespaceResolver resolver = info.getNamespaceResolverForDescriptor();
String prefix = resolver.resolveNamespaceURI(namespaceUri);
desc.setNamespaceResolver(resolver);
desc.setDefaultRootElement("");
desc.addRootElement(getQualifiedString(prefix, next.getLocalPart()));
} else {
if(namespaceUri.equals("")) {
desc.setDefaultRootElement(next.getLocalPart());
} else {
NamespaceResolver resolver = new NamespaceResolver();
String prefix = getPrefixForNamespace(namespaceUri, resolver, null);
desc.setNamespaceResolver(resolver);
desc.setDefaultRootElement("");
desc.addRootElement(getQualifiedString(prefix, next.getLocalPart()));
}
}
}
project.addDescriptor(desc);
}
return generatedClass;
}
private String getQualifiedString(String prefix, String localPart){
if(prefix == null){
return localPart;
}
return prefix + XMLConstants.COLON + localPart;
}
private NamespaceInfo getNamespaceInfoForURI(String namespaceUri) {
Iterator<NamespaceInfo> namespaces = this.packageToNamespaceMappings.values().iterator();
while(namespaces.hasNext()) {
NamespaceInfo next = namespaces.next();
if(next.getNamespace().equals(namespaceUri)) {
return next;
}
}
return null;
}
@SuppressWarnings("unused")
private String getPackageNameForURI(String namespaceUri) {
for(String next:this.packageToNamespaceMappings.keySet()) {
if(packageToNamespaceMappings.get(next).getNamespace().equals(namespaceUri)) {
return next;
}
}
return null;
}
public Class generateWrapperClass(String className, String attributeType, boolean isList, QName theQName) {
org.eclipse.persistence.internal.libraries.asm.ClassWriter cw = new org.eclipse.persistence.internal.libraries.asm.ClassWriter(false);
CodeVisitor cv;
cw.visit(Constants.V1_5, Constants.ACC_PUBLIC, className.replace(".", "/"), org.eclipse.persistence.internal.libraries.asm.Type.getType(WrappedValue.class).getInternalName(), new String[0], 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;
}
cv = cw.visitMethod(Constants.ACC_PUBLIC, "<init>", "()V", null, null);
cv.visitVarInsn(Constants.ALOAD, 0);
cv.visitTypeInsn(Constants.NEW, "javax/xml/namespace/QName");
cv.visitInsn(Constants.DUP);
cv.visitLdcInsn(theQName.getNamespaceURI());
cv.visitLdcInsn(theQName.getLocalPart());
cv.visitMethodInsn(Constants.INVOKESPECIAL, "javax/xml/namespace/QName", "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
cv.visitLdcInsn(Type.getType(fieldType));
cv.visitInsn(Constants.ACONST_NULL);
cv.visitMethodInsn(Constants.INVOKESPECIAL, "org/eclipse/persistence/internal/jaxb/WrappedValue", "<init>", "(Ljavax/xml/namespace/QName;Ljava/lang/Class;Ljava/lang/Object;)V");
cv.visitInsn(Constants.RETURN);
cv.visitMaxs(5, 1);
cw.visitEnd();
byte[] classBytes = cw.toByteArray();
JaxbClassLoader loader = (JaxbClassLoader)helper.getClassLoader();
Class generatedClass = loader.generateClass(className, classBytes);
return generatedClass;
}
public HashMap<QName, Class> getQNamesToGeneratedClasses() {
return qNamesToGeneratedClasses;
}
public HashMap<String, Class> getClassToGeneratedClasses() {
return classToGeneratedClasses;
}
public HashMap<QName, Class> getQNamesToDeclaredClasses() {
return qNamesToDeclaredClasses;
}
private Map<MapEntryGeneratedKey, Class> getGeneratedMapEntryClasses() {
if(generatedMapEntryClasses == null){
generatedMapEntryClasses = new HashMap<MapEntryGeneratedKey, Class>();
}
return generatedMapEntryClasses;
}
private class MapEntryGeneratedKey {
String keyClassName;
String valueClassName;
public MapEntryGeneratedKey(String keyClass, String valueClass){
keyClassName = keyClass;
valueClassName = valueClass;
}
}
}