diff --git a/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java b/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java index 8ae4384389e6bac0d63482a1470a8b0c135f4c46..a6d9f1f72195de50940341398df56b19c958602a 100644 --- a/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java +++ b/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java @@ -41,6 +41,12 @@ import lcsb.mapviewer.common.exception.InvalidXmlSchemaException; * */ public class XmlParser { + + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(XmlParser.class); + /** * Base of the hex representation. */ @@ -51,28 +57,34 @@ public class XmlParser { * that will manipulate xml nodes. */ private static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); - - /** - * Default class logger. - */ - private Logger logger = Logger.getLogger(XmlParser.class.getName()); + private static DocumentBuilderFactory nonValidateDocumentBuilderFactory; + static { + nonValidateDocumentBuilderFactory = DocumentBuilderFactory.newInstance(); + nonValidateDocumentBuilderFactory.setNamespaceAware(false); + nonValidateDocumentBuilderFactory.setValidating(false); + try { + nonValidateDocumentBuilderFactory.setFeature("http://xml.org/sax/features/namespaces", false); + nonValidateDocumentBuilderFactory.setFeature("http://xml.org/sax/features/validation", false); + nonValidateDocumentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", + false); + nonValidateDocumentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", + false); + } catch (ParserConfigurationException e) { + logger.error(e, e); + } + } /** * DOM document builder used for xml transformations. */ - private DocumentBuilder db; + private DocumentBuilder validatedDocumentBuilder; + + private DocumentBuilder nonValidatedDocumentBuilder; /** - * Default constructor that prevents from instatiation of the class and - * initializes fields. + * Default constructor that prevents from instantiation of the class. */ protected XmlParser() { - try { - db = documentBuilderFactory.newDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new InvalidStateException("Problem with xml parser"); - } - } /** @@ -188,8 +200,10 @@ public class XmlParser { * @throws InvalidXmlSchemaException * thrown when there is a problem with xml */ - protected Document getXmlDocumentFromInputSource(final InputSource stream) throws InvalidXmlSchemaException { + protected Document getXmlDocumentFromInputSource(final InputSource stream, boolean validate) + throws InvalidXmlSchemaException { try { + DocumentBuilder db = getDocumentBuilder(validate); synchronized (db) { // DocumentBuilder cannot parse few objects at the // same time return db.parse(stream); @@ -201,26 +215,69 @@ public class XmlParser { } } + /** + * Return proper document builder. + * + * @param validate + * - should the document builder validate input xml or not + * @return + */ + private DocumentBuilder getDocumentBuilder(boolean validate) { + try { + if (validate) { + if (validatedDocumentBuilder == null) { + validatedDocumentBuilder = documentBuilderFactory.newDocumentBuilder(); + } + return validatedDocumentBuilder; + } else { + if (nonValidatedDocumentBuilder == null) { + nonValidatedDocumentBuilder = nonValidateDocumentBuilderFactory.newDocumentBuilder(); + } + return nonValidatedDocumentBuilder; + + } + } catch (ParserConfigurationException e) { + throw new InvalidStateException("Problem with xml parser"); + } + } + /** * Method returns the xml Document from text given as a source. * * @param text * string representing xml document + * @param validate + * should the parser validate the input (if validation is off it's much + * faster in some cases, especially when dtd files don't have to be + * downloaded from web) * @return Document for the xml document given in the input * @throws InvalidXmlSchemaException * thrown when there is a problem with xml */ - protected Document getXmlDocumentFromString(final String text) throws InvalidXmlSchemaException { + protected Document getXmlDocumentFromString(final String text, boolean validate) throws InvalidXmlSchemaException { InputSource is = new InputSource(); is.setCharacterStream(new StringReader(text)); try { - return getXmlDocumentFromInputSource(is); + return getXmlDocumentFromInputSource(is, validate); } catch (NullPointerException e) { logger.error("Problem with input xml: " + text); throw new InvalidXmlSchemaException(e); } } + /** + * Method returns the xml Document from text given as a source. + * + * @param text + * string representing xml document + * @return Document for the xml document given in the input + * @throws InvalidXmlSchemaException + * thrown when there is a problem with xml + */ + protected Document getXmlDocumentFromString(final String text) throws InvalidXmlSchemaException { + return getXmlDocumentFromString(text, true); + } + /** * Transforms node into string xml format. * diff --git a/commons/src/test/java/lcsb/mapviewer/common/XmlParserTest.java b/commons/src/test/java/lcsb/mapviewer/common/XmlParserTest.java index a2bd25fb3984cca2128a256b43a47a20f5dca638..3a60aef79c75d4c0fd34ee50444f07e2afe60236 100644 --- a/commons/src/test/java/lcsb/mapviewer/common/XmlParserTest.java +++ b/commons/src/test/java/lcsb/mapviewer/common/XmlParserTest.java @@ -203,7 +203,7 @@ public class XmlParserTest { @Test public void testGetXmlDocumentFromInvalidInputStream() throws Exception { try { - parser.getXmlDocumentFromInputSource(new InputSource()); + parser.getXmlDocumentFromInputSource(new InputSource(), true); fail("Exception expected"); } catch (InvalidXmlSchemaException e) { } catch (Exception e) {