blob: 8f5c098bae18b920b620a0adac4795b9c56c3897 [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.jaxb.compiler;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.namespace.QName;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.jaxb.compiler.facets.Facet;
import org.eclipse.persistence.internal.jaxb.GenericsClassHelper;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.jaxb.javamodel.*;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaClassImpl;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAbstractNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElementRef;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElementWrapper;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElements;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJoinNodes;
import org.eclipse.persistence.jaxb.xmlmodel.XmlMarshalNullRepresentation;
import org.eclipse.persistence.jaxb.xmlmodel.XmlTransformation;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLField;
/**
* INTERNAL:
* <p><b>Purpose:</b>To store information about a property on a class during JAXB 2.0 Generation
* <p><b>Responsibilities:</b><ul>
* <li>Store information about the java property such as property name, if it's a method or field,
* and it's type.</li>
* <li>Store some schema-specific information such as the schema name, the schema type, and mimeType</li>
* <li>Store some JAXB 2.0 Runtime specific information such as JAXB 2.0 Adapter classes</li>
* </ul>
* <p>This class is used to store information about a property on a JAXB 2.0 annotated class. It is
* created by the AnnotationsProcessor during pre-processing and stored on a TypeInfo object
*
* @see org.eclipse.persistence.jaxb.compiler.TypeInfo
* @see org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor
*
* @author mmacivor
*/
public class Property implements Cloneable {
private String propertyName;
private QName schemaName;
private boolean isMethodProperty;
private QName schemaType;
private boolean isSwaAttachmentRef;
private boolean isMtomAttachment;
private boolean isInlineBinaryData;
private String mimeType;
private JavaClass type;
private JavaHasAnnotations element;
private JavaClass genericType;
private boolean isAttribute = false;
private boolean isAnyAttribute = false;
private boolean isAnyElement = false;
private Helper helper;
private Map<Object, Object> userProperties;
private List<Facet> facets = new ArrayList<Facet>();
private boolean isXmlValueExtension;
private boolean isXmlIdExtension;
//Original get and set methods for this property
//Used to keep track of overrides
private String originalGetMethodName;
private String originalSetMethodName;
private String getMethodName;
private String setMethodName;
private boolean isRequired = false;
private boolean isNillable = false;
private boolean isXmlList = false;
private boolean isTransient;
private String defaultValue;
private boolean isMixedContent = false;
private boolean xmlElementType = false;
private JavaClass originalType;
private String fixedValue;
private Boolean isReadOnly;
private Boolean isWriteOnly;
private Boolean isCdata;
private boolean isVirtual = false;
private XmlTransformation xmlTransformation;
private XmlAbstractNullPolicy nullPolicy;
private XmlJavaTypeAdapter xmlJavaTypeAdapter;
private XmlElementWrapper xmlElementWrapper;
private boolean isXmlValue = false;
private boolean isXmlId = false;
private boolean isXmlIdRef = false;
private boolean isXmlTransformation = false;
private boolean isXmlLocation = false;
private String inverseReferencePropertyName;
private String inverseReferencePropertyGetMethodName;
private String inverseReferencePropertySetMethodName;
private JavaClass inverseReferencePropertyContainerClass;
private boolean isInverseReference;
private boolean isWriteableInverseReference;
// XmlAnyElement specific attributes
private boolean lax;
private String domHandlerClassName;
private String variableAttributeName;
private String variableClassName;
private boolean variableNodeAttribute;
// XmlMap specific attributes
private JavaClass keyType;
private JavaClass valueType;
private JavaClass valueGenericType;
public static final String DEFAULT_KEY_NAME = "key";
public static final String DEFAULT_VALUE_NAME = "value";
private boolean isMap = false;
private String xmlPath;
// XmlElements specific attributes
private Collection<Property> choiceProperties;
private XmlElements xmlElements;
private boolean isChoice = false;
// XmlElementRef specific attributes
private ArrayList<ElementDeclaration> referencedElements;
private List<XmlElementRef> xmlElementRefs;
private boolean isReference = false;
// XmlJoinNodes specific attributes
private XmlJoinNodes xmlJoinNodes;
private List<XmlJoinNodes> xmlJoinNodesList;
private boolean isSuperClassProperty;
private boolean isTransientType;
private static final String MARSHAL_METHOD_NAME = "marshal";
private JavaClass xmlAdapterClass;
private JavaClass objectClass;
private boolean isTyped;
private Integer minOccurs;
private Integer maxOccurs;
private boolean notNullAnnotated;
public Property() {}
public Property(Helper helper) {
this.helper = helper;
xmlAdapterClass = helper.getJavaClass(XmlAdapter.class);
objectClass = helper.getJavaClass(Object.class);
}
public void setHelper(Helper helper) {
this.helper = helper;
}
/**
* Set an XmlAdapter on this Property. The type, generic type and
* original type will be set as required based on the XmlAdapter's
* marshal method return type and input parameters.
*
*/
public void setAdapterClass(JavaClass adapterCls) {
if (adapterCls.instanceOf() == JavaClassInstanceOf.JAVA_CLASS_IMPL) {
Type[] parameterizedTypeArguments = GenericsClassHelper.getParameterizedTypeArguments(((JavaClassImpl)adapterCls).getJavaClass(), XmlAdapter.class);
if (null != parameterizedTypeArguments && null != parameterizedTypeArguments[0]) {
JavaClass valueTypeClass = getJavaClassFromType(parameterizedTypeArguments[0]);
JavaClass boundType = getJavaClassFromType(parameterizedTypeArguments[1]);
if (valueTypeClass.isInterface()) {
valueTypeClass = objectClass; // during unmarshalling we'll need to instantiate this, so -> no interfaces
}
setTypeFromAdapterClass(valueTypeClass, boundType);
return;
}
}
// If no generic superclass was found, use the old method of looking at
// marshal method return type. This mechanism is used for Dynamic JAXB.
ArrayList<JavaMethod> marshalMethods = new ArrayList<JavaMethod>();
// Look for marshal method
for (JavaMethod method : adapterCls.getMethods()) {
if (!method.isBridge() && method.getName().equals(MARSHAL_METHOD_NAME)) {
final JavaClass[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != 1)
continue;
JavaClass returnType = method.getReturnType();
// Try and find a marshal method where Object is not the return type,
// to avoid processing an inherited default marshal method
if (!returnType.getQualifiedName().equals(objectClass.getQualifiedName()) && !returnType.isInterface()) { // if it's interface, we'll use OBJECT instead later
setTypeFromAdapterClass(returnType, parameterTypes[0]);
return;
}
// Found a marshal method with an Object return type; add
// it to the list in case we need to process it later
marshalMethods.add(method);
}
}
// At this point we didn't find a marshal method with a non-Object return type
for (JavaMethod method : marshalMethods) {
JavaClass paramType = method.getParameterTypes()[0];
// look for non-Object parameter type
if (!paramType.getQualifiedName().equals(objectClass.getQualifiedName())) {
setTypeFromAdapterClass(objectClass, paramType);
return;
}
}
if (!marshalMethods.isEmpty())
setTypeFromAdapterClass(objectClass, null);
// else impossible? - looks like provided adapted doesn't contain marshal(...) method
}
private JavaClass getJavaClassFromType(Type t) {
if (t instanceof Class) {
return helper.getJavaClass((Class) t);
} else if (t instanceof ParameterizedType) {
ParameterizedType paramValueType = (ParameterizedType) t;
Type rawType = paramValueType.getRawType();
if (rawType instanceof Class) {
return helper.getJavaClass((Class) rawType);
}
} else if (t instanceof TypeVariable<?>) {
TypeVariable<?> valueTypeVariable = (TypeVariable<?>) t;
return helper.getJavaClass((Class) valueTypeVariable.getBounds()[0]);
} else if (t instanceof GenericArrayType) {
GenericArrayType genericArrayValueType = (GenericArrayType) t;
Type rawType = genericArrayValueType.getGenericComponentType();
if (rawType instanceof Class) {
return helper.getJavaClass(Array.newInstance((Class) rawType, 1).getClass());
}
}
return objectClass;
}
/**
* This convenience method will set the generic type, type and original type
* for this Porperty as required based on a given 'new' type and parameter
* type. This method will typically be called when setting the type during
* adapter processing.
*
*/
private void setTypeFromAdapterClass(JavaClass newType, JavaClass parameterType) {
boolean isArray = this.getType().isArray() && !this.getType().getRawName().equals("byte[]");
boolean isParamTypeArray = false;
if(parameterType != null) {
isParamTypeArray = parameterType.isArray() && !parameterType.getRawName().equals("byte[]");
}
if ((helper.isCollectionType(this.getType()) || isArray) && !(helper.isCollectionType(parameterType) || isParamTypeArray)) {
this.setGenericType(newType);
} else {
this.setOriginalType(this.getType());
this.setType(newType);
}
}
public JavaHasAnnotations getElement() {
return element;
}
public void setElement(JavaHasAnnotations element) {
this.element = element;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public QName getSchemaName() {
return this.schemaName;
}
public void setSchemaName(QName schemaName) {
this.schemaName = schemaName;
}
public boolean isMethodProperty() {
return isMethodProperty;
}
public void setMethodProperty(boolean isMethod) {
isMethodProperty = isMethod;
}
public void setType(JavaClass cls) {
if(cls == null){
return;
}
if(type != null && type == cls){
return;
}
String clsName= cls.getRawName();
if(helper.isCollectionType(cls)){
genericType = getGenericType(cls, 0, helper);
type = cls;
}else if(cls.isArray() && !clsName.equals("byte[]") ){
type = cls;
genericType = cls.getComponentType();
}else{
type = cls;
genericType = null;
}
boolean isNewTypeMap = helper.getJavaClass(java.util.Map.class).isAssignableFrom(type);
setIsMap(isNewTypeMap);
if(isMap()){
if(type.getPackageName().startsWith("java.")) {
Object[] types = type.getActualTypeArguments().toArray();
if(types.length >=2){
keyType = (JavaClass)types[0];
valueType = (JavaClass)types[1];
if (helper.isCollectionType(valueType)) {
valueGenericType = getGenericType(valueType, 0, helper);
} else if (valueType.isArray() && !"byte[]".equals(valueType.getRawName())) {
valueGenericType = valueType.getComponentType();
} else {
valueGenericType = null;
}
}else{
keyType = helper.getJavaClass(Object.class);
valueType = helper.getJavaClass(Object.class);
}
} else {
keyType = getGenericType(type, 0, helper);
valueType = getGenericType(type, 1, helper);
}
}
}
private JavaClass getGenericType(JavaClass cls, int argument, Helper helper){
Collection typeArgs = cls.getActualTypeArguments();
Object[] typeArgsArray = typeArgs.toArray();
JavaClass genericType = null;
if(cls.getPackageName().startsWith("java.")) {
if(typeArgs.size() > argument){
Iterator iterator = typeArgs.iterator();
for(int x=0; x<argument; x++) {
iterator.next();
}
return (JavaClass) iterator.next();
} else {
return helper.getJavaClass(Object.class);
}
}else{
Map<String, JavaClass> variableToType = null;
if(cls instanceof JavaClassImpl){
variableToType = new HashMap<String, JavaClass>();
TypeVariable[] tvs = ((JavaClassImpl)cls).getJavaClass().getTypeParameters();
if(tvs.length == typeArgsArray.length){
for (int x = 0; x < tvs.length; x++) {
variableToType.put(tvs[x].getName(), (JavaClass)typeArgsArray[x]);
}
}
}
Type genericTypeType = getGenericType(cls.getGenericSuperclass(), argument, variableToType);
if(null == genericTypeType) {
for(Type genericInterface : cls.getGenericInterfaces()) {
genericTypeType = getGenericType(genericInterface, argument, variableToType);
if(null != genericTypeType) {
break;
}
}
}
if(genericTypeType instanceof TypeVariable) {
TypeVariable typeVariable = (TypeVariable) genericTypeType;
JavaClass existing = variableToType.get(typeVariable.getName());
if( existing != null){
return existing;
}else{
Type[] typeVariableBounds = typeVariable.getBounds();
if(typeVariableBounds.length > 0) {
genericTypeType = typeVariableBounds[0];
}
}
}
if(genericTypeType instanceof Class) {
genericType = helper.getJavaClass((Class) genericTypeType);
}
if(null == genericType || genericTypeType == Object.class) {
if(typeArgs.size() > argument){
Iterator iterator = typeArgs.iterator();
for(int x=0; x<argument; x++) {
iterator.next();
}
genericType = (JavaClass) iterator.next();
} else {
genericType = helper.getJavaClass(Object.class);
}
}
return genericType;
}
}
private Type getGenericType(Type type, int argument, Map<String, JavaClass> variableToType) {
if(type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type rawType = parameterizedType.getRawType();
if(rawType instanceof Class) {
Class rawTypeClass = (Class) rawType;
Type[] typeArgs = parameterizedType.getActualTypeArguments();
TypeVariable[] tvs = rawTypeClass.getTypeParameters();
if(tvs.length == typeArgs.length){
for (int x = 0; x < tvs.length; x++) {
String name = tvs[x].getName();
Type theType = typeArgs[x];
if(!variableToType.containsKey(name) && theType instanceof Class){
variableToType.put(name, helper.getJavaClass((Class)theType));
}
}
}
if(rawTypeClass.getPackage().getName().startsWith("java.")) {
Type actualType = parameterizedType.getActualTypeArguments()[argument];
return actualType;
}
Type genericType = getGenericType(rawType, argument, variableToType);
if(genericType != null) {
return genericType;
} else {
return parameterizedType.getActualTypeArguments()[argument];
}
} else {
return getGenericType(parameterizedType.getRawType(), argument,variableToType);
}
} else if(type instanceof Class) {
Class clazz = (Class) type;
for(Type genericInterface : clazz.getGenericInterfaces()) {
Type genericType = getGenericType(genericInterface, argument, variableToType);
if(null != genericType) {
return genericType;
}
}
return getGenericType(clazz.getGenericSuperclass(), argument, variableToType);
}
return null;
}
public JavaClass getType() {
return type;
}
public JavaClass getGenericType() {
return genericType;
}
public void setGenericType(JavaClass genericType) {
this.genericType = genericType;
}
public QName getSchemaType() {
return schemaType;
}
public void setSchemaType(QName type) {
schemaType = type;
}
public boolean isSwaAttachmentRef() {
return isSwaAttachmentRef;
}
public void setIsSwaAttachmentRef(boolean b) {
isSwaAttachmentRef = b;
}
public boolean isMtomAttachment() {
return isMtomAttachment;
}
public void setIsMtomAttachment(boolean b) {
isMtomAttachment = b;
}
/**
* Indicates if XOP encoding should be disabled for datatypes that
* are bound to base64-encoded binary data in XML.
*
* @return true if XOP encoding should be disabled for datatypes
* that are bound to base64-encoded binary data in XML; false if
* not
*/
public boolean isInlineBinaryData() {
return isInlineBinaryData;
}
/**
* Sets the flag that indicates if XOP encoding should be disabled
* for datatypes that are bound to base64-encoded binary data in
* XML.
* @param b if true, XOP encoding will be disabled for datatypes
* that are bound to base64-encoded binary data in XML.
*/
public void setisInlineBinaryData(boolean b) {
isInlineBinaryData = b;
}
public boolean isRequired() {
return isRequired;
}
public boolean isTransientType() {
return isTransientType;
}
public void setTransientType(boolean isTransientType) {
this.isTransientType = isTransientType;
}
public void setIsRequired(boolean b) {
isRequired = b;
}
public String getMimeType() {
return mimeType;
}
public void setMimeType(String mType) {
mimeType = mType;
}
public boolean isAttribute() {
return isAttribute || isAnyAttribute;
}
public boolean isAnyAttribute() {
return isAnyAttribute;
}
public void setIsAttribute(boolean attribute) {
isAttribute = attribute;
}
public void setIsAnyAttribute(boolean anyAtribute) {
isAnyAttribute = anyAtribute;
}
public String getGetMethodName() {
return getMethodName;
}
public void setGetMethodName(String methodName) {
getMethodName = methodName;
}
public String getSetMethodName() {
return setMethodName;
}
public void setSetMethodName(String methodName) {
setMethodName = methodName;
}
public String getOriginalGetMethodName() {
return originalGetMethodName;
}
public void setOriginalGetMethodName(String methodName) {
originalGetMethodName = methodName;
}
public String getOriginalSetMethodName() {
return originalSetMethodName;
}
public void setOriginalSetMethodName(String methodName) {
originalSetMethodName = methodName;
}
/**
* Indicates if this property represents a choice property.
*
*/
public boolean isChoice() {
return isChoice;
}
/**
* Set flag to indicate whether this property represents a choice
* property.
*
*/
public void setChoice(boolean choice) {
isChoice = choice;
}
/**
* Returns indicator for XmlAnyElement
*
*/
public boolean isAny() {
return isAnyElement;
}
/**
* Set indicator for XmlAnyElement.
*
*/
public void setIsAny(boolean isAnyElement) {
this.isAnyElement = isAnyElement;
}
/**
* Indicates if this Property is a reference property.
*
*/
public boolean isReference() {
return isReference;
}
/**
* Set flag to indicate whether this property represents a reference
* property.
*
*/
public void setIsReference(boolean isReference) {
this.isReference = isReference;
}
public boolean isNillable() {
return isNillable;
}
public void setNillable(boolean isNillable) {
this.isNillable = isNillable;
}
public boolean isTransient() {
return isTransient;
}
public void setTransient(boolean isTransient) {
this.isTransient = isTransient;
}
/**
* @param defaultValue the defaultValue to set
*/
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
/**
* @return the defaultValue
*/
public String getDefaultValue() {
return defaultValue;
}
/**
* @return the isSetDefaultValue
*/
public boolean isSetDefaultValue() {
return defaultValue != null;
}
public boolean isMixedContent() {
return isMixedContent;
}
public void setMixedContent(boolean b) {
this.isMixedContent = b;
}
public void setHasXmlElementType(boolean hasXmlElementType) {
this.xmlElementType = hasXmlElementType;
}
public boolean isXmlElementType() {
return xmlElementType;
}
/**
* Return the generic type if it was set (collection or array item type) otherwise return the
* type of this property
*
*/
public JavaClass getActualType() {
if (genericType != null) {
return genericType;
}
return type;
}
/**
* Get the original type of the property. This is typically used when
* the type has been changed via @XmlElement annotation and the
* original type is desired.
*
*/
public JavaClass getOriginalType() {
if (originalType == null) // in case of adapter which returns the same type - original type is the same as type
return type;
return originalType;
}
/**
* Set the original type of the property. This is typically used when
* the type will been changed via @XmlElement annotation and the
* original type may be needed.
*/
public void setOriginalType(JavaClass type) {
originalType = type;
}
/**
* Indicates if an XmlJavaTypeAdapter has been set, i.e. the
* xmlJavaTypeAdapter property is non-null.
*
* @return true if xmlJavaTypeAdapter is non-null, false otherwise
* @see XmlJavaTypeAdapter
*/
public boolean isSetXmlJavaTypeAdapter() {
return getXmlJavaTypeAdapter() != null;
}
/**
* Return the xmlJavaTypeAdapter set on this Property.
*
* @return xmlJavaTypeAdapter, or null if not set
* @see XmlJavaTypeAdapter
*/
public XmlJavaTypeAdapter getXmlJavaTypeAdapter() {
return xmlJavaTypeAdapter;
}
/**
* Set an XmlJavaTypeAdapter on this Property. This call sets the adapterClass
* property to the given adapter's value.
*
* @see XmlJavaTypeAdapter
*/
public void setXmlJavaTypeAdapter(XmlJavaTypeAdapter xmlJavaTypeAdapter) {
this.xmlJavaTypeAdapter = xmlJavaTypeAdapter;
if (xmlJavaTypeAdapter == null) {
setType(originalType);
} else {
// set the adapter class
setAdapterClass(helper.getJavaClass(xmlJavaTypeAdapter.getValue()));
}
}
/**
* Indicates if an XmlElementWrapper has been set, i.e. the
* xmlElementWrapper property is non-null.
* @return true if xmlElementWrapper is non-null, false otherwise
*/
public boolean isSetXmlElementWrapper() {
return getXmlElementWrapper() != null;
}
/**
* Return the XmlElementWrapper set on this property.
*
* @return XmlElementWrapper instance if non-null, null otherwise
*/
public XmlElementWrapper getXmlElementWrapper() {
return xmlElementWrapper;
}
/**
* Set the XmlElementWrapper for this property.
*
*/
public void setXmlElementWrapper(XmlElementWrapper xmlElementWrapper) {
this.xmlElementWrapper = xmlElementWrapper;
}
/**
* Set the isXmlValue property.
*
*/
public void setIsXmlValue(boolean isXmlValue) {
this.isXmlValue = isXmlValue;
}
/**
* Indicates if this property is an XmlValue.
*
*/
public boolean isXmlValue() {
return this.isXmlValue;
}
/**
* Set the isXmlValueExtension property.
*
*/
public void setIsXmlValueExtension(boolean isXmlValueExtension) {
this.isXmlValueExtension = isXmlValueExtension;
}
/**
* Indicates if this property is an XmlValueExtension.
*
*/
public boolean isXmlValueExtension() {
return this.isXmlValueExtension;
}
/**
* Set the isXmlList property.
*
*/
public void setIsXmlList(boolean isXmlList) {
this.isXmlList = isXmlList;
if(isXmlList){
this.setNillable(false);
}
}
/**
* Indicates if this property is an XmlList.
*
*/
public boolean isXmlList() {
return this.isXmlList;
}
public String getInverseReferencePropertyName() {
return this.inverseReferencePropertyName;
}
public void setInverseReferencePropertyName(String name) {
this.inverseReferencePropertyName = name;
}
public String getInverseReferencePropertyGetMethodName() {
return this.inverseReferencePropertyGetMethodName;
}
public String getInverseReferencePropertySetMethodName() {
return this.inverseReferencePropertySetMethodName;
}
public void setInverseReferencePropertyGetMethodName(String methodName) {
this.inverseReferencePropertyGetMethodName = methodName;
}
public void setInverseReferencePropertySetMethodName(String methodName) {
this.inverseReferencePropertySetMethodName = methodName;
}
public JavaClass getInverseReferencePropertyContainerClass() {
return this.inverseReferencePropertyContainerClass;
}
public void setInverseReferencePropertyContainerClass(JavaClass cls) {
this.inverseReferencePropertyContainerClass = cls;
}
/**
* Indicates if this property is an ID field.
*
*/
public boolean isXmlId() {
return isXmlId;
}
/**
* Sets the indicator that identifies this property as an ID field.
*
*/
public void setIsXmlId(boolean isXmlId) {
this.isXmlId = isXmlId;
}
/**
* Indicates if this property is an ID extension field.
*
*/
public boolean isXmlIdExtension() {
return isXmlIdExtension;
}
/**
* Sets the indicator that identifies this property as an ID extension field.
*
*/
public void setIsXmlIdExtension(boolean isXmlIdExtension) {
this.isXmlIdExtension = isXmlIdExtension;
}
/**
* Indicates if this property is a reference to an ID field.
*
*/
public boolean isXmlIdRef() {
return isXmlIdRef;
}
/**
* Sets the indicator that identifies this property as a reference
* to an ID field.
*
*/
public void setIsXmlIdRef(boolean isXmlIdRef) {
this.isXmlIdRef = isXmlIdRef;
}
// XmlAnyElement specific methods
/**
* Used with XmlAnyElement.
*
*/
public boolean isLax() {
return lax;
}
/**
* Used with XmlAnyElement.
*
*/
public void setLax(boolean b) {
lax = b;
}
/**
* Return the DomHandler class name.
* Used with XmlAnyElement.
*
*/
public String getDomHandlerClassName() {
return domHandlerClassName;
}
/**
* Set the DomHandler class name.
* Used with XmlAnyElement.
*
*/
public void setDomHandlerClassName(String domHandlerClassName) {
this.domHandlerClassName = domHandlerClassName;
}
public JavaClass getKeyType() {
return keyType;
}
public void setKeyType(JavaClass keyType) {
this.keyType = keyType;
}
public JavaClass getValueType() {
return valueType;
}
/**
* Return the generic type if it was set (collection or array item type) otherwise return the
* type of this property
*
*/
public JavaClass getActualValueType() {
if (valueGenericType != null) {
return valueGenericType;
}
return valueType;
}
public void setValueType(JavaClass valueType) {
this.valueType = valueType;
}
public JavaClass getValueGenericType() {
return valueGenericType;
}
public void setValueGenericType(JavaClass valueGenericType) {
this.valueGenericType = valueGenericType;
}
public boolean isMap() {
return isMap;
}
private void setIsMap(boolean isMap) {
this.isMap = isMap;
}
public boolean isInverseReference() {
return isInverseReference;
}
public void setInverseReference(boolean isInverseReference, boolean isWriteable) {
this.isInverseReference = isInverseReference;
this.isWriteableInverseReference = isWriteable;
}
public boolean isWriteableInverseReference(){
return isWriteableInverseReference;
}
/**
* Return the XmlElements object set for this Property. Typically
* this will only be set if we are dealing with a 'choice'.
*
*/
public XmlElements getXmlElements() {
return xmlElements;
}
/**
* Set the XmlElements object for this Property. Typically
* this will only be set if we are dealing with a 'choice'.
*
*/
public void setXmlElements(XmlElements xmlElements) {
this.xmlElements = xmlElements;
}
/**
* Return the choice properties set on this property. Typically this
* will only contain properties if we are dealing with a 'choice'.
*
*/
public Collection<Property> getChoiceProperties() {
return this.choiceProperties;
}
/**
* Set the choice properties for this property. Typically this
* will only contain properties if we are dealing with a 'choice'.
*
*/
public void setChoiceProperties(Collection<Property> properties) {
this.choiceProperties = properties;
}
/**
* Return the List of XmlElementRef(s) for this Property.
*
*/
public List<XmlElementRef> getXmlElementRefs() {
return xmlElementRefs;
}
/**
* Set the List of XmlElementRef(s) for this Property.
*
*/
public void setXmlElementRefs(List<XmlElementRef> xmlElementRefs) {
this.xmlElementRefs = xmlElementRefs;
}
/**
* Add an ElementDeclaration to the list of referenced elements. Typically this
* will only contain ElementDeclarations if we are dealing with a 'reference'.
*
*/
public void addReferencedElement(ElementDeclaration element) {
if (referencedElements == null) {
referencedElements = new ArrayList<ElementDeclaration>();
}
if (!referencedElements.contains(element)) {
referencedElements.add(element);
}
}
/**
* Return the list of referenced elements. Typically this will only
* contain ElementDeclarations if we are dealing with a 'reference'.
*
*/
public List<ElementDeclaration> getReferencedElements() {
return referencedElements;
}
public String getFixedValue() {
return fixedValue;
}
public void setFixedValue(String fixedValue) {
this.fixedValue = fixedValue;
}
/**
* Indicates if this property is mapped by position, i.e. 'name="data[1]"',
* or is mapped by attribute value (predicate mapping), i.e.
* 'personal-info[@pi-type='last-name']/name[@name-type='surname']/text()'
*
*/
public boolean isPositional() {
if (getXmlPath() == null) {
return false;
}
Field<XMLConversionManager, NamespaceResolver> field = new XMLField(getXmlPath());
XPathFragment frag = field.getXPathFragment();
// loop until we have the last non-null, non-attribute, non-text fragment
while (true) {
if (frag.getNextFragment() != null && !frag.getNextFragment().isAttribute() && !frag.getNextFragment().nameIsText()) {
frag = frag.getNextFragment();
} else {
break;
}
}
return frag.containsIndex() || frag.getPredicate() != null;
}
/**
* Flag the mapping for this Property as read-only.
*
* @param isReadOnly the true/false value to set
*/
public void setReadOnly(boolean isReadOnly) {
this.isReadOnly = isReadOnly;
}
/**
* Indicates if the mapping for this Property is read-only.
*
* @return true if read-only, false if not
*/
public boolean isReadOnly() {
if (isReadOnly == null) {
return false;
}
return isReadOnly;
}
/**
* Indicates if the isReadOnly flag was set via external metadata.
*
*/
public boolean isSetReadOnly() {
return isReadOnly != null;
}
/**
* Flag the mapping for this Property as write-only.
*
* @param isWriteOnly the true/false value to set
*/
public void setWriteOnly(boolean isWriteOnly) {
this.isWriteOnly = isWriteOnly;
}
/**
* @return true if write-only, false if not
*/
public boolean isWriteOnly() {
if (isWriteOnly == null) {
return false;
}
return isWriteOnly;
}
/**
* Indicates if the isWriteOnly flag was set via external metadata.
*
*/
public boolean isSetWriteOnly() {
return isWriteOnly != null;
}
/**
* Flag the mapping for this Property as containing character data.
*
* @param isCdata the true/false value to set
*/
public void setCdata(boolean isCdata) {
this.isCdata = isCdata;
}
/**
* @return true if character data, false if not
*/
public boolean isCdata() {
if (isCdata == null) {
return false;
}
return isCdata;
}
/**
* Indicates if the isCdata flag was set via external metadata.
*
*/
public boolean isSetCdata() {
return isCdata != null;
}
/**
* Return the xpath for this property.
*
*/
public String getXmlPath() {
return xmlPath;
}
/**
* Set the xpath for this property.
*
*/
public void setXmlPath(String xmlPath) {
this.xmlPath = xmlPath;
}
/**
* Indicates if an xpath is set for this property.
*
*/
public boolean isSetXmlPath() {
return xmlPath != null;
}
/**
* Returns the null policy for this property.
*
* @return null policy or null if not set
*/
public XmlAbstractNullPolicy getNullPolicy() {
return nullPolicy;
}
/**
* Set the null policy for this property.
*
*/
public void setNullPolicy(XmlAbstractNullPolicy nullPolicy) {
this.nullPolicy = nullPolicy;
}
/**
* Indicates if a null policy is set for this property.
*
*/
public boolean isSetNullPolicy() {
return nullPolicy != null;
}
/**
* Indicates if nillable='true' should be set on a given schema component.
* This will typically be called by SchemaGenerator.
* The value returned will be true if one of the following is true:
*
* - isNillable
* - isSetNullPolicy {@literal &&} xsi-nil-represents-null == 'true'
* - isSetNullPolicy {@literal &&} null-representation-for-xml == 'XSI_NIL'
*
*/
public boolean shouldSetNillable() {
if (isNillable()) {
return true;
}
if (isSetNullPolicy()) {
return (getNullPolicy().isXsiNilRepresentsNull() || getNullPolicy().getNullRepresentationForXml() == XmlMarshalNullRepresentation.XSI_NIL);
}
return false;
}
/**
* Return the Map of user-defined properties.
*
*/
public Map<Object, Object> getUserProperties() {
return userProperties;
}
/**
* Set the Map of user-defined properties.
*
*/
public void setUserProperties(Map<Object, Object> userProperties) {
this.userProperties = userProperties;
}
/**
* Indicates if a map of userProperties is set for this property.
*
* @return true if the userProperties property has been set,
* i.e. is non-null, otherwise false
*/
public boolean isSetUserProperties() {
return userProperties != null;
}
/**
* Return the XmlTransformation set on this property.
*
* @return the XmlTransformation set on this property, or null if one has not been set.
*/
public XmlTransformation getXmlTransformation() {
return xmlTransformation;
}
/**
* Set the XmlTransformation for this property. The info contained in
* the XmlTransformation will be used to construct an
* XmlTransformationMapping.
*
*/
public void setXmlTransformation(XmlTransformation xmlTransformation) {
this.xmlTransformation = xmlTransformation;
}
/**
* Indicates if an XmlTransformation is set for this porperty.
*
* @return true if the xmlTransformation property has been set,
* i.e. is non-null, otherwise false
*/
public boolean isSetXmlTransformation() {
return xmlTransformation != null;
}
/**
* Indicates if this property represents an XmlTransformation.
*
* @return value of isXmlTransformation property
*/
public boolean isXmlTransformation() {
return isXmlTransformation;
}
/**
* Set flag that indicates if this property represents an XmlTransformation.
*
*/
public void setIsXmlTransformation(boolean isXmlTransformation) {
this.isXmlTransformation = isXmlTransformation;
}
/**
* Set XmlJoinNodes for this property.
*
* @param xmlJoinNodes the xmlJoinNodes to set
*/
public void setXmlJoinNodes(XmlJoinNodes xmlJoinNodes) {
this.xmlJoinNodes = xmlJoinNodes;
if(xmlJoinNodes != null && !CompilerHelper.hasNonAttributeJoinNodes(this)) {
this.isAttribute = true;
}
}
/**
* Return the XmlJoinNodes for this property.
*
* @return the xmlJoinNodes
*/
public XmlJoinNodes getXmlJoinNodes() {
return xmlJoinNodes;
}
/**
* Indicates if this property has XmlJoinNodes set.
*
* return true if xmlJoinNodes is non-null, otherwise false
*/
public boolean isSetXmlJoinNodes() {
return this.xmlJoinNodes != null;
}
/**
* Return a shallow copy of this Property.
* Simply calls super.clone().
*/
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// will never get here
}
return null;
}
/**
* Return the list of XmlJoinNodes for this Property, if any.
* This will typically be set when processing an XmlElements
* declaration containing XmlJoinNodes.
*
*/
public List<XmlJoinNodes> getXmlJoinNodesList() {
return xmlJoinNodesList;
}
/**
* Set the list of XmlJoinNodes for this Property. This method
* will typically be called when processing an XmlElements
* declaration containing XmlJoinNodes.
*
*/
public void setXmlJoinNodesList(List<XmlJoinNodes> xmlJoinNodesList) {
this.xmlJoinNodesList = xmlJoinNodesList;
if(xmlJoinNodesList != null && !(xmlJoinNodesList.isEmpty()) && !CompilerHelper.hasNonAttributeJoinNodes(this)) {
this.isAttribute = true;
}
}
/**
* Indicates if xmlJoinNodesList has been set, i.e. is non-null
*
* @return true if xmlJoinNodesList is non-null, false otherwise
*/
public boolean isSetXmlJoinNodesList() {
return this.xmlJoinNodesList != null;
}
public boolean isVirtual() {
return isVirtual;
}
public void setExtension(boolean value) {
this.isVirtual = value;
}
public boolean isXmlLocation() {
return isXmlLocation;
}
public void setXmlLocation(boolean isXmlLocation) {
this.isXmlLocation = isXmlLocation;
}
/**
* This event is called when all of the metadata for this property has been
* processed and provides a chance to deference anything that is no longer
* needed to reduce the memory footprint of this object.
*/
void postInitialize() {
this.element = null;
}
public boolean isSuperClassProperty() {
return this.isSuperClassProperty;
}
public void setIsSuperClassProperty(boolean b) {
this.isSuperClassProperty = b;
}
public String getVariableAttributeName() {
return variableAttributeName;
}
public void setVariableAttributeName(String variableAttributeName) {
this.variableAttributeName = variableAttributeName;
}
public String getVariableClassName() {
return variableClassName;
}
public void setVariableClassName(String variableClassName) {
this.variableClassName = variableClassName;
}
public boolean isVariableNodeAttribute() {
return variableNodeAttribute;
}
public void setVariableNodeAttribute(boolean variableNodeAttribute) {
this.variableNodeAttribute = variableNodeAttribute;
}
public boolean isTyped() {
return isTyped;
}
public void setTyped(boolean isTyped) {
this.isTyped = isTyped;
}
public List<Facet> getFacets() {
return facets;
}
public void addFacet(Facet facet) {
facets.add(facet);
}
public void setMinOccurs(int minOccurs) {
this.minOccurs = minOccurs;
}
public Integer getMinOccurs() {
return minOccurs;
}
public void setMaxOccurs(int maxOccurs) {
this.maxOccurs = maxOccurs;
}
public Integer getMaxOccurs() {
return maxOccurs;
}
public void setNotNullAnnotated(boolean notNullAnnotated) {
this.notNullAnnotated = notNullAnnotated;
}
public boolean isNotNullAnnotated() {
return notNullAnnotated;
}
}