/******************************************************************************* * Copyright (c) 1998, 2015 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 v1.0 and Eclipse Distribution License v1.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: * rbarkhouse - May 26 2008 - 1.0M8 - Initial implementation * rbarkhouse - July 14 2008 - 1.1 - Modified to enable wrappers to have multiple associated QNames ******************************************************************************/ package org.eclipse.persistence.sdo.types; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.xml.namespace.QName; import org.eclipse.persistence.exceptions.SDOException; import org.eclipse.persistence.oxm.NamespaceResolver; import org.eclipse.persistence.oxm.XMLConstants; import org.eclipse.persistence.oxm.XMLDescriptor; import org.eclipse.persistence.oxm.XMLField; import org.eclipse.persistence.oxm.mappings.XMLDirectMapping; import org.eclipse.persistence.oxm.mappings.XMLTransformationMapping; import org.eclipse.persistence.oxm.schema.XMLSchemaURLReference; import org.eclipse.persistence.sdo.SDOConstants; import org.eclipse.persistence.sdo.SDODataObject; import org.eclipse.persistence.sdo.SDOProperty; import org.eclipse.persistence.sdo.SDOType; import org.eclipse.persistence.sdo.helper.SDOClassLoader; import org.eclipse.persistence.sdo.helper.SDOMethodAttributeAccessor; import org.eclipse.persistence.sdo.helper.SDOTypeHelper; import org.eclipse.persistence.sdo.helper.SDOXMLHelper; import org.eclipse.persistence.sdo.helper.extension.SDOUtil; import org.eclipse.persistence.sdo.helper.metadata.NamespaceURITransformer; import org.eclipse.persistence.sdo.helper.metadata.QNameTransformer; import org.eclipse.persistence.sessions.Project; import commonj.sdo.Type; /** * Wrapper for XML datatypes. * @author rbarkhou */ public class SDOWrapperType extends SDOType implements Type { private static final String PACKAGE_NAME = "org.eclipse.persistence.sdo.dataobjects."; private static final String ATTRIBUTE_NAME = "value"; private static final String XPATH = "text()"; private String typeName; private Map<QName, XMLDescriptor> descriptorsMap; public SDOWrapperType(Type aPropertyType, String aTypeName, SDOTypeHelper aSDOTypeHelper) { this(aPropertyType, aTypeName, aSDOTypeHelper, (QName) null, null); } public SDOWrapperType(Type aPropertyType, String aTypeName, SDOTypeHelper aSDOTypeHelper, QName aSchemaType) { this(aPropertyType, aTypeName, aSDOTypeHelper, new QName[] { aSchemaType }, null); } public SDOWrapperType(Type aPropertyType, String aTypeName, SDOTypeHelper aSDOTypeHelper, QName aSchemaType, Class<? extends SDODataObject> implClass) { this(aPropertyType, aTypeName, aSDOTypeHelper, new QName[] { aSchemaType }, new Class[] { implClass }); } public SDOWrapperType(Type aPropertyType, String aTypeName, SDOTypeHelper aSDOTypeHelper, QName[] schemaTypes) { this(aPropertyType, aTypeName, aSDOTypeHelper, schemaTypes, null); } public SDOWrapperType(Type aPropertyType, String aTypeName, SDOTypeHelper aSDOTypeHelper, QName[] schemaTypes, Class<? extends SDODataObject>[] implClasses) { super(SDOConstants.ORACLE_SDO_URL, aTypeName, aSDOTypeHelper); typeName = aTypeName; SDOProperty valueProperty = new SDOProperty(aHelperContext); valueProperty.setName("value"); valueProperty.setType(aPropertyType); valueProperty.setXsdType(schemaTypes[0]); addDeclaredProperty(valueProperty); String normalizedTypeName = SDOUtil.className(aTypeName, true, true, false); if(null == implClasses || null == implClasses[0]) { // Remove any special characters from the type name to create the class name: String implClassName = PACKAGE_NAME + normalizedTypeName + "WrapperImpl" ; setImplClassName(implClassName); getImplClass(); } else { this.javaImplClass = implClasses[0]; this.xmlDescriptor.setJavaClass(javaImplClass); } // Add a new map to typehelperdelegate // interface --> sdotype // add (this) into map during constructor i.e. here // change getType(Class) on typehelperdelegate to check map first initializeDescriptor(xmlDescriptor, schemaTypes[0], aPropertyType, valueProperty); descriptorsMap = new HashMap<QName, XMLDescriptor>(); descriptorsMap.put(schemaTypes[0], xmlDescriptor); setSchemaContext(xmlDescriptor, schemaTypes[0]); if (schemaTypes.length > 1) { for (int i = 1; i < schemaTypes.length; i++) { XMLDescriptor d = new XMLDescriptor(); QName schemaType = schemaTypes[i]; String className = PACKAGE_NAME + normalizedTypeName + "_" + schemaType.getLocalPart() + "Wrapper"; // Now generate the class in memory try { if(null == implClasses || null == implClasses[i]) { SDOClassLoader loader = ((SDOXMLHelper)aHelperContext.getXMLHelper()).getLoader(); d.setJavaClass(loader.loadClass(className + "Impl", this)); } else { d.setJavaClass(implClasses[i]); } } catch (ClassNotFoundException e) { throw SDOException.classNotFound(e, getURI(), getName()); } catch (SecurityException e) { throw SDOException.classNotFound(e, getURI(), getName()); } initializeDescriptor(d, schemaType, aPropertyType, valueProperty); descriptorsMap.put(schemaTypes[i], d); setSchemaContext(d, schemaTypes[i]); } } } /** * Convenience method that sets a schema context (as QName) on a given descriptor. * * If either schemaType or desc is null, no action is performed. * * @param desc XML descriptor to which an XMLSchemaReference will be added * @param schemaType QName that will be set as the schema context QName */ private void setSchemaContext(XMLDescriptor desc, QName schemaType) { if (schemaType == null || desc == null) { return; } XMLSchemaURLReference urlRef = new XMLSchemaURLReference(); urlRef.setSchemaContextAsQName(schemaType); desc.setSchemaReference(urlRef); } private void initializeDescriptor(XMLDescriptor aDescriptor, QName aQName, Type aPropertyType, SDOProperty aValueProperty) { aDescriptor.setNamespaceResolver(null); SDOMethodAttributeAccessor accessor = null; accessor = new SDOMethodAttributeAccessor(aValueProperty); if (XMLConstants.QNAME_QNAME.equals(aQName)) { XMLTransformationMapping mapping = new XMLTransformationMapping(); mapping.setAttributeName(ATTRIBUTE_NAME); QNameTransformer transformer = new QNameTransformer("text()"); mapping.setAttributeTransformer(transformer); mapping.addFieldTransformer(XPATH, transformer); NamespaceResolver nsr = new NamespaceResolver(); nsr.setDefaultNamespaceURI(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI); XMLField field = new XMLField(); field.setNamespaceResolver(nsr); field.setXPath("@" + javax.xml.XMLConstants.XMLNS_ATTRIBUTE); mapping.addFieldTransformer(field, new NamespaceURITransformer()); mapping.setAttributeAccessor(accessor); aDescriptor.addMapping(mapping); } else { XMLDirectMapping mapping = new XMLDirectMapping(); mapping.setAttributeName(ATTRIBUTE_NAME); mapping.setXPath(XPATH); mapping.setAttributeClassification(aPropertyType.getInstanceClass()); ((XMLField) mapping.getField()).setSchemaType(aQName); mapping.setAttributeAccessor(accessor); aDescriptor.addMapping(mapping); } aDescriptor.setIsWrapper(true); } public XMLDescriptor getXmlDescriptor(QName aQName) { XMLDescriptor d = descriptorsMap.get(aQName); if (d == null) { // Return the default return xmlDescriptor; } return d; } public Map getDescriptorsMap() { return descriptorsMap; } public void addDescriptorToProject(Project project) { Iterator<XMLDescriptor> it = descriptorsMap.values().iterator(); while (it.hasNext()) { project.addDescriptor(it.next()); } } public List getAliasNames() { return Collections.EMPTY_LIST; } public List getBaseTypes() { return Collections.EMPTY_LIST; } public String getName() { return typeName; } public String getURI() { return SDOConstants.ORACLE_SDO_URL; } public boolean isAbstract() { return false; } public boolean isDataType() { return false; } public boolean isOpen() { return false; } public boolean isSequenced() { return false; } public boolean isFinalized() { return true; } public boolean isWrapperType() { return true; } public String toString() { StringBuffer str = new StringBuffer(); str.append(getClass().getSimpleName() + "@" + Integer.toHexString(hashCode())); str.append("{uri="); str.append(getURI()); str.append(" name="); str.append(getName()); str.append("}"); return str.toString(); } public static class BooleanObjectWrapperImpl extends SDODataObject {} public static class BooleanWrapperImpl extends SDODataObject {} public static class ByteObjectWrapperImpl extends SDODataObject {} public static class BytesWrapperImpl extends SDODataObject {} public static class ByteWrapperImpl extends SDODataObject {} public static class Bytes_hexBunaryWrapperImpl extends SDODataObject {}; public static class CharacterObjectWrapperImpl extends SDODataObject {} public static class CharacterWrapperImpl extends SDODataObject {} public static class DateTimeWrapperImpl extends SDODataObject {} public static class DateWrapperImpl extends SDODataObject {} public static class DayWrapperImpl extends SDODataObject {} public static class DecimalWrapperImpl extends SDODataObject {} public static class DoubleObjectWrapperImpl extends SDODataObject {} public static class DoubleWrapperImpl extends SDODataObject {} public static class DurationWrapperImpl extends SDODataObject {} public static class FloatObjectWrapperImpl extends SDODataObject {} public static class FloatWrapperImpl extends SDODataObject {} public static class IntegerWrapperImpl extends SDODataObject {} public static class IntObjectWrapperImpl extends SDODataObject {} public static class IntWrapperImpl extends SDODataObject {} public static class LongObjectWrapperImpl extends SDODataObject {} public static class LongWrapperImpl extends SDODataObject {} public static class MonthDayWrapperImpl extends SDODataObject {} public static class MonthWrapperImpl extends SDODataObject {} public static class ObjectWrapperImpl extends SDODataObject {} public static class ShortObjectWrapperImpl extends SDODataObject {} public static class ShortWrapperImpl extends SDODataObject {} public static class StringsWrapperImpl extends SDODataObject {} public static class StringWrapperImpl extends SDODataObject {} public static class TimeWrapperImpl extends SDODataObject {} public static class URIWrapperImpl extends SDODataObject {} public static class URI_QNameWrapperImpl extends SDODataObject {} public static class YearMonthDayWrapperImpl extends SDODataObject {} public static class YearMonthWrapperImpl extends SDODataObject {} public static class YearWrapperImpl extends SDODataObject {} }