Improve design hugly.
This commit is contained in:
parent
e89ab6ea09
commit
5617603b29
5 changed files with 596 additions and 178 deletions
|
@ -1,14 +1,11 @@
|
||||||
package fr.devinsy.xidyn.presenters;
|
package fr.devinsy.xidyn.presenters;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.w3c.dom.Document;
|
|
||||||
|
|
||||||
import fr.devinsy.xidyn.data.TagDataManager;
|
import fr.devinsy.xidyn.data.TagDataManager;
|
||||||
import fr.devinsy.xidyn.utils.XidynUtils;
|
import fr.devinsy.xidyn.utils.XidynUtils;
|
||||||
|
@ -16,14 +13,13 @@ import fr.devinsy.xidyn.utils.XidynUtils;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class FilePresenter implements Presenter
|
public class FilePresenter extends StringPresenter
|
||||||
{
|
{
|
||||||
static Logger logger = LoggerFactory.getLogger(FilePresenter.class);
|
static Logger logger = LoggerFactory.getLogger(FilePresenter.class);
|
||||||
|
|
||||||
private Document doc;
|
private File source;
|
||||||
private String sourceFilePathname;
|
private String sourceFilePathname;
|
||||||
private long sourceFileTime;
|
private long sourceTime;
|
||||||
private String doctype;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -75,51 +71,46 @@ public class FilePresenter implements Presenter
|
||||||
|
|
||||||
logger.info("dynamize file [" + this.sourceFilePathname + "]");
|
logger.info("dynamize file [" + this.sourceFilePathname + "]");
|
||||||
|
|
||||||
// Get the good tree.
|
//
|
||||||
File source;
|
if (this.source == null)
|
||||||
if (this.sourceFilePathname.matches("file://.+"))
|
|
||||||
{
|
{
|
||||||
source = new File(new URI(this.sourceFilePathname));
|
String errorMessage = "source not defined";
|
||||||
|
logger.error(errorMessage);
|
||||||
|
result = null;
|
||||||
|
throw new Exception(errorMessage);
|
||||||
}
|
}
|
||||||
else
|
else if (!source.exists())
|
||||||
{
|
|
||||||
source = new File(this.sourceFilePathname);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!source.exists())
|
|
||||||
{
|
{
|
||||||
String errorMessage = "source file defined but not found (" + this.sourceFilePathname + ")";
|
String errorMessage = "source file defined but not found (" + this.sourceFilePathname + ")";
|
||||||
logger.error(errorMessage);
|
logger.error(errorMessage);
|
||||||
result = null;
|
result = null;
|
||||||
throw new Exception(errorMessage);
|
throw new Exception(errorMessage);
|
||||||
}
|
}
|
||||||
else if ((this.doc == null) || (this.sourceFileTime != source.lastModified()))
|
else
|
||||||
{
|
{
|
||||||
this.sourceFileTime = source.lastModified();
|
long currentTime = this.source.lastModified();
|
||||||
this.doc = XidynUtils.fileToDom(this.sourceFilePathname);
|
if ((super.getSource() == null) || (this.sourceTime != currentTime))
|
||||||
if (this.doc != null)
|
|
||||||
{
|
{
|
||||||
XidynUtils.addMetaTag(doc, "generator", "XID 0.0");
|
super.setSource(XidynUtils.load(this.source));
|
||||||
|
this.sourceTime = currentTime;
|
||||||
}
|
}
|
||||||
this.doctype = getDoctype(this.sourceFilePathname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the web page.
|
// Build the web page.
|
||||||
StringWriter htmlCode = new StringWriter(XidynUtils.estimatedTargetLength(source.length()));
|
result = super.dynamize(data);
|
||||||
htmlCode.write(doctype);
|
|
||||||
htmlCode.write('\n');
|
|
||||||
|
|
||||||
TagDataManager targetData;
|
//
|
||||||
if (data == null)
|
return (result);
|
||||||
{
|
|
||||||
targetData = new TagDataManager();
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public File getFile()
|
||||||
{
|
{
|
||||||
targetData = data;
|
File result;
|
||||||
}
|
|
||||||
DomPresenterCore.dynamize(htmlCode, doc, targetData);
|
result = this.source;
|
||||||
result = htmlCode.getBuffer();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
return (result);
|
return (result);
|
||||||
|
@ -143,12 +134,23 @@ public class FilePresenter implements Presenter
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isOutdated()
|
public boolean isOutdated() throws Exception
|
||||||
{
|
{
|
||||||
boolean result;
|
boolean result;
|
||||||
|
|
||||||
// TODO
|
//
|
||||||
|
if (super.isOutdated())
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else if (this.sourceTime == this.source.lastModified())
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
result = false;
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
@ -161,23 +163,54 @@ public class FilePresenter implements Presenter
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
|
super.setSource(null);
|
||||||
|
this.source = null;
|
||||||
|
this.sourceFilePathname = null;
|
||||||
|
this.sourceTime = 0;
|
||||||
setSource((String) null);
|
setSource((String) null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setSource(source.getAbsolutePath());
|
this.source = source;
|
||||||
|
this.sourceFilePathname = source.getAbsolutePath();
|
||||||
|
this.sourceTime = 0;
|
||||||
|
super.setSource(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @throws Exception
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void setSource(final String filePathname)
|
public void setSource(final String filePathname)
|
||||||
{
|
{
|
||||||
|
if (filePathname == null)
|
||||||
|
{
|
||||||
|
setSource((File) null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this.sourceFilePathname.matches("file://.+"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.source = new File(new URI(this.sourceFilePathname));
|
||||||
|
}
|
||||||
|
catch (URISyntaxException exception)
|
||||||
|
{
|
||||||
|
exception.printStackTrace();
|
||||||
|
throw new IllegalArgumentException("Bad URI argument.", exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.source = new File(this.sourceFilePathname);
|
||||||
|
}
|
||||||
this.sourceFilePathname = filePathname;
|
this.sourceFilePathname = filePathname;
|
||||||
this.sourceFileTime = 0;
|
this.sourceTime = 0;
|
||||||
this.doc = null;
|
super.setSource(null);
|
||||||
this.doctype = "";
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,35 +242,4 @@ public class FilePresenter implements Presenter
|
||||||
//
|
//
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePathname
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
static public String getDoctype(final String filePathname) throws Exception
|
|
||||||
{
|
|
||||||
String result;
|
|
||||||
|
|
||||||
//
|
|
||||||
BufferedReader in = new BufferedReader(new FileReader(filePathname));
|
|
||||||
String doctype = in.readLine();
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
logger.info("doctype=[" + doctype + "]");
|
|
||||||
|
|
||||||
//
|
|
||||||
if ((doctype.startsWith("<!DOCTYPE")) || (doctype.startsWith("<!doctype")))
|
|
||||||
{
|
|
||||||
result = doctype;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package fr.devinsy.xidyn.presenters;
|
package fr.devinsy.xidyn.presenters;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -18,7 +17,8 @@ public class StringPresenter implements Presenter
|
||||||
static private Logger logger = LoggerFactory.getLogger(StringPresenter.class);
|
static private Logger logger = LoggerFactory.getLogger(StringPresenter.class);
|
||||||
|
|
||||||
private String source;
|
private String source;
|
||||||
private Document doc;
|
private String doctype;
|
||||||
|
private Document dom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -54,44 +54,49 @@ public class StringPresenter implements Presenter
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public StringBuffer dynamize(final TagDataManager datas) throws Exception
|
public StringBuffer dynamize(final TagDataManager data) throws Exception
|
||||||
{
|
{
|
||||||
StringBuffer result;
|
StringBuffer result;
|
||||||
|
|
||||||
//
|
// Build the DOM.
|
||||||
if (this.doc == null)
|
if (this.dom == null)
|
||||||
{
|
{
|
||||||
// Build doc from this.html.
|
// Build the source HTML.
|
||||||
String sourceHtml;
|
String sourceHtml;
|
||||||
if (source == null)
|
if (this.source == null)
|
||||||
{
|
{
|
||||||
String errorMessage = "source not defined";
|
String errorMessage = "source not defined";
|
||||||
logger.error(errorMessage);
|
logger.error(errorMessage);
|
||||||
result = null;
|
result = null;
|
||||||
throw new Exception(errorMessage);
|
throw new Exception(errorMessage);
|
||||||
}
|
}
|
||||||
else if ((this.source.startsWith("<!DOCTYPE")) || (this.source.startsWith("<!doctype")) || (this.source.startsWith("<html>")) || (this.source.startsWith("<HTML>")))
|
|
||||||
{
|
|
||||||
sourceHtml = this.source;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
this.doctype = XidynUtils.extractDoctype(this.source);
|
||||||
|
|
||||||
|
if (this.doctype == null)
|
||||||
{
|
{
|
||||||
StringBuffer buffer = new StringBuffer(source.length() + 100);
|
StringBuffer buffer = new StringBuffer(source.length() + 100);
|
||||||
buffer.append("<html><head></head><body>\n");
|
buffer.append("<html><head></head><body>\n");
|
||||||
buffer.append(source);
|
buffer.append(this.source);
|
||||||
buffer.append("</body></html>");
|
buffer.append("</body></html>");
|
||||||
sourceHtml = buffer.toString();
|
sourceHtml = buffer.toString();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sourceHtml = this.source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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 = XidynUtils.buildDom(new ByteArrayInputStream(sourceHtml.getBytes()));
|
this.dom = XidynUtils.buildDom(sourceHtml);
|
||||||
XidynUtils.addMetaTag(this.doc, "generator", "XIDYN");
|
XidynUtils.addMetaTag(this.dom, "generator", "XIDYN");
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
if (datas == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
result = dynamize();
|
result = dynamize();
|
||||||
}
|
}
|
||||||
|
@ -99,11 +104,13 @@ public class StringPresenter implements Presenter
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
StringWriter htmlCode = new StringWriter(XidynUtils.estimatedTargetLength(this.source.length()));
|
StringWriter htmlCode = new StringWriter(XidynUtils.estimatedTargetLength(this.source.length()));
|
||||||
if ((this.source.startsWith("<!DOCTYPE")) || (this.source.startsWith("<!doctype")))
|
if ((this.doctype != null))
|
||||||
{
|
{
|
||||||
htmlCode.write(this.source.substring(0, this.source.indexOf('>')));
|
htmlCode.write(this.doctype);
|
||||||
|
htmlCode.write('\n');
|
||||||
}
|
}
|
||||||
DomPresenterCore.dynamize(htmlCode, doc, datas);
|
|
||||||
|
DomPresenterCore.dynamize(htmlCode, dom, data);
|
||||||
StringBuffer htmlTarget = htmlCode.getBuffer();
|
StringBuffer htmlTarget = htmlCode.getBuffer();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -111,7 +118,7 @@ public class StringPresenter implements Presenter
|
||||||
{
|
{
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
else if ((this.source.startsWith("<!DOCTYPE")) || (this.source.startsWith("<!doctype")) || (this.source.startsWith("<html>")) || (this.source.startsWith("<HTML>")))
|
else if (this.doctype != null)
|
||||||
{
|
{
|
||||||
result = htmlTarget;
|
result = htmlTarget;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +163,7 @@ public class StringPresenter implements Presenter
|
||||||
{
|
{
|
||||||
boolean result;
|
boolean result;
|
||||||
|
|
||||||
if (this.doc == null)
|
if (this.dom == null)
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +182,8 @@ public class StringPresenter implements Presenter
|
||||||
public void setSource(final String html)
|
public void setSource(final String html)
|
||||||
{
|
{
|
||||||
this.source = html;
|
this.source = html;
|
||||||
this.doc = null;
|
this.doctype = null;
|
||||||
|
this.dom = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -192,4 +200,33 @@ public class StringPresenter implements Presenter
|
||||||
//
|
//
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean hasHtmlTag(final String source)
|
||||||
|
{
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (source.matches("<[hH][tT][mM][lL]>"))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
package fr.devinsy.xidyn.presenters;
|
package fr.devinsy.xidyn.presenters;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.w3c.dom.Document;
|
|
||||||
|
|
||||||
import fr.devinsy.xidyn.data.TagDataManager;
|
import fr.devinsy.xidyn.data.TagDataManager;
|
||||||
import fr.devinsy.xidyn.utils.XidynUtils;
|
import fr.devinsy.xidyn.utils.XidynUtils;
|
||||||
|
@ -17,15 +13,13 @@ import fr.devinsy.xidyn.utils.XidynUtils;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class URLPresenter implements Presenter
|
public class URLPresenter extends StringPresenter
|
||||||
{
|
{
|
||||||
static private Logger logger = LoggerFactory.getLogger(URLPresenter.class);
|
static private Logger logger = LoggerFactory.getLogger(URLPresenter.class);
|
||||||
|
|
||||||
private Document doc;
|
|
||||||
private String sourcePathname;
|
private String sourcePathname;
|
||||||
private URL sourceURL;
|
private URL source;
|
||||||
private long sourceFileTime;
|
private long sourceTime;
|
||||||
private String doctype;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -69,44 +63,31 @@ public class URLPresenter implements Presenter
|
||||||
* No need to be synchronized.
|
* No need to be synchronized.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public StringBuffer dynamize(final TagDataManager datas) throws Exception
|
public StringBuffer dynamize(final TagDataManager data) throws Exception
|
||||||
{
|
{
|
||||||
StringBuffer result;
|
StringBuffer result;
|
||||||
|
|
||||||
logger.info("dynamize URL [" + this.sourcePathname + "]");
|
logger.info("dynamize URL [" + this.sourcePathname + "]");
|
||||||
|
|
||||||
if (this.sourceURL == null)
|
//
|
||||||
|
if (this.source == null)
|
||||||
{
|
{
|
||||||
String errorMessage = "source file defined but not found (" + this.sourcePathname + ")";
|
String errorMessage = "source not defined";
|
||||||
logger.error(errorMessage);
|
logger.error(errorMessage);
|
||||||
result = null;
|
result = null;
|
||||||
throw new Exception(errorMessage);
|
throw new Exception(errorMessage);
|
||||||
}
|
}
|
||||||
else if (datas == null)
|
|
||||||
{
|
|
||||||
result = dynamize(new TagDataManager());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
long lastModified = this.sourceURL.openConnection().getLastModified();
|
long currentSourceTime = this.source.openConnection().getLastModified();
|
||||||
if ((this.doc == null) || (this.sourceFileTime != lastModified))
|
if ((super.getSource() == null) || (this.sourceTime != currentSourceTime))
|
||||||
{
|
{
|
||||||
this.sourceFileTime = lastModified;
|
super.setSource(XidynUtils.load(this.source));
|
||||||
this.doc = XidynUtils.buildDom(this.sourceURL.openStream());
|
this.sourceTime = currentSourceTime;
|
||||||
if (this.doc != null)
|
|
||||||
{
|
|
||||||
XidynUtils.addMetaTag(this.doc, "generator", "XIDYN");
|
|
||||||
}
|
|
||||||
this.doctype = "<!DOCTYPE HTML>"; // TODO Made generic.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the web page.
|
// Build the web page.
|
||||||
StringWriter htmlCode = new StringWriter(XidynUtils.estimatedTargetLength(sourceURL.openConnection().getContentLength()));
|
result = super.dynamize(data);
|
||||||
htmlCode.write(doctype);
|
|
||||||
htmlCode.write('\n');
|
|
||||||
|
|
||||||
DomPresenterCore.dynamize(htmlCode, doc, datas);
|
|
||||||
result = htmlCode.getBuffer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -121,7 +102,7 @@ public class URLPresenter implements Presenter
|
||||||
{
|
{
|
||||||
String result;
|
String result;
|
||||||
|
|
||||||
result = this.sourceURL.toString();
|
result = this.source.toString();
|
||||||
|
|
||||||
//
|
//
|
||||||
return (result);
|
return (result);
|
||||||
|
@ -133,18 +114,22 @@ public class URLPresenter implements Presenter
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isOutdated() throws IOException
|
public boolean isOutdated() throws Exception
|
||||||
{
|
{
|
||||||
boolean result;
|
boolean result;
|
||||||
|
|
||||||
long lastModified = this.sourceURL.openConnection().getLastModified();
|
//
|
||||||
if (this.sourceFileTime == lastModified)
|
if (super.isOutdated())
|
||||||
{
|
{
|
||||||
result = false;
|
result = true;
|
||||||
|
}
|
||||||
|
else if (this.sourceTime == this.source.openConnection().getLastModified())
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = true;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -154,6 +139,7 @@ public class URLPresenter implements Presenter
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void setSource(final String source)
|
public void setSource(final String source)
|
||||||
{
|
{
|
||||||
URL url;
|
URL url;
|
||||||
|
@ -169,6 +155,7 @@ public class URLPresenter implements Presenter
|
||||||
}
|
}
|
||||||
catch (final MalformedURLException exception)
|
catch (final MalformedURLException exception)
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
logger.warn("UNKNOWN PROTOCOL [" + source + "]");
|
logger.warn("UNKNOWN PROTOCOL [" + source + "]");
|
||||||
url = null;
|
url = null;
|
||||||
}
|
}
|
||||||
|
@ -189,16 +176,18 @@ public class URLPresenter implements Presenter
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
|
this.source = null;
|
||||||
this.sourcePathname = null;
|
this.sourcePathname = null;
|
||||||
|
this.sourceTime = 0;
|
||||||
|
super.setSource(null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
this.source = source;
|
||||||
this.sourcePathname = source.toString();
|
this.sourcePathname = source.toString();
|
||||||
|
this.sourceTime = 0;
|
||||||
|
super.setSource(null);
|
||||||
}
|
}
|
||||||
this.sourceURL = source;
|
|
||||||
this.sourceFileTime = 0;
|
|
||||||
this.doc = null;
|
|
||||||
this.doctype = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,35 +219,4 @@ public class URLPresenter implements Presenter
|
||||||
//
|
//
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePathname
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
static public String getDoctype(final String filePathname) throws Exception
|
|
||||||
{
|
|
||||||
String result;
|
|
||||||
|
|
||||||
//
|
|
||||||
BufferedReader in = new BufferedReader(new FileReader(filePathname));
|
|
||||||
String doctype = in.readLine();
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
logger.info("doctype=[" + doctype + "]");
|
|
||||||
|
|
||||||
//
|
|
||||||
if ((doctype.startsWith("<!DOCTYPE")) || (doctype.startsWith("<!doctype")))
|
|
||||||
{
|
|
||||||
result = doctype;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package fr.devinsy.xidyn.utils;
|
package fr.devinsy.xidyn.utils;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -18,6 +22,7 @@ import org.w3c.dom.Document;
|
||||||
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.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,6 +127,78 @@ public class XidynUtils
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method builds a DOM object from a source.
|
||||||
|
*/
|
||||||
|
static public Document buildDom(final String source) throws Exception
|
||||||
|
{
|
||||||
|
Document result;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create a DocumentBuilderFactory and configure it.
|
||||||
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
|
|
||||||
|
// Set various configuration options.
|
||||||
|
dbf.setValidating(false);
|
||||||
|
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(new InputSource(new StringReader(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.
|
||||||
*/
|
*/
|
||||||
|
@ -184,15 +261,97 @@ public class XidynUtils
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define in Presenter cause <object> needs this possibility.
|
* This method extracts the string before the <i>html</i> tag.
|
||||||
|
*
|
||||||
|
* A possible way is to use pattern searching for
|
||||||
|
* <i>$(.*)<html>.*^</i>. But if there is no <i>html</i> tag, all the
|
||||||
|
* source is read for nothing.
|
||||||
|
*
|
||||||
|
* A best way is to analyze each < while it is a XML tag or a DOCTYPE tag
|
||||||
|
* or the <HTML> tag.
|
||||||
|
*
|
||||||
|
* Uses cases:
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* <?xml version='1.0' encoding='UTF-8' ?><!-- TOTOT --><!DOCTYPE
|
||||||
|
* html><html xmlns='http://www.w3.org/1999/xhtml'>...
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @return the string before the <i>html</i> tag or null if no <i>html</i>
|
||||||
|
* tag found. So, "" if there is a <i>html</i> tag without doctype.
|
||||||
*/
|
*/
|
||||||
static public Document fileToDom(final String fileName) throws Exception
|
static public String extractDoctype(final String source)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boolean ended = false;
|
||||||
|
result = null;
|
||||||
|
int currentPosition = 0;
|
||||||
|
while (!ended)
|
||||||
|
{
|
||||||
|
currentPosition = source.indexOf('<', currentPosition);
|
||||||
|
|
||||||
|
if (currentPosition == -1)
|
||||||
|
{
|
||||||
|
ended = true;
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (currentPosition + 1 < source.length())
|
||||||
|
{
|
||||||
|
if (Character.toLowerCase(source.charAt(currentPosition + 1)) == 'h')
|
||||||
|
{
|
||||||
|
if (source.substring(currentPosition + 1, currentPosition + 5).matches("^[hH][tT][mM][lL]$"))
|
||||||
|
{
|
||||||
|
ended = true;
|
||||||
|
result = source.substring(0, currentPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char letter = source.charAt(currentPosition + 1);
|
||||||
|
if ((letter != '?') && (letter != '!'))
|
||||||
|
{
|
||||||
|
ended = true;
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentPosition += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ended = true;
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static public Document fileToDom(final File source) throws Exception
|
||||||
{
|
{
|
||||||
Document result;
|
Document result;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = buildDom(new FileInputStream(new File(fileName)));
|
result = buildDom(new FileInputStream(source));
|
||||||
}
|
}
|
||||||
catch (IOException exception)
|
catch (IOException exception)
|
||||||
{
|
{
|
||||||
|
@ -294,6 +453,170 @@ public class XidynUtils
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
static public String load(final File source) throws IOException
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
final String DEFAULT_CHARSET_NAME = "UTF-8";
|
||||||
|
result = load(source, DEFAULT_CHARSET_NAME);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static String load(final File source, final String charsetName) throws IOException
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = loadToStringBuffer(source, charsetName).toString();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
static public String load(final URL source) throws IOException
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
final String DEFAULT_CHARSET_NAME = "UTF-8";
|
||||||
|
result = load(source, DEFAULT_CHARSET_NAME);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static String load(final URL source, final String charsetName) throws IOException
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
//
|
||||||
|
StringBuffer buffer = new StringBuffer(source.openConnection().getContentLength() + 1);
|
||||||
|
read(buffer, source.openStream(), charsetName);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = buffer.toString();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static StringBuffer loadToStringBuffer(final File file, final String charsetName) throws IOException
|
||||||
|
{
|
||||||
|
StringBuffer result;
|
||||||
|
|
||||||
|
BufferedReader in = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
in = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName));
|
||||||
|
|
||||||
|
boolean ended = false;
|
||||||
|
final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||||
|
result = new StringBuffer((int) file.length() + 1);
|
||||||
|
while (!ended)
|
||||||
|
{
|
||||||
|
String line = in.readLine();
|
||||||
|
|
||||||
|
if (line == null)
|
||||||
|
{
|
||||||
|
ended = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.append(line).append(LINE_SEPARATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (in != null)
|
||||||
|
{
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void read(final StringBuffer out, final InputStream is, final String charsetName) throws IOException
|
||||||
|
{
|
||||||
|
BufferedReader in = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
in = new BufferedReader(new InputStreamReader(is, charsetName));
|
||||||
|
|
||||||
|
boolean ended = false;
|
||||||
|
final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||||
|
|
||||||
|
while (!ended)
|
||||||
|
{
|
||||||
|
String line = in.readLine();
|
||||||
|
|
||||||
|
if (line == null)
|
||||||
|
{
|
||||||
|
ended = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.append(line).append(LINE_SEPARATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (in != null)
|
||||||
|
{
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
@ -350,4 +673,27 @@ public class XidynUtils
|
||||||
//
|
//
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static public Document urlToDom(final URL source) throws Exception
|
||||||
|
{
|
||||||
|
Document result;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = buildDom(source.openStream());
|
||||||
|
}
|
||||||
|
catch (IOException exception)
|
||||||
|
{
|
||||||
|
String errorMessage = "IOError during parsing." + exception.getMessage();
|
||||||
|
logger.error(errorMessage);
|
||||||
|
result = null;
|
||||||
|
throw new Exception(errorMessage, exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package fr.devinsy.xidyn.utils;
|
package fr.devinsy.xidyn.utils;
|
||||||
|
|
||||||
|
import org.apache.log4j.BasicConfigurator;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
import org.fest.assertions.Assertions;
|
import org.fest.assertions.Assertions;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,6 +12,16 @@ import org.junit.Test;
|
||||||
*/
|
*/
|
||||||
public class XidynUtilsTest
|
public class XidynUtilsTest
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void before()
|
||||||
|
{
|
||||||
|
BasicConfigurator.configure();
|
||||||
|
Logger.getRootLogger().setLevel(Level.ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -55,4 +69,65 @@ public class XidynUtilsTest
|
||||||
String target = XidynUtils.extractBodyContent(source);
|
String target = XidynUtils.extractBodyContent(source);
|
||||||
Assertions.assertThat(target).isEqualTo("hello");
|
Assertions.assertThat(target).isEqualTo("hello");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testExtractDoctype01()
|
||||||
|
{
|
||||||
|
String source = "aaaaa<boDY>hello</Body>zzzzz";
|
||||||
|
|
||||||
|
String target = XidynUtils.extractDoctype(source);
|
||||||
|
Assertions.assertThat(target).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testExtractDoctype02()
|
||||||
|
{
|
||||||
|
String source = "<html xmlns='http://www.w3.org/1999/xhtml'>aaaaa<boDY>hello</Body>zzzzz";
|
||||||
|
|
||||||
|
String target = XidynUtils.extractDoctype(source);
|
||||||
|
Assertions.assertThat(target).isEqualTo("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testExtractDoctype03()
|
||||||
|
{
|
||||||
|
String source = "<!DOCTYPE html><html xmlns='http://www.w3.org/1999/xhtml'>aaaaa<boDY>hello</Body>zzzzz";
|
||||||
|
|
||||||
|
String target = XidynUtils.extractDoctype(source);
|
||||||
|
Assertions.assertThat(target).isEqualTo("<!DOCTYPE html>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testExtractDoctype04()
|
||||||
|
{
|
||||||
|
String source = "<?xml version='1.0' encoding='UTF-8' ?><!DOCTYPE html><html xmlns='http://www.w3.org/1999/xhtml'>aaaaa<boDY>hello</Body>zzzzz";
|
||||||
|
|
||||||
|
String target = XidynUtils.extractDoctype(source);
|
||||||
|
Assertions.assertThat(target).isEqualTo("<?xml version='1.0' encoding='UTF-8' ?><!DOCTYPE html>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testExtractDoctype05()
|
||||||
|
{
|
||||||
|
String source = "<?xml version='1.0' encoding='UTF-8' ?><!-- TOTOT --><!DOCTYPE html><html xmlns='http://www.w3.org/1999/xhtml'>aaaaa<boDY>hello</Body>zzzzz";
|
||||||
|
|
||||||
|
String target = XidynUtils.extractDoctype(source);
|
||||||
|
Assertions.assertThat(target).isEqualTo("<?xml version='1.0' encoding='UTF-8' ?><!-- TOTOT --><!DOCTYPE html>");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue