Move DOM methods in XidynUtils. Rewrite findHeadNode method.

This commit is contained in:
Christian P. MOMON 2013-08-01 01:30:05 +02:00
parent 9c887e6cc4
commit 8c4d84cce2
7 changed files with 237 additions and 193 deletions

View file

@ -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_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_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_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_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true

View file

@ -8,13 +8,14 @@ import org.w3c.dom.Document;
import fr.devinsy.xidyn.data.TagDataListById; import fr.devinsy.xidyn.data.TagDataListById;
import fr.devinsy.xidyn.data.TagDataManager; import fr.devinsy.xidyn.data.TagDataManager;
import fr.devinsy.xidyn.utils.XidynUtils;
/** /**
* *
*/ */
public class DomPresenter implements Presenter 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 Document doc;
private boolean isOutdated; private boolean isOutdated;
private StringBuffer defaultHtmlTarget; private StringBuffer defaultHtmlTarget;
@ -144,7 +145,7 @@ public class DomPresenter implements Presenter
public void setSource(final Document doc) public void setSource(final Document doc)
{ {
this.doc = doc; this.doc = doc;
DomPresenterCore.addMetaTag(this.doc, "generator", "XIDYN"); XidynUtils.addMetaTag(this.doc, "generator", "XIDYN");
this.isOutdated = true; this.isOutdated = true;
} }

View file

@ -1,20 +1,11 @@
package fr.devinsy.xidyn.presenters; 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.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr; import org.w3c.dom.Attr;
@ -23,7 +14,6 @@ import org.w3c.dom.DocumentType;
import org.w3c.dom.NamedNodeMap; import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import fr.devinsy.xidyn.data.SimpleTagData; import fr.devinsy.xidyn.data.SimpleTagData;
import fr.devinsy.xidyn.data.TagAttributes; import fr.devinsy.xidyn.data.TagAttributes;
@ -41,105 +31,6 @@ public class DomPresenterCore
static final public char INDEX_SEPARATOR = '_'; static final public char INDEX_SEPARATOR = '_';
static private Logger logger = LoggerFactory.getLogger(DomPresenterCore.class); 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. * Dynamize a doc with data.
*/ */
@ -184,82 +75,6 @@ public class DomPresenterCore
dynamize(result, doc, data.getIdsDataById()); dynamize(result, doc, data.getIdsDataById());
} }
/**
* Define in Presenter cause <object> 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 &lt;head&gt; 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;
}
/** /**
* *
*/ */

View file

@ -96,10 +96,10 @@ public class FilePresenter implements Presenter
else if ((this.doc == null) || (this.sourceFileTime != source.lastModified())) else if ((this.doc == null) || (this.sourceFileTime != source.lastModified()))
{ {
this.sourceFileTime = source.lastModified(); this.sourceFileTime = source.lastModified();
this.doc = DomPresenterCore.fileToDom(this.sourceFilePathname); this.doc = XidynUtils.fileToDom(this.sourceFilePathname);
if (this.doc != null) if (this.doc != null)
{ {
DomPresenterCore.addMetaTag(doc, "generator", "XID 0.0"); XidynUtils.addMetaTag(doc, "generator", "XID 0.0");
} }
this.doctype = getDoctype(this.sourceFilePathname); this.doctype = getDoctype(this.sourceFilePathname);
} }

View file

@ -86,7 +86,8 @@ public class StringPresenter implements Presenter
// StringBufferInputStream is deprecated so we use another solution. // StringBufferInputStream is deprecated so we use another solution.
// (see // (see
// http://www.developpez.net/forums/archive/index.php/t-14101.html). // 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");
} }
// //

View file

@ -92,10 +92,10 @@ public class URLPresenter implements Presenter
if ((this.doc == null) || (this.sourceFileTime != lastModified)) if ((this.doc == null) || (this.sourceFileTime != lastModified))
{ {
this.sourceFileTime = lastModified; this.sourceFileTime = lastModified;
this.doc = DomPresenterCore.buildDom(this.sourceURL.openStream()); this.doc = XidynUtils.buildDom(this.sourceURL.openStream());
if (this.doc != null) if (this.doc != null)
{ {
DomPresenterCore.addMetaTag(doc, "generator", "XID 0.0"); XidynUtils.addMetaTag(this.doc, "generator", "XIDYN");
} }
this.doctype = "<!DOCTYPE HTML>"; // TODO Made generic. this.doctype = "<!DOCTYPE HTML>"; // TODO Made generic.
} }

View file

@ -1,15 +1,131 @@
package fr.devinsy.xidyn.utils; 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.Matcher;
import java.util.regex.Pattern; 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 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*</[bB][oO][dD][yY]>.*$"); private static final Pattern BODY_PATTERN = Pattern.compile("^.*<[bB][oO][dD][yY]>\\s*(.*\\S)\\s*</[bB][oO][dD][yY]>.*$");
/**
* 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. * Good estimation of the target length able to optimize performance.
*/ */
@ -71,6 +187,117 @@ public class XidynUtils
return (result); return (result);
} }
/**
* Define in Presenter cause <object> 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 &lt;head&gt; 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 &lt;head&gt; 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 * Any ampersand lt;, ampersand gt; and ampersand amp; sequences in text
* nodes get read in as symbols. This method converts them back to entities. * nodes get read in as symbols. This method converts them back to entities.