src.com.ibm.as400.data.PcmlSAXParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400-jdk8 Show documentation
Show all versions of jt400-jdk8 Show documentation
The Open Source version of the IBM Toolbox for Java
The newest version!
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: PcmlSAXParser.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2010 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.data;
//@E0C
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.SAXNotRecognizedException; //@E1A
import org.xml.sax.SAXNotSupportedException; //@E1A
import com.ibm.as400.access.BinaryConverter; //@E1A
import org.xml.sax.XMLReader;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.io.BufferedInputStream; //@E1A
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.HashSet;
import java.util.Stack;
import java.util.Vector;
import com.ibm.as400.access.Trace;
class PcmlSAXParser extends DefaultHandler
{
private transient PcmlDocument m_rootNode;
private transient PcmlDocNode m_currentNode;
private transient String m_docName;
private transient XMLErrorHandler m_xh;
private transient boolean exceptionIfParseError_;
// @E1A - New variables for XPCML.
// @E1A - Hold current value of attributes
Vector curAttrs = new Vector();
Vector curQName = new Vector();
int curDim = -1;
String lastQName="";
int[] dimArray = {0,0,0,0,0,0,0,0,0,0};
PcmlDimensions dimensions = new PcmlDimensions(dimArray);
// @E1A - initValue is used to keep track of XML data value for an element
private String initValue=""; //@E1A
// @E1A -- docIsXPCML - is the document an XPCML doc vs a PCML doc?
private boolean docIsXPCML = false; //@E1A
//private String xsdStreamName; //@E1A // Used to determine if this is first instance of this node or if its an array
private boolean firstInstance=true; //@E1A
/** xsd transformed as a byte array input and output stream **/
ByteArrayOutputStream xmlOut = new ByteArrayOutputStream();
ByteArrayInputStream xmlIn;
/** xsd file **/
private InputStream xsdFileStream;
// @E1A -- Set features for XML parser. Need to set for full schema checking
// @E1A feature ids
/** Namespaces feature id (http://xml.org/sax/features/namespaces). */
private static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces"; //@E1A
/** Namespace prefixes feature id (http://xml.org/sax/features/namespace-prefixes). */
private static final String NAMESPACE_PREFIXES_FEATURE_ID = "http://xml.org/sax/features/namespace-prefixes"; //@E1A
/** Validation feature id (http://xml.org/sax/features/validation). */
private static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation"; //@E1A
/** Schema validation feature id (http://apache.org/xml/features/validation/schema). */
private static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema"; //@E1A
/** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). */
private static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking"; //@E1A
/** Dynamic validation feature id (http://apache.org/xml/features/validation/dynamic). */
private static final String DYNAMIC_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/dynamic"; //@E1A
private static HashSet knownTypes_ = null;
private static HashSet knownArrayTypes_ = null;
PcmlSAXParser(String docName, InputStream docStream, InputStream xsdStream, boolean docIsXPCML, boolean exceptionIfParseError)
throws MissingResourceException, IOException, ParseException, PcmlSpecificationException,
FactoryConfigurationError, ParserConfigurationException, SAXException
{
m_rootNode = null;
m_currentNode = null;
exceptionIfParseError_ = exceptionIfParseError;
String qualDocName; // Potentially package qualified document name @A2A
xsdFileStream = xsdStream; // xsd stream holder @E1A
this.docIsXPCML = docIsXPCML; // Fix for JTOpen Bug 1778759 - set the global docIsXPCML variable
// initialize parsing vectors
curAttrs.add(0,new AttributesImpl());
curQName.add(0,"");
// Save the document name (strip the suffix if present)
if (docName.endsWith(".pcml") || docName.endsWith(".pcmlsrc") ||
docName.endsWith(".xpcml") || docName.endsWith(".xpcmlsrc")) //@E1C
{
qualDocName = docName.substring(0, docName.lastIndexOf('.') ); // @A2C
}
else
{
qualDocName = docName; // @A2C
}
m_docName = qualDocName.substring(qualDocName.lastIndexOf('.') + 1); // @A2A
// @E1A -- Changes for XPCML. First find out if document is XPCML. Then setup SequenceInputStream
InputStream isHeader=null; //@E1A
InputStream instream = null;
try
{
// First check if xsd stream is valid if this is XPCML
if (docIsXPCML)
{
// Transform the xsd stream to a byte stream we can more easily read
if (xsdFileStream != null)
{
try
{
XPCMLHelper.doSimplifyXSDTransform(xsdFileStream, xmlOut);
}
catch (IOException e)
{
throw e;
}
catch (SAXException e)
{
throw e;
}
xmlIn = new ByteArrayInputStream(xmlOut.toByteArray());
if (xmlIn == null)
throw new MissingResourceException(SystemResourceFinder.format(DAMRI.PCML_DTD_NOT_FOUND, new Object[] {"xmlOut"}), "xmlOut", "");
}
// Doc is an XPCML document
// Now try to open the XPCML file
instream = new BufferedInputStream(docStream);
}
else // doc is PCML //@E1A
{
// Doc is a PCML document. Do old processing...
// Open the PCML header document that contains the DTD
isHeader = SystemResourceFinder.getPCMLHeader();
// Concatenate the two input streams
instream = new SequenceInputStream(isHeader, docStream);
}
// Instantiate our error listener
m_xh = new XMLErrorHandler(m_docName, SystemResourceFinder.getHeaderLineCount());
SAXParserFactory factory = SAXParserFactory.newInstance(); //@E0A
factory.setValidating(true); //@E0A
factory.setNamespaceAware(false); //@E0A
// @E1A -- Set new features for XPCML
// set parser features
if (docIsXPCML)
setFeatures(factory);
SAXParser parser;
// Android do not support the validating parser.
// If this fails, request a non-validating parser. @L4A
try {
parser = factory.newSAXParser(); //@E0A
} catch (javax.xml.parsers.ParserConfigurationException pce ) {
factory.setValidating(false);
parser = factory.newSAXParser();
}
//@E0D SAXParser parser = new SAXParser(); // @C2C
//@E0D try { // @C2A
//@E0D parser.setFeature("http://xml.org/sax/features/validation", true); // @C2A
//@E0D parser.setFeature( "http://xml.org/sax/features/namespaces", false ); // @C2A
//@E0D } catch (org.xml.sax.SAXException se) { // @C2A
//@E0D }
//@E0D parser.setErrorHandler(xh);
//@E0D parser.setDocumentHandler(this); // @C3C
// Create an InputSource for passing to the parser.
// Wrap any SAXExceptions as ParseExceptions.
try
{
XMLReader reader = parser.getXMLReader(); //@E0A
reader.setErrorHandler(m_xh); //@E0A
parser.parse(new InputSource(instream), this); //@E0C
// Close the input stream
instream.close();
instream = null;
}
catch (SAXException e)
{
Trace.log(Trace.PCML, e);
ParseException pe = new ParseException(SystemResourceFinder.format(DAMRI.FAILED_TO_PARSE, new Object[] {m_docName} ) );
pe.addMessage(e.getMessage());
throw pe;
}
// Check for errors
ParseException exc = m_xh.getException();
if (exc != null)
{
exc.reportErrors();
throw exc;
}
// Recursively walk the document tree and augment the tree with
// cloned subtrees for nodes.
augmentTree(m_rootNode, new Stack());
// Perform post-parsing attribute checking.
// Recursively walk the document tree and ask each node
// to verify all attributes.
// Note that this phase must be performed after the document is completely
// parsed because some attributes (length=, count=, etc.) make reference
// to named document elements occuring later in the document.
checkAttributes(m_rootNode);
// Copy in values from augmented nodes
try
{
if (docIsXPCML)
m_rootNode.copyValues(m_rootNode, m_rootNode);
}
catch (XmlException e)
{
Trace.log(Trace.PCML, "All data values may not have been copied to struct parm refs.", e);
throw new SAXException(e);
}
if (m_rootNode != null && m_rootNode.getPcmlSpecificationException() != null)
{
throw m_rootNode.getPcmlSpecificationException();
}
}
finally
{
if (isHeader != null) {
try { isHeader.close(); } catch (Exception e) {}
}
if (instream != null) {
try { instream.close(); } catch (Exception e) {}
}
}
}
// @E1A -- New method to do feature checking
static void setFeatures(SAXParserFactory factory) throws SAXException, SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException
{
// @E1A -- Set new features for XPCML
// set parser features
factory.setFeature(NAMESPACES_FEATURE_ID, true);
factory.setFeature(NAMESPACE_PREFIXES_FEATURE_ID, true);
factory.setFeature(VALIDATION_FEATURE_ID, true);
factory.setFeature(SCHEMA_VALIDATION_FEATURE_ID, true);
factory.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, true);
factory.setFeature(DYNAMIC_VALIDATION_FEATURE_ID, false);
}
// Process the PcmlDocNode tree and add new PcmlDocNode subtrees
// for tags that reference tags.
// (e.g.
// This process must be done after the initial tree is built
// because there is no requirement that the referenced
// tag be defined before the referencing tag.
PcmlDocument getPcmlDocument()
{
return m_rootNode;
}
// Process the PcmlDocNode tree and add new PcmlDocNode subtrees
// for tags that reference tags.
// (e.g.
// This process must be done after the initial tree is built
// because there is no requirement that the referenced
// tag be defined before the referencing tag.
private void augmentTree(PcmlDocNode pcmlElem, Stack recursionStack)
{
Enumeration children;
PcmlDocNode child;
String structName;
PcmlDocNode structNode;
PcmlData dataNode;
children = pcmlElem.getChildren();
if (children == null)
return;
while (children.hasMoreElements())
{
child = (PcmlDocNode) children.nextElement();
// Only augment the tree for items.
// This also makes sure the node has no children
// though this should always be the case because the DTD does
// allow the tag to have nested elements.
if (child instanceof PcmlData) // This node is a tag
{
dataNode = (PcmlData) child;
if (dataNode.getDataType() == PcmlData.STRUCT) // and it is type="struct"
{
if (dataNode.getNbrChildren() == 0) // and it has no children
{
structName = dataNode.getStruct();
if (structName != null)
{
structNode = (PcmlDocNode) m_rootNode.getElement(structName);
if (structNode instanceof PcmlStruct)
{
if (recursionStack.search(structNode) != -1)
{
m_rootNode.addPcmlSpecificationError(DAMRI.CIRCULAR_REFERENCE, new Object[] {structName, dataNode.getBracketedTagName(), dataNode.getNameForException()} );
}
else
{
Enumeration structChildren = structNode.getChildren();
while (structChildren.hasMoreElements())
{
PcmlDocNode structChild = (PcmlDocNode) structChildren.nextElement();
PcmlDocNode newChild = (PcmlDocNode) structChild.clone();
// Link the new node into the document tree
dataNode.addChild(newChild);
// Recursively add all of the new node's children
// to the document's hashtable.
m_rootNode.addToHashtable(newChild); // @C1C
}
// Insert subtree for this structure
//makeChildren(structNode.getXmlNode(), dataNode);
}
}
else
{
if (structNode == null)
{
m_rootNode.addPcmlSpecificationError(DAMRI.REF_NOT_FOUND, new Object[] {structName, "", dataNode.getBracketedTagName(), dataNode.getNameForException()} );
}
else
{
m_rootNode.addPcmlSpecificationError(DAMRI.REF_WRONG_TYPE, new Object[] {structName, "", dataNode.getBracketedTagName(), dataNode.getNameForException()} );
}
}
}
}
else
{
// Not allowed by the DTD
}
}
}
// Recursively augment the newly created tree
recursionStack.push(child);
augmentTree(child, recursionStack);
recursionStack.pop();
}
}
// Process the PcmlDocNode tree to resolve references to
// named nodes in the tree.
//
// Some nodes (e.g. ) have attributes with named references
// to other nodes (e.g. offset="xyz"). The named reference can
// be either a simple name or a qualified name. The name
// resolution is performed by walking up the document heirarchy looking
// for a named element relative to the current location in the tree.
//
// Given the following document structure:
//
//
//
//
//
//
//
//
//
//
//
// The element named "lengthOfXyz" is referenced by element "xyz" as
// the length of the character field. In this case the following
// names could be specified on the length attribute and would
// resolve to the same element in the docuement:
// -- length="lengthOfXyz"
// -- length="struct1.lengthOfXyz"
// -- length="parm1.struct1.lengthOfXyz"
// -- length="qabc.parm1.struct1.lengthOfXyz"
//
// The resolution process recursively asks the nodes's parent if the
// name string is a descendant of the current node.
private void checkAttributes(PcmlDocNode pcmlElem)
{
Enumeration children;
PcmlDocNode child;
children = pcmlElem.getChildren();
if (children == null)
return;
while (children.hasMoreElements())
{
child = (PcmlDocNode) children.nextElement();
child.checkAttributes();
// Recursively resolve references for all nodes in the tree
checkAttributes(child);
}
}
public void startElement(String uri, String localName, String qName, Attributes xmlAttrs) //@E0C
{
String tagName = qName; //@E0A
PcmlDocNode newNode = null;
// String parmName="";
String equivQName=qName;
AttributesImpl uAttrs= new AttributesImpl();
boolean uDefinedQName=false;
boolean extendedType=false;
// Reset initValue
initValue="";
if (!docIsXPCML) // Copy old PCML code exactly - do not change
{
// Create a PcmlAttributeList to hold all the
// attributes for this node.
PcmlAttributeList attrs = new PcmlAttributeList(xmlAttrs.getLength());
for (int attr = 0; attr < xmlAttrs.getLength(); attr++)
{
attrs.addAttribute( new PcmlAttribute(xmlAttrs.getQName(attr), // @C3C
xmlAttrs.getValue(attr),
(true | false)) );
}
// Create PcmlDocNode subclass based on tag name
if (tagName.equals("pcml"))
{
newNode = new PcmlDocument(attrs, m_docName);
}
else if (tagName.equals("program"))
{
newNode = new PcmlProgram(attrs);
}
else if (tagName.equals("struct"))
{
newNode = new PcmlStruct(attrs);
}
else if (tagName.equals("data"))
{
newNode = new PcmlData(attrs);
}
else
{
newNode = null;
// Unrecognized tag name should never happen, if the tags parse successfully.
if (m_rootNode != null)
{
m_rootNode.addPcmlSpecificationError(DAMRI.BAD_TAG, new Object[] {tagName, getBracketedTagName(tagName)} );
}
else // we haven't established a root node yet
{
// This method has no 'throws' clause in its signature.
// Therefore, to report the error and terminate processing, we have no choice but to throw a RuntimeException.
PcmlSpecificationException pse = new PcmlSpecificationException(SystemResourceFinder.format(DAMRI.BAD_TAG, new Object[] {tagName, getBracketedTagName(tagName)}));
throw new RuntimeException(pse);
}
}
if (newNode != null)
{
if (m_rootNode == null)
{
m_rootNode = (PcmlDocument) newNode;
m_currentNode = newNode;
}
else
{
m_currentNode.addChild(newNode);
m_currentNode = newNode;
}
}
}
if (docIsXPCML)
{
if (xsdFileStream != null)
{
// Check if this is a user defined element. If so, convert to equivalent XPCML element
if (!getKnownTypes().contains(qName))
{
// User defined parameter. Need to find it in XSD stream.
uDefinedQName=true;
ByteArrayInputStream xmlIn1 = new ByteArrayInputStream(xmlOut.toByteArray());
if (xmlIn1 == null)
throw new MissingResourceException(SystemResourceFinder.format(DAMRI.PCML_DTD_NOT_FOUND, new Object[] {"xmlOut"}), "xmlOut", "");
// Cache the line count of the header
LineNumberReader lnr = new LineNumberReader(new InputStreamReader(xmlIn1));
try
{
String line;
line=lnr.readLine();
boolean found=false;
while (line != null && !found)
{
if (line.indexOf("name="+"\""+qName+"\"") != -1 && line.indexOf("parm type=") != -1)
{
if (line.indexOf("parm type=string") != -1)
{
// String parm found
equivQName = "stringParm";
found=true;
}
else if (line.indexOf("parm type=int") != -1)
{
// Int parm found
equivQName="intParm";
found=true;
}
else if (line.indexOf("parm type=uint") != -1)
{
// Unsigned Int parm found
equivQName="unsignedIntParm";
found=true;
}
else if (line.indexOf("parm type=hexBinary") != -1)
{
// hexBinary parm found
equivQName="hexBinaryParm";
found=true;
}
else if (line.indexOf("parm type=byte") != -1)
{
// Byte parm found
equivQName="byteParm";
found=true;
}
else if (line.indexOf("parm type=ubyte") != -1)
{
// Unsigned Byte parm found
equivQName="unsignedByteParm";
found=true;
}
else if (line.indexOf("parm type=short") != -1)
{
// Short parm found
equivQName="shortParm";
found=true;
}
else if (line.indexOf("parm type=ushort") != -1)
{
// Unsigned Short parm found
equivQName="unsignedShortParm";
found=true;
}
else if (line.indexOf("parm type=long") != -1)
{
// Long parm found
equivQName="longParm";
found=true;
}
else if (line.indexOf("parm type=ulong") != -1)
{
// Unsigned Long parm found
equivQName="unsignedLongParm";
found=true;
}
else if (line.indexOf("parm type=float") != -1)
{
// Float parm found
equivQName="floatParm";
found=true;
}
else if (line.indexOf("parm type=double") != -1)
{
// Double parm found
equivQName="doubleParm";
found=true;
}
else if (line.indexOf("parm type=packed") != -1)
{
// Packed parm found
equivQName="packedDecimalParm";
found=true;
}
else if (line.indexOf("parm type=zoned") != -1)
{
// Zoned parm found
equivQName="zonedDecimalParm";
found=true;
}
else if (line.indexOf("parm type=date") != -1)
{
// Date parm found
equivQName="dateParm";
found=true;
}
else if (line.indexOf("parm type=time") != -1)
{
// Time parm found
equivQName="timeParm";
found=true;
}
else if (line.indexOf("parm type=timestamp") != -1)
{
// Timestamp parm found
equivQName="timestampParm";
found=true;
}
else if (line.indexOf("parm type=structParm") != -1)
{
// Struct parm found
equivQName="structParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfString") != -1)
{
// String parm found
equivQName = "arrayOfStringParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfInt") != -1)
{
// Int parm found
equivQName="arrayOfIntParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfUInt") != -1)
{
// Unsigned Int parm found
equivQName="arrayOfUnsignedIntParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfHexBinary") != -1)
{
// hexBinary parm found
equivQName="arrayOfHexBinaryParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfShort") != -1)
{
// Short parm found
equivQName="arrayOfShortParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfUShort") != -1)
{
// Unsigned Short parm found
equivQName="arrayOfUnsignedShortParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfLong") != -1)
{
// Long parm found
equivQName="arrayOfLongParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfULong") != -1)
{
// Unsigned Long parm found
equivQName="arrayOfUnsignedLongParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfFloat") != -1)
{
// Float parm found
equivQName="arrayOfFloatParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfDouble") != -1)
{
// Double parm found
equivQName="arrayOfDoubleParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfPacked") != -1)
{
// Packed parm found
equivQName="arrayOfPackedDecimalParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfZoned") != -1)
{
// Zoned parm found
equivQName="arrayOfZonedDecimalParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfDate") != -1)
{
// Date parm found
equivQName="arrayOfDateParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfTime") != -1)
{
// Time parm found
equivQName="arrayOfTimeParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfTimestamp") != -1)
{
// Timestamp parm found
equivQName="arrayOfTimestampParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfStructParm") != -1)
{
// Struct parm found
equivQName="arrayOfStructParm";
found=true;
}
else if (line.indexOf("parm type=structArray") != -1)
{
// Struct found
equivQName="arrayOfStruct";
found=true;
}
else
{
// Should never reach here. Should get parse error if invalid type passed in
Trace.log(Trace.WARNING,"User defined type passed in not found in xsd stream");
}
// Now get attributes and set them to equivalent XPCML base attributes
// Find and print attributes
if (found==true)
{
line = lnr.readLine();
while (line != null && line.indexOf("parm type=") == -1)
{
// Save attributes attributes
String attrName="";
String attrVal="";
// Parse line into attribute, value pair
if (line.indexOf("attributeName=") != -1)
{
// Found an attribute
attrName=line.substring(line.indexOf("attributeName=")+14, line.indexOf("attributeValue=")).trim();
}
if (line.indexOf("attributeValue=") != -1)
{
attrVal=line.substring(line.indexOf("attributeValue=")+15).trim();
}
// Save the attribute in the attribute list
uAttrs.addAttribute("","",attrName,"",attrVal);
// Read next line. While loop checks if its still an attribute line
line = lnr.readLine();
}
}
} // end if
if (!found)
line=lnr.readLine();
} // end while
} // end try
catch (IOException e)
{
Trace.log(Trace.PCML,"Error reading xsd stream in startElement.", e);
}
}
} // end if xsdStream not null
if (getKnownArrayTypes().contains(equivQName)) //@L7C
{
curDim++;
if (uDefinedQName)
{
if (curAttrs.size() > curDim)
curAttrs.set(curDim,uAttrs);
else
curAttrs.add(curDim,uAttrs);
}
else
{
if (curAttrs.size() > curDim)
curAttrs.set(curDim, new AttributesImpl(xmlAttrs));
else
curAttrs.add(curDim, new AttributesImpl(xmlAttrs));
}
if (curQName.size() > curDim)
curQName.set(curDim,equivQName);
else
curQName.add(curDim,equivQName);
lastQName = equivQName;
}
// Create a PcmlAttributeList to hold all the
// attributes for this node.
AttributesImpl curList;
String curName;
if (equivQName.equals("i") || equivQName.equals("struct_i"))
{
// Check if this is first element in array. If not, then increase dimensions by 1
if (lastQName.indexOf("arrayOf") == -1) // Last element not arrayOf element so up by 1
{
// This is not first element so up index by 1
dimensions.set(curDim, dimensions.at(curDim)+1);
}
curList = new AttributesImpl( (AttributesImpl) curAttrs.elementAt(curDim));
curName = (String)curQName.elementAt(curDim);
}
else
{
if (uDefinedQName)
{
curList = uAttrs;
for (int attr = 0; attr < xmlAttrs.getLength(); attr++)
{
if (curList.getIndex(xmlAttrs.getQName(attr)) == -1)
{
extendedType=true;
curList.addAttribute(xmlAttrs.getURI(attr),
xmlAttrs.getLocalName(attr),
xmlAttrs.getQName(attr),
xmlAttrs.getType(attr),
xmlAttrs.getValue(attr));
}
}
}
else
curList = new AttributesImpl(xmlAttrs);
curName = equivQName;
}
// Check if this is the first instance of this node. If not, do not create the node again
firstInstance = true;
if (m_currentNode != null)
{
if (m_currentNode.getNodeType() == PcmlNodeType.STRUCT && !equivQName.equals("struct_i") && !equivQName.equals("struct") && !equivQName.equals("xpcml"))
{
boolean isInTree;
isInTree = inTree(equivQName,curList);
if (isInTree)
firstInstance=false;
}
}
for (int i=0; i<= curDim; ++i)
{
if (dimensions.at(i) > 0)
firstInstance=false;
}
// Set current dimension to index value if specified
if (equivQName.equals("i") || equivQName.equals("struct_i"))
{
for (int attr=0; attr < xmlAttrs.getLength(); attr++)
{
if (xmlAttrs.getQName(attr).equals("index"))
{
// Set current dimension to index value
Integer indexInt = new Integer(xmlAttrs.getValue(attr));
dimensions.set(curDim,indexInt.intValue());
}
}
}
// Set attributes if this is the first instance of this node
lastQName = equivQName;
if (firstInstance && !equivQName.equals("i") && !equivQName.equals("struct_i"))
{
PcmlAttributeList attrs= new PcmlAttributeList(curList.getLength()+2);
for (int attr = 0; attr < curList.getLength(); attr++)
{
//@E1A -- XPCML code. Need to convert XPCML representation of attributes to their PCML
// equivalents.
//if (curList.getQName(attr).equals("name"))
// parmName = curList.getValue(attr);
if (curList.getQName(attr).equals("passDirection")) //@E1A
{
//@E1A
if (curList.getValue(attr).equals("in")) //@E1A
attrs.addAttribute( new PcmlAttribute("usage", //@E1A
"input",
(true | false)) );
else if (curList.getValue(attr).equals("inout")) //@E1A
attrs.addAttribute( new PcmlAttribute("usage", //@E1A
"inputoutput",
(true | false)) );
else if (curList.getValue(attr).equals("out")) //@E1A
attrs.addAttribute( new PcmlAttribute("usage", //@E1A
"output",
(true | false)) );
else if (curList.getValue(attr).equals("inherit")) //@E1A
attrs.addAttribute( new PcmlAttribute("usage", //@E1A
"inherit",
(true | false)) );
}
else if (curList.getQName(attr).equals("passMode")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("passby", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("bytesPerChar")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("chartype", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("totalBytes")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("length", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("outputSize")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("outputsize", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("entryPoint")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("entrypoint", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("returnValue")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("returnvalue", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("threadSafe")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("threadsafe", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("offsetFrom")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("offsetfrom", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("totalDigits")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("length", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("fractionDigits")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("precision", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("parseOrder")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("parseorder", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("bidiStringType")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("bidistringtype", //@E1A
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("isEmptyString")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("init", //@E1A
"",
(true | false)) );
}
else if (curList.getQName(attr).equals("dateFormat"))
{
attrs.addAttribute( new PcmlAttribute("dateformat",
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("dateSeparator"))
{
attrs.addAttribute( new PcmlAttribute("dateseparator",
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("timeFormat"))
{
attrs.addAttribute( new PcmlAttribute("timeformat",
curList.getValue(attr),
(true | false)) );
}
else if (curList.getQName(attr).equals("timeSeparator"))
{
attrs.addAttribute( new PcmlAttribute("timeseparator",
curList.getValue(attr),
(true | false)) );
}
// Note: This 'else if' clause needs to be the last one in the sequence.
else if (!qName.equals("xpcml") || (qName.equals("xpcml") && curList.getQName(attr).equals("version")))
{
attrs.addAttribute( new PcmlAttribute(curList.getQName(attr), // @C3C @E0C
curList.getValue(attr),
(true | false)) );
}
else
{
//System.out.println("Unrecognized attr: |" + curList.getQName(attr) + "|");
}
} // end for loop
// Create PcmlDocNode subclass based on tag name
if (tagName.equals("program"))
{
newNode = new PcmlProgram(attrs);
// Reset dimensions
for (int i=0; i< dimensions.size();++i)
dimensions.set(i, 0);
}
else if (tagName.equals("struct"))
{
newNode = new PcmlStruct(attrs);
// Check if outside program parameter list. If so, then reset dimensions
//
}
else if (tagName.equals("arrayOfStruct"))
{
newNode = new PcmlStruct(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("arrayOfStructParm"))
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"struct",
(true | false)) );
newNode = new PcmlData(attrs); //@E1A
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (tagName.equals("xpcml")) //@E1A
{
newNode = new PcmlDocument(attrs,m_docName); //@E1A
}
else if (equivQName.equals("stringParm") || equivQName.equals("arrayOfStringParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", //@E1A
"char",
(true | false)) );
newNode = new PcmlData(attrs); //@E1A
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("hexBinaryParm") || equivQName.equals("arrayOfHexBinaryParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"byte",
(true | false)) );
newNode = new PcmlData(attrs); //@E1A
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("intParm") || equivQName.equals("arrayOfIntParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"int",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length", // @E1A
"4",
(true | false)) );
newNode = new PcmlData(attrs); //@E1A
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("unsignedIntParm") || equivQName.equals("arrayOfUnsignedIntParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"int",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length", // @E1A
"4",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("precision", // @E1A
"32",
(true | false)) );
newNode = new PcmlData(attrs); //@E1A
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("byteParm") || equivQName.equals("arrayOfByteParm"))
{
attrs.addAttribute( new PcmlAttribute("type",
"int",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length",
"1",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("unsignedByteParm") || equivQName.equals("arrayOfUnsignedByteParm"))
{
attrs.addAttribute( new PcmlAttribute("type",
"int",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length",
"1",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("precision",
"8",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("shortParm") || equivQName.equals("arrayOfShortParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"int",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length", // @E1A
"2",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("unsignedShortParm") || equivQName.equals("arrayOfUnsignedShortParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"int",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length", // @E1A
"2",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("precision", // @E1A
"16",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("longParm") || equivQName.equals("arrayOfLongParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"int",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length", // @E1A
"8",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("unsignedLongParm") || equivQName.equals("arrayOfUnsignedLongParm"))
{
attrs.addAttribute( new PcmlAttribute("type",
"int",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length",
"8",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("precision",
"64",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("floatParm") || equivQName.equals("arrayOfFloatParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"float",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length", // @E1A
"4",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("doubleParm") || equivQName.equals("arrayOfDoubleParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"float",
(true | false)) );
attrs.addAttribute( new PcmlAttribute("length", // @E1A
"8",
(true | false)) );
newNode = new PcmlData(attrs); //@E1A
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("zonedDecimalParm") || equivQName.equals("arrayOfZonedDecimalParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"zoned",
(true | false)) );
newNode = new PcmlData(attrs); //@E1A
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("packedDecimalParm") || equivQName.equals("arrayOfPackedDecimalParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"packed",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("dateParm") || equivQName.equals("arrayOfDateParm"))
{
attrs.addAttribute( new PcmlAttribute("type",
"date",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("timeParm") || equivQName.equals("arrayOfTimeParm"))
{
attrs.addAttribute( new PcmlAttribute("type",
"time",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("timestampParm") || equivQName.equals("arrayOfTimestampParm"))
{
attrs.addAttribute( new PcmlAttribute("type",
"timestamp",
(true | false)) );
newNode = new PcmlData(attrs);
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else if (equivQName.equals("structParm")) //@E1A
{
attrs.addAttribute( new PcmlAttribute("type", // @E1A
"struct",
(true | false)) );
newNode = new PcmlData(attrs); //@E1A
// Check if this is a user-defined element. Update field in docNode if so
if (uDefinedQName)
newNode.setCondensedName(qName);
}
else
{
// Unrecognized tag name should never happen, if the tags parse successfully
newNode = null;
}
if (newNode != null)
{
if (extendedType)
{
newNode.setIsExtendedType(true);
}
if (m_rootNode == null)
{
m_rootNode = (PcmlDocument) newNode;
m_currentNode = newNode;
}
else
{
if (m_currentNode != null) m_currentNode.addChild(newNode);
m_currentNode = newNode;
}
}
} // end if firstInstance
else
{
// Not first instance of node so we need to retrieve the node from the tree and set
// it to current node
if (m_currentNode.getNodeType()== PcmlNodeType.STRUCT && !equivQName.equals("struct_i") ||
(m_currentNode.getNodeType()==PcmlNodeType.DATA && m_currentNode.getAttributeValue("type").equals("struct") ) &&
!equivQName.equals("struct_i"))
{
String pName="";
for (int attr = 0; attr < curList.getLength(); attr++)
{
if (curList.getQName(attr).equals("name"))
pName = curList.getValue(attr);
}
Enumeration items;
PcmlNode child=null;
items = m_currentNode.getChildren();
if (items == null)
return;
boolean found=false;
while (items.hasMoreElements() && !found)
{
child = (PcmlNode) items.nextElement();
if (child.getName().equals(pName))
found=true;
}
m_currentNode = (PcmlDocNode) child;
}
}
} // end docIsXPCML
}
/*** @E1A - New for XPCML **/
/** Characters. This is the actual text of the elements */
/* We need this method in XPCML because data can be */
/** passed in on input. */
public void characters(char ch[], int start, int length) throws SAXException {
if (m_currentNode != null &&
m_currentNode.getNodeType() == PcmlNodeType.DATA &&
(m_currentNode.getAttributeValue("type") == null ||
!m_currentNode.getAttributeValue("type").equals("struct"))) //@E1A
{
//@E1A
String str = new String(ch,start,length); //@E1A
// Set the value based on the dimensions
if (!getKnownArrayTypes().contains(lastQName))
{
// Concatenate to current value of init
// if (str.trim().length() > 0)
// {
if (lastQName.equals("i"))
{
if (str.indexOf(0x0a) != -1)
{
initValue = initValue+str.substring(0,str.indexOf(0x0a)); //@E1A
}
else
initValue = initValue+str;
}
else
initValue = initValue+str;
// }
try
{
// Need to determine if current node's type is byte and decode the string to
// a byte array if so
if (m_currentNode.getAttributeValue("type").equals("byte"))
{
// Need to convert hex input to bytes
byte[] byteA = BinaryConverter.stringToBytes(initValue);
((PcmlData) m_currentNode).setValue(byteA, dimensions);
}
else
{
if (m_currentNode.getAttributeValue("type").equals("char") &&
m_currentNode.getAttributeValue("isEmptyString") != null &&
m_currentNode.getAttributeValue("isEmptyString").equals("true"))
{
Trace.log(Trace.PCML, "Setting an empty string");
( (PcmlData) m_currentNode).setValue("", new PcmlDimensions(dimensions) );
}
else if (initValue.trim().length() > 0 || m_currentNode.getAttributeValue("type").equals("char"))
{
( (PcmlData) m_currentNode).setInit(initValue);
( (PcmlData) m_currentNode).setValue(initValue, dimensions);
}
}
if (!firstInstance ||
lastQName.equals("i") || lastQName.equals("struct_i"))
{
// Reset init value if more than one of this node exists
// This keeps subsequent nodes from getting set with value of init value of last node
( (PcmlData) m_currentNode).setInit(null);
}
}
catch (Exception e)
{
Trace.log(Trace.PCML,"Exception when doing setValue.", e);
Trace.log(Trace.PCML,"current node=" + m_currentNode.getQualifiedName());
Trace.log(Trace.PCML,"initial value=" + initValue + "..");
try
{
int length2 = ((PcmlData)m_currentNode).getLength(dimensions);
Trace.log(Trace.PCML,"length2 is "+length2);
}
catch (Exception e1)
{
Trace.log(Trace.PCML,"Exception due to length not being set when doing setValue.", e);
Trace.log(Trace.PCML,"setValue not done but init attribute set.");
return;
}
throw new SAXException(e);
}
}
} //@E1A
} // characters(char[],int,int);
public void endElement(String uri, String localName, String qName) //@E0C
{
String equivQName=qName;
// boolean uDefinedQName=false;
if (!docIsXPCML)
m_currentNode = (PcmlDocNode) m_currentNode.getParent();
if (docIsXPCML)
{
if (xsdFileStream != null)
{
// Check if this is a user defined element. If so, convert to equivalent XPCML element
if (!getKnownTypes().contains(qName))
{
// User defined parameter. Need to find it in XSD stream.
// uDefinedQName=true;
ByteArrayInputStream xmlIn1 = new ByteArrayInputStream(xmlOut.toByteArray());
// Dead code..
// if (xmlIn1 == null)
// throw new MissingResourceException(SystemResourceFinder.format(DAMRI.PCML_DTD_NOT_FOUND, new Object[] {"xmlOut"}), "xmlOut", "");
// Cache the line count of the header
LineNumberReader lnr = new LineNumberReader(new InputStreamReader(xmlIn1));
try
{
String line = lnr.readLine();
boolean found=false;
while (line != null && !found)
{
if (line.indexOf("name="+"\""+qName+"\"") != -1 && line.indexOf("parm type=") != -1)
{
if (line.indexOf("parm type=string") != -1)
{
// String parm found
equivQName = "stringParm";
found=true;
}
else if (line.indexOf("parm type=int") != -1)
{
// Int parm found
equivQName="intParm";
found=true;
}
else if (line.indexOf("parm type=uint") != -1)
{
// Unsigned Int parm found
equivQName="unsignedIntParm";
found=true;
}
else if (line.indexOf("parm type=hexBinary") != -1)
{
// hexBinary parm found
equivQName="hexBinaryParm";
found=true;
}
else if (line.indexOf("parm type=byte") != -1)
{
// byte parm found
equivQName="byteParm";
found=true;
}
else if (line.indexOf("parm type=ubyte") != -1)
{
// Unsigned Byte parm found
equivQName="unsignedByteParm";
found=true;
}
else if (line.indexOf("parm type=short") != -1)
{
// Short parm found
equivQName="shortParm";
found=true;
}
else if (line.indexOf("parm type=ushort") != -1)
{
// Unsigned Short parm found
equivQName="unsignedShortParm";
found=true;
}
else if (line.indexOf("parm type=long") != -1)
{
// Long parm found
equivQName="longParm";
found=true;
}
else if (line.indexOf("parm type=ulong") != -1)
{
// Unsigned Long parm found
equivQName="unsignedLongParm";
found=true;
}
else if (line.indexOf("parm type=float") != -1)
{
// Float parm found
equivQName="floatParm";
found=true;
}
else if (line.indexOf("parm type=double") != -1)
{
// Double parm found
equivQName="doubleParm";
found=true;
}
else if (line.indexOf("parm type=packed") != -1)
{
// Packed parm found
equivQName="packedDecimalParm";
found=true;
}
else if (line.indexOf("parm type=zoned") != -1)
{
// Zoned parm found
equivQName="zonedDecimalParm";
found=true;
}
else if (line.indexOf("parm type=date") != -1)
{
// Date parm found
equivQName="dateParm";
found=true;
}
else if (line.indexOf("parm type=time") != -1)
{
// Time parm found
equivQName="timeParm";
found=true;
}
else if (line.indexOf("parm type=timestamp") != -1)
{
// Timestamp parm found
equivQName="timestampParm";
found=true;
}
else if (line.indexOf("parm type=structParm") != -1)
{
// Struct parm found
equivQName="structParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfString") != -1)
{
// String parm found
equivQName = "arrayOfStringParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfInt") != -1)
{
// Int parm found
equivQName="arrayOfIntParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfUInt") != -1)
{
// Unsigned Int parm found
equivQName="arrayOfUnsignedIntParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfHexBinary") != -1)
{
// hexBinary parm found
equivQName="arrayOfHexBinaryParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfByte") != -1)
{
// Byte parm found
equivQName="arrayOfByteParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfUByte") != -1)
{
// Unsigned Byte parm found
equivQName="arrayOfUnsignedByteParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfShort") != -1)
{
// Short parm found
equivQName="arrayOfShortParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfUShort") != -1)
{
// Unsigned Short parm found
equivQName="arrayOfUnsignedShortParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfLong") != -1)
{
// Long parm found
equivQName="arrayOfLongParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfULong") != -1)
{
// Unsigned Long parm found
equivQName="arrayOfUnsignedLongParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfFloat") != -1)
{
// Float parm found
equivQName="arrayOfFloatParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfDouble") != -1)
{
// Double parm found
equivQName="arrayOfDoubleParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfPacked") != -1)
{
// Packed parm found
equivQName="arrayOfPackedDecimalParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfZoned") != -1)
{
// Zoned parm found
equivQName="arrayOfZonedDecimalParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfDate") != -1)
{
// Date parm found
equivQName="arrayOfDateParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfTime") != -1)
{
// Time parm found
equivQName="arrayOfTimeParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfTimestamp") != -1)
{
// Timestamp parm found
equivQName="arrayOfTimestampParm";
found=true;
}
else if (line.indexOf("parm type=arrayOfStructParm") != -1)
{
// Struct parm found
equivQName="arrayOfStructParm";
found=true;
}
else if (line.indexOf("parm type=structArray") != -1)
{
// Struct parm found
equivQName="arrayOfStruct";
found=true;
}
{
// Should never reach here. Should get parse error if invalid type passed in
// What should I do here?
Trace.log(Trace.PCML,"Error parsing xsd stream in endElement:", line);
}
}
line=lnr.readLine();
}
}
catch (IOException e)
{
Trace.log(Trace.PCML,"Error reading xsd stream in endElement.", e);
}
}
}
if (!equivQName.equals("parameterList") && !equivQName.equals("i") && !equivQName.equals("struct_i"))
m_currentNode = (PcmlDocNode) m_currentNode.getParent();
// Backing up tree. Reset dimensions and current dimension
if (getKnownArrayTypes().contains(equivQName)) //@L7C
{
dimensions.set(curDim, 0); //reset
curDim--;
}
} // end if docIsXPCML
}
// Returns a string containing the tag name enclosed in brackets.
private final static String getBracketedTagName(String tagName)
{
return "<" + tagName + ">";
}
/** Determine if node is in tree already -- used for array processing ****/
boolean inTree(String equivQName, AttributesImpl curList)
{
boolean found=false;
String pName="";
for (int attr = 0; attr < curList.getLength(); attr++)
{
if (curList.getQName(attr).equals("name"))
pName = curList.getValue(attr);
}
Enumeration items;
PcmlNode child=null;
items = m_currentNode.getChildren();
if (items != null)
{
while (items.hasMoreElements() && !found)
{
child = (PcmlNode) items.nextElement();
if (child.getName().equals(pName) && pName.length() > 0)
found=true;
}
}
return found;
}
// See Java Bug ID 4806878, http://developer.java.sun.com/developer/bugParade/bugs/4806878.html:
// "[The] W3C XML Spec says that validation errors are not fatalerrors. And DefaultHandler implementation doesn't print out any errors for the validation errors. If user is interested in seeing the validation errors, then they need to extend the DefaultHandler [by re-implementing error() and fatalerror().]"
public void warning(SAXParseException spe)
throws SAXException
{
if (exceptionIfParseError_)
{
// new behavior (consistent with RfmlSAXParser)
if (m_xh == null) throw spe;
else m_xh.warning(spe);
}
else
{
// old behavior
Trace.log(Trace.PCML, "[Warning]: "+ spe.getMessage());
}
}
public void error(SAXParseException spe)
throws SAXException
{
if (exceptionIfParseError_)
{
// new behavior (consistent with RfmlSAXParser)
if (m_xh == null) throw spe;
else m_xh.error(spe);
}
else
{
// old behavior
Trace.log(Trace.PCML, "[Error]: "+ spe.getMessage());
}
}
public void fatalError(SAXParseException spe)
throws SAXException
{
if (m_xh == null) throw spe;
else m_xh.error(spe);
}
// Note: After the HashSet is initially built, it is never modified.
// Therefore we don't need to synchronize accesses after it is built.
private static HashSet getKnownTypes()
{
if (knownTypes_ == null)
{
synchronized (PcmlSAXParser.class)
{
if (knownTypes_ == null)
{
knownTypes_ = new HashSet(50);
knownTypes_.addAll(getKnownArrayTypes());
String[] types =
{
"byteParm",
"dateParm",
"doubleParm",
"floatParm",
"hexBinaryParm",
"intParm",
"longParm",
"packedDecimalParm",
"parameterList", // no corresponding 'array' type
"program", // no corresponding 'array' type
"shortParm",
"stringParm",
"struct",
"structParm",
"timeParm",
"timestampParm",
"unsignedByteParm",
"unsignedIntParm",
"unsignedLongParm",
"unsignedShortParm",
"xpcml", // no corresponding 'array' type
"zonedDecimalParm"
// 41 types (including 19 array types): 12 new, plus 29 old
};
for (int i=0; i