Move DOM methods in XidynUtils. Rewrite findHeadNode method.
This commit is contained in:
parent
9c887e6cc4
commit
8c4d84cce2
7 changed files with 237 additions and 193 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <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 <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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -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 = "<!DOCTYPE HTML>"; // TODO Made generic.
|
||||
}
|
||||
|
|
|
@ -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*</[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.
|
||||
*/
|
||||
|
@ -71,6 +187,117 @@ public class XidynUtils
|
|||
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 <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.
|
||||
|
|
Loading…
Reference in a new issue