/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.axis2.schema; import javax.xml.namespace.QName; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; /** * This class is used as a holder to pass on the meta information to the bean writer. * This meta information is used by the writer to write the databinding conversion code. * Note - Metainfholders are not meant to be reused!!!. They are per-class basis and are strictly * not thread safe!!!! */ public class BeanWriterMetaInfoHolder { protected boolean ordered = false; protected boolean anonymous = false; protected boolean choice = false; protected boolean simple = false; protected boolean extension = false; protected boolean restriction = false; private String extensionClassName = ""; private String restrictionClassName = ""; private QName extensionBaseType = null; private QName restrictionBaseType = null; protected Map<QName,QName> elementToSchemaQNameMap = new LinkedHashMap<QName,QName>(); protected Map<QName,String> elementToJavaClassMap = new LinkedHashMap<QName,String>(); protected Map<QName,Integer> specialTypeFlagMap = new LinkedHashMap<QName,Integer>(); protected Map<QName,Long> qNameMaxOccursCountMap = new LinkedHashMap<QName,Long>(); protected Map<QName,Long> qNameMinOccursCountMap = new LinkedHashMap<QName,Long>(); protected Map<Integer,QName> qNameOrderMap = new LinkedHashMap<Integer,QName>(); protected QName ownQname = null; protected String ownClassName = null; protected long lengthFacet = -1; protected long maxLengthFacet = -1; protected long minLengthFacet = -1; protected ArrayList<String> enumFacet = new ArrayList<String>(); protected String patternFacet = null; protected String totalDigitsFacet = null; protected String maxExclusiveFacet = null; protected String minExclusiveFacet = null; protected String maxInclusiveFacet = null; protected String minInclusiveFacet = null; protected Map<QName,String> memberTypes = new HashMap<QName,String>(); protected Map<String,String> xmlNameJavaNameMap = new HashMap<String,String>(); // TODO: why do we need this (instead of using memberTypes.keySet()? protected List<QName> memberTypesKeys = new ArrayList<QName>(); protected Map<QName,String> elementQNameToDefulatValueMap = new HashMap<QName,String>(); protected QName itemTypeQName; protected String itemTypeClassName; protected boolean isUnion; protected boolean isList; protected boolean isParticleClass; // keep whether this class has a partical class type variable protected boolean hasParticleType; protected List<QName> nillableQNameList = new ArrayList<QName>(); protected List<QName> fixedQNameList = new ArrayList<QName>(); //the parent metainfo holder, useful in handling extensions and //restrictions protected BeanWriterMetaInfoHolder parent = null; public boolean isChoice() { return choice; } public void setChoice(boolean choice) { this.choice = choice; } public boolean isSimple() { return simple; } public void setSimple(boolean simple) { this.simple = simple; } public String getOwnClassName() { return ownClassName; } public void setOwnClassName(String ownClassName) { this.ownClassName = ownClassName; } public QName getOwnQname() { return ownQname; } public void setOwnQname(QName ownQname) { this.ownQname = ownQname; } /** * Gets the parent */ public BeanWriterMetaInfoHolder getParent() { return parent; } /** * Gets the anonymous status. * * @return Returns boolean. */ public boolean isAnonymous() { return anonymous; } /** * Sets the anonymous flag. * * @param anonymous */ public void setAnonymous(boolean anonymous) { this.anonymous = anonymous; } /** * Sets the extensions base class name. Valid only when the isExtension * returns true. * * @return Returns String. */ public String getExtensionClassName() { return extensionClassName; } /** * Sets the extensions base class name. Valid only when the isExtension * returns true. * * @param extensionClassName */ public void setExtensionClassName(String extensionClassName) { this.extensionClassName = extensionClassName; } /** * Gets the extension status. * * @return Returns boolean. */ public boolean isExtension() { return extension; } /** * Sets the extension status. * * @param extension */ public void setExtension(boolean extension) { this.extension = extension; } public String getRestrictionClassName() { return restrictionClassName; } /** * Sets the restriction base class name. Valid only when the isRestriction * returns true. * * @param restrictionClassName */ public void setRestrictionClassName(String restrictionClassName) { this.restrictionClassName = restrictionClassName; } /** * Gets the restriction status. * * @return Returns boolean. */ public boolean isRestriction() { return restriction; } /** * Sets the restriction status. * * @param restriction */ public void setRestriction(boolean restriction) { this.restriction = restriction; } /** * Sets the extension basetype. * * @param extensionBaseType */ public void setExtensionBaseType(QName extensionBaseType) { this.extensionBaseType = extensionBaseType; } /** * Checks if it is a extension base type. * * @param extensionBaseType */ public boolean isExtensionBaseType(QName extensionBaseType) { return (this.extensionBaseType == extensionBaseType); } /** * Sets the restriction basetype. * * @param restrictionBaseType */ public void setRestrictionBaseType(QName restrictionBaseType) { this.restrictionBaseType = restrictionBaseType; } /** * Checks if it is a restriction base type. * * @param restrictionBaseType */ public boolean isRestrictionBaseType(QName restrictionBaseType) { QName baseTypeQName = this.elementToSchemaQNameMap.get(restrictionBaseType); if (restriction && simple && baseTypeQName != null && restrictionBaseType != null) { return true; } else if (this.restrictionBaseType != null && baseTypeQName != null && this.restrictionBaseType.equals(baseTypeQName)) { return true; } return false; } /** * Gets the ordered status. * * @return Returns boolean. */ public boolean isOrdered() { return ordered; } /** * Sets the ordered flag. * * @param ordered */ public void setOrdered(boolean ordered) { this.ordered = ordered; } /** * Registers a mapping. * * @param qName * @param schemaName * @param javaClassName */ public void registerMapping(QName qName, QName schemaName, String javaClassName) { registerMapping(qName, schemaName, javaClassName, SchemaConstants.ELEMENT_TYPE); } /** * Registers a Qname as nillable * The qName better be of an element * * @param qName * @param schemaName * @param javaClassName */ public void registerNillableQName(QName eltQName) { nillableQNameList.add(eltQName); } /** * Returns whether a QName is nillable or not * * @param eltQName */ public boolean isNillable(QName eltQName) { return nillableQNameList.contains(eltQName); } /** * Registers a Qname as fixed * The qName better be of an element * * @param eltQName */ public void registerFixedQName(QName eltQName) { fixedQNameList.add(eltQName); } /** * Returns whether a QName is fixed or not * * @param eltQName */ public boolean isFixed(QName eltQName) { return fixedQNameList.contains(eltQName); } /** * Registers a mapping. * * @param qName * @param schemaName * @param javaClassName * @param type */ public void registerMapping(QName qName, QName schemaName, String javaClassName, int type) { this.elementToJavaClassMap.put(qName, javaClassName); this.elementToSchemaQNameMap.put(qName, schemaName); addtStatus(qName, type); } /** * this method registers the defult value agaist the element qname. * @param qname * @param value */ public void registerDefaultValue(QName qname,String value){ this.elementQNameToDefulatValueMap.put(qname,value); } /** * * @param qname * @return is a default value available for this qname */ public boolean isDefaultValueAvailable(QName qname){ return this.elementQNameToDefulatValueMap.containsKey(qname); } /** * gets the default value for qname * @param qname * @return default value for this qname */ public String getDefaultValueForQName(QName qname){ return this.elementQNameToDefulatValueMap.get(qname); } /** * Gets the schema name for the given QName. * * @param eltQName * @return Returns QName. */ public QName getSchemaQNameForQName(QName eltQName) { return this.elementToSchemaQNameMap.get(eltQName); } /** * Gets the class name for the QName. * * @param eltQName * @return Returns String. */ public String getClassNameForQName(QName eltQName) { return this.elementToJavaClassMap.get(eltQName); } /** * Gets whether a given QName is an attribute * * @param qName * @return Returns boolean. */ public boolean getAttributeStatusForQName(QName qName) { Integer state = specialTypeFlagMap.get(qName); return state != null && getStatus(state.intValue(), SchemaConstants.ATTRIBUTE_TYPE); } /** * checks the element corresponds to the qName type is xsd:anyType * * @param qName * @return is element corresponds to qName has xsd:anyType */ public boolean getDefaultStatusForQName(QName qName) { boolean isDefault = false; QName schemaTypeQName = this.elementToSchemaQNameMap.get(qName); if (schemaTypeQName != null) { isDefault = schemaTypeQName.equals(SchemaConstants.XSD_ANYTYPE); } return isDefault; } /** * Gets whether a given QName represents a anyType * * @param qName * @return Returns boolean. */ public boolean getAnyStatusForQName(QName qName) { Integer state = specialTypeFlagMap.get(qName); return state != null && getStatus(state.intValue(), SchemaConstants.ANY_TYPE); } /** * Gets whether a given QName refers to an array. * * @param qName * @return Returns boolean. */ public boolean getArrayStatusForQName(QName qName) { Integer state = specialTypeFlagMap.get(qName); return state != null && getStatus(state.intValue(), SchemaConstants.ARRAY_TYPE); } /** * Gets whether a given QName refers to binary. * * @param qName * @return Returns boolean. */ public boolean getBinaryStatusForQName(QName qName) { Integer state = specialTypeFlagMap.get(qName); return state != null && getStatus(state.intValue(), SchemaConstants.BINARY_TYPE); } /** * * @param qName * @return is this a inner choice */ public boolean getInnerChoiceStatusForQName(QName qName){ Integer state = specialTypeFlagMap.get(qName); return state != null && getStatus(state.intValue(), SchemaConstants.INNER_CHOICE_ELEMENT); } /** * Gets whether a given QName refers to Simple Type. * * @param qName * @return Returns boolean. */ public boolean getSimpleStatusForQName(QName qName) { Integer state = specialTypeFlagMap.get(qName); return state != null && getStatus(state.intValue(), SchemaConstants.SIMPLE_TYPE_OR_CONTENT); } /** * * @param qName * @return whether the attribute is a partical class or not */ public boolean getParticleTypeStatusForQName(QName qName){ Integer state = specialTypeFlagMap.get(qName); return state != null && getStatus(state.intValue(), SchemaConstants.PARTICLE_TYPE_ELEMENT); } /** * Gets whether a given QName has the any attribute status. * * @param qName * @return Returns boolean. */ public boolean getAnyAttributeStatusForQName(QName qName) { return getArrayStatusForQName(qName) && getAnyStatusForQName(qName); } /** * Gets whether a given QName has the optional attribute status. * * @param qName QName of attribute * @return Returns <code>true</code> if attribute has optional status */ public boolean getOptionalAttributeStatusForQName(QName qName) { Integer state = specialTypeFlagMap.get(qName); return state != null && getStatus(state.intValue(), SchemaConstants.OPTIONAL_TYPE); } /** * Clears the whole set of tables. */ public void clearTables() { this.elementToJavaClassMap.clear(); this.elementToSchemaQNameMap.clear(); this.elementToSchemaQNameMap.clear(); this.elementToJavaClassMap.clear(); this.specialTypeFlagMap.clear(); this.qNameMaxOccursCountMap.clear(); this.qNameMinOccursCountMap.clear(); this.qNameOrderMap.clear(); this.elementQNameToDefulatValueMap.clear(); } /** * Adds the minOccurs associated with a QName. * * @param qName * @param minOccurs */ public void addMinOccurs(QName qName, long minOccurs) { this.qNameMinOccursCountMap.put(qName, minOccurs); } /** * Registers a QName for the order. * * @param qName * @param index */ public void registerQNameIndex(QName qName, int index) { this.qNameOrderMap.put(index, qName); } /** * Adds the minOccurs associated with a QName. * * @param qName * @return Returns long. */ public long getMinOccurs(QName qName) { Long l = this.qNameMinOccursCountMap.get(qName); return l != null ? l.longValue() : 1; //default for min is 1 } /** * Gets the maxOccurs associated with a QName. * * @param qName * @return Returns long. */ public long getMaxOccurs(QName qName) { Long l = this.qNameMaxOccursCountMap.get(qName); return l != null ? l.longValue() : 1; //default for max is 1 } /** * Adds the maxOccurs associated with a QName. * * @param qName * @param maxOccurs */ public void addMaxOccurs(QName qName, long maxOccurs) { this.qNameMaxOccursCountMap.put(qName, maxOccurs); } /** * @return Returns Iterator. * @deprecated Use #getQNameArray */ public Iterator<QName> getElementQNameIterator() { return elementToJavaClassMap.keySet().iterator(); } /** * Gets the QName array - may not be ordered. * * @return Returns QName[]. */ public QName[] getQNameArray() { Set<QName> keySet = elementToJavaClassMap.keySet(); return keySet.toArray(new QName[keySet.size()]); } /** * Gets the ordered QName array - useful in sequences where the order needs to be preserved * Note - #registerQNameIndex needs to be called if this is to work properly! * * @return Returns QName[]. */ public QName[] getOrderedQNameArray() { //get the keys of the order map Set<Integer> set = qNameOrderMap.keySet(); int count = set.size(); Integer[] keys = set.toArray(new Integer[count]); Arrays.sort(keys); //Now refill the Ordered QName Array List<QName> returnQNames = new ArrayList<QName>(); for (int i = 0; i < keys.length; i++) { returnQNames.add(qNameOrderMap.get(keys[i])); } //we've missed the attributes, so if there are attributes //add them explicitly to the end of this list QName[] allNames = getQNameArray(); for (int i = 0; i < allNames.length; i++) { if (getAttributeStatusForQName(allNames[i])) { returnQNames.add(allNames[i]); } } return returnQNames.toArray(new QName[returnQNames.size()]); } /** * Finds the starting count for the addition of new items to the order * * @return the starting number for the sequence */ public int getOrderStartPoint() { return qNameOrderMap.size(); } /** * Creates link to th * * @param metaInfo */ public void setAsParent(BeanWriterMetaInfoHolder metaInfo) { parent = metaInfo; } /** * Adds a another status to a particular Qname. * A Qname can be associated with multiple status flags * and they all will be preserved * * @param type * @param mask */ public void addtStatus(QName type, int mask) { Integer preValue = this.specialTypeFlagMap.get(type); if (preValue != null) { this.specialTypeFlagMap.put(type, preValue | mask); } else { this.specialTypeFlagMap.put(type, mask); } } private boolean getStatus(int storedStatus, int mask) { //when the mask is anded with the status then we should get //the mask it self! return (mask == (mask & storedStatus)); } /** * Sets the length facet. * * @param lengthFacet */ public void setLengthFacet(long lengthFacet) { this.lengthFacet = lengthFacet; } /** * Gets the length facet. * * @return Returns length facet. */ public long getLengthFacet() { return this.lengthFacet; } /** * Sets the totalDigits * * @param totalDigitsFacet */ public void setTotalDigitsFacet(String totalDigitsFacet) { this.totalDigitsFacet = totalDigitsFacet; } /** * * @return Returns the totalDigits */ public String getTotalDigitsFacet() { return this.totalDigitsFacet; } /** * Sets the maxExclusive. * * @param maxExclusiveFacet */ public void setMaxExclusiveFacet(String maxExclusiveFacet) { this.maxExclusiveFacet = maxExclusiveFacet; } /** * Gets the maxExclusive. * * @return Returns the maxExclusive. */ public String getMaxExclusiveFacet() { return this.maxExclusiveFacet; } /** * Sets the minExclusive. * * @param minExclusiveFacet */ public void setMinExclusiveFacet(String minExclusiveFacet) { this.minExclusiveFacet = minExclusiveFacet; } /** * Gets the minExclusive. * * @return Returns the minExclusive. */ public String getMinExclusiveFacet() { return this.minExclusiveFacet; } /** * Sets the maxInclusive. * * @param maxInclusiveFacet */ public void setMaxInclusiveFacet(String maxInclusiveFacet) { this.maxInclusiveFacet = maxInclusiveFacet; } /** * Gets the maxInclusive. * * @return Returns the maxInclusive. */ public String getMaxInclusiveFacet() { return this.maxInclusiveFacet; } /** * Sets the minInclusive. * * @param minInclusiveFacet */ public void setMinInclusiveFacet(String minInclusiveFacet) { this.minInclusiveFacet = minInclusiveFacet; } /** * Gets the minInclusive. * * @return Returns the minInclusive. */ public String getMinInclusiveFacet() { return this.minInclusiveFacet; } /** * Sets the maxLength. * * @param maxLengthFacet */ public void setMaxLengthFacet(long maxLengthFacet) { this.maxLengthFacet = maxLengthFacet; } /** * Gets the maxLength. * * @return Returns maxLength. */ public long getMaxLengthFacet() { return this.maxLengthFacet; } /** * Sets the minLength. * * @param minLengthFacet */ public void setMinLengthFacet(long minLengthFacet) { this.minLengthFacet = minLengthFacet; } /** * Gets the minLength. * * @return Returns minLength. */ public long getMinLengthFacet() { return this.minLengthFacet; } /** * Sets the enumeration. * * @param enumFacet */ public void setEnumFacet(ArrayList<String> enumFacet) { this.enumFacet = enumFacet; } /** * Adds the enumeration. * * @param enumFacet */ public void addEnumFacet(String enumFacet) { this.enumFacet.add(enumFacet); } /** * Gets the enumeration. * * @return Returns enumeration. */ public List<String> getEnumFacet() { return this.enumFacet; } /** * Sets the pattern. * * @param patternFacet */ public void setPatternFacet(String patternFacet) { this.patternFacet = patternFacet; } /** * Gets the pattern. * * @return Returns pattern. */ public String getPatternFacet() { return this.patternFacet; } /** * * @return Returns is union */ public boolean isUnion() { return isUnion; } public void setUnion(boolean union) { isUnion = union; } /** * * @return Returns memeber type in a union */ public Map<QName,String> getMemberTypes() { return memberTypes; } public void setMemberTypes(Map<QName,String> memberTypes) { this.memberTypes = memberTypes; } public List<QName> getMemberTypesKeys() { return memberTypesKeys; } public void setMemberTypesKeys(List<QName> memberTypesKeys) { this.memberTypesKeys = memberTypesKeys; } public void addMemberType(QName qname,String className){ this.memberTypes.put(qname,className); this.memberTypesKeys.add(qname); } public boolean isList() { return isList; } public void setList(boolean list) { isList = list; } public QName getItemTypeQName() { return itemTypeQName; } public void setItemTypeQName(QName itemTypeQName) { this.itemTypeQName = itemTypeQName; } public String getItemTypeClassName() { return itemTypeClassName; } public void setItemTypeClassName(String itemTypeClassName) { this.itemTypeClassName = itemTypeClassName; } public boolean isParticleClass() { return isParticleClass; } public void setParticleClass(boolean particleClass) { isParticleClass = particleClass; } public boolean isHasParticleType() { return hasParticleType; } public void setHasParticleType(boolean hasParticleType) { this.hasParticleType = hasParticleType; } public void addXmlNameJavaNameMapping(String xmlName,String javaName){ this.xmlNameJavaNameMap.put(xmlName,javaName); } public boolean isJavaNameMappingAvailable(String xmlName){ return this.xmlNameJavaNameMap.containsKey(xmlName); } public String getJavaName(String xmlName){ return this.xmlNameJavaNameMap.get(xmlName); } public QName getRestrictionBaseType() { return restrictionBaseType; } @Override public String toString() { return "BeanWriterMetaInfoHolder [anonymous=" + anonymous + ", choice=" + choice + ", elementQNameToDefulatValueMap=" + elementQNameToDefulatValueMap + ", elementToJavaClassMap=" + elementToJavaClassMap + ", elementToSchemaQNameMap=" + elementToSchemaQNameMap + ", enumFacet=" + enumFacet + ", extension=" + extension + ", extensionBaseType=" + extensionBaseType + ", extensionClassName=" + extensionClassName + ", hasParticleType=" + hasParticleType + ", isList=" + isList + ", isParticleClass=" + isParticleClass + ", isUnion=" + isUnion + ", itemTypeClassName=" + itemTypeClassName + ", itemTypeQName=" + itemTypeQName + ", lengthFacet=" + lengthFacet + ", maxExclusiveFacet=" + maxExclusiveFacet + ", maxInclusiveFacet=" + maxInclusiveFacet + ", maxLengthFacet=" + maxLengthFacet + ", memberTypes=" + memberTypes + ", memberTypesKeys=" + memberTypesKeys + ", minExclusiveFacet=" + minExclusiveFacet + ", minInclusiveFacet=" + minInclusiveFacet + ", minLengthFacet=" + minLengthFacet + ", nillableQNameList=" + nillableQNameList + ", ordered=" + ordered + ", ownClassName=" + ownClassName + ", ownQname=" + ownQname + ", parent=" + parent + ", patternFacet=" + patternFacet + ", qNameMaxOccursCountMap=" + qNameMaxOccursCountMap + ", qNameMinOccursCountMap=" + qNameMinOccursCountMap + ", qNameOrderMap=" + qNameOrderMap + ", restriction=" + restriction + ", restrictionBaseType=" + restrictionBaseType + ", restrictionClassName=" + restrictionClassName + ", simple=" + simple + ", specialTypeFlagMap=" + specialTypeFlagMap + ", totalDigitsFacet=" + totalDigitsFacet + ", xmlNameJavaNameMap=" + xmlNameJavaNameMap + ", fixedQNameList=" + fixedQNameList + "]"; } }