From 8c4d84cce2bd7b46816a5fbb8f27915de6bd1a21 Mon Sep 17 00:00:00 2001 From: "Christian P. MOMON" Date: Thu, 1 Aug 2013 01:30:05 +0200 Subject: [PATCH] Move DOM methods in XidynUtils. Rewrite findHeadNode method. --- .settings/org.eclipse.jdt.core.prefs | 2 +- .../xidyn/presenters/DomPresenter.java | 5 +- .../xidyn/presenters/DomPresenterCore.java | 185 -------------- .../xidyn/presenters/FilePresenter.java | 4 +- .../xidyn/presenters/StringPresenter.java | 3 +- .../xidyn/presenters/URLPresenter.java | 4 +- src/fr/devinsy/xidyn/utils/XidynUtils.java | 227 ++++++++++++++++++ 7 files changed, 237 insertions(+), 193 deletions(-) diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index fbb080d..85a4f62 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -83,7 +83,7 @@ org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_de org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=false org.eclipse.jdt.core.formatter.indent_empty_lines=false org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true diff --git a/src/fr/devinsy/xidyn/presenters/DomPresenter.java b/src/fr/devinsy/xidyn/presenters/DomPresenter.java index d521204..f535961 100644 --- a/src/fr/devinsy/xidyn/presenters/DomPresenter.java +++ b/src/fr/devinsy/xidyn/presenters/DomPresenter.java @@ -8,13 +8,14 @@ import org.w3c.dom.Document; import fr.devinsy.xidyn.data.TagDataListById; import fr.devinsy.xidyn.data.TagDataManager; +import fr.devinsy.xidyn.utils.XidynUtils; /** * */ public class DomPresenter implements Presenter { - static private Logger logger = LoggerFactory.getLogger(DomPresenter.class); + static private final Logger logger = LoggerFactory.getLogger(DomPresenter.class); private Document doc; private boolean isOutdated; private StringBuffer defaultHtmlTarget; @@ -144,7 +145,7 @@ public class DomPresenter implements Presenter public void setSource(final Document doc) { this.doc = doc; - DomPresenterCore.addMetaTag(this.doc, "generator", "XIDYN"); + XidynUtils.addMetaTag(this.doc, "generator", "XIDYN"); this.isOutdated = true; } diff --git a/src/fr/devinsy/xidyn/presenters/DomPresenterCore.java b/src/fr/devinsy/xidyn/presenters/DomPresenterCore.java index 49b74fd..bdc7616 100644 --- a/src/fr/devinsy/xidyn/presenters/DomPresenterCore.java +++ b/src/fr/devinsy/xidyn/presenters/DomPresenterCore.java @@ -1,20 +1,11 @@ package fr.devinsy.xidyn.presenters; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; import java.io.StringWriter; import java.io.Writer; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.validation.Schema; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Attr; @@ -23,7 +14,6 @@ import org.w3c.dom.DocumentType; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; import fr.devinsy.xidyn.data.SimpleTagData; import fr.devinsy.xidyn.data.TagAttributes; @@ -41,105 +31,6 @@ public class DomPresenterCore static final public char INDEX_SEPARATOR = '_'; static private Logger logger = LoggerFactory.getLogger(DomPresenterCore.class); - /** - * This method adds a tag to a DOM object. - */ - static public void addMetaTag(final Document doc, final String name, final String content) - { - // Find head tag. - - Node headNode = findHeadNode(doc); - - Node metaNode = doc.createElement("meta"); - - NamedNodeMap attrMap = metaNode.getAttributes(); - Node attrNode = doc.createAttribute("name"); - attrMap.setNamedItem(attrNode); - attrNode.setNodeValue(name); - - attrNode = doc.createAttribute("content"); - attrMap.setNamedItem(attrNode); - attrNode.setNodeValue(content); - headNode.insertBefore(metaNode, headNode.getFirstChild()); - } - - /** - * This method build a DOM object from a source. - */ - static public Document buildDom(final InputStream source) throws Exception - { - Document result; - - try - { - // Create a DocumentBuilderFactory and configure it. - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - - // Set various configuration options. - dbf.setValidating(true); - dbf.setIgnoringComments(true); - dbf.setIgnoringElementContentWhitespace(false); - dbf.setCoalescing(false); - - // Keep entity references as they are. - dbf.setExpandEntityReferences(false); - - // Create a DocumentBuilder that satisfies the constraints - // specified by the DocumentBuilderFactory. - DocumentBuilder db = dbf.newDocumentBuilder(); - - ParserErrorHandler errorHandler; - errorHandler = new ParserErrorHandler(); - - // Set the error handler. - db.setErrorHandler(errorHandler); - - Schema schema = db.getSchema(); - - logger.debug("schema=" + schema); - - // Parse the input file. - result = db.parse(source); - - if (errorHandler.hasError()) - { - // Most time, error is (with StringPresenter): - // "Error at line 1 : Document root element "html", must match DOCTYPE root "null". - // Error at line 1 : Document is invalid: no grammar found. - // We ignore it. STU - logger.debug(errorHandler.toString()); - } - else - { - DomPresenterCore.addMetaTag(result, "generator", "XIDYN"); - } - } - catch (ParserConfigurationException exception) - { - String errorMessage = "Parser configuration exception: " + exception.getMessage(); - logger.error(errorMessage); - result = null; - throw new Exception(errorMessage, exception); - } - catch (SAXException exception) - { - String errorMessage = "Error during SAX parsing: " + exception.getMessage(); - logger.error(errorMessage); - result = null; - throw new Exception(errorMessage, exception); - } - catch (IOException exception) - { - String errorMessage = "IOError during parsing." + exception.getMessage(); - logger.error(errorMessage); - result = null; - throw new Exception(errorMessage, exception); - } - - // - return (result); - } - /** * Dynamize a doc with data. */ @@ -184,82 +75,6 @@ public class DomPresenterCore dynamize(result, doc, data.getIdsDataById()); } - /** - * Define in Presenter cause needs this possibility. - */ - static public Document fileToDom(final String fileName) throws Exception - { - Document result; - - try - { - result = buildDom(new FileInputStream(new File(fileName))); - } - catch (IOException exception) - { - String errorMessage = "IOError during parsing." + exception.getMessage(); - logger.error(errorMessage); - result = null; - throw new Exception(errorMessage, exception); - } - - // - return (result); - } - - /** - * Finds the node containing the <head> tag. - * - * @param node - * Document node. - * @return The head tag node - */ - private static Node findHeadNode(final Node node) - { - Node headNode = null; - - int type = node.getNodeType(); - switch (type) - { - // print document - case Node.DOCUMENT_NODE: - { - headNode = findHeadNode(((Document) node).getDocumentElement()); - break; - } - - case Node.ELEMENT_NODE: - { - String tag = node.getNodeName(); - - if ("head".equals(tag)) - { - headNode = node; - break; - } - - NodeList children = node.getChildNodes(); - int numChildren = 0; - - if (children != null) - { - numChildren = children.getLength(); - } - - for (int i = 0; i < numChildren; i++) - { - headNode = findHeadNode(children.item(i)); - if (headNode != null) - { - break; - } - } - break; - } - } - return headNode; - } - /** * */ diff --git a/src/fr/devinsy/xidyn/presenters/FilePresenter.java b/src/fr/devinsy/xidyn/presenters/FilePresenter.java index 9af0307..35be10f 100644 --- a/src/fr/devinsy/xidyn/presenters/FilePresenter.java +++ b/src/fr/devinsy/xidyn/presenters/FilePresenter.java @@ -96,10 +96,10 @@ public class FilePresenter implements Presenter else if ((this.doc == null) || (this.sourceFileTime != source.lastModified())) { this.sourceFileTime = source.lastModified(); - this.doc = DomPresenterCore.fileToDom(this.sourceFilePathname); + this.doc = XidynUtils.fileToDom(this.sourceFilePathname); if (this.doc != null) { - DomPresenterCore.addMetaTag(doc, "generator", "XID 0.0"); + XidynUtils.addMetaTag(doc, "generator", "XID 0.0"); } this.doctype = getDoctype(this.sourceFilePathname); } diff --git a/src/fr/devinsy/xidyn/presenters/StringPresenter.java b/src/fr/devinsy/xidyn/presenters/StringPresenter.java index bb4b66c..c8a552a 100644 --- a/src/fr/devinsy/xidyn/presenters/StringPresenter.java +++ b/src/fr/devinsy/xidyn/presenters/StringPresenter.java @@ -86,7 +86,8 @@ public class StringPresenter implements Presenter // StringBufferInputStream is deprecated so we use another solution. // (see // http://www.developpez.net/forums/archive/index.php/t-14101.html). - this.doc = DomPresenterCore.buildDom(new ByteArrayInputStream(sourceHtml.getBytes())); + this.doc = XidynUtils.buildDom(new ByteArrayInputStream(sourceHtml.getBytes())); + XidynUtils.addMetaTag(this.doc, "generator", "XIDYN"); } // diff --git a/src/fr/devinsy/xidyn/presenters/URLPresenter.java b/src/fr/devinsy/xidyn/presenters/URLPresenter.java index 7943c4c..38cdd94 100644 --- a/src/fr/devinsy/xidyn/presenters/URLPresenter.java +++ b/src/fr/devinsy/xidyn/presenters/URLPresenter.java @@ -92,10 +92,10 @@ public class URLPresenter implements Presenter if ((this.doc == null) || (this.sourceFileTime != lastModified)) { this.sourceFileTime = lastModified; - this.doc = DomPresenterCore.buildDom(this.sourceURL.openStream()); + this.doc = XidynUtils.buildDom(this.sourceURL.openStream()); if (this.doc != null) { - DomPresenterCore.addMetaTag(doc, "generator", "XID 0.0"); + XidynUtils.addMetaTag(this.doc, "generator", "XIDYN"); } this.doctype = ""; // TODO Made generic. } diff --git a/src/fr/devinsy/xidyn/utils/XidynUtils.java b/src/fr/devinsy/xidyn/utils/XidynUtils.java index 0c83e2b..9c5bc85 100644 --- a/src/fr/devinsy/xidyn/utils/XidynUtils.java +++ b/src/fr/devinsy/xidyn/utils/XidynUtils.java @@ -1,15 +1,131 @@ package fr.devinsy.xidyn.utils; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.validation.Schema; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import fr.devinsy.xidyn.presenters.DomPresenterCore; +import fr.devinsy.xidyn.presenters.ParserErrorHandler; + /** * */ public class XidynUtils { + static private final Logger logger = LoggerFactory.getLogger(DomPresenterCore.class); private static final Pattern BODY_PATTERN = Pattern.compile("^.*<[bB][oO][dD][yY]>\\s*(.*\\S)\\s*.*$"); + /** + * This method adds a tag to a DOM object. + */ + static public void addMetaTag(final Document doc, final String name, final String content) + { + // Find head tag. + + Node headNode = findHeadNode(doc); + + Node metaNode = doc.createElement("meta"); + + NamedNodeMap attrMap = metaNode.getAttributes(); + Node attrNode = doc.createAttribute("name"); + attrMap.setNamedItem(attrNode); + attrNode.setNodeValue(name); + + attrNode = doc.createAttribute("content"); + attrMap.setNamedItem(attrNode); + attrNode.setNodeValue(content); + headNode.insertBefore(metaNode, headNode.getFirstChild()); + } + + /** + * This method builds a DOM object from a source. + */ + static public Document buildDom(final InputStream source) throws Exception + { + Document result; + + try + { + // Create a DocumentBuilderFactory and configure it. + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + // Set various configuration options. + dbf.setValidating(true); + dbf.setIgnoringComments(true); + dbf.setIgnoringElementContentWhitespace(false); + dbf.setCoalescing(false); + + // Keep entity references as they are. + dbf.setExpandEntityReferences(false); + + // Create a DocumentBuilder that satisfies the constraints + // specified by the DocumentBuilderFactory. + DocumentBuilder db = dbf.newDocumentBuilder(); + + ParserErrorHandler errorHandler; + errorHandler = new ParserErrorHandler(); + + // Set the error handler. + db.setErrorHandler(errorHandler); + + Schema schema = db.getSchema(); + + logger.debug("schema=" + schema); + + // Parse the input file. + result = db.parse(source); + + if (errorHandler.hasError()) + { + // Most time, error is (with StringPresenter): + // "Error at line 1 : Document root element "html", must match DOCTYPE root "null". + // Error at line 1 : Document is invalid: no grammar found. + // We ignore it. STU + logger.debug(errorHandler.toString()); + } + } + catch (ParserConfigurationException exception) + { + String errorMessage = "Parser configuration exception: " + exception.getMessage(); + logger.error(errorMessage); + result = null; + throw new Exception(errorMessage, exception); + } + catch (SAXException exception) + { + String errorMessage = "Error during SAX parsing: " + exception.getMessage(); + logger.error(errorMessage); + result = null; + throw new Exception(errorMessage, exception); + } + catch (IOException exception) + { + String errorMessage = "IOError during parsing." + exception.getMessage(); + logger.error(errorMessage); + result = null; + throw new Exception(errorMessage, exception); + } + + // + return (result); + } + /** * Good estimation of the target length able to optimize performance. */ @@ -71,6 +187,117 @@ public class XidynUtils return (result); } + /** + * Define in Presenter cause needs this possibility. + */ + static public Document fileToDom(final String fileName) throws Exception + { + Document result; + + try + { + result = buildDom(new FileInputStream(new File(fileName))); + } + catch (IOException exception) + { + String errorMessage = "IOError during parsing." + exception.getMessage(); + logger.error(errorMessage); + result = null; + throw new Exception(errorMessage, exception); + } + + // + return (result); + } + + /** + * Finds the node containing the <head> tag. + * + * @param node + * Document node. + * @return The head tag node + */ + public static Node findHeadNode(final Node node) + { + Node result; + + result = findNodeByName(node, "head"); + + // + return result; + } + + /** + * Finds the node containing the <head> tag. + * + * @param node + * Document node. + * @return The head tag node + */ + public static Node findNodeByName(final Node node, final String name) + { + Node result; + + switch (node.getNodeType()) + { + case Node.DOCUMENT_NODE: + { + result = findNodeByName(((Document) node).getDocumentElement(), name); + } + break; + + case Node.ELEMENT_NODE: + { + String tag = node.getNodeName(); + + if ((tag != null) && tag.equals(name)) + { + result = node; + } + else + { + NodeList children = node.getChildNodes(); + int childrenCount; + if (children == null) + { + childrenCount = 0; + } + else + { + childrenCount = children.getLength(); + } + + boolean ended = false; + int childrenIndex = 0; + result = null; + while (!ended) + { + if (childrenIndex < childrenCount) + { + result = findNodeByName(children.item(childrenIndex), name); + if (result != null) + { + ended = true; + } + } + else + { + ended = true; + result = null; + } + } + } + } + break; + + default: + result = null; + } + + // + return result; + } + /** * Any ampersand lt;, ampersand gt; and ampersand amp; sequences in text * nodes get read in as symbols. This method converts them back to entities.