| | |
| | | import java.io.OutputStream; |
| | | import java.net.URL; |
| | | import java.text.ParseException; |
| | | import java.util.concurrent.atomic.AtomicBoolean; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | import java.util.ArrayList; |
| | | import java.util.Enumeration; |
| | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.StringTokenizer; |
| | | import java.util.logging.Level; |
| | | import java.util.logging.Logger; |
| | | |
| | | import javax.servlet.http.HttpServlet; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.servlet.ServletConfig; |
| | | import javax.servlet.ServletException; |
| | | import javax.xml.XMLConstants; |
| | | import javax.xml.bind.JAXBContext; |
| | | import javax.xml.bind.JAXBElement; |
| | | import javax.xml.bind.JAXBException; |
| | |
| | | import javax.xml.bind.Unmarshaller; |
| | | import javax.xml.parsers.DocumentBuilder; |
| | | import javax.xml.parsers.DocumentBuilderFactory; |
| | | import javax.xml.parsers.ParserConfigurationException; |
| | | import javax.xml.parsers.SAXParserFactory; |
| | | import javax.xml.soap.*; |
| | | import javax.xml.soap.SOAPConstants; |
| | | import javax.xml.validation.Schema; |
| | |
| | | import org.w3c.dom.Document; |
| | | import org.xml.sax.Attributes; |
| | | import org.xml.sax.helpers.DefaultHandler; |
| | | import org.xml.sax.helpers.XMLReaderFactory; |
| | | import org.xml.sax.InputSource; |
| | | import org.xml.sax.SAXException; |
| | | import org.xml.sax.SAXNotRecognizedException; |
| | | import org.xml.sax.SAXNotSupportedException; |
| | | import org.xml.sax.XMLReader; |
| | | |
| | | |
| | |
| | | * using SOAP or JAXB. |
| | | */ |
| | | private DSMLContentHandler contentHandler; |
| | | /** Prevent multiple logging when trying to set unavailable/unsupported parser features */ |
| | | private static AtomicBoolean logFeatureWarnings = new AtomicBoolean(false); |
| | | |
| | | private String hostName; |
| | | private Integer port; |
| | |
| | | messageFactorySOAP_1_2 = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL); |
| | | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); |
| | | dbf.setNamespaceAware(true); |
| | | dbf.setXIncludeAware(false); |
| | | dbf.setExpandEntityReferences(false); |
| | | db = dbf.newDocumentBuilder(); |
| | | |
| | | this.contentHandler = new DSMLContentHandler(); |
| | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Safely set a feature on an XMLReader instance. |
| | | * |
| | | * @param xmlReader The reader to configure. |
| | | * @param feature The feature string to set. |
| | | * @param flag The value to set the feature to. |
| | | */ |
| | | private void safeSetFeature(XMLReader xmlReader, String feature, Boolean flag) |
| | | { |
| | | try |
| | | { |
| | | xmlReader.setFeature(feature, flag); |
| | | } |
| | | catch (SAXNotSupportedException e) |
| | | { |
| | | if (logFeatureWarnings.compareAndSet(false, true)) |
| | | { |
| | | Logger.getLogger(PKG_NAME).log(Level.SEVERE, "XMLReader unsupported feature " + feature); |
| | | } |
| | | } |
| | | catch (SAXNotRecognizedException e) |
| | | { |
| | | if (logFeatureWarnings.compareAndSet(false, true)) |
| | | { |
| | | Logger.getLogger(PKG_NAME).log(Level.SEVERE, "XMLReader unrecognized feature " + feature); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns an error response after a parsing error. The response has the |
| | | * requestID of the batch request, the error response message of the parsing |
| | | * exception message and the type 'malformed request'. |
| | | * |
| | | * @param is the xml InputStream to parse |
| | | * @param is the XML InputStream to parse |
| | | * @param batchResponse the JAXB object to fill in |
| | | * @param parserErrorMessage the parsing error message |
| | | * |
| | |
| | | String parserErrorMessage) { |
| | | ErrorResponse errorResponse = objFactory.createErrorResponse(); |
| | | |
| | | try { |
| | | try |
| | | { |
| | | // try alternative XML parsing using SAX to retrieve requestID value |
| | | XMLReader xmlReader = XMLReaderFactory.createXMLReader(); |
| | | SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); |
| | | // Ensure we are doing basic secure processing. |
| | | saxParserFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); |
| | | saxParserFactory.setXIncludeAware(false); |
| | | saxParserFactory.setNamespaceAware(true); |
| | | |
| | | // Configure a safe XMLReader appropriate for SOAP. |
| | | XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader(); |
| | | safeSetFeature(xmlReader, "http://xml.org/sax/features/validation", false); |
| | | safeSetFeature(xmlReader, "http://xml.org/sax/features/external-general-entities", false); |
| | | safeSetFeature(xmlReader, "http://xml.org/sax/features/external-parameter-entities", false); |
| | | safeSetFeature(xmlReader, "http://xml.org/sax/features/namespaces", true); |
| | | safeSetFeature(xmlReader, "http://apache.org/xml/features/disallow-doctype-decl", true); |
| | | |
| | | // clear previous match |
| | | this.contentHandler.requestID = null; |
| | | xmlReader.setContentHandler(this.contentHandler); |
| | | is.reset(); |
| | | |
| | | xmlReader.parse(new InputSource(is)); |
| | | } catch (Throwable e) { |
| | | // document cannot be parsed, so will jump here |
| | | } |
| | | catch (ParserConfigurationException e) |
| | | { |
| | | // ignore |
| | | } |
| | | catch (SAXException e) |
| | | { |
| | | // ignore |
| | | } |
| | | catch (IOException e) |
| | | { |
| | | // ignore |
| | | } |
| | | if ( parserErrorMessage!= null ) { |
| | | errorResponse.setMessage(parserErrorMessage); |
| | |
| | | } |
| | | |
| | | /** |
| | | * This class is used when a xml request is malformed to retrieve the |
| | | * requestID value using an event xml parser. |
| | | * This class is used when an XML request is malformed to retrieve the |
| | | * requestID value using an event XML parser. |
| | | */ |
| | | private static class DSMLContentHandler extends DefaultHandler { |
| | | private String requestID; |