// // Copyright (c)1998-2011 Pearson Education, Inc. or its affiliate(s). // All rights reserved. // package openadk.library.impl; import java.io.Reader; import java.io.StringReader; import java.util.List; import javax.xml.namespace.QName; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import openadk.library.ADK; import openadk.library.ADKParsingException; import openadk.library.ADKTypeParseException; import openadk.library.DTD; import openadk.library.Element; import openadk.library.ElementDef; import openadk.library.ElementVersionInfo; import openadk.library.SIFDTD; import openadk.library.SIFElement; import openadk.library.SIFErrorCategory; import openadk.library.SIFErrorCodes; import openadk.library.SIFException; import openadk.library.SIFFormatter; import openadk.library.SIFParser; import openadk.library.SIFSimpleType; import openadk.library.SIFString; import openadk.library.SIFTypeConverter; import openadk.library.SIFTypeConverters; import openadk.library.SIFVersion; import openadk.library.SIFWriter; import openadk.library.SimpleField; import openadk.library.Zone; import openadk.library.common.CommonDTD; import openadk.library.common.SIF_ExtendedElement; import openadk.library.common.XMLData; import openadk.library.datamodel.DatamodelDTD; import openadk.library.impl.surrogates.RenderSurrogate; import openadk.library.infra.SIF_Query; import openadk.library.infra.SIF_QueryObject; import openadk.library.infra.SIF_Request; import openadk.util.XMLNodeReader; import openadk.util.XMLStreamDocumentBuilder; import org.apache.log4j.Logger; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; /** * * A SIF Parser implementation that uses StAX-based parsing, using the SUN * StAXParser * * @author Andrew Elmhorst * */ public class SIFPullParser extends SIFParser { private SIFElement fParsed; /** * The constructor is made protected so that access can only be done using * the factory method. */ public SIFPullParser() { } private static XMLInputFactory sFactory = createXmlInputFactory(); /** * Creates an instance of an XMLInputFactory for use with this parser * * @return */ private static XMLInputFactory createXmlInputFactory() { XMLInputFactory factory = XMLInputFactory.newInstance(); // Not all XMLInputFactory service providers support all properties, so that will now be checked before attempting to set them for (String propertyToEnable : new String[] {"reuse-instance", XMLInputFactory.IS_COALESCING}) { if (factory.isPropertySupported(propertyToEnable)) { try { factory.setProperty(propertyToEnable, true); } catch (IllegalArgumentException iae) { iae.printStackTrace(); } } } return factory; } /** * Closes the XMLStreamReader and translates any exceptions to an * ADKException * * @param reader * @param zone * @throws ADKParsingException */ private void closeXmlReader(XMLStreamReader reader, Zone zone) throws ADKParsingException { try { reader.close(); } catch (XMLStreamException xse) { throw new ADKParsingException(xse.getLocalizedMessage(), zone, xse); } } /** * Creates an XMLStreamReader instance that reads from the specified Reader * * @param msg * @return * @throws ADKParsingException */ private XMLStreamReader getXmlReader(Reader reader) throws ADKParsingException { try { synchronized (sFactory) { return sFactory.createXMLStreamReader(reader); } } catch (XMLStreamException xse) { throw new ADKParsingException(xse.getLocalizedMessage(), null, xse); } } /* * (non-Javadoc) * * @see openadk.library.SIFParser#parse(java.lang.String ) */ @Override public SIFElement parse(String msg) throws ADKParsingException, SIFException { return parse(msg, null, 0); } /* * (non-Javadoc) * * @see openadk.library.SIFParser#parse(java.lang.String, * openadk.library.Zone) */ @Override public SIFElement parse(String msg, Zone zone) throws ADKParsingException, SIFException { return parse(msg, zone, 0); } /* * (non-Javadoc) * * @see openadk.library.SIFParser#parse(java.lang.String, * openadk.library.Zone, int) */ @Override public SIFElement parse(String msg, Zone zone, int flags) throws ADKParsingException, SIFException { return parse(msg, zone, flags, null); } /* * (non-Javadoc) * * @see openadk.library.SIFParser#parse(java.lang.String, * openadk.library.Zone, int, * openadk.library.SIFVersion) */ @Override public SIFElement parse(String msg, Zone zone, int flags, SIFVersion version) throws ADKParsingException, SIFException { StringReader sr = new StringReader(msg); XMLStreamReader reader = getXmlReader(sr); SIFElement parsed = parse(reader, zone, flags, version); closeXmlReader(reader, zone); sr.close(); return parsed; } /* * (non-Javadoc) * * @see openadk.library.SIFParser#parse(java.io.Reader, * openadk.library.Zone) */ @Override public SIFElement parse(Reader msg, Zone zone) throws ADKParsingException, SIFException { XMLStreamReader reader = getXmlReader(msg); SIFElement parsed = parse(reader, zone, 0, null); closeXmlReader(reader, zone); return parsed; } /* * (non-Javadoc) * * @see openadk.library.SIFParser#parse(java.io.Reader, * openadk.library.Zone, int) */ @Override public SIFElement parse(Reader msg, Zone zone, int flags) throws ADKParsingException, SIFException { XMLStreamReader reader = getXmlReader(msg); SIFElement parsed = parse(reader, zone, flags, null); closeXmlReader(reader, zone); return parsed; } /* * (non-Javadoc) * * @see openadk.library.SIFParser#parse(java.io.Reader, * openadk.library.Zone, int, * openadk.library.SIFVersion) */ @Override public SIFElement parse(Reader msg, Zone zone, int flags, SIFVersion version) throws ADKParsingException, SIFException { XMLStreamReader reader = getXmlReader(msg); SIFElement parsed = parse(reader, zone, flags, version); closeXmlReader(reader, zone); return parsed; } /* * (non-Javadoc) * * @see openadk.library.SIFParser#getParsed() */ @Override public SIFElement getParsed() { return fParsed; } private SIFElement parse(XMLStreamReader reader, Zone zone, int flags, SIFVersion version) throws ADKParsingException, SIFException { // Move to the first element in the XML document fParsed = null; if (reader.getEventType() != XMLStreamConstants.START_ELEMENT) { try { reader.nextTag(); } catch (XMLStreamException xse) { throw new ADKParsingException(xse.getLocalizedMessage(), zone, xse); } } if (reader.getLocalName().equals("SIF_Message")) { SIFElement element = readSIFMessageElement(reader, ADK.DTD(), zone, flags, version); return element.getChildList().get(0); } else { version = parseVersion(reader, ADK.DTD(), zone, flags, version); return parseElementStream(reader, version, ADK.DTD(), zone, flags); } } /** * Reads a SIF_Message element, which sets the version and namespace scope * for the rest of the xml parsing * * @param reader * @param dtd * @param zone * @param flags * @param defaultVersion * @return */ protected SIFElement readSIFMessageElement(XMLStreamReader reader, DTD dtd, Zone zone, int flags, SIFVersion defaultVersion) throws ADKParsingException, SIFException { SIFVersion version = parseVersion(reader, dtd, zone, flags, defaultVersion); SIF_Message message = new SIF_Message(); // Note: Always reset fParsed to the current message // This allows a proper SIF_Ack to be returned in Pull mode, even if // the payload doesn't parse properly fParsed = message; // Set the namespace from our working version message.setXmlns(version.getXmlns()); if (version.compareTo(SIFVersion.SIF11) >= 0) { // If we are at SifVersion 1.1 or greater, set the version attribute message.setVersionAttribute(version.toString()); } try { reader.nextTag(); } catch (XMLStreamException xse) { throw new ADKParsingException(xse.getLocalizedMessage(), zone, xse); } SIFElement element = parseElementStream(reader, version, dtd, zone, flags); // Do we need to bump message version - JEN if (element instanceof SIF_Request) { SIF_Request request = (SIF_Request) element; SIF_Query query = request.getSIF_Query(); if (query != null) { SIF_QueryObject queryObject = query.getSIF_QueryObject(); String queryObjectName = queryObject.getObjectName(); ElementDef def = ADK.DTD().lookupElementDef(queryObjectName); if (def != null) { String earlistVersion = def.getEarliestVersion().toString(); SIFVersion earlier = SIFVersion.parse(earlistVersion); SIFVersion base = SIFVersion.parse("2.0r1"); if (((earlier.getMajor() == base.getMajor()) && (earlier.getMinor() > base.getMinor())) || (earlier.getMajor() > base.getMajor())) { message.setVersion(earlistVersion); } } } } message.addChild(element); return message; } private SIFVersion parseVersion(XMLStreamReader reader, DTD dtd, Zone zone, int flags, SIFVersion defaultVersion) throws ADKParsingException, SIFException { SIFVersion version = null; // TODO: For now, we are using a reader that doesn't support namespaces, // so we can't look up the version attribute by name (for now) String verAttr = reader.getAttributeValue(null, "Version"); if (verAttr == null) { for (int a = 0; a < reader.getAttributeCount(); a++) { if (reader.getAttributeLocalName(a).equals("Version")) { verAttr = reader.getAttributeValue(a); } } } // Order of precedence: // 1) Version attribute of message // 2) The version passed in (if not null) // 3) The namespace version (if able to parse) // 4) The ADK SIF Version if (verAttr != null) { version = SIFVersion.parse(verAttr); } else if (defaultVersion != null) { version = defaultVersion; } else { String namespace = reader.getNamespaceURI(); version = SIFVersion.parseXmlns(namespace); if (version == null) { version = ADK.getSIFVersion(); } } // Do validation on the version if (!ADK.isSIFVersionSupported(version)) { throw new SIFException(SIFErrorCategory.GENERIC, SIFErrorCodes.GENERIC_VERSION_NOT_SUPPORTED_3, "SIF " + version.toString() + " not supported", reader.getNamespaceURI(), zone); } else if (zone != null && zone.getProperties().getStrictVersioning()) { if (version.compareTo(ADK.getSIFVersion()) != 0) { throw new SIFException(SIFErrorCategory.GENERIC, SIFErrorCodes.GENERIC_VERSION_NOT_SUPPORTED_3, "SIF " + version.toString() + " message support disabled by this agent", "This agent is running in strict SIF " + ADK.getSIFVersion().toString() + " mode", zone); } } return version; } private SIFElement parseElementStream(XMLStreamReader reader, SIFVersion version, DTD dtd, Zone zone, int flags) throws ADKParsingException, SIFException { boolean legacyParse = version.compareTo(SIFVersion.SIF20) < 0; // The current SIFElement being parsed SIFElement currentElement = null; SIFFormatter formatter = ADK.DTD().getFormatter(version); String xmlName = ""; try { int nodeType = reader.getEventType(); while (reader.hasNext()) { if (nodeType == XMLStreamConstants.CHARACTERS) { if (reader.isWhiteSpace()) { // JEN Alert Message problem - here try { nodeType = reader.nextTag(); } catch (Exception e) { String errorMessage = xmlName + " Tag Parse Exception:"; ADK.getLog().warn(errorMessage, e); nodeType = reader.next(); } continue; } if (currentElement.getElementDef().hasSimpleContent()) { // This is a SIFElement that allows a Text value to be // set to it. // The XMLStreamReader cursor will automatically be // advanced by this method to what should be the // END_ELEMENT setFieldValueFromElement(currentElement.getElementDef(), currentElement, reader, version, formatter, zone); nodeType = reader.getEventType(); continue; } } else if (nodeType == XMLStreamConstants.START_ELEMENT) { if (reader.getLocalName().equals("SIF_Message")) { // Special case for embedded SIF_Message envelopes if ((flags & SIFParser.FLG_EXPECT_INNER_ENVELOPE) != 0) { SIFElement msgElement = readSIFMessageElement(reader, dtd, zone, 0, version); currentElement.addChild(msgElement); currentElement = msgElement; } else { throw new ADKParsingException("Unexpected SIF_Message encountered in parsing", zone); } } else { xmlName = reader.getLocalName(); ElementDef foundDef = lookupElementDef(currentElement, xmlName, dtd, version, zone); if (foundDef == null) { if (legacyParse) { nodeType = parseLegacyXML(reader, version, zone, currentElement, formatter, xmlName); continue; } else if (currentElement != null && currentElement.getElementDef().name().equals("XMLData")) { // Parse this into a DOM and set on the XMLData // element XMLNodeReader nestedReader = new XMLNodeReader(reader); org.w3c.dom.Document doc = XMLStreamDocumentBuilder.build(nestedReader, false, true, null); ((XMLData) currentElement).setXML(doc); nodeType = reader.nextTag(); continue; } else { String _tag = currentElement != null ? currentElement.getElementDef().name() + "/" + xmlName : xmlName; throw new SIFException(SIFErrorCategory.XML_VALIDATION, SIFErrorCodes.XML_GENERIC_VALIDATION_3, "Unknown element or attribute", _tag + " is not a recognized element of SIF " + version.toString(), zone); } } if (legacyParse) { ElementVersionInfo evi = foundDef.getVersionInfo(version); if (evi != null) { RenderSurrogate rs = evi.getSurrogate(); if (rs != null) { try { if (rs.readRaw(reader, version, currentElement, formatter)) { nodeType = reader.getEventType(); continue; } else { throw new SIFException(SIFErrorCategory.XML_VALIDATION, SIFErrorCodes.XML_GENERIC_VALIDATION_3, "Unknown element or attribute", reader.getLocalName() + " was not able to be parsed by " + rs, zone); } } catch (ADKTypeParseException atpe) { handleTypeParseException("Unable to parse value: " + atpe.getMessage(), atpe, zone); nodeType = reader.getEventType(); continue; } } } } if (reader.getLocalName().equals("SIF_ExtendedElement") || foundDef.equals(CommonDTD.SIF_EXTENDEDELEMENT)) { readSIFExtendedElement(reader, dtd, zone, currentElement, version, formatter); nodeType = reader.getEventType(); continue; } else if (foundDef.isField()) { setFieldValueFromElement(foundDef, currentElement, reader, version, formatter, zone); nodeType = reader.nextTag(); continue; } else { currentElement = readSIFElementFromElementNode(foundDef, reader, version, dtd, currentElement, formatter, zone); // TODO: Empty repeatable fields, such as Email, // that contain no data are not getting set to nil. // Should treat <Email Type="Primary"/> equivalent // to <Email Type="Primary" xsi:nil="true"/> } } } else if (nodeType == XMLStreamConstants.END_ELEMENT) { if (currentElement.getElementDef().hasSimpleContent() && currentElement.getSIFValue() == null && currentElement.getChildCount() < 1) { SIFTypeConverter<?> defConverter = currentElement.getElementDef().getTypeConverter(); if (defConverter == null) { defConverter = SIFTypeConverters.STRING; } SIFSimpleType<?> val = null; SimpleField<?> sifAction = currentElement.getField("SIF_Action"); if (sifAction != null && "Delete".equals(sifAction.getTextValue())) { val = defConverter.getSIFSimpleType(null); } else { val = defConverter.getSIFSimpleType(""); } currentElement.setField(currentElement.getElementDef(), val); } if (currentElement.getParent() != null) { currentElement = (SIFElement) currentElement.getParent(); while (legacyParse && currentElement.getElementDef().isCollapsed(version)) { currentElement = (SIFElement) currentElement.getParent(); } } if (reader.getLocalName().equals("SIF_Message")) { // We need to return here. If we let the reader keep // reading, and we are reading an embedded // SIF_Message, it will keep parsing the end tags and // not let the stack of SIFElement objects // properly unwind. We're done anyway. break; } // Advance to the nexttag (faster than calling next()) if (!reader.isEndElement()) { nodeType = reader.nextTag(); continue; } } // Advance the cursor nodeType = reader.next(); } } catch (XMLStreamException xse) { throw new ADKParsingException(xse.getLocalizedMessage(), zone, xse); } if (currentElement == null) { return null; } else { // Now, unwind and pop off the top element parsed Element top = currentElement; Element current; while ((current = top.getParent()) != null) { top = current; } return (SIFElement) top; } } protected int parseLegacyXML(XMLStreamReader reader, SIFVersion version, Zone zone, SIFElement currentElement, SIFFormatter formatter, String xmlName) throws SIFException { int nodeType; boolean handled = false; // Determine if any surrogate formatters that are defined as children // of the current element can resolve it // NOTE: Until we fix this in the ADK, elements from the common package // loose their // metadata information that was originally defined. ElementDef currentDef = currentElement.getElementDef(); List<ElementDef> children = currentDef.getChildren(); if (children == null || children.size() == 0) { // try to get the actual element def // WARNING! this is somewhat of a hack until // we get support for what we need in the ADK try { Class<?> actualElement = Class.forName(currentDef.getFQClassName()); SIFElement copy = (SIFElement) actualElement.newInstance(); children = copy.getElementDef().getChildren(); } catch (Exception cnfe) { throw new SIFException(SIFErrorCategory.XML_VALIDATION, SIFErrorCodes.XML_GENERIC_VALIDATION_3, "Unable to parse" + xmlName + " " + version.toString() + cnfe.getMessage(), zone); } } for (ElementDef candidate : children) { if (candidate.getEarliestVersion().compareTo(version) > 0) { continue; } RenderSurrogate rs = candidate.getVersionInfo(version).getSurrogate(); if (rs != null) { try { if (rs.readRaw(reader, version, currentElement, formatter)) { handled = true; break; } } catch (ADKTypeParseException e) { handleTypeParseException("Unable to parse element or attribute value: " + e.getMessage(), e, zone); handled = true; break; } catch (ADKParsingException e) { throw new SIFException(SIFErrorCategory.XML_VALIDATION, SIFErrorCodes.XML_GENERIC_VALIDATION_3, "unable to parse xml: " + e.getMessage() + version.toString(), zone); } } } if (!handled) { String _tag = currentElement != null ? currentElement.getElementDef().name() + "/" + xmlName : xmlName; throw new SIFException(SIFErrorCategory.XML_VALIDATION, SIFErrorCodes.XML_GENERIC_VALIDATION_3, "Unknown element or attribute", _tag + " is not a recognized element of SIF " + version.toString(), zone); } nodeType = reader.getEventType(); return nodeType; } protected SIFElement readSIFElementFromElementNode(ElementDef def, XMLStreamReader reader, SIFVersion version, DTD dtd, SIFElement parent, SIFFormatter formatter, Zone zone) throws ADKParsingException, SIFException, XMLStreamException { SIFElement element = null; try { element = SIFElement.create(parent, def); } catch (Exception e) { throw new ADKParsingException("Could not create an instance of '" + def.getFQClassName() + "' to wrap a " + reader.getLocalName() + " object. " + e, zone, e); } if (fParsed == null) { fParsed = element; } element.setElementDef(def); element.setSIFVersion(version); if (parent != null) { element = formatter.addChild(parent, element, version); } // Set the attributes to fields of the SIFElement int attrCount = reader.getAttributeCount(); for (int a = 0; a < attrCount; a++) { setFieldValueFromAttribute(element, a, reader, dtd, version, formatter, zone); } return element; } /** * Looks up an ElementDef representing the current XML Element or Attribute * * @param parent * @param reader * @param dtd * @param version * @param zone * @return * @throws SIFException */ protected ElementDef lookupElementDef(SIFElement parent, String xmlName, DTD dtd, SIFVersion version, Zone zone) { // Lookup the ElementDef metadata in the SifDtd object for the // version of SIF we are parsing. First try looking up a ElementDef // for a field or complex object that is a child of another element, // such as StudentPersonal_Name, SIF_Ack_SIF_Header, etc. If none // found then look for a root-level element such as StudentPersonal, // SIF_Ack, etc. If still nothing is found we don't know how to // parse this element -- it is neither a top-level object element // nor a child field element for this version of SIF. String elementName = xmlName; ElementDef def = null; if (parent != null) { def = dtd.lookupElementDef(parent.getElementDef(), elementName); } if (def == null) { def = dtd.lookupElementDef(elementName); } // Beginning with SIF 1.5 *any* object can have a SIF_ExtendedElements // child, so we need to check for that case since the Adk metadata // does not add SIF_ExtendedElements to all object types if (def == null && elementName.equals("SIF_ExtendedElements")) { def = CommonDTD.SIF_EXTENDEDELEMENTS; } // Beginning with SIF 2.0 *any* object can have a SIF_ExtendedElements // child, so we need to check for that case since the Adk metadata // does not add SIF_ExtendedElements to all object types if (def == null && elementName.equals("SIF_Metadata")) { def = DatamodelDTD.SIF_METADATA; } /* * JEN - todo Big Service Hack * * @see * openadk.library.DTD#lookupAnyElementDef(java.lang.String) */ if (def == null) { // def = dtd.lookupAnyElementDef(elementName); for (String defKey : SIFDTD.sElementDefs.keySet()) { if (defKey.contains(elementName)) { def = SIFDTD.sElementDefs.get(defKey); ADK.getLog().info("SIFDTD lookupAnyElementDef returned: " + defKey + " for " + elementName); break; } } } // Note: def returned can be null. return def; } /** * Sets the value of a SimpleField from the contents of an Xml Attribute * * @param element * @param attributeIndex * @param reader * @param dtd * @param formatter * @param zone * @throws ADKParsingException * @throws SIFException */ private void setFieldValueFromAttribute(SIFElement element, int attributeIndex, XMLStreamReader reader, DTD dtd, SIFVersion version, SIFFormatter formatter, Zone zone) throws ADKParsingException, SIFException { ElementDef elementDef = element.getElementDef(); QName attrName = reader.getAttributeName(attributeIndex); ElementDef field = dtd.lookupElementDef(elementDef, attrName.getLocalPart()); if (field == null && attrName.getPrefix() != null) { if (SIFWriter.NIL.equals(attrName.getLocalPart()) && SIFWriter.XSI_NAMESPACE.equals(attrName.getNamespaceURI())) { SIFTypeConverter<?> converter = elementDef.getTypeConverter(); if (converter != null) { SIFSimpleType<?> sst = converter.getSIFSimpleType(null); element.setField(elementDef, sst); } return; } else if ("xmlns".equals(reader.getPrefix())) { return; } else { field = dtd.lookupElementDef(elementDef, attrName.getPrefix() + ":" + attrName.getLocalPart()); } } if (field != null) { String strVal = reader.getAttributeValue(attributeIndex); SIFSimpleType<?> val = parseValue(field, strVal, version, formatter, zone); element.setField(field, val); } else { throw new SIFException(SIFErrorCategory.XML_VALIDATION, SIFErrorCodes.XML_GENERIC_VALIDATION_3, "Unknown element or attribute", attrName + " is not a recognized attribute of the " + elementDef.name() + " element (SIF " + element.effectiveSIFVersion().toString() + ")", zone); } } /** * Sets the value of SimpleField from the contents of an XML Element and * advances the reader to the END_ELEMENT tag * * @param def * @param element * @param reader * @param formatter * @throws XMLStreamException * @throws ADKParsingException */ protected void setFieldValueFromElement(ElementDef def, SIFElement element, XMLStreamReader reader, SIFVersion version, SIFFormatter formatter, Zone zone) throws XMLStreamException, SIFException { int nodeType = reader.getEventType(); while (nodeType == XMLStreamConstants.START_ELEMENT) { // Look for the xsi:nill attribute that signals a null value int attrCount = reader.getAttributeCount(); if (attrCount > 0) { for (int i = 0; i < attrCount; i++) { QName attrName = reader.getAttributeName(i); if (SIFWriter.NIL.equals(attrName.getLocalPart()) && SIFWriter.XSI_NAMESPACE.equals(attrName.getNamespaceURI())) { SIFTypeConverter<?> defConverter = def.getTypeConverter(); if (defConverter == null) { defConverter = SIFTypeConverters.STRING; } SIFSimpleType<?> val = defConverter.getSIFSimpleType(null); element.setField(def, val); reader.nextTag(); return; } } } nodeType = reader.next(); } if (nodeType == XMLStreamConstants.CHARACTERS || nodeType == XMLStreamConstants.CDATA) { int textNodeType = nodeType; StringBuffer buf = new StringBuffer(); while (nodeType == textNodeType) { buf.append(reader.getText()); nodeType = reader.next(); } String elementText = buf.toString(); SIFSimpleType<?> data = parseValue(def, elementText, version, formatter, zone); // JEN try { formatter.setField(element, def, data, version); } catch (NumberFormatException e) { String errorMessage = "Unable to parse element or attribute '" + def.name() + "'" + e.getMessage() + " (SIF " + version.toString() + ")"; ADKTypeParseException ex = new ADKTypeParseException(errorMessage, zone, e); handleTypeParseException(errorMessage, ex, zone); } } else if (nodeType == XMLStreamConstants.END_ELEMENT) { // Treat empty field values the same as xsi:nill attribute to signal // a null value SIFTypeConverter<?> defConverter = def.getTypeConverter(); if (defConverter == null) { defConverter = SIFTypeConverters.STRING; } SIFSimpleType<?> val = defConverter.getSIFSimpleType(null); element.setField(def, val); } } private SIFSimpleType<?> parseValue(ElementDef def, String value, SIFVersion version, SIFFormatter formatter, Zone zone) throws SIFException { try { SIFTypeConverter<?> converter = def.getTypeConverter(); if (converter == null) { // TODO: Should we not allow this in "STRICT" mode? converter = SIFTypeConverters.STRING; } return converter.parse(formatter, value); } catch (ADKTypeParseException pe) { String errorMessage = "Unable to parse element or attribute '" + def.name() + "'" + pe.getMessage() + " (SIF " + version.toString() + ")"; handleTypeParseException(errorMessage, pe, zone); return null; } } /** * Evaluates the ADK StrictTypeParsing property to determine if a * SIFException should be thrown for a failed parse * * @param errorMessage * @param pe * @param zone * @throws SIFException */ protected void handleTypeParseException(String errorMessage, ADKTypeParseException pe, Zone zone) throws SIFException { Logger log = ADK.getLog(); if (zone != null) { log = zone.getLog(); if (zone.getProperties().getStrictTypeParsing()) { throw new SIFException(SIFErrorCategory.XML_VALIDATION, SIFErrorCodes.XML_INVALID_VALUE_4, errorMessage, zone, pe); } } if ((ADK.debug & ADK.DBG_EXCEPTIONS) > 0) { log.warn(errorMessage, pe); } } //} else if (currentElement != null && currentElement.getElementDef().name().equals("SIF_ExtendedElement")) { // XMLNodeReader nestedReader = new XMLNodeReader(reader); // org.w3c.dom.Document doc = XMLStreamDocumentBuilder.build(nestedReader, false, true, null); // ((SIF_ExtendedElement) currentElement).setXML(doc); // nodeType = reader.nextTag(); // continue; /** * Reads a SIF_ExtendedElement element, handling arbitrary xml children and other special cases * * @param reader * @param dtd * @param zone * @param flags * @param defaultVersion * @return * @throws XMLStreamException */ protected SIFElement readSIFExtendedElement(XMLStreamReader reader, DTD dtd, Zone zone, SIFElement parent, SIFVersion version, SIFFormatter formatter) throws ADKParsingException, SIFException, XMLStreamException { SIF_ExtendedElement see = (SIF_ExtendedElement)readSIFElementFromElementNode(CommonDTD.SIF_EXTENDEDELEMENT, reader, version, dtd, parent, formatter, zone); XMLNodeReader nestedReader = new XMLNodeReader(reader); org.w3c.dom.Document doc = XMLStreamDocumentBuilder.build(nestedReader, false, true, null); see.setXML((org.w3c.dom.Element)doc.getFirstChild()); return see; } }