| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.sdo; |
| |
| import commonj.sdo.Property; |
| import commonj.sdo.Type; |
| import commonj.sdo.helper.HelperContext; |
| |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.Vector; |
| |
| import javax.xml.namespace.QName; |
| import org.eclipse.persistence.sdo.helper.AttributeMimeTypePolicy; |
| import org.eclipse.persistence.sdo.helper.InstanceClassConverter; |
| import org.eclipse.persistence.sdo.helper.ListWrapper; |
| import org.eclipse.persistence.sdo.helper.SDOMethodAttributeAccessor; |
| import org.eclipse.persistence.sdo.helper.SDOXSDHelper; |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.exceptions.SDOException; |
| import org.eclipse.persistence.internal.helper.ClassConstants; |
| import org.eclipse.persistence.internal.security.PrivilegedAccessHelper; |
| import org.eclipse.persistence.mappings.DatabaseMapping; |
| import org.eclipse.persistence.oxm.NamespaceResolver; |
| import org.eclipse.persistence.oxm.XMLConstants; |
| import org.eclipse.persistence.oxm.XMLField; |
| import org.eclipse.persistence.oxm.mappings.FixedMimeTypePolicy; |
| import org.eclipse.persistence.oxm.mappings.MimeTypePolicy; |
| import org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLBinaryDataCollectionMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLChoiceObjectMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLChoiceCollectionMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLCollectionReferenceMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLFragmentCollectionMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLFragmentMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLDirectMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLNillableMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping; |
| import org.eclipse.persistence.oxm.mappings.XMLTransformationMapping; |
| import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy; |
| import org.eclipse.persistence.oxm.mappings.nullpolicy.IsSetNullPolicy; |
| import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType; |
| import org.eclipse.persistence.sdo.helper.SDOFragmentMappingAttributeAccessor; |
| import org.eclipse.persistence.sdo.helper.metadata.NamespaceURITransformer; |
| import org.eclipse.persistence.sdo.helper.metadata.QNameTransformer; |
| |
| /** |
| * <p><b>Purpose</b>:A representation of a Property in the {@link Type type} of a {@link commonj.sdo.DataObject data object}. |
| * <p><b>Responsibilities</b>:<ul> |
| * <li> A property represents an element or attribute in XML |
| * </ul> |
| */ |
| public class SDOProperty implements Property, Serializable { |
| private String propertyName;// unique name for this Type within Type |
| private SDOType type;// the Type of this Property |
| private SDOType containingType; |
| private boolean isContainment;// if this Property is containment |
| private boolean hasMany;// if this Property is many-valued |
| private boolean readOnly;// if this Property is read-only |
| private List aliasNames;// a list of alias names for this Property |
| private Object defaultValue;// default value of this Property |
| private boolean isDefaultSet;// flag whether the default was defined in the schema |
| private int indexInType = -1; |
| private int indexInDeclaredProperties = -1; |
| private SDOProperty opposite;// the opposite Property |
| private boolean xsd; |
| private String xsdLocalName; |
| private Boolean isElement; |
| private boolean global; |
| private boolean namespaceQualified; |
| private transient DatabaseMapping xmlMapping; |
| private Map<Property, Object> propertyValues; |
| private boolean nullable; |
| private QName xsdType; |
| private boolean valueProperty; |
| private List appInfoElements; |
| private Map appInfoMap; |
| private boolean nameCollision; |
| private String uri; |
| private boolean isSubstitutable; |
| private Collection<SDOProperty> substitutableElements; |
| private boolean finalized; |
| private static boolean isActivationAvailable; |
| |
| static { |
| isActivationAvailable = false; |
| try { |
| PrivilegedAccessHelper.getClassForName("jakarta.activation.DataHandler"); |
| PrivilegedAccessHelper.getClassForName("jakarta.mail.internet.MimeMultipart"); |
| isActivationAvailable = true; |
| } catch(ClassNotFoundException ex) { |
| //ignore this exception and let the boolean remain false; |
| } |
| } |
| // hold the context containing all helpers so that we can preserve inter-helper relationships |
| private HelperContext aHelperContext; |
| |
| public SDOProperty(HelperContext aContext) { |
| aHelperContext = aContext; |
| } |
| |
| public SDOProperty(HelperContext aContext, String aName) { |
| this(aContext); |
| setName(aName); |
| } |
| |
| public SDOProperty(HelperContext aContext, String aName, SDOType aType) { |
| this(aContext, aName); |
| setType(aType); |
| } |
| |
| public SDOProperty(HelperContext aContext, String aName, SDOType aType, boolean hasMany) { |
| this(aContext, aName); |
| setType(aType); |
| this.hasMany = hasMany; |
| } |
| |
| public SDOProperty(HelperContext aContext, String aUri, String aName, SDOType aType) { |
| this(aContext, aName, aType); |
| this.setUri(aUri); |
| } |
| |
| /** |
| * Returns the name of the Property. |
| * @return the Property name. |
| */ |
| @Override |
| public String getName() { |
| return propertyName; |
| } |
| |
| /** |
| * Returns the type of the Property. |
| * @return the Property type. |
| */ |
| @Override |
| public SDOType getType() { |
| return type; |
| } |
| |
| /** |
| * Returns whether the Property is many-valued. |
| * @return <code>true</code> if the Property is many-valued. |
| */ |
| @Override |
| public boolean isMany() { |
| return hasMany; |
| } |
| |
| /** |
| * Return whether or not this is an open content property. |
| * @return true if this property is an open content property. |
| */ |
| @Override |
| public boolean isOpenContent() { |
| int idx = getIndexInType(); |
| if (idx == -1) { |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| /** |
| * Returns whether the Property is containment, i.e., whether it represents by-value composition. |
| * @return <code>true</code> if the Property is containment. |
| */ |
| @Override |
| public boolean isContainment() { |
| return isContainment; |
| } |
| |
| /** |
| * Returns the containing type of this Property. |
| * @return the Property's containing type. |
| * @see Type#getProperties() |
| */ |
| @Override |
| public SDOType getContainingType() { |
| return containingType; |
| } |
| |
| /** |
| * Returns the default value this Property will have in a {@link commonj.sdo.DataObject data object} where the Property hasn't been set. |
| * @return the default value. |
| */ |
| @Override |
| public Object getDefault() { |
| if (null == defaultValue) { |
| // return an Object wrapper for numeric primitives or null |
| return type.getPseudoDefault(); |
| } else { |
| return defaultValue; |
| } |
| } |
| |
| /** |
| * Returns true if values for this Property cannot be modified using the SDO APIs. |
| * When true, DataObject.set(Property property, Object value) throws an exception. |
| * Values may change due to other factors, such as services operating on DataObjects. |
| * @return true if values for this Property cannot be modified. |
| */ |
| @Override |
| public boolean isReadOnly() { |
| return readOnly; |
| } |
| |
| /** |
| * Returns the opposite Property if the Property is bi-directional or null otherwise. |
| * @return the opposite Property if the Property is bi-directional or null |
| */ |
| @Override |
| public SDOProperty getOpposite() { |
| return opposite; |
| } |
| |
| public boolean hasAliasNames() { |
| return aliasNames != null && aliasNames.size() > 0; |
| } |
| |
| /** |
| * Return a list of alias names for this Property. |
| * @return a list of alias names for this Property. |
| */ |
| @Override |
| public List getAliasNames() { |
| if (aliasNames == null) { |
| aliasNames = new ArrayList(); |
| } |
| return aliasNames; |
| } |
| |
| /** |
| * INTERNAL: |
| * Assign a string as a unique name of this Property among Properties that belongs |
| * to a DataObject. |
| * @param name a string representing unique name of a property of a DataObject. |
| */ |
| public void setName(String name) { |
| if(null != name) { |
| name = name.intern(); |
| } |
| propertyName = name; |
| } |
| |
| /** |
| * INTERNAL: |
| * Assign a Type to this Property. |
| * @param type the type of this property. |
| */ |
| public void setType(Type type) { |
| this.type = (SDOType) type; |
| if(isNullable()){ |
| updateType(); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Set this Property's Containment which shows parent-child relationship in a tree |
| * of DataObjects. |
| * @param containment a boolean value showing if this Property is containment. |
| */ |
| public void setContainment(boolean containment) { |
| isContainment = containment; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set this property as single-valued(false) or many-valued(true). |
| * Default is false. |
| * @param many a boolean value if this property is many-valued or not. |
| */ |
| public void setMany(boolean many) { |
| hasMany = many; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set this Property as read-only Property. |
| * @param readOnly boolean value implying this Property is readonly. |
| */ |
| public void setReadOnly(boolean readOnly) { |
| this.readOnly = readOnly; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set this Property's alias name list which are unique within the Type. |
| * @param names a list of alias name of this Property. |
| */ |
| public void setAliasNames(List names) { |
| aliasNames = names; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set the containing type of this Property. |
| * @param type a Type which is the containing type of this Property |
| */ |
| public void setContainingType(Type type) { |
| containingType = (SDOType) type; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set the default value of this Property. |
| * @param aDefaultValue an Object to be the default value of this type. |
| */ |
| public void setDefault(Object aDefaultValue) { |
| defaultValue = aDefaultValue; |
| isDefaultSet = true; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set the opposite Property. If not null then this Property is a of a bi-directional Property. |
| * @param property the opposite Property if the Property is bi-directional, otherwise null |
| */ |
| public void setOpposite(Property property) { |
| opposite = (SDOProperty) property; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set if this property was declared in an XML schema. |
| * @param xsd a boolean representing if this property was declared in an XML schema |
| */ |
| public void setXsd(boolean xsd) { |
| this.xsd = xsd; |
| } |
| |
| /** |
| * INTERNAL: |
| * Returns if this property was declared in an XML schema. Defaults to false. |
| * @return if this property was declared in an XML schema |
| */ |
| public boolean isXsd() { |
| return xsd; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set the local name of this property. |
| * @param xsdLocalName a String representing the local name of this property if it was declared in an XML schema |
| */ |
| public void setXsdLocalName(String xsdLocalName) { |
| this.xsdLocalName = xsdLocalName; |
| } |
| |
| /** |
| * INTERNAL: |
| * Returns the local name of the Property. |
| * @return the local name of the property. |
| */ |
| public String getXsdLocalName() { |
| return xsdLocalName; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set if the element or attribute corresponding to this Property is namespace qualified in the XSD. |
| * @param namespaceQualified a boolean representing if the element or attribute corresponding to this Property is namespace qualified in the XSD. |
| **/ |
| public void setNamespaceQualified(boolean namespaceQualified) { |
| this.namespaceQualified = namespaceQualified; |
| } |
| |
| /** |
| * INTERNAL: |
| * Returns if the element or attribute corresponding to this Property should be namespace qualified in the XSD. |
| * @return if the element or attribute corresponding to this Property should be namespace qualified in the XSD. |
| */ |
| public boolean isNamespaceQualified() { |
| return namespaceQualified; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setXmlMapping(DatabaseMapping xmlMapping) { |
| this.xmlMapping = xmlMapping; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public DatabaseMapping getXmlMapping() { |
| return xmlMapping; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setGlobal(boolean global) { |
| this.global = global; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public boolean isGlobal() { |
| return global; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return true if the property is an element, false if the property is an |
| * attribute, and null if it has not been specified. This property has been |
| * added as a performance optimization to reduce the number of Maps created |
| * for the propertyValues property. |
| */ |
| protected Boolean isElement() { |
| return isElement; |
| } |
| |
| /** |
| * INTERNAL: |
| * Alter the default state of the policy to act as a nillable null policy |
| * @param aMapping |
| * @param propertyName |
| */ |
| private void setIsSetNillablePolicyOnMapping(XMLNillableMapping aMapping, Object propertyName) { |
| AbstractNullPolicy aNullPolicy = setIsSetPolicyOnMapping(aMapping, propertyName); |
| // Alter unmarshal policy state |
| aNullPolicy.setNullRepresentedByEmptyNode(false); |
| aNullPolicy.setNullRepresentedByXsiNil(true); |
| // Alter marshal policy state |
| aNullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL); |
| } |
| |
| /** |
| * INTERNAL |
| * Alter the default state of the policy to act as an optional non-nillable null policy |
| * @param aMapping |
| * @param propertyName |
| */ |
| private void setIsSetOptionalPolicyOnMapping(XMLNillableMapping aMapping, Object propertyName) { |
| AbstractNullPolicy aNullPolicy = setIsSetPolicyOnMapping(aMapping, propertyName); |
| // Alter unmarshal policy state |
| aNullPolicy.setNullRepresentedByEmptyNode(false); |
| aNullPolicy.setNullRepresentedByXsiNil(false); |
| // Alter marshal policy state |
| aNullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.EMPTY_NODE);//.ABSENT_NODE); |
| } |
| |
| /** |
| * INTERNAL: |
| * Create and set an IsSetNodePolicy on the mapping - leaving the policy in default state |
| * @param aMapping |
| * @param propertyName |
| * @return |
| */ |
| private AbstractNullPolicy setIsSetPolicyOnMapping(XMLNillableMapping aMapping, Object propertyName) { |
| AbstractNullPolicy aNullPolicy = new IsSetNullPolicy(); |
| // Set the isSet method signature on policy |
| ((IsSetNullPolicy)aNullPolicy).setIsSetMethodName(SDOConstants.SDO_ISSET_METHOD_NAME); |
| // Set fields even though defaults are set |
| //aNullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.EMPTY_NODE); |
| // Parameter type is always String |
| ((IsSetNullPolicy)aNullPolicy).setIsSetParameterTypes(new Class[] { ClassConstants.STRING }); |
| ((IsSetNullPolicy)aNullPolicy).setIsSetParameters(new Object[] { propertyName }); |
| aMapping.setNullPolicy(aNullPolicy); |
| return aNullPolicy; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void buildMapping(String mappingUri) { |
| buildMapping(mappingUri, -1); |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void buildMapping(String mappingUri, int indexToAdd) { |
| if (getContainingType().isDataType()) { |
| return; |
| } |
| |
| if (getType().isChangeSummaryType()) { |
| buildChangeSummaryMapping(); |
| addMappingToOwner(false, indexToAdd); |
| } else if (isNameCollision()) { |
| xmlMapping = new XMLAnyCollectionMapping(); |
| xmlMapping.setAttributeName(getName()); |
| addMappingToOwner(true, indexToAdd); |
| } else { |
| boolean sdoMethodAccessor = true; |
| if (!getType().isDataType()) { |
| if (getType().isDataObjectType()) { |
| getType().setImplClassName(SDOConstants.SDO_DATA_OBJECT_IMPL_CLASS_NAME); |
| if(getXsdType() != null && !getXsdType().equals(SDOConstants.ANY_TYPE_QNAME)) { |
| if (isMany()) { |
| xmlMapping = buildXMLCompositeCollectionMapping(mappingUri); |
| } else { |
| xmlMapping = buildXMLCompositeObjectMapping(mappingUri); |
| } |
| }else{ |
| sdoMethodAccessor = false; |
| if (isMany()) { |
| xmlMapping = buildXMLFragmentCollectionMapping(mappingUri); |
| } else { |
| xmlMapping = buildXMLFragmentMapping(mappingUri); |
| } |
| } |
| } else { |
| if (!getType().isFinalized()) { |
| getType().getNonFinalizedReferencingProps().add(this); |
| getType().getNonFinalizedMappingURIs().add(mappingUri); |
| return; |
| } |
| if(isSubstitutable()) { |
| if(isMany()) { |
| xmlMapping = buildXMLChoiceCollectionMapping(mappingUri); |
| } else { |
| xmlMapping = buildXMLChoiceObjectMapping(mappingUri); |
| } |
| } |
| else if (isMany()) { |
| if (isContainment()) { |
| xmlMapping = buildXMLCompositeCollectionMapping(mappingUri); |
| } else { |
| xmlMapping = buildXMLCollectionReferenceMapping(mappingUri); |
| } |
| } else { |
| if (isContainment()) { |
| xmlMapping = buildXMLCompositeObjectMapping(mappingUri); |
| } else { |
| xmlMapping = buildXMLObjectReferenceMapping(mappingUri); |
| } |
| } |
| } |
| } else { |
| if (isMany()) { |
| MimeTypePolicy mimeTypePolicy = getMimeTypePolicy(); |
| |
| //Removed check for XSD type since XSD type can't be set via typeHelper.define |
| if (isActivationAvailable && (!aHelperContext.getXSDHelper().isAttribute(this) && ((mimeTypePolicy != null) || |
| ((getType().getInstanceClass() != null) && getType().getInstanceClass().getName().equals("jakarta.activation.DataHandler")) || |
| (getXsdType() != null && getXsdType().equals(XMLConstants.BASE_64_BINARY_QNAME))))) { |
| xmlMapping = buildXMLBinaryDataCollectionMapping(mappingUri, mimeTypePolicy); |
| } else { |
| if(!isActivationAvailable && ((getType().getInstanceClass() != null) && getType().getInstanceClass().getName().equals("jakarta.activation.DataHandler"))) { |
| throw SDOException.unableToMapDataHandlerDueToMissingDependency(this.propertyName, this.getContainingType().getQName().toString()); |
| } |
| if(isSubstitutable()) { |
| xmlMapping = buildXMLChoiceCollectionMapping(mappingUri); |
| } else { |
| xmlMapping = buildXMLCompositeDirectCollectionMapping(mappingUri); |
| } |
| } |
| } else { |
| MimeTypePolicy mimeTypePolicy = getMimeTypePolicy(); |
| |
| //Removed check for XSD type since XSD type can't be set via typeHelper.define |
| if (isActivationAvailable && (!aHelperContext.getXSDHelper().isAttribute(this) && ((mimeTypePolicy != null) || |
| ((getType().getInstanceClass() != null) && getType().getInstanceClass().getName().equals("jakarta.activation.DataHandler")) || |
| (getXsdType() != null && getXsdType().equals(XMLConstants.BASE_64_BINARY_QNAME))))) { |
| xmlMapping = buildXMLBinaryDataMapping(mappingUri, mimeTypePolicy); |
| } else { |
| if(!isActivationAvailable && ((getType().getInstanceClass() != null) && getType().getInstanceClass().getName().equals("jakarta.activation.DataHandler"))) { |
| //throw exception |
| throw SDOException.unableToMapDataHandlerDueToMissingDependency(this.propertyName, this.getContainingType().getQName().toString()); |
| } |
| if(isSubstitutable()) { |
| xmlMapping = buildXMLChoiceObjectMapping(mappingUri); |
| } else { |
| if(XMLConstants.QNAME_QNAME.equals(xsdType)) { |
| xmlMapping = buildXMLTransformationMapping(mappingUri); |
| } else { |
| xmlMapping = buildXMLDirectMapping(mappingUri); |
| } |
| } |
| } |
| } |
| } |
| addMappingToOwner(sdoMethodAccessor, indexToAdd); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void buildChangeSummaryMapping() { |
| XMLCompositeObjectMapping aCMapping = new XMLCompositeObjectMapping(); |
| aCMapping.setAttributeName(getName()); |
| String xpath = getQualifiedXPath(getContainingType().getURI(), false); |
| |
| aCMapping.setXPath(xpath); |
| aCMapping.setGetMethodName("getChangeSummary"); |
| aCMapping.setSetMethodName("_setChangeSummary"); |
| aCMapping.setReferenceClass(SDOChangeSummary.class); |
| // Handle nillable element support via the nullable property |
| if (nullable) { |
| setIsSetNillablePolicyOnMapping(aCMapping, propertyName); |
| } else { |
| // elements or attributes |
| setIsSetOptionalPolicyOnMapping(aCMapping, propertyName); |
| } |
| setXmlMapping(aCMapping); |
| |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void addMappingToOwner(boolean sdoMethodAttributeAccessor, int indexToAdd) { |
| if (xmlMapping != null) { |
| if (sdoMethodAttributeAccessor) { |
| SDOMethodAttributeAccessor accessor = null; |
| if (this.getType().isDataType()) { |
| Class theClass = getType().getInstanceClass(); |
| accessor = new SDOMethodAttributeAccessor(this, theClass); |
| } else { |
| accessor = new SDOMethodAttributeAccessor(this); |
| } |
| xmlMapping.setAttributeAccessor(accessor); |
| } |
| if ((getContainingType() != null) && !getContainingType().isDataType()) { |
| ClassDescriptor containingDescriptor = getContainingType().getXmlDescriptor(); |
| xmlMapping.setDescriptor(containingDescriptor); |
| XMLMapping mapping = (XMLMapping)getContainingType().getXmlDescriptor().getMappingForAttributeName(getName()); |
| if (mapping != null) { |
| getContainingType().getXmlDescriptor().getMappings().remove(mapping); |
| } |
| if(indexToAdd == -1) { |
| getContainingType().getXmlDescriptor().getMappings().add(xmlMapping); |
| } else { |
| //iterate over the mappings and find the correct place to insert this mapping relative to the |
| //indecies of the others. |
| SDOType containingType = getContainingType(); |
| Vector<DatabaseMapping> mappings = containingType.getXmlDescriptor().getMappings(); |
| boolean added = false; |
| for(int i = 0; i < mappings.size(); i++) { |
| DatabaseMapping next = mappings.get(i); |
| SDOProperty associatedProperty = containingType.getProperty(next.getAttributeName()); |
| if(associatedProperty != null && indexToAdd < associatedProperty.getIndexInType()) { |
| mappings.add(i, xmlMapping); |
| added = true; |
| break; |
| } |
| } |
| if(!added) { |
| getContainingType().getXmlDescriptor().getMappings().add(xmlMapping); |
| } |
| } |
| } |
| } |
| } |
| |
| private DatabaseMapping buildXMLBinaryDataMapping(String mappingUri, MimeTypePolicy mimeTypePolicy) { |
| XMLBinaryDataMapping mapping = new XMLBinaryDataMapping(); |
| mapping.setAttributeName(getName()); |
| String xpath = getQualifiedXPath(mappingUri, false); |
| mapping.setMimeTypePolicy(mimeTypePolicy); |
| mapping.setXPath(xpath); |
| |
| ((XMLField)mapping.getField()).setSchemaType(XMLConstants.BASE_64_BINARY_QNAME); |
| |
| if (shouldAddInstanceClassConverter()) { |
| InstanceClassConverter converter = new InstanceClassConverter(); |
| converter.setCustomClass(getType().getInstanceClass()); |
| mapping.setConverter(converter); |
| } |
| |
| // Set the null policy on the mapping |
| // Use NullPolicy or IsSetNullPolicy |
| if (nullable) { // elements only |
| setIsSetNillablePolicyOnMapping(mapping, propertyName); |
| } else { |
| // elements or attributes |
| setIsSetOptionalPolicyOnMapping(mapping, propertyName); |
| } |
| mapping.getNullPolicy().setNullRepresentedByEmptyNode(true); |
| |
| return mapping; |
| } |
| |
| private DatabaseMapping buildXMLBinaryDataCollectionMapping(String mappingUri, MimeTypePolicy mimeTypePolicy) { |
| XMLBinaryDataCollectionMapping mapping = new XMLBinaryDataCollectionMapping(); |
| mapping.setAttributeName(getName()); |
| String xpath = getQualifiedXPath(mappingUri, false); |
| |
| if (!getType().getInstanceClassName().equals("jakarta.activation.DataHandler")) { |
| mapping.setAttributeElementClass(getType().getInstanceClass()); |
| } |
| mapping.setMimeTypePolicy(mimeTypePolicy); |
| mapping.setXPath(xpath); |
| |
| ((XMLField)mapping.getField()).setSchemaType(XMLConstants.BASE_64_BINARY_QNAME); |
| |
| if (shouldAddInstanceClassConverter()) { |
| InstanceClassConverter converter = new InstanceClassConverter(); |
| converter.setCustomClass(getType().getInstanceClass()); |
| mapping.setValueConverter(converter); |
| } |
| |
| // mapping.setShouldInlineBinaryData(true); |
| return mapping; |
| } |
| |
| private DatabaseMapping buildXMLTransformationMapping(String mappingUri) { |
| XMLTransformationMapping mapping = new XMLTransformationMapping(); |
| mapping.setAttributeName(getName()); |
| |
| String xpath = getQualifiedXPath(mappingUri, true); |
| String xpathMinusText; |
| int indexOfTextXPath = xpath.lastIndexOf("/text()"); |
| if (indexOfTextXPath < 0) { |
| xpathMinusText = xpath; |
| } else { |
| xpathMinusText = xpath.substring(0, indexOfTextXPath); |
| } |
| QNameTransformer transformer = new QNameTransformer(xpath); |
| |
| mapping.setAttributeTransformer(transformer); |
| mapping.addFieldTransformer(xpath, transformer); |
| |
| NamespaceResolver nsr = new NamespaceResolver(); |
| nsr.put(javax.xml.XMLConstants.XMLNS_ATTRIBUTE, javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI); |
| |
| XMLField field = new XMLField(); |
| field.setNamespaceResolver(nsr); |
| field.setXPath(xpathMinusText + "/@" + javax.xml.XMLConstants.XMLNS_ATTRIBUTE + ":" + QNameTransformer.QNAME_NAMESPACE_PREFIX); |
| |
| mapping.addFieldTransformer(field, new NamespaceURITransformer()); |
| |
| return mapping; |
| } |
| |
| private DatabaseMapping buildXMLDirectMapping(String mappingUri) { |
| XMLDirectMapping mapping = new XMLDirectMapping(); |
| mapping.setNullValueMarshalled(true); |
| mapping.setAttributeName(getName()); |
| String xpath = getQualifiedXPath(mappingUri, true); |
| mapping.setXPath(xpath); |
| |
| if (getXsdType() != null) { |
| ((XMLField)mapping.getField()).setSchemaType(getXsdType()); |
| } |
| |
| if (getType().getInstanceClass() != null) { |
| if (shouldAddInstanceClassConverter()) { |
| InstanceClassConverter converter = new InstanceClassConverter(); |
| converter.setCustomClass(getType().getInstanceClass()); |
| mapping.setConverter(converter); |
| } |
| } |
| |
| // Set the null policy on the mapping |
| // Use NullPolicy or IsSetNullPolicy |
| if (nullable) { // elements only |
| setIsSetNillablePolicyOnMapping(mapping, propertyName); |
| } else { |
| // elements or attributes |
| setIsSetOptionalPolicyOnMapping(mapping, propertyName); |
| } |
| if(this.isDefaultSet()) { |
| mapping.setNullValue(getDefault()); |
| mapping.getNullPolicy().setNullRepresentedByEmptyNode(false); |
| |
| } else { |
| mapping.getNullPolicy().setNullRepresentedByEmptyNode(true); |
| } |
| return mapping; |
| } |
| |
| private DatabaseMapping buildXMLCompositeDirectCollectionMapping(String mappingUri) { |
| XMLCompositeDirectCollectionMapping mapping = new XMLCompositeDirectCollectionMapping(); |
| mapping.setAttributeName(getName()); |
| String xpath = getQualifiedXPath(mappingUri, true); |
| |
| mapping.setXPath(xpath); |
| mapping.setAttributeElementClass(getType().getInstanceClass()); |
| |
| if (getXsdType() != null) { |
| ((XMLField)mapping.getField()).setSchemaType(getXsdType()); |
| } |
| |
| if (getType().equals(SDOConstants.SDO_STRINGS)) { |
| mapping.setUsesSingleNode(true); |
| } |
| |
| if (getType().getInstanceClass() != null) { |
| if (shouldAddInstanceClassConverter()) { |
| InstanceClassConverter converter = new InstanceClassConverter(); |
| converter.setCustomClass(getType().getInstanceClass()); |
| mapping.setValueConverter(converter); |
| } |
| } |
| |
| return mapping; |
| } |
| |
| private DatabaseMapping buildXMLCompositeCollectionMapping(String mappingUri) { |
| XMLCompositeCollectionMapping mapping = new XMLCompositeCollectionMapping(); |
| mapping.setAttributeName(getName()); |
| String xpath = getQualifiedXPath(mappingUri, false); |
| |
| mapping.setXPath(xpath); |
| |
| if (!getType().isDataObjectType()) { |
| QName schemaContext = getType().getXmlDescriptor().getSchemaReference().getSchemaContextAsQName(getType().getXmlDescriptor().getNamespaceResolver()); |
| ((XMLField)mapping.getField()).setLeafElementType(schemaContext); |
| |
| mapping.setReferenceClassName(getType().getImplClassName()); |
| mapping.setReferenceClass(getType().getImplClass()); |
| }else{ |
| if(getXsdType()!= null){ |
| ((XMLField)mapping.getField()).setLeafElementType(getXsdType()); |
| } |
| } |
| mapping.useCollectionClass(ListWrapper.class); |
| |
| // Set null policy on mapping for xsi:nil support: |
| // - aNullPolicy.setNullRepresentedByEmptyNode(false); |
| // - aNullPolicy.setNullRepresentedByXsiNil(true); |
| setIsSetNillablePolicyOnMapping(mapping, propertyName); |
| return mapping; |
| } |
| |
| private DatabaseMapping buildXMLCompositeObjectMapping(String mappingUri) { |
| XMLCompositeObjectMapping mapping = new XMLCompositeObjectMapping(); |
| mapping.setAttributeName(getName()); |
| String xpath = getQualifiedXPath(mappingUri, false); |
| |
| mapping.setXPath(xpath); |
| |
| if (!getType().isDataObjectType()) { |
| QName schemaContext = getType().getXmlDescriptor().getSchemaReference().getSchemaContextAsQName(getType().getXmlDescriptor().getNamespaceResolver()); |
| ((XMLField)mapping.getField()).setLeafElementType(schemaContext); |
| mapping.setReferenceClassName(getType().getImplClassName()); |
| mapping.setReferenceClass(getType().getImplClass()); |
| }else{ |
| if(getXsdType()!= null){ |
| ((XMLField)mapping.getField()).setLeafElementType(getXsdType()); |
| } |
| } |
| |
| // Handle nillable element support via the nullable property |
| if (nullable) { |
| setIsSetNillablePolicyOnMapping(mapping, propertyName); |
| } else { |
| // elements or attributes |
| setIsSetOptionalPolicyOnMapping(mapping, propertyName); |
| } |
| return mapping; |
| } |
| |
| private DatabaseMapping buildXMLObjectReferenceMapping(String mappingUri) { |
| XMLObjectReferenceMapping mapping = new XMLObjectReferenceMapping(); |
| mapping.setAttributeName(getName()); |
| |
| if (getType().isDataObjectType()) { |
| getType().setImplClassName(SDOConstants.SDO_DATA_OBJECT_IMPL_CLASS_NAME); |
| } |
| mapping.setReferenceClassName(getType().getImplClassName()); |
| mapping.setReferenceClass(getType().getImplClass()); |
| |
| String sourcexpath = getQualifiedXPath(getContainingType().getURI(), true); |
| |
| // Get reference ID property if it exists |
| SDOProperty targetIDProp = getIDProp(getType()); |
| |
| if (targetIDProp != null) { |
| String targetxpath = targetIDProp.getQualifiedXPath(getType().getURI(), true); |
| mapping.addSourceToTargetKeyFieldAssociation(sourcexpath, targetxpath); |
| } else { |
| throw SDOException.noTargetIdSpecified(getType().getURI(), getType().getName()); |
| } |
| return mapping; |
| } |
| |
| private DatabaseMapping buildXMLChoiceObjectMapping(String mappingUri) { |
| XMLChoiceObjectMapping mapping = new XMLChoiceObjectMapping(); |
| mapping.setAttributeName(getName()); |
| |
| //First add XPath for this property |
| String xPath = getQualifiedXPath(mappingUri, getType().isDataType()); |
| mapping.addChoiceElement(xPath, getType().getImplClass()); |
| //For each substitutable property, create the xpath and add it. |
| Iterator<SDOProperty> properties = this.getSubstitutableElements().iterator(); |
| while(properties.hasNext()) { |
| SDOProperty nextProp = properties.next(); |
| xPath = nextProp.getQualifiedXPath(mappingUri, nextProp.getType().isDataType(), getContainingType()); |
| mapping.addChoiceElement(xPath, nextProp.getType().getImplClass()); |
| } |
| return mapping; |
| } |
| |
| private DatabaseMapping buildXMLChoiceCollectionMapping(String mappingUri) { |
| XMLChoiceCollectionMapping mapping = new XMLChoiceCollectionMapping(); |
| mapping.setAttributeName(getName()); |
| mapping.useCollectionClass(ListWrapper.class); |
| //First add XPath for this property |
| String xPath = getQualifiedXPath(mappingUri, getType().isDataType()); |
| mapping.addChoiceElement(xPath, getType().getImplClass()); |
| //For each substitutable property, create the xpath and add it. |
| Iterator<SDOProperty> properties = this.getSubstitutableElements().iterator(); |
| while(properties.hasNext()) { |
| SDOProperty nextProp = properties.next(); |
| xPath = nextProp.getQualifiedXPath(mappingUri, nextProp.getType().isDataType(), getContainingType()); |
| mapping.addChoiceElement(xPath, nextProp.getType().getImplClass()); |
| } |
| return mapping; |
| } |
| |
| /** |
| * INTERNAL: |
| * Get the reference ID open content Property if it exists for this Type. |
| * @return id Property or null |
| */ |
| private SDOProperty getIDProp(Type aType) { |
| return (SDOProperty)aType.getProperty((String) aType.get(SDOConstants.ID_PROPERTY)); |
| } |
| |
| private DatabaseMapping buildXMLCollectionReferenceMapping(String mappingUri) { |
| XMLCollectionReferenceMapping mapping = new XMLCollectionReferenceMapping(); |
| mapping.setAttributeName(getName()); |
| |
| if (getType().isDataObjectType()) { |
| getType().setImplClassName(SDOConstants.SDO_DATA_OBJECT_IMPL_CLASS_NAME); |
| } |
| mapping.setReferenceClassName(getType().getImplClassName()); |
| mapping.setReferenceClass(getType().getImplClass()); |
| mapping.setUsesSingleNode(true); |
| |
| mapping.useCollectionClass(ArrayList.class); |
| String sourcexpath = getQualifiedXPath(getContainingType().getURI(), true); |
| |
| // Get reference ID property if it exists |
| SDOProperty targetIDProp = getIDProp(getType()); |
| if (targetIDProp != null) { |
| String targetxpath = targetIDProp.getQualifiedXPath(getType().getURI(), true); |
| mapping.addSourceToTargetKeyFieldAssociation(sourcexpath, targetxpath); |
| } else { |
| throw SDOException.noTargetIdSpecified(getType().getURI(), getType().getName()); |
| } |
| return mapping; |
| } |
| |
| private boolean shouldAddInstanceClassConverter() { |
| Object value = getType().get(SDOConstants.JAVA_CLASS_PROPERTY); |
| if (getType().isDataType() && (value != null)) { |
| Class instanceClass = getType().getInstanceClass(); |
| String instanceClassName = getType().getInstanceClassName(); |
| if (((instanceClassName != null) && instanceClassName.equals("jakarta.activation.DataHandler")) ||// |
| (instanceClass == ClassConstants.ABYTE) ||// |
| (instanceClass == ClassConstants.APBYTE) ||// |
| (instanceClass == ClassConstants.BYTE) ||// |
| (instanceClass == ClassConstants.PBYTE) ||// |
| (instanceClass == ClassConstants.CHAR) ||// |
| (instanceClass == ClassConstants.PCHAR) ||// |
| (instanceClass == ClassConstants.DOUBLE) ||// |
| (instanceClass == ClassConstants.PDOUBLE) ||// |
| (instanceClass == ClassConstants.FLOAT) ||// |
| (instanceClass == ClassConstants.PFLOAT) ||// |
| (instanceClass == ClassConstants.LONG) ||// |
| (instanceClass == ClassConstants.PLONG) ||// |
| (instanceClass == ClassConstants.SHORT) ||// |
| (instanceClass == ClassConstants.PSHORT) ||// |
| (instanceClass == ClassConstants.INTEGER) ||// |
| (instanceClass == ClassConstants.PINT) ||// |
| (instanceClass == ClassConstants.BIGDECIMAL) ||// |
| (instanceClass == ClassConstants.BIGINTEGER) ||// |
| (instanceClass == ClassConstants.STRING) ||// |
| (instanceClass == ClassConstants.UTILDATE) ||// |
| (instanceClass == ClassConstants.CALENDAR) ||// |
| (instanceClass == ClassConstants.TIME) ||// |
| (instanceClass == ClassConstants.SQLDATE) ||// |
| (instanceClass == ClassConstants.TIMESTAMP)) { |
| return false; |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public String getXPath() { |
| String xpath = getXsdLocalName(); |
| if (xpath == null) { |
| xpath = getName(); |
| } |
| return xpath; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public String getQualifiedXPath(String uri, boolean simple) { |
| SDOType containingType = this.getContainingType(); |
| return getQualifiedXPath(uri, simple, containingType); |
| } |
| |
| private String getQualifiedXPath(String uri, boolean simple, SDOType containingType) { |
| if (valueProperty) { |
| return "text()"; |
| } |
| String xpath = getXPath(); |
| String prefix = null; |
| if (isNamespaceQualified()) { |
| prefix = containingType.getXmlDescriptor().getNonNullNamespaceResolver().resolveNamespaceURI(uri); |
| } |
| |
| if (aHelperContext.getXSDHelper().isAttribute(this)) { |
| if (prefix != null) { |
| xpath = prefix + ":" + xpath; |
| } |
| xpath = "@" + xpath; |
| } else { |
| if (prefix != null) { |
| xpath = prefix + ":" + xpath; |
| } |
| if (simple) { |
| xpath = xpath + "/text()"; |
| } |
| } |
| return xpath; |
| } |
| |
| @Override |
| public Object get(Property property) { |
| if(SDOConstants.XMLELEMENT_PROPERTY.equals(property)) { |
| return isElement; |
| } |
| if(null == propertyValues) { |
| return null; |
| } |
| return propertyValues.get(property); |
| } |
| |
| @Override |
| public List getInstanceProperties() { |
| return new ArrayList(getPropertyValues().keySet()); |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setPropertyValues(Map properties) { |
| this.propertyValues = properties; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public Map getPropertyValues() { |
| if (propertyValues == null) { |
| propertyValues = new HashMap<Property, Object>(1); |
| if(null != isElement) { |
| propertyValues.put(SDOConstants.XMLELEMENT_PROPERTY, isElement); |
| } |
| |
| } |
| return propertyValues; |
| } |
| |
| public void setInstanceProperty(Property property, Object value) { |
| if(SDOConstants.XMLELEMENT_PROPERTY.equals(property)) { |
| isElement = (Boolean) value; |
| if(null != propertyValues) { |
| propertyValues.put(SDOConstants.XMLELEMENT_PROPERTY, isElement); |
| } |
| } else { |
| if(null == propertyValues) { |
| if(null != isElement) { |
| propertyValues = new HashMap<Property, Object>(2); |
| propertyValues.put(SDOConstants.XMLELEMENT_PROPERTY, isElement); |
| } else { |
| propertyValues = new HashMap<Property, Object>(1); |
| } |
| } |
| propertyValues.put(property, value); |
| if(SDOConstants.SDOXML_URL.equals(((SDOProperty) property).getUri()) && SDOConstants.SDOXML_DATATYPE.equals(property.getName()) && value instanceof Type) { |
| setType((Type)value); |
| } |
| if(SDOConstants.ORACLE_SDO_URL.equals(((SDOProperty) property).getUri()) && SDOConstants.XML_SCHEMA_TYPE_NAME.equals(property.getName()) && value instanceof Type) { |
| Type schemaType = (Type)value; |
| QName schemaTypeQName = new QName(schemaType.getURI(), schemaType.getName()); |
| setXsdType(schemaTypeQName); |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setIndexInType(int indexInType) { |
| this.indexInType = indexInType; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public int getIndexInType() { |
| if ((indexInType == -1) && (getContainingType() != null)) { |
| indexInType = getContainingType().getProperties().indexOf(this); |
| } |
| return indexInType; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void incrementIndexInType() { |
| // increment index in type if it is already set |
| if (indexInType != -1) { |
| setIndexInType(getIndexInType() + 1); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setNullable(boolean nullable) { |
| this.nullable = nullable; |
| if(nullable && getType() != null){ |
| updateType(); |
| } |
| } |
| |
| @Override |
| public boolean isNullable() { |
| return nullable; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setXsdType(QName xsdType) { |
| this.xsdType = xsdType; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public QName getXsdType() { |
| return xsdType; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public MimeTypePolicy getMimeTypePolicy() { |
| String mimeType = (String)get(SDOConstants.MIME_TYPE_PROPERTY); |
| if (mimeType != null) { |
| return new FixedMimeTypePolicy(mimeType); |
| } else { |
| mimeType = (String)get(SDOConstants.MIME_TYPE_PROPERTY_PROPERTY); |
| if (mimeType != null) { |
| return new AttributeMimeTypePolicy(mimeType); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setIndexInDeclaredProperties(int indexInDeclaredProperties) { |
| this.indexInDeclaredProperties = indexInDeclaredProperties; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public int getIndexInDeclaredProperties() { |
| if ((indexInDeclaredProperties == -1) && (getContainingType() != null)) { |
| indexInDeclaredProperties = getContainingType().getDeclaredProperties().indexOf(this); |
| } |
| return indexInDeclaredProperties; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setValueProperty(boolean valueProperty) { |
| this.valueProperty = valueProperty; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public boolean isValueProperty() { |
| return valueProperty; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setAppInfoElements(List appInfoElements) { |
| this.appInfoElements = appInfoElements; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public List getAppInfoElements() { |
| return appInfoElements; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public Map getAppInfoMap() { |
| if (appInfoMap == null) { |
| appInfoMap = ((SDOXSDHelper)aHelperContext.getXSDHelper()).buildAppInfoMap(appInfoElements); |
| } |
| return appInfoMap; |
| } |
| |
| public void setNameCollision(boolean nameCollision) { |
| this.nameCollision = nameCollision; |
| } |
| |
| public boolean isNameCollision() { |
| return nameCollision; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return whether the default value has been set by the schema |
| * either via a define by an XSD or a DataObject. |
| * @return isDefaultSet |
| */ |
| public boolean isDefaultSet() { |
| return isDefaultSet; |
| } |
| |
| public void setUri(String uri) { |
| if(null != uri) { |
| uri = uri.intern(); |
| } |
| this.uri = uri; |
| } |
| |
| public String getUri() { |
| return uri; |
| } |
| |
| public XMLFragmentMapping buildXMLFragmentMapping(String uri) { |
| XMLFragmentMapping mapping = new XMLFragmentMapping(); |
| mapping.setAttributeName(getName()); |
| mapping.setXPath(getQualifiedXPath(uri, false)); |
| mapping.setAttributeAccessor(new SDOFragmentMappingAttributeAccessor(this, aHelperContext)); |
| |
| return mapping; |
| } |
| |
| public XMLFragmentCollectionMapping buildXMLFragmentCollectionMapping(String mappingUri) { |
| XMLFragmentCollectionMapping mapping = new XMLFragmentCollectionMapping(); |
| mapping.setAttributeName(getName()); |
| mapping.setXPath(getQualifiedXPath(mappingUri, false)); |
| mapping.setAttributeAccessor(new SDOFragmentMappingAttributeAccessor(this, aHelperContext)); |
| |
| return mapping; |
| } |
| |
| public boolean isSubstitutable() { |
| return this.isSubstitutable; |
| } |
| |
| public void setSubstitutable(boolean substitutable) { |
| this.isSubstitutable = substitutable; |
| } |
| |
| public Collection<SDOProperty> getSubstitutableElements() { |
| return this.substitutableElements; |
| } |
| |
| public void setSubstitutableElements(Collection<SDOProperty> elements) { |
| this.substitutableElements = elements; |
| } |
| |
| public void setFinalized(boolean isFinalized){ |
| finalized = isFinalized; |
| } |
| |
| public boolean isFinalized(){ |
| return finalized; |
| } |
| |
| /** |
| * Return a unique hashCode (as an int) for this instance. |
| */ |
| @Override |
| public int hashCode() { |
| int hash = 7; |
| hash = (31 * hash) + ((null == getName()) ? 0 : getName().hashCode()); |
| hash = (31 * hash) + ((null == getUri()) ? 0 : getUri().hashCode()); |
| return hash; |
| } |
| |
| /** |
| * Indicate if a given SDOProperty instance is equal to this instance. |
| * Equality is determined based on name, uri, and type. In addition, |
| * checking will be done to ensure that both properties are to be |
| * serialized in the same manner, ie. both to XML element or both to |
| * XML attribute. |
| * |
| * @param obj Object to compare to this SDOProperty instance |
| * @return true if obj is equal to this SDOProperty instance, false if not |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (obj == null) { |
| return false; |
| } |
| SDOProperty prop; |
| try { |
| prop = (SDOProperty) obj; |
| } catch (ClassCastException ccx) { |
| // not an SDOProperty |
| return false; |
| } |
| // check type |
| if (prop.getType() == null) { |
| if (this.getType() != null) { |
| return false; |
| } |
| } else if (this.getType() == null || !this.getType().equals(prop.getType())) { |
| return false; |
| } |
| // check name and URI |
| if (prop.getName() == null) { |
| if (this.getName() != null) { |
| return false; |
| } |
| } else if (this.getName() == null || !this.getName().equals(prop.getName())) { |
| return false; |
| } |
| if (prop.getUri() == null) { |
| if (this.getUri() != null) { |
| return false; |
| } |
| } else if (this.getUri() == null || !this.getUri().equals(prop.getUri())) { |
| return false; |
| } |
| // check attribute vs. element |
| Boolean propIsElement = prop.isElement(); |
| if(null == isElement) { |
| if(null != propIsElement) { |
| return false; |
| } |
| } else { |
| if(!isElement.equals(propIsElement)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| private void updateType(){ |
| if (type == SDOConstants.SDO_BOOLEAN) { |
| setType(SDOConstants.SDO_BOOLEANOBJECT); |
| } else if (type == SDOConstants.SDO_BYTE) { |
| setType(SDOConstants.SDO_BYTEOBJECT); |
| } else if (type == SDOConstants.SDO_CHARACTER) { |
| setType(SDOConstants.SDO_CHARACTEROBJECT); |
| } else if (type == SDOConstants.SDO_DOUBLE) { |
| setType(SDOConstants.SDO_DOUBLEOBJECT); |
| } else if (type == SDOConstants.SDO_FLOAT) { |
| setType(SDOConstants.SDO_FLOATOBJECT); |
| } else if (type == SDOConstants.SDO_INT) { |
| setType(SDOConstants.SDO_INTOBJECT); |
| } else if (type == SDOConstants.SDO_LONG) { |
| setType(SDOConstants.SDO_LONGOBJECT); |
| } else if (type == SDOConstants.SDO_SHORT) { |
| setType(SDOConstants.SDO_SHORTOBJECT); |
| } |
| } |
| } |