Improve classes organization.
This commit is contained in:
parent
bc26b40750
commit
27e8c74721
7 changed files with 1139 additions and 1069 deletions
|
@ -1,41 +1,18 @@
|
|||
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;
|
||||
import org.w3c.dom.Document;
|
||||
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;
|
||||
import fr.devinsy.xidyn.data.TagData;
|
||||
import fr.devinsy.xidyn.data.TagDataListById;
|
||||
import fr.devinsy.xidyn.data.TagDataListByIndex;
|
||||
import fr.devinsy.xidyn.data.TagDataManager;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DomPresenter extends Presenter
|
||||
public class DomPresenter extends DomPresenterCore implements Presenter
|
||||
{
|
||||
static final public char INDEX_SEPARATOR = '_';
|
||||
static private Logger logger = LoggerFactory.getLogger(DomPresenter.class);
|
||||
|
@ -57,6 +34,13 @@ public class DomPresenter extends Presenter
|
|||
setSource(doc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuffer dynamize() throws Exception
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -76,7 +60,7 @@ public class DomPresenter extends Presenter
|
|||
{
|
||||
// Build the web page.
|
||||
StringWriter htmlCode = new StringWriter();
|
||||
DomPresenter.dynamize(htmlCode, this.doc, datas);
|
||||
DomPresenterCore.dynamize(htmlCode, this.doc, datas);
|
||||
result = new StringBuffer(htmlCode.toString());
|
||||
}
|
||||
|
||||
|
@ -124,7 +108,7 @@ public class DomPresenter extends Presenter
|
|||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean isOutdated()
|
||||
public boolean isOutdated() throws Exception
|
||||
{
|
||||
boolean result;
|
||||
|
||||
|
@ -148,918 +132,6 @@ public class DomPresenter extends Presenter
|
|||
public void setSource(final Document doc)
|
||||
{
|
||||
this.doc = doc;
|
||||
DomPresenter.addMetaTag(this.doc, "generator", "XIDYN 1.0.0");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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
|
||||
{
|
||||
DomPresenter.addMetaTag(result, "generator", "XID 0.0");
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Xidyn a file with data.
|
||||
*/
|
||||
static public StringBuffer dynamize(final Document doc, final TagDataListById datas) throws Exception
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
StringWriter htmlCode = new StringWriter();
|
||||
DomPresenter.dynamize(htmlCode, doc, datas);
|
||||
result = htmlCode.getBuffer();
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamize a file with data.
|
||||
*/
|
||||
static public void dynamize(final Writer result, final Document doc, final TagDataListById data) throws Exception
|
||||
{
|
||||
process(result, doc, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static String getClassAttributeValue(final Node node)
|
||||
{
|
||||
String result;
|
||||
|
||||
NamedNodeMap attributes = node.getAttributes();
|
||||
if (attributes == null)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Node nameAttribute = attributes.getNamedItem("class");
|
||||
|
||||
if (nameAttribute == null)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = nameAttribute.getNodeValue();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text for an element. Converts new lines to spaces.
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
static private String getElementText(final Node node)
|
||||
{
|
||||
String result;
|
||||
|
||||
NodeList children = node.getChildNodes();
|
||||
if ((children == null) || (children.getLength() == 0))
|
||||
{
|
||||
result = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean ended = false;
|
||||
result = ""; // Grrrr, Java ...
|
||||
int childCounter = 0;
|
||||
int childCount = children.getLength();
|
||||
while (!ended)
|
||||
{
|
||||
if (childCounter >= childCount)
|
||||
{
|
||||
ended = true;
|
||||
result = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
Node child = children.item(childCounter);
|
||||
if (child.getNodeType() == Node.TEXT_NODE)
|
||||
{
|
||||
// STU (+=, newLines...)
|
||||
result = newLinesToSpaces(child.getNodeValue());
|
||||
ended = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
childCounter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private TagAttributes mergeAttributes(final TagAttributes target, final TagAttributes source)
|
||||
{
|
||||
TagAttributes result;
|
||||
|
||||
//
|
||||
if (target == null)
|
||||
{
|
||||
result = source;
|
||||
}
|
||||
else if (source == null)
|
||||
{
|
||||
result = target;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new TagAttributes(target);
|
||||
|
||||
Iterator<Map.Entry<String, String>> iterator = source.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Map.Entry<String, String> attribute = iterator.next();
|
||||
|
||||
String currentValue = target.get(attribute.getKey());
|
||||
|
||||
if (currentValue == null)
|
||||
{
|
||||
result.put(attribute.getKey(), attribute.getValue());
|
||||
}
|
||||
else if (attribute.getKey().equals("style"))
|
||||
{
|
||||
result.put(attribute.getKey(), currentValue + attribute.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
result.put(attribute.getKey(), attribute.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts New Line characters to spaces. This is used when for example the
|
||||
* text in a div tag goes over several lines.
|
||||
*
|
||||
* @param text
|
||||
* String
|
||||
* @return String
|
||||
*/
|
||||
static private String newLinesToSpaces(final String text)
|
||||
{
|
||||
StringBuffer result = new StringBuffer(text);
|
||||
|
||||
for (int i = 0; i < result.length(); i++)
|
||||
{
|
||||
if (result.charAt(i) == '\n')
|
||||
{
|
||||
result.setCharAt(i, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void process(final Writer result, final Node node, final TagDataListById datas) throws Exception
|
||||
{
|
||||
DomPresenter.process(result, node, datas, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive method that processes a node and any child nodes.
|
||||
*
|
||||
*/
|
||||
static private void process(final Writer result, final Node node, final TagDataListById datas, final String suffix) throws Exception
|
||||
{
|
||||
logger.debug("process - started");
|
||||
String TRANSITIONAL_DTD = "xhtml1-transitional.dtd";
|
||||
String TRANSITIONAL_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " + "Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
|
||||
|
||||
// Is there anything to do?
|
||||
if (node != null)
|
||||
{
|
||||
logger.debug("nodeName=[{}]", node.getNodeName());
|
||||
// Find the name attribute value.
|
||||
String name;
|
||||
name = getClassAttributeValue(node);
|
||||
|
||||
if ((name == null) || ((name != null) && (!name.equals("xid:nodisplay"))))
|
||||
{
|
||||
int type = node.getNodeType();
|
||||
switch (type)
|
||||
{
|
||||
case Node.DOCUMENT_NODE:
|
||||
{
|
||||
logger.debug("case Node.DOCUMENT_NODE");
|
||||
DocumentType dt = ((Document) node).getDoctype();
|
||||
|
||||
if (dt != null)
|
||||
{
|
||||
// String publicId = dt.getPublicId();
|
||||
String systemId = dt.getSystemId();
|
||||
|
||||
if ((systemId != null) && (systemId.equals(TRANSITIONAL_DTD)))
|
||||
{
|
||||
result.append(TRANSITIONAL_DOCTYPE);
|
||||
}
|
||||
|
||||
// Log.write(Log.TRACE,"publicId = " + publicId);
|
||||
// Log.write(Log.TRACE,"systemId = " + systemId);
|
||||
}
|
||||
|
||||
DomPresenter.process(result, ((Document) node).getDocumentElement(), datas, suffix);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Node.ELEMENT_NODE:
|
||||
{
|
||||
logger.debug("case Node.ELEMENT_NODE [{}]", node.getNodeName());
|
||||
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
Node idAttr = attrs.getNamedItem("id");
|
||||
|
||||
if (idAttr != null)
|
||||
{
|
||||
DomPresenter.processElementWithId(result, node, attrs, idAttr, datas, suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
DomPresenter.processElementBasically(result, node, datas, suffix);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// handle entity reference nodes
|
||||
case Node.ENTITY_REFERENCE_NODE:
|
||||
{
|
||||
logger.debug("case Node.ENTITY_REFERENCE_NODE");
|
||||
|
||||
result.append('&');
|
||||
result.append(node.getNodeName());
|
||||
result.append(';');
|
||||
break;
|
||||
}
|
||||
|
||||
// print cdata sections
|
||||
case Node.CDATA_SECTION_NODE:
|
||||
{
|
||||
logger.debug("case Node.CDATA_SECTION_NODE");
|
||||
|
||||
result.append("<![CDATA[");
|
||||
result.append(node.getNodeValue());
|
||||
result.append("]]>");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// print text
|
||||
case Node.TEXT_NODE:
|
||||
{
|
||||
logger.debug("case Node.TEXTE_NODE");
|
||||
result.append(Presenter.restoreEntities(new StringBuffer(node.getNodeValue())));
|
||||
break;
|
||||
}
|
||||
|
||||
// print processing instruction
|
||||
case Node.PROCESSING_INSTRUCTION_NODE:
|
||||
{
|
||||
logger.debug("Node.PROCESSING_INSTRUCTION_NODE");
|
||||
|
||||
result.append("<?");
|
||||
result.append(node.getNodeName());
|
||||
String value = node.getNodeValue();
|
||||
if ((value != null) && (value.length() > 0))
|
||||
{
|
||||
result.append(' ');
|
||||
result.append(value);
|
||||
}
|
||||
result.append("?>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// logger.info ("result=" + result);
|
||||
logger.debug("process - ended");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private StringBuffer processAttributes(final NamedNodeMap attrs)
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
result = processAttributes(attrs, null, null, "");
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private StringBuffer processAttributes(final NamedNodeMap attrs, final TagAttributes dataAttributes)
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
result = processAttributes(attrs, dataAttributes, "");
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private StringBuffer processAttributes(final NamedNodeMap attrs, final TagAttributes dataAttributes, final String suffix)
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
result = new StringBuffer();
|
||||
|
||||
// Build the original attributes list.
|
||||
HashMap<String, String> mergedAttributes;
|
||||
mergedAttributes = new HashMap<String, String>();
|
||||
for (int attributeCounter = 0; attributeCounter < attrs.getLength(); attributeCounter++)
|
||||
{
|
||||
Attr attr = (Attr) attrs.item(attributeCounter);
|
||||
mergedAttributes.put(attr.getNodeName(), attr.getNodeValue());
|
||||
}
|
||||
|
||||
// Put model attributes in the merged attributes list.
|
||||
if (dataAttributes != null)
|
||||
{
|
||||
Iterator<Map.Entry<String, String>> iterator = dataAttributes.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Map.Entry<String, String> attribute = iterator.next();
|
||||
|
||||
if (mergedAttributes.containsKey(attribute.getKey()))
|
||||
{
|
||||
if (attribute.getKey().equalsIgnoreCase("style"))
|
||||
{
|
||||
mergedAttributes.put(attribute.getKey(), mergedAttributes.get(attribute.getKey()) + attribute.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
mergedAttributes.put(attribute.getKey(), attribute.getValue());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mergedAttributes.put(attribute.getKey(), attribute.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display the attributes
|
||||
Iterator<Map.Entry<String, String>> iterator = mergedAttributes.entrySet().iterator();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Map.Entry<String, String> attribute = iterator.next();
|
||||
|
||||
if ((attribute.getKey().equals("id")) && (suffix.length() != 0))
|
||||
{
|
||||
result.append(" " + attribute.getKey() + "=\"" + attribute.getValue() + INDEX_SEPARATOR + suffix + "\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append(" " + attribute.getKey() + "=\"" + attribute.getValue() + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private StringBuffer processAttributes(final NamedNodeMap attrs, final TagAttributes dataAttributes, final TagAttributes namedDataAttributes, final String suffix)
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
result = processAttributes(attrs, mergeAttributes(dataAttributes, namedDataAttributes), suffix);
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private void processChildren(final Writer result, final Node node, final TagDataListById datas) throws Exception
|
||||
{
|
||||
processChildren(result, node, datas, "");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void processChildren(final Writer result, final Node node, final TagDataListById datas, final String suffix) throws Exception
|
||||
{
|
||||
// Get the iteration strategy.
|
||||
SimpleTagData.IterationStrategy strategy;
|
||||
|
||||
NamedNodeMap attributes = node.getAttributes();
|
||||
if (attributes == null)
|
||||
{
|
||||
strategy = SimpleTagData.IterationStrategy.ALL_ROWS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Node id = attributes.getNamedItem("id");
|
||||
|
||||
if (id == null)
|
||||
{
|
||||
strategy = SimpleTagData.IterationStrategy.ALL_ROWS;
|
||||
}
|
||||
else
|
||||
{
|
||||
TagData dataCore = datas.getId(id.getNodeValue());
|
||||
if (dataCore == null)
|
||||
{
|
||||
strategy = SimpleTagData.IterationStrategy.ALL_ROWS;
|
||||
}
|
||||
else if (dataCore instanceof SimpleTagData)
|
||||
{
|
||||
SimpleTagData data = (SimpleTagData) dataCore;
|
||||
strategy = data.iterationStrategy();
|
||||
}
|
||||
else
|
||||
{
|
||||
strategy = SimpleTagData.IterationStrategy.ALL_ROWS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate.
|
||||
NodeList children = node.getChildNodes();
|
||||
int childrenCount = children.getLength();
|
||||
|
||||
switch (strategy)
|
||||
{
|
||||
case ONLY_FIRST_ROW:
|
||||
int lineCounter = 0;
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
if (children.item(childIndex).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
lineCounter += 1;
|
||||
if (lineCounter == 1)
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ONLY_FIRST_TWO_ROWS:
|
||||
lineCounter = 0;
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
if (children.item(childIndex).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
lineCounter += 1;
|
||||
|
||||
if ((lineCounter == 1) || (lineCounter == 2))
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ONLY_ROWS_WITH_ID:
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
if (children.item(childIndex).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
NamedNodeMap attrs2 = children.item(childIndex).getAttributes();
|
||||
|
||||
if ((attrs2 != null) && (attrs2.getNamedItem("id") != null))
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ONLY_ROWS_WITHOUT_ID:
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
if (children.item(childIndex).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
NamedNodeMap attrs2 = children.item(childIndex).getAttributes();
|
||||
if ((attrs2 == null) || (attrs2.getNamedItem("id") == null))
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ALL_ROWS:
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO remove?
|
||||
*/
|
||||
private static void processElementBasically(final Writer result, final Node node, final TagDataListById datas) throws Exception
|
||||
{
|
||||
processElementBasically(result, node, datas, "");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void processElementBasically(final Writer result, final Node node, final TagDataListById datas, final String suffix) throws Exception
|
||||
{
|
||||
logger.debug("processElementBasically - started [{}]", node.getNodeName());
|
||||
|
||||
// Open the tag.
|
||||
result.append('<');
|
||||
result.append(node.getNodeName());
|
||||
|
||||
// Build the tag attributes.
|
||||
// Attributes tagAttributes;
|
||||
|
||||
result.append(processAttributes(node.getAttributes(), null, suffix));
|
||||
|
||||
//
|
||||
if ((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0))
|
||||
{
|
||||
result.append(" />");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append('>');
|
||||
|
||||
processChildren(result, node, datas, suffix);
|
||||
|
||||
result.append("</");
|
||||
result.append(node.getNodeName());
|
||||
result.append('>');
|
||||
}
|
||||
|
||||
logger.debug("processElementBasically - ended");
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a node that has dynamic content. Calls the appropriate code
|
||||
* generator method, depending on the tag.
|
||||
*
|
||||
* @param node
|
||||
* Current node.
|
||||
* @param attrs
|
||||
* The tag attributes.
|
||||
* @param idAttr
|
||||
* The ID.
|
||||
*/
|
||||
static private void processElementWithId(final Writer result, final Node node, final NamedNodeMap attrs, final Node idAttr, final TagDataListById datas) throws Exception
|
||||
|
||||
{
|
||||
processElementWithId(result, node, attrs, idAttr, datas, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a node that has dynamic content. Calls the appropriate code
|
||||
* generator method, depending on the tag.
|
||||
*
|
||||
* @param node
|
||||
* Current node.
|
||||
* @param attrs
|
||||
* The tag attributes.
|
||||
* @param idAttr
|
||||
* The ID.
|
||||
*/
|
||||
static private void processElementWithId(final Writer result, final Node node, final NamedNodeMap attrs, final Node idAttr, final TagDataListById datas, final String suffix) throws Exception
|
||||
{
|
||||
String tag = node.getNodeName();
|
||||
|
||||
// String idValue = idAttr.getNodeValue();
|
||||
|
||||
logger.debug("tag=" + tag);
|
||||
|
||||
// Get data of this id.
|
||||
TagData dataCore = datas.get(idAttr.getNodeValue());
|
||||
|
||||
if (dataCore == null)
|
||||
{
|
||||
DomPresenter.processElementBasically(result, node, datas, suffix);
|
||||
}
|
||||
else if (dataCore instanceof SimpleTagData)
|
||||
{
|
||||
SimpleTagData data = (SimpleTagData) dataCore;
|
||||
|
||||
String theClass = data.attributes().getAttribute("class");
|
||||
|
||||
if ((theClass == null) || (!theClass.equals("xid:nodisplay")))
|
||||
{
|
||||
// Open the tag.
|
||||
result.append("<");
|
||||
result.append(node.getNodeName());
|
||||
|
||||
// Build attributes.
|
||||
result.append(processAttributes(attrs, data.attributes(), suffix));
|
||||
|
||||
if (((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0)) && ((data == null) || (data.display() == null)))
|
||||
{
|
||||
// Close the tag.
|
||||
result.append(" />");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append('>');
|
||||
|
||||
// CHANGED, cpm:
|
||||
|
||||
// Insert data.
|
||||
if ((data == null) || (data.display() == null))
|
||||
{
|
||||
processChildren(result, node, datas, suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append(data.display());
|
||||
}
|
||||
|
||||
// Close the tag.
|
||||
result.append("</");
|
||||
result.append(node.getNodeName());
|
||||
result.append('>');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dataCore instanceof TagDataListByIndex)
|
||||
{
|
||||
TagDataListByIndex tags = (TagDataListByIndex) dataCore;
|
||||
|
||||
int nbLines = tags.size();
|
||||
for (int nLine = 0; nLine < nbLines; nLine++)
|
||||
{
|
||||
if (tags.elementAt(nLine) instanceof SimpleTagData)
|
||||
{
|
||||
SimpleTagData data = (SimpleTagData) tags.elementAt(nLine);
|
||||
|
||||
// Open the tag.
|
||||
result.append("<");
|
||||
result.append(node.getNodeName());
|
||||
|
||||
result.append(processAttributes(attrs, data.attributes(), Integer.toString(nLine)));
|
||||
|
||||
if (((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0)) && ((data == null) || (data.display() == null)))
|
||||
{
|
||||
// Close the tag.
|
||||
result.append(" />\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append('>');
|
||||
|
||||
// CHANGED, cpm
|
||||
|
||||
// Insert data.
|
||||
if ((data == null) || (data.display() == null))
|
||||
{
|
||||
processChildren(result, node, datas, suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append(data.display());
|
||||
}
|
||||
|
||||
// Close the tag.
|
||||
result.append("</");
|
||||
result.append(node.getNodeName());
|
||||
result.append(">\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Manage a Hashmap.
|
||||
TagDataListById data = (TagDataListById) tags.elementAt(nLine);
|
||||
|
||||
DomPresenter.processElementWithId(result, node, attrs, idAttr, data, Integer.toString(nLine));
|
||||
result.append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Unknow type of IdDataId");
|
||||
}
|
||||
|
||||
//
|
||||
logger.debug("Exit");
|
||||
DomPresenterCore.addMetaTag(this.doc, "generator", "XIDYN 1.0.0");
|
||||
}
|
||||
}
|
||||
|
|
954
src/fr/devinsy/xidyn/presenters/DomPresenterCore.java
Normal file
954
src/fr/devinsy/xidyn/presenters/DomPresenterCore.java
Normal file
|
@ -0,0 +1,954 @@
|
|||
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;
|
||||
import org.w3c.dom.Document;
|
||||
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;
|
||||
import fr.devinsy.xidyn.data.TagData;
|
||||
import fr.devinsy.xidyn.data.TagDataListById;
|
||||
import fr.devinsy.xidyn.data.TagDataListByIndex;
|
||||
import fr.devinsy.xidyn.data.TagDataManager;
|
||||
import fr.devinsy.xidyn.utils.XidynUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DomPresenterCore
|
||||
{
|
||||
static final public char INDEX_SEPARATOR = '_';
|
||||
static private Logger logger = LoggerFactory.getLogger(DomPresenterCore.class);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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", "XID 0.0");
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Xidyn a file with data.
|
||||
*/
|
||||
static public StringBuffer dynamize(final Document doc, final TagDataListById datas) throws Exception
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
StringWriter htmlCode = new StringWriter();
|
||||
DomPresenterCore.dynamize(htmlCode, doc, datas);
|
||||
result = htmlCode.getBuffer();
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamize a file with data.
|
||||
*/
|
||||
static public void dynamize(final Writer result, final Document doc, final TagDataListById data) throws Exception
|
||||
{
|
||||
process(result, doc, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static String getClassAttributeValue(final Node node)
|
||||
{
|
||||
String result;
|
||||
|
||||
NamedNodeMap attributes = node.getAttributes();
|
||||
if (attributes == null)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Node nameAttribute = attributes.getNamedItem("class");
|
||||
|
||||
if (nameAttribute == null)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = nameAttribute.getNodeValue();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text for an element. Converts new lines to spaces.
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
static private String getElementText(final Node node)
|
||||
{
|
||||
String result;
|
||||
|
||||
NodeList children = node.getChildNodes();
|
||||
if ((children == null) || (children.getLength() == 0))
|
||||
{
|
||||
result = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean ended = false;
|
||||
result = ""; // Grrrr, Java ...
|
||||
int childCounter = 0;
|
||||
int childCount = children.getLength();
|
||||
while (!ended)
|
||||
{
|
||||
if (childCounter >= childCount)
|
||||
{
|
||||
ended = true;
|
||||
result = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
Node child = children.item(childCounter);
|
||||
if (child.getNodeType() == Node.TEXT_NODE)
|
||||
{
|
||||
// STU (+=, newLines...)
|
||||
result = newLinesToSpaces(child.getNodeValue());
|
||||
ended = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
childCounter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private TagAttributes mergeAttributes(final TagAttributes target, final TagAttributes source)
|
||||
{
|
||||
TagAttributes result;
|
||||
|
||||
//
|
||||
if (target == null)
|
||||
{
|
||||
result = source;
|
||||
}
|
||||
else if (source == null)
|
||||
{
|
||||
result = target;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new TagAttributes(target);
|
||||
|
||||
Iterator<Map.Entry<String, String>> iterator = source.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Map.Entry<String, String> attribute = iterator.next();
|
||||
|
||||
String currentValue = target.get(attribute.getKey());
|
||||
|
||||
if (currentValue == null)
|
||||
{
|
||||
result.put(attribute.getKey(), attribute.getValue());
|
||||
}
|
||||
else if (attribute.getKey().equals("style"))
|
||||
{
|
||||
result.put(attribute.getKey(), currentValue + attribute.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
result.put(attribute.getKey(), attribute.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts New Line characters to spaces. This is used when for example the
|
||||
* text in a div tag goes over several lines.
|
||||
*
|
||||
* @param text
|
||||
* String
|
||||
* @return String
|
||||
*/
|
||||
static private String newLinesToSpaces(final String text)
|
||||
{
|
||||
StringBuffer result = new StringBuffer(text);
|
||||
|
||||
for (int i = 0; i < result.length(); i++)
|
||||
{
|
||||
if (result.charAt(i) == '\n')
|
||||
{
|
||||
result.setCharAt(i, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void process(final Writer result, final Node node, final TagDataListById datas) throws Exception
|
||||
{
|
||||
DomPresenterCore.process(result, node, datas, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive method that processes a node and any child nodes.
|
||||
*
|
||||
*/
|
||||
static private void process(final Writer result, final Node node, final TagDataListById datas, final String suffix) throws Exception
|
||||
{
|
||||
logger.debug("process - started");
|
||||
String TRANSITIONAL_DTD = "xhtml1-transitional.dtd";
|
||||
String TRANSITIONAL_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " + "Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
|
||||
|
||||
// Is there anything to do?
|
||||
if (node != null)
|
||||
{
|
||||
logger.debug("nodeName=[{}]", node.getNodeName());
|
||||
// Find the name attribute value.
|
||||
String name;
|
||||
name = getClassAttributeValue(node);
|
||||
|
||||
if ((name == null) || ((name != null) && (!name.equals("xid:nodisplay"))))
|
||||
{
|
||||
int type = node.getNodeType();
|
||||
switch (type)
|
||||
{
|
||||
case Node.DOCUMENT_NODE:
|
||||
{
|
||||
logger.debug("case Node.DOCUMENT_NODE");
|
||||
DocumentType dt = ((Document) node).getDoctype();
|
||||
|
||||
if (dt != null)
|
||||
{
|
||||
// String publicId = dt.getPublicId();
|
||||
String systemId = dt.getSystemId();
|
||||
|
||||
if ((systemId != null) && (systemId.equals(TRANSITIONAL_DTD)))
|
||||
{
|
||||
result.append(TRANSITIONAL_DOCTYPE);
|
||||
}
|
||||
|
||||
// Log.write(Log.TRACE,"publicId = " + publicId);
|
||||
// Log.write(Log.TRACE,"systemId = " + systemId);
|
||||
}
|
||||
|
||||
DomPresenterCore.process(result, ((Document) node).getDocumentElement(), datas, suffix);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Node.ELEMENT_NODE:
|
||||
{
|
||||
logger.debug("case Node.ELEMENT_NODE [{}]", node.getNodeName());
|
||||
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
Node idAttr = attrs.getNamedItem("id");
|
||||
|
||||
if (idAttr != null)
|
||||
{
|
||||
DomPresenterCore.processElementWithId(result, node, attrs, idAttr, datas, suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
DomPresenterCore.processElementBasically(result, node, datas, suffix);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// handle entity reference nodes
|
||||
case Node.ENTITY_REFERENCE_NODE:
|
||||
{
|
||||
logger.debug("case Node.ENTITY_REFERENCE_NODE");
|
||||
|
||||
result.append('&');
|
||||
result.append(node.getNodeName());
|
||||
result.append(';');
|
||||
break;
|
||||
}
|
||||
|
||||
// print cdata sections
|
||||
case Node.CDATA_SECTION_NODE:
|
||||
{
|
||||
logger.debug("case Node.CDATA_SECTION_NODE");
|
||||
|
||||
result.append("<![CDATA[");
|
||||
result.append(node.getNodeValue());
|
||||
result.append("]]>");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// print text
|
||||
case Node.TEXT_NODE:
|
||||
{
|
||||
logger.debug("case Node.TEXTE_NODE");
|
||||
result.append(XidynUtils.restoreEntities(new StringBuffer(node.getNodeValue())));
|
||||
break;
|
||||
}
|
||||
|
||||
// print processing instruction
|
||||
case Node.PROCESSING_INSTRUCTION_NODE:
|
||||
{
|
||||
logger.debug("Node.PROCESSING_INSTRUCTION_NODE");
|
||||
|
||||
result.append("<?");
|
||||
result.append(node.getNodeName());
|
||||
String value = node.getNodeValue();
|
||||
if ((value != null) && (value.length() > 0))
|
||||
{
|
||||
result.append(' ');
|
||||
result.append(value);
|
||||
}
|
||||
result.append("?>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// logger.info ("result=" + result);
|
||||
logger.debug("process - ended");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private StringBuffer processAttributes(final NamedNodeMap attrs)
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
result = processAttributes(attrs, null, null, "");
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private StringBuffer processAttributes(final NamedNodeMap attrs, final TagAttributes dataAttributes)
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
result = processAttributes(attrs, dataAttributes, "");
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private StringBuffer processAttributes(final NamedNodeMap attrs, final TagAttributes dataAttributes, final String suffix)
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
result = new StringBuffer();
|
||||
|
||||
// Build the original attributes list.
|
||||
HashMap<String, String> mergedAttributes;
|
||||
mergedAttributes = new HashMap<String, String>();
|
||||
for (int attributeCounter = 0; attributeCounter < attrs.getLength(); attributeCounter++)
|
||||
{
|
||||
Attr attr = (Attr) attrs.item(attributeCounter);
|
||||
mergedAttributes.put(attr.getNodeName(), attr.getNodeValue());
|
||||
}
|
||||
|
||||
// Put model attributes in the merged attributes list.
|
||||
if (dataAttributes != null)
|
||||
{
|
||||
Iterator<Map.Entry<String, String>> iterator = dataAttributes.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Map.Entry<String, String> attribute = iterator.next();
|
||||
|
||||
if (mergedAttributes.containsKey(attribute.getKey()))
|
||||
{
|
||||
if (attribute.getKey().equalsIgnoreCase("style"))
|
||||
{
|
||||
mergedAttributes.put(attribute.getKey(), mergedAttributes.get(attribute.getKey()) + attribute.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
mergedAttributes.put(attribute.getKey(), attribute.getValue());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mergedAttributes.put(attribute.getKey(), attribute.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display the attributes
|
||||
Iterator<Map.Entry<String, String>> iterator = mergedAttributes.entrySet().iterator();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Map.Entry<String, String> attribute = iterator.next();
|
||||
|
||||
if ((attribute.getKey().equals("id")) && (suffix.length() != 0))
|
||||
{
|
||||
result.append(" " + attribute.getKey() + "=\"" + attribute.getValue() + INDEX_SEPARATOR + suffix + "\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append(" " + attribute.getKey() + "=\"" + attribute.getValue() + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private StringBuffer processAttributes(final NamedNodeMap attrs, final TagAttributes dataAttributes, final TagAttributes namedDataAttributes, final String suffix)
|
||||
{
|
||||
StringBuffer result;
|
||||
|
||||
result = processAttributes(attrs, mergeAttributes(dataAttributes, namedDataAttributes), suffix);
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private void processChildren(final Writer result, final Node node, final TagDataListById datas) throws Exception
|
||||
{
|
||||
processChildren(result, node, datas, "");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void processChildren(final Writer result, final Node node, final TagDataListById datas, final String suffix) throws Exception
|
||||
{
|
||||
// Get the iteration strategy.
|
||||
SimpleTagData.IterationStrategy strategy;
|
||||
|
||||
NamedNodeMap attributes = node.getAttributes();
|
||||
if (attributes == null)
|
||||
{
|
||||
strategy = SimpleTagData.IterationStrategy.ALL_ROWS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Node id = attributes.getNamedItem("id");
|
||||
|
||||
if (id == null)
|
||||
{
|
||||
strategy = SimpleTagData.IterationStrategy.ALL_ROWS;
|
||||
}
|
||||
else
|
||||
{
|
||||
TagData dataCore = datas.getId(id.getNodeValue());
|
||||
if (dataCore == null)
|
||||
{
|
||||
strategy = SimpleTagData.IterationStrategy.ALL_ROWS;
|
||||
}
|
||||
else if (dataCore instanceof SimpleTagData)
|
||||
{
|
||||
SimpleTagData data = (SimpleTagData) dataCore;
|
||||
strategy = data.iterationStrategy();
|
||||
}
|
||||
else
|
||||
{
|
||||
strategy = SimpleTagData.IterationStrategy.ALL_ROWS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate.
|
||||
NodeList children = node.getChildNodes();
|
||||
int childrenCount = children.getLength();
|
||||
|
||||
switch (strategy)
|
||||
{
|
||||
case ONLY_FIRST_ROW:
|
||||
int lineCounter = 0;
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
if (children.item(childIndex).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
lineCounter += 1;
|
||||
if (lineCounter == 1)
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ONLY_FIRST_TWO_ROWS:
|
||||
lineCounter = 0;
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
if (children.item(childIndex).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
lineCounter += 1;
|
||||
|
||||
if ((lineCounter == 1) || (lineCounter == 2))
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ONLY_ROWS_WITH_ID:
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
if (children.item(childIndex).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
NamedNodeMap attrs2 = children.item(childIndex).getAttributes();
|
||||
|
||||
if ((attrs2 != null) && (attrs2.getNamedItem("id") != null))
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ONLY_ROWS_WITHOUT_ID:
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
if (children.item(childIndex).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
NamedNodeMap attrs2 = children.item(childIndex).getAttributes();
|
||||
if ((attrs2 == null) || (attrs2.getNamedItem("id") == null))
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ALL_ROWS:
|
||||
for (int childIndex = 0; childIndex < childrenCount; childIndex++)
|
||||
{
|
||||
process(result, children.item(childIndex), datas, suffix);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO remove?
|
||||
*/
|
||||
private static void processElementBasically(final Writer result, final Node node, final TagDataListById datas) throws Exception
|
||||
{
|
||||
processElementBasically(result, node, datas, "");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void processElementBasically(final Writer result, final Node node, final TagDataListById datas, final String suffix) throws Exception
|
||||
{
|
||||
logger.debug("processElementBasically - started [{}]", node.getNodeName());
|
||||
|
||||
// Open the tag.
|
||||
result.append('<');
|
||||
result.append(node.getNodeName());
|
||||
|
||||
// Build the tag attributes.
|
||||
// Attributes tagAttributes;
|
||||
|
||||
result.append(processAttributes(node.getAttributes(), null, suffix));
|
||||
|
||||
//
|
||||
if ((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0))
|
||||
{
|
||||
result.append(" />");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append('>');
|
||||
|
||||
processChildren(result, node, datas, suffix);
|
||||
|
||||
result.append("</");
|
||||
result.append(node.getNodeName());
|
||||
result.append('>');
|
||||
}
|
||||
|
||||
logger.debug("processElementBasically - ended");
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a node that has dynamic content. Calls the appropriate code
|
||||
* generator method, depending on the tag.
|
||||
*
|
||||
* @param node
|
||||
* Current node.
|
||||
* @param attrs
|
||||
* The tag attributes.
|
||||
* @param idAttr
|
||||
* The ID.
|
||||
*/
|
||||
static private void processElementWithId(final Writer result, final Node node, final NamedNodeMap attrs, final Node idAttr, final TagDataListById datas) throws Exception
|
||||
|
||||
{
|
||||
processElementWithId(result, node, attrs, idAttr, datas, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a node that has dynamic content. Calls the appropriate code
|
||||
* generator method, depending on the tag.
|
||||
*
|
||||
* @param node
|
||||
* Current node.
|
||||
* @param attrs
|
||||
* The tag attributes.
|
||||
* @param idAttr
|
||||
* The ID.
|
||||
*/
|
||||
static private void processElementWithId(final Writer result, final Node node, final NamedNodeMap attrs, final Node idAttr, final TagDataListById datas, final String suffix) throws Exception
|
||||
{
|
||||
String tag = node.getNodeName();
|
||||
|
||||
// String idValue = idAttr.getNodeValue();
|
||||
|
||||
logger.debug("tag=" + tag);
|
||||
|
||||
// Get data of this id.
|
||||
TagData dataCore = datas.get(idAttr.getNodeValue());
|
||||
|
||||
if (dataCore == null)
|
||||
{
|
||||
DomPresenterCore.processElementBasically(result, node, datas, suffix);
|
||||
}
|
||||
else if (dataCore instanceof SimpleTagData)
|
||||
{
|
||||
SimpleTagData data = (SimpleTagData) dataCore;
|
||||
|
||||
String theClass = data.attributes().getAttribute("class");
|
||||
|
||||
if ((theClass == null) || (!theClass.equals("xid:nodisplay")))
|
||||
{
|
||||
// Open the tag.
|
||||
result.append("<");
|
||||
result.append(node.getNodeName());
|
||||
|
||||
// Build attributes.
|
||||
result.append(processAttributes(attrs, data.attributes(), suffix));
|
||||
|
||||
if (((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0)) && ((data == null) || (data.display() == null)))
|
||||
{
|
||||
// Close the tag.
|
||||
result.append(" />");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append('>');
|
||||
|
||||
// CHANGED, cpm:
|
||||
|
||||
// Insert data.
|
||||
if ((data == null) || (data.display() == null))
|
||||
{
|
||||
processChildren(result, node, datas, suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append(data.display());
|
||||
}
|
||||
|
||||
// Close the tag.
|
||||
result.append("</");
|
||||
result.append(node.getNodeName());
|
||||
result.append('>');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dataCore instanceof TagDataListByIndex)
|
||||
{
|
||||
TagDataListByIndex tags = (TagDataListByIndex) dataCore;
|
||||
|
||||
int nbLines = tags.size();
|
||||
for (int nLine = 0; nLine < nbLines; nLine++)
|
||||
{
|
||||
if (tags.elementAt(nLine) instanceof SimpleTagData)
|
||||
{
|
||||
SimpleTagData data = (SimpleTagData) tags.elementAt(nLine);
|
||||
|
||||
// Open the tag.
|
||||
result.append("<");
|
||||
result.append(node.getNodeName());
|
||||
|
||||
result.append(processAttributes(attrs, data.attributes(), Integer.toString(nLine)));
|
||||
|
||||
if (((node.getChildNodes() == null) || (node.getChildNodes().getLength() == 0)) && ((data == null) || (data.display() == null)))
|
||||
{
|
||||
// Close the tag.
|
||||
result.append(" />\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append('>');
|
||||
|
||||
// CHANGED, cpm
|
||||
|
||||
// Insert data.
|
||||
if ((data == null) || (data.display() == null))
|
||||
{
|
||||
processChildren(result, node, datas, suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append(data.display());
|
||||
}
|
||||
|
||||
// Close the tag.
|
||||
result.append("</");
|
||||
result.append(node.getNodeName());
|
||||
result.append(">\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Manage a Hashmap.
|
||||
TagDataListById data = (TagDataListById) tags.elementAt(nLine);
|
||||
|
||||
DomPresenterCore.processElementWithId(result, node, attrs, idAttr, data, Integer.toString(nLine));
|
||||
result.append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Unknow type of IdDataId");
|
||||
}
|
||||
|
||||
//
|
||||
logger.debug("Exit");
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import fr.devinsy.xidyn.data.TagDataListById;
|
||||
import fr.devinsy.xidyn.data.TagDataManager;
|
||||
import fr.devinsy.xidyn.utils.XidynUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -87,7 +88,7 @@ public class FilePresenter extends DomPresenter
|
|||
}
|
||||
|
||||
// Build the web page.
|
||||
StringWriter htmlCode = new StringWriter(Presenter.estimatedTargetLength(source.length()));
|
||||
StringWriter htmlCode = new StringWriter(XidynUtils.estimatedTargetLength(source.length()));
|
||||
htmlCode.write(doctype);
|
||||
htmlCode.write('\n');
|
||||
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
package fr.devinsy.xidyn.presenters;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import fr.devinsy.xidyn.data.TagDataListById;
|
||||
import fr.devinsy.xidyn.data.TagDataManager;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class Presenter<E>
|
||||
public interface Presenter
|
||||
{
|
||||
private static final Pattern BODY_PATTERN = Pattern.compile("^.*<[bB][oO][dD][yY]>\\s*(.*\\S)\\s*</[bB][oO][dD][yY]>.*$");
|
||||
|
||||
/**
|
||||
*
|
||||
* @param datas
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public abstract StringBuffer dynamize() throws Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -40,122 +44,4 @@ public abstract class Presenter<E>
|
|||
* @return
|
||||
*/
|
||||
public abstract boolean isOutdated() throws Exception;
|
||||
|
||||
/**
|
||||
* Good estimation of the target length able to optimize performance.
|
||||
*/
|
||||
public static int estimatedTargetLength(final long sourceLength)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (sourceLength < 1000)
|
||||
{
|
||||
result = (int) (sourceLength * 5);
|
||||
}
|
||||
else if (sourceLength < 50000)
|
||||
{
|
||||
result = (int) (sourceLength * 2);
|
||||
}
|
||||
else if (sourceLength < 800000)
|
||||
{
|
||||
result = (1000000);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (int) (sourceLength + 30000);
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static public String extractBodyContent(final CharSequence source)
|
||||
{
|
||||
String result;
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
result = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
Matcher matcher = BODY_PATTERN.matcher(source);
|
||||
if ((matcher.find()) && (matcher.groupCount() == 1))
|
||||
{
|
||||
// for (int i = 0; i <= matcher.groupCount(); i++)
|
||||
// {
|
||||
// System.out.println(i + " " + matcher.group(i));
|
||||
// }
|
||||
|
||||
result = matcher.group(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = "";
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
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.
|
||||
*
|
||||
* @param source
|
||||
* String that is to have the entities restored..
|
||||
* @return The processed string.
|
||||
*/
|
||||
static public String restoreEntities(final StringBuffer source)
|
||||
{
|
||||
String result;
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer(source.length() * 2);
|
||||
|
||||
int len = (source != null) ? source.length() : 0;
|
||||
for (int index = 0; index < len; index++)
|
||||
{
|
||||
char letter = source.charAt(index);
|
||||
switch (letter)
|
||||
{
|
||||
case '<':
|
||||
{
|
||||
buffer.append("<");
|
||||
break;
|
||||
}
|
||||
|
||||
case '>':
|
||||
{
|
||||
buffer.append(">");
|
||||
break;
|
||||
}
|
||||
|
||||
case '&':
|
||||
{
|
||||
buffer.append("&");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
buffer.append(letter);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = buffer.toString();
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import fr.devinsy.xidyn.data.TagDataListById;
|
||||
import fr.devinsy.xidyn.data.TagDataManager;
|
||||
import fr.devinsy.xidyn.utils.XidynUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -68,7 +69,7 @@ public class StringPresenter extends DomPresenter
|
|||
doc = DomPresenter.buildDom(new ByteArrayInputStream(htmlSource.getBytes()));
|
||||
}
|
||||
|
||||
StringWriter htmlCode = new StringWriter(Presenter.estimatedTargetLength(this.html.length()));
|
||||
StringWriter htmlCode = new StringWriter(XidynUtils.estimatedTargetLength(this.html.length()));
|
||||
if ((this.html.startsWith("<!DOCTYPE")) || (this.html.startsWith("<!doctype")))
|
||||
{
|
||||
htmlCode.write(this.html.substring(0, this.html.indexOf('>')));
|
||||
|
@ -86,7 +87,7 @@ public class StringPresenter extends DomPresenter
|
|||
}
|
||||
else
|
||||
{
|
||||
String bodyContent = extractBodyContent(htmlTarget);
|
||||
String bodyContent = XidynUtils.extractBodyContent(htmlTarget);
|
||||
|
||||
if (bodyContent == null)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@ package fr.devinsy.xidyn.presenters;
|
|||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
import java.net.MalformedURLException;
|
||||
|
@ -12,6 +13,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import fr.devinsy.xidyn.data.TagDataListById;
|
||||
import fr.devinsy.xidyn.data.TagDataManager;
|
||||
import fr.devinsy.xidyn.utils.XidynUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -34,7 +36,6 @@ public class URLPresenter extends DomPresenter
|
|||
}
|
||||
|
||||
/**
|
||||
* @throws MalformedURLException
|
||||
*
|
||||
*/
|
||||
public URLPresenter(final String source)
|
||||
|
@ -53,6 +54,7 @@ public class URLPresenter extends DomPresenter
|
|||
/**
|
||||
* No need to be synchronized.
|
||||
*/
|
||||
@Override
|
||||
public StringBuffer dynamize() throws Exception
|
||||
{
|
||||
StringBuffer result;
|
||||
|
@ -106,7 +108,7 @@ public class URLPresenter extends DomPresenter
|
|||
}
|
||||
|
||||
// Build the web page.
|
||||
StringWriter htmlCode = new StringWriter(Presenter.estimatedTargetLength(sourceURL.openConnection().getContentLength()));
|
||||
StringWriter htmlCode = new StringWriter(XidynUtils.estimatedTargetLength(sourceURL.openConnection().getContentLength()));
|
||||
htmlCode.write(doctype);
|
||||
htmlCode.write('\n');
|
||||
|
||||
|
@ -119,7 +121,7 @@ public class URLPresenter extends DomPresenter
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public StringBuffer dynamize(final TagDataManager datas) throws Exception
|
||||
|
@ -128,7 +130,7 @@ public class URLPresenter extends DomPresenter
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getSource()
|
||||
|
@ -141,6 +143,30 @@ public class URLPresenter extends DomPresenter
|
|||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public boolean isOutdated() throws IOException
|
||||
{
|
||||
boolean result;
|
||||
|
||||
long lastModified = this.sourceURL.openConnection().getLastModified();
|
||||
if (this.sourceFileTime == lastModified)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
130
src/fr/devinsy/xidyn/utils/XidynUtils.java
Normal file
130
src/fr/devinsy/xidyn/utils/XidynUtils.java
Normal file
|
@ -0,0 +1,130 @@
|
|||
package fr.devinsy.xidyn.utils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class XidynUtils
|
||||
{
|
||||
private static final Pattern BODY_PATTERN = Pattern.compile("^.*<[bB][oO][dD][yY]>\\s*(.*\\S)\\s*</[bB][oO][dD][yY]>.*$");
|
||||
|
||||
/**
|
||||
* Good estimation of the target length able to optimize performance.
|
||||
*/
|
||||
public static int estimatedTargetLength(final long sourceLength)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (sourceLength < 1000)
|
||||
{
|
||||
result = (int) (sourceLength * 5);
|
||||
}
|
||||
else if (sourceLength < 50000)
|
||||
{
|
||||
result = (int) (sourceLength * 2);
|
||||
}
|
||||
else if (sourceLength < 800000)
|
||||
{
|
||||
result = (1000000);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (int) (sourceLength + 30000);
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static public String extractBodyContent(final CharSequence source)
|
||||
{
|
||||
String result;
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
result = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
Matcher matcher = BODY_PATTERN.matcher(source);
|
||||
if ((matcher.find()) && (matcher.groupCount() == 1))
|
||||
{
|
||||
// for (int i = 0; i <= matcher.groupCount(); i++)
|
||||
// {
|
||||
// System.out.println(i + " " + matcher.group(i));
|
||||
// }
|
||||
|
||||
result = matcher.group(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = "";
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
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.
|
||||
*
|
||||
* @param source
|
||||
* String that is to have the entities restored..
|
||||
* @return The processed string.
|
||||
*/
|
||||
static public String restoreEntities(final StringBuffer source)
|
||||
{
|
||||
String result;
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer(source.length() * 2);
|
||||
|
||||
int len = (source != null) ? source.length() : 0;
|
||||
for (int index = 0; index < len; index++)
|
||||
{
|
||||
char letter = source.charAt(index);
|
||||
switch (letter)
|
||||
{
|
||||
case '<':
|
||||
{
|
||||
buffer.append("<");
|
||||
break;
|
||||
}
|
||||
|
||||
case '>':
|
||||
{
|
||||
buffer.append(">");
|
||||
break;
|
||||
}
|
||||
|
||||
case '&':
|
||||
{
|
||||
buffer.append("&");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
buffer.append(letter);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = buffer.toString();
|
||||
}
|
||||
|
||||
//
|
||||
return (result);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue