com.hfg.xml.xsd.XsdElement Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.xml.xsd;
import java.util.*;
import com.hfg.util.collection.CollectionUtil;
import com.hfg.util.CompareUtil;
import com.hfg.util.StringUtil;
import com.hfg.xml.XMLName;
import com.hfg.xml.XMLNamespace;
import com.hfg.xml.XMLNode;
//------------------------------------------------------------------------------
/**
Representation of an element in an XML Schema Definition (XSD) specification.
@author J. Alex Taylor, hairyfatguy.com
*/
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class XsdElement extends XsdContent implements Comparable
{
private String mName;
private String mTypeString;
private XsdType mType;
private String mAnnotation;
private XMLName mRef;
private XMLNamespace mNamespace;
private static Map>> sSubtagIndexMap = new HashMap<>();
//---------------------------------------------------------------------------
public XsdElement(String inName)
{
mName = inName;
}
//---------------------------------------------------------------------------
public XsdElement(XMLNode inTag)
{
super(inTag);
inTag.verifyTagName(XsdXML.ELEMENT.getLocalName());
mName = inTag.getAttributeValue(XsdXML.NAME_ATT.getLocalName());
mTypeString = inTag.getAttributeValue(XsdXML.TYPE_ATT.getLocalName());
String refString = inTag.getAttributeValue(XsdXML.REF_ATT.getLocalName());
if (StringUtil.isSet(refString))
{
mRef = new XMLName(refString);
}
for (XMLNode subtag : inTag.getXMLNodeSubtags())
{
if (subtag.getTagName().equals(XsdXML.ANNOTATION.getLocalName()))
{
setAnnotation(subtag.getRequiredSubtagByName(XsdXML.DOCUMENTATION.getLocalName()).getUnescapedContent());
}
}
}
//---------------------------------------------------------------------------
public String toString()
{
return getQualifiedName() + (mAnnotation != null ? " (" + mAnnotation + ")" : "");
}
//---------------------------------------------------------------------------
protected XsdElement setName(String inValue)
{
mName = inValue;
return this;
}
//---------------------------------------------------------------------------
public String getLocalName()
{
return mName;
}
//---------------------------------------------------------------------------
public String getQualifiedName()
{
return (mNamespace != null && mNamespace.getPrefix() != null ? mNamespace.getPrefix() + ":" : "") + mName;
}
//---------------------------------------------------------------------------
public XMLName getRef()
{
if (mRef != null
&& null == mRef.getNamespace()
&& getNamespace() != null)
{
// Transfer the namespace if one wasn't defined on the ref
mRef.setNamespace(getNamespace());
}
return mRef;
}
//---------------------------------------------------------------------------
public XsdElement setType(XsdType inValue)
{
mType = inValue;
return this;
}
//---------------------------------------------------------------------------
public XsdType getType()
{
return mType;
}
//---------------------------------------------------------------------------
public String getTypeName()
{
return mTypeString;
}
//---------------------------------------------------------------------------
public String getQualifiedTypeName()
{
return mTypeString;
}
//---------------------------------------------------------------------------
@Override
public XsdElement setMaxOccurs(int inValue)
{
super.setMaxOccurs(inValue);
return this;
}
//---------------------------------------------------------------------------
@Override
public XsdElement setMinOccurs(int inValue)
{
super.setMinOccurs(inValue);
return this;
}
//---------------------------------------------------------------------------
public XsdElement setAnnotation(String inValue)
{
mAnnotation = inValue;
return this;
}
//---------------------------------------------------------------------------
public String getAnnotation()
{
return mAnnotation;
}
//------------------------------------------------------------------------
public Map> getSubtagIndexMap(String inTagName)
{
if (null == sSubtagIndexMap.get(this))
{
sSubtagIndexMap.put(this, generateSubtagIndex());
}
return sSubtagIndexMap.get(this);
}
//---------------------------------------------------------------------------
public XsdElement setNamespace(XMLNamespace inValue)
{
mNamespace = inValue;
if (mTypeString != null
&& ! mTypeString.contains(":")
&& inValue.getPrefix() != null)
{
mTypeString = inValue.getPrefix() + ":" + mTypeString;
}
return this;
}
//---------------------------------------------------------------------------
public XMLNamespace getNamespace()
{
return mNamespace;
}
//------------------------------------------------------------------------
@Override
public int compareTo(XsdElement inXsdElement2)
{
int result = 0;
if (inXsdElement2 != null)
{
result = CompareUtil.compare(getQualifiedName(), inXsdElement2.getQualifiedName());
if (0 == result)
{
result = CompareUtil.compare(getTypeName(), inXsdElement2.getTypeName());
}
}
else
{
result = -1;
}
return result;
}
//------------------------------------------------------------------------
@Override
public boolean equals(Object inObj2)
{
boolean result = false;
if (inObj2 != null
&& inObj2 instanceof XsdElement)
{
XsdElement element2 = (XsdElement) inObj2;
result = (0 == compareTo(element2));
}
return result;
}
//------------------------------------------------------------------------
@Override
public int hashCode()
{
int hashCode = 31 * getQualifiedName().hashCode();
if (getTypeName() != null)
{
hashCode += 31 * getTypeName().hashCode();
}
return hashCode;
}
//------------------------------------------------------------------------
private Map> generateSubtagIndex()
{
Map> subtagIndexMap = new HashMap<>(25);
if (getType() != null
&& getType() instanceof XsdComplexType)
{
recursivelyGenerateSubtagIndex(subtagIndexMap, new ArrayList<>(), (XsdComplexType) getType());
}
return subtagIndexMap;
}
//------------------------------------------------------------------------
private void recursivelyGenerateSubtagIndex(Map> inSubtagIndexMap, List inLevelSortList, XsdComplexType inXsdComplexType)
{
// Start w/ any base type subtags
if (inXsdComplexType.getBaseType() != null)
{
recursivelyGenerateSubtagIndex(inSubtagIndexMap, inLevelSortList, inXsdComplexType.getBaseType());
}
List xsdContents = inXsdComplexType.getContent();
if (CollectionUtil.hasValues(xsdContents))
{
for (XsdContent xsdContent : xsdContents)
{
if (xsdContent instanceof XsdSequence)
{
parseSequence((XsdSequence) xsdContent, inSubtagIndexMap, inLevelSortList);
}
else if (xsdContent instanceof XsdChoice)
{
parseChoice((XsdChoice) xsdContent, inSubtagIndexMap, inLevelSortList);
}
else if (xsdContent instanceof XsdGroup)
{
parseGroup((XsdGroup) xsdContent, inSubtagIndexMap, inLevelSortList);
}
}
}
}
//------------------------------------------------------------------------
private void parseSequence(XsdSequence inXsdSequence, Map> inSubtagIndexMap, List inLevelSortList)
{
List xsdContents = inXsdSequence.getContent();
if (CollectionUtil.hasValues(xsdContents))
{
int index = 0;
for (XsdContent xsdContent : xsdContents)
{
List levelSortList = new ArrayList<>(inLevelSortList.size() + 1);
levelSortList.addAll(inLevelSortList);
levelSortList.add(index++);
if (xsdContent instanceof XsdElement)
{
inSubtagIndexMap.put(((XsdElement) xsdContent).getLocalName(), levelSortList);
}
else if (xsdContent instanceof XsdSequence)
{
parseSequence((XsdSequence) xsdContent, inSubtagIndexMap, levelSortList);
}
else if (xsdContent instanceof XsdChoice)
{
parseChoice((XsdChoice) xsdContent, inSubtagIndexMap, levelSortList);
}
else if (xsdContent instanceof XsdGroup)
{
parseGroup((XsdGroup) xsdContent, inSubtagIndexMap, levelSortList);
}
}
}
}
//------------------------------------------------------------------------
private void parseChoice(XsdChoice inXsdChoice, Map> inSubtagIndexMap, List inLevelSortList)
{
Set xsdContents = inXsdChoice.getOptions();
if (CollectionUtil.hasValues(xsdContents))
{
int index = 0;
for (XsdContent xsdContent : xsdContents)
{
List levelSortList = new ArrayList<>(inLevelSortList.size() + 1);
levelSortList.addAll(inLevelSortList);
levelSortList.add(index);
if (xsdContent instanceof XsdElement)
{
inSubtagIndexMap.put(((XsdElement) xsdContent).getLocalName(), levelSortList);
}
else if (xsdContent instanceof XsdSequence)
{
parseSequence((XsdSequence) xsdContent, inSubtagIndexMap, levelSortList);
}
else if (xsdContent instanceof XsdChoice)
{
parseChoice((XsdChoice) xsdContent, inSubtagIndexMap, levelSortList);
}
else if (xsdContent instanceof XsdGroup)
{
parseGroup((XsdGroup) xsdContent, inSubtagIndexMap, levelSortList);
}
}
}
}
//------------------------------------------------------------------------
private void parseGroup(XsdGroup inXsdGroup, Map> inSubtagIndexMap, List inLevelSortList)
{
List xsdContents = inXsdGroup.getContent();
if (CollectionUtil.hasValues(xsdContents))
{
int index = 0;
for (XsdContent xsdContent : xsdContents)
{
List levelSortList = new ArrayList<>(inLevelSortList.size() + 1);
levelSortList.addAll(inLevelSortList);
levelSortList.add(index++);
if (xsdContent instanceof XsdElement)
{
inSubtagIndexMap.put(((XsdElement) xsdContent).getLocalName(), levelSortList);
}
else if (xsdContent instanceof XsdSequence)
{
parseSequence((XsdSequence) xsdContent, inSubtagIndexMap, levelSortList);
}
else if (xsdContent instanceof XsdChoice)
{
parseChoice((XsdChoice) xsdContent, inSubtagIndexMap, levelSortList);
}
else if (xsdContent instanceof XsdGroup)
{
parseGroup((XsdGroup) xsdContent, inSubtagIndexMap, levelSortList);
}
}
}
}
}