Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.sf.gluebooster.java.booster.basic.text.html.HtmlDocumentationWriter Maven / Gradle / Ivy
package net.sf.gluebooster.java.booster.basic.text.html;
import java.io.File;
import java.util.Arrays;
import java.util.Date;
import java.util.Hashtable;
import javax.activation.UnsupportedDataTypeException;
import javax.naming.Context;
import javax.naming.Name;
import javax.script.ScriptEngine;
import javax.swing.text.html.HTML;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import net.sf.gluebooster.java.booster.basic.container.BoostedNode;
import net.sf.gluebooster.java.booster.basic.events.RuntimeExceptionThrowingThrowableHandler;
import net.sf.gluebooster.java.booster.basic.events.ThrowableHandler;
import net.sf.gluebooster.java.booster.basic.meta.DocumentationContext;
import net.sf.gluebooster.java.booster.basic.resources.FileResourceSystem;
import net.sf.gluebooster.java.booster.basic.text.general.BookBoostUtils;
import net.sf.gluebooster.java.booster.basic.text.general.BookContext;
import net.sf.gluebooster.java.booster.basic.text.general.DocumentationResourcesId;
import net.sf.gluebooster.java.booster.essentials.container.ResourceSystem;
import net.sf.gluebooster.java.booster.essentials.eventsCommands.Callable;
import net.sf.gluebooster.java.booster.essentials.eventsCommands.CallableAbstraction;
import net.sf.gluebooster.java.booster.essentials.meta.objects.IoDescription;
import net.sf.gluebooster.java.booster.essentials.utils.Check;
import net.sf.gluebooster.java.booster.essentials.utils.Constants;
import net.sf.gluebooster.java.booster.essentials.utils.ContainerBoostUtils;
import net.sf.gluebooster.java.booster.essentials.utils.DomBoostUtils;
import net.sf.gluebooster.java.booster.essentials.utils.GuiBoostUtils;
import net.sf.gluebooster.java.booster.essentials.utils.IoBoostUtils;
import net.sf.gluebooster.java.booster.essentials.utils.TextBoostUtils;
import net.sf.gluebooster.java.booster.essentials.utils.ThreadBoostUtils;
/**
* Writes a documentation as html.
*
* @defaultParamText documentationNode the root node of the documentation
*
* @author CBauer
*
*/
public class HtmlDocumentationWriter extends CallableAbstraction {
/**
* The handler of warnings.
*/
private ThrowableHandler warningHandler = new RuntimeExceptionThrowingThrowableHandler();
/**
* The default context of the documentation.
*/
private IoDescription output;
/**
* Transforms text that is no plain string into html.
*
*/
private Callable textTransformer = null;
/**
* May add something to the html head. Call parameters are document, html head element
*/
private Callable htmlHeadAppender = null;
/**
* Adds text as nodes. The call arguments are Document, Element, text
*/
private Callable textNodeBuilder = null;
public HtmlDocumentationWriter() {
}
public HtmlDocumentationWriter(IoDescription output) {
this.output = output;
}
/**
* Writes the html of a documentationNode and its children.
*
* @param outputDirectory
* the directory of the created html
* @return the (main) file with the html
*/
public IoDescription write(BoostedNode documentationNode, File outputDirectory) throws Exception {
return write(documentationNode, new IoDescription(new FileResourceSystem(), outputDirectory));
}
/**
* Writes the html of a documentationNode and its children
*
* @param documentationNode
* the node to write
* @param outputDirectory
* the directory of the created html
* @return the (main) file with the html
* @throws Exception
*/
@SuppressWarnings("unchecked")
public IoDescription write(BoostedNode documentationNode, IoDescription outputDirectory) throws Exception {
getLog().debug("write html");
Object type = documentationNode.getAttributes().getType();
if (BookBoostUtils.BOOK.equals(type)) {
Document doc = DomBoostUtils.createDefaultDocumentBuilder().newDocument();
// Pair newDir = new ImmutablePair(outputDirectory.getLeft(),
// new File(outputDirectory.getRight(), documentationNode.getAttributes().getName().toString()));
fillBook(doc, documentationNode, outputDirectory);
IoDescription out = outputDirectory.getOutputStream("index.html");
DomBoostUtils.write(doc, out.getOutputStream(), true);
out.getOutputStream().close();
return out;
} else if (BookBoostUtils.SLIPCASE.equals(type) || BookBoostUtils.BOOKSHELF.equals(type)) {
getLog().debug("writig " + type);
// write the list of books or slipcases
Document doc = DomBoostUtils.createDefaultDocumentBuilder().newDocument();
Element body = createHtml(doc, documentationNode.getAttributes().getName(), HTML.Tag.BODY);
Element list = DomBoostUtils.appendElement(doc, body, HTML.Tag.UL);
for (BoostedNode zoomInFocusPoint: documentationNode.getAllZoomInFocus()){
BoostedNode zoomInNode = documentationNode.getZoomIn(zoomInFocusPoint, null);
Object subtype = zoomInNode.getAttributes().getType();
if (BookBoostUtils.BOOK.equals(subtype) || BookBoostUtils.BOOKSHELF.equals(subtype) || BookBoostUtils.SLIPCASE.equals(subtype)) {
String subdirectory = "" + zoomInNode.getAttributes().getName();
Element li = DomBoostUtils.appendElement(doc, list, HTML.Tag.LI);
DomBoostUtils.appendElement(
doc,
li,
HTML.Tag.A,
ContainerBoostUtils.createMap("href", subdirectory + "/index.html", "target", "content"),
zoomInNode.getAttributes().getName());
write(zoomInNode, outputDirectory.getChildFile(subdirectory));
} else {
throw new IllegalStateException("subtype not supported: " + subtype);
}
}
IoDescription out = outputDirectory.getOutputStream("booklist.html");
DomBoostUtils.write(doc, out.getOutputStream(), true);
out.getOutputStream().close();
//write the index
doc = DomBoostUtils.createDefaultDocumentBuilder().newDocument();
body = createHtml(doc, documentationNode.getAttributes().getName(), HTML.Tag.FRAMESET, "cols", "250,*");
DomBoostUtils.appendElement(doc, body, HTML.Tag.FRAME, ContainerBoostUtils
.createMap("src", "booklist.html", "name", "navigation"));
DomBoostUtils.appendElement(doc, body, HTML.Tag.FRAME,
ContainerBoostUtils.createMap("name", "content"));
out = outputDirectory.getOutputStream("index.html");
DomBoostUtils.write(doc, out.getOutputStream(), true);
return out;
} else {
throw new IllegalStateException("type not supported: " + type);
/*
warningHandler.handleThrowable(new UnsupportedOperationException(
"close currently not supported for type " + type));
*/
}
}
/**
* Fill a book with the content of a document
*
* @param doc
* contains the content
* @param bookNode
* the root node of the book
* @param outputDirectory
* the directory of the created html
*/
private void fillBook(Document doc, BoostedNode bookNode, IoDescription outputDirectory) throws Exception {
Element body = createHtml(doc, bookNode.getAttributes().getName(), HTML.Tag.BODY);
BookContext bookContext = new BookContext();
bookContext.setChapterBreadcrumb(new Object[]{0});//you are in the first navigation level, with 0 chapters before
fillBookChapter(bookNode, bookContext, doc, body, false, outputDirectory);
}
/**
* Create html from a document.
*
* @param doc
* contains the content
* @param bodyOrFrameset
* body or frameset information
* @param bodyAttributes
* additional attributes of the body
* @param title
* the title of the html
* @return the body element
*/
@SuppressWarnings({ "unchecked", "unused" })
private Element createHtml(Document doc, Object title, Object bodyOrFrameset, Object... bodyAttributes) throws Exception {
Element html = DomBoostUtils.appendElement(doc, doc, HTML.Tag.HTML);
Element head = DomBoostUtils.appendElement(doc, html,HTML.Tag.HEAD);
DomBoostUtils.appendElement(doc, head, HTML.Tag.META, ContainerBoostUtils
.createMap("name", "date", "content", new Date().toString()),
"");
if (htmlHeadAppender != null) {
htmlHeadAppender.call(doc, head);
}
Element body = DomBoostUtils.appendElement(doc, html, bodyOrFrameset,
ContainerBoostUtils.createMap(bodyAttributes));
Element titleElement = DomBoostUtils.appendElement(doc, body, HTML.Tag.DIV,
ContainerBoostUtils.createMap("style", "font-size:xx-large"),
title);
return body;
}
/**
* Adds default attributes of a node to an html element
*
* @param node
* the source of the attributes
* @param element
* will be modified
*/
private void addDefaultAttributes(BoostedNode node, Element element) {
Object id = node.getAttributes().getId();
if (id != null) {
element.setAttribute("id", id.toString());
}
}
/**
* Fill in a chapter of the book
*
* @param chapterNode
* the root element with the content of the chapter
* @param bookContext
* the context of the book
* @param doc
* the document of the book
* @param parentElement
* the parent of the chapter
* @param writeChapterHeadline
* should a headline be written
* @param outputDirectory
* the directory of the created html
*
*/
private void fillBookChapter(BoostedNode chapterNode, BookContext bookContext, Document doc, Element parentElement, boolean writeChapterHeadline,
IoDescription outputDirectory) throws Exception {
if (writeChapterHeadline){
int chapterLevel = bookContext.getChapterBreadcrumb().length;
Object tag;
//HTML has only h1 ... h6
if (chapterLevel <7)
tag = "h" + chapterLevel;
else {
tag = HTML.Tag.DIV;
}
// Element node = DomBoostUtils.appendElement(doc, parentElement, tag, null, chapterNode.getAttributes().getName());xxx
Element node = DomBoostUtils.appendElement(doc, parentElement, tag);
addDefaultAttributes(chapterNode, node);
appendText(doc, node, chapterNode.getAttributes().getName());
}
int chapterCount = 0;
for (BoostedNode zoomInFocusPoint: chapterNode.getAllZoomInFocus()){
BoostedNode zoomInNode = chapterNode.getZoomIn(zoomInFocusPoint, null);
Object type = zoomInNode.getAttributes().getType();
if (DocumentationResourcesId.CHAPTER.equals(type)) {
BookContext newBookContext = (BookContext) bookContext.clone();
newBookContext.setChapterBreadcrumb(Arrays.copyOf(newBookContext.getChapterBreadcrumb(), newBookContext.getChapterBreadcrumb().length + 1) );
newBookContext.getChapterBreadcrumb()[bookContext.getChapterBreadcrumb().length] = chapterCount++;
fillBookChapter(zoomInNode, newBookContext, doc, parentElement, true, outputDirectory);
}else if (HTML.Tag.DIV.equals(type)){
Element div = DomBoostUtils.appendElement(doc, parentElement, HTML.Tag.DIV);
Object[] meta = BookBoostUtils.getMeta(zoomInNode);
if (meta != null) {
for (Object metaPart : meta) {
// currently all meta data is written as subtag (reasonable for STRONG, EM, ...)
div = DomBoostUtils.appendElement(doc, div, metaPart);
}
}
fillBookChapter(zoomInNode, bookContext, doc, div, false, outputDirectory);
} else if (TextBoostUtils.TEXT.equals(type)) {
appendText(doc, parentElement, zoomInNode.getAttributes().getValue());
// Object text = zoomInNode.getAttributes().getValue();
// if (text instanceof CharSequence || textTransformer == null) {
// DomBoostUtils.appendText(doc, parentElement, text);
// } else {
// DomBoostUtils.appendRaw(doc, parentElement, textTransformer.call(text));
// }
} else if (Constants.RAW.is(type)) {
DomBoostUtils.appendRaw(doc, parentElement, zoomInNode.getAttributes().getValue());
}else if (GuiBoostUtils.TYPE_IMAGE.equals(type)){
String filename = (String) zoomInNode.getAttributes().getAttribute(ScriptEngine.FILENAME);
if (filename == null) {
ThreadBoostUtils.sleep(2);// to get a new time
filename = "images/file"
+ System.currentTimeMillis()
+ "."
+ zoomInNode.getAttributes().getAttribute(Constants.FORMAT);
zoomInNode.getAttributes().setAttribute(
ScriptEngine.FILENAME, filename);
}
Element img = DomBoostUtils.appendElement(doc, parentElement,
HTML.Tag.IMG, ContainerBoostUtils.createMap(
HTML.Attribute.SRC, filename));
// the image must be stored in the same directory as the html
IoDescription out = outputDirectory.getOutputStream(filename);
out.getOutputStream().write((byte[]) zoomInNode.getAttributes().getValue());
out.getOutputStream().close();
}else {
warningHandler.handleThrowable(new UnsupportedDataTypeException("type " + type ));
}
}
}
/**
* Appends text to a node.
*
* @param doc
* the html document of the node
* @param parentElement
* the node
* @param text
* may be a charsequence or be composed of parts (transformed by the textTransformer)
*/
private void appendText(Document doc, Element parentElement, Object text) throws Exception {
if (text instanceof CharSequence || (textTransformer == null && textNodeBuilder == null)) {
DomBoostUtils.appendText(doc, parentElement, text);
} else {
if (textTransformer != null) {
DomBoostUtils.appendRaw(doc, parentElement, textTransformer.call(text));
} else if (textNodeBuilder != null) {
textNodeBuilder.call(doc, parentElement, text);
} else {
throw new IllegalStateException("no text transformation possible");
}
}
}
public ThrowableHandler getWarningHandler() {
return warningHandler;
}
public void setWarningHandler(
ThrowableHandler warningHandler) {
this.warningHandler = warningHandler;
}
/**
* Creates html from a BoostedNode Structure. TODO the documentation of the environment keys must be put somewhere more abstract.
*
* @param boostedNode
* the root of the document
* @param environment
* Keys: File.class the target directory of the html; ResourceSystem.class the system which will write the file
* @return The file of the index.html
* @throws Exception
*/
private IoDescription createHtml(Object boostedNode, Hashtable, ?> environment) throws Exception {
ResourceSystem filesystem = Check.notNullWithDefault((environment == null) ? null : environment.get(ResourceSystem.class), "resource system",
(output == null) ? null : output.getResourceSystem(), new FileResourceSystem());
File directory = IoBoostUtils.getFile(Check.notNullWithDefault((environment == null) ? null : environment.get(File.class), "Target directory file",
(environment == null) ? null : environment.get(DocumentationContext.DOCUMENTATION_TARGET_PARAMETER),
(output == null) ? null : output.getFile()));
BoostedNode document = Check.notNull(boostedNode, "BoostedNode containing the document root");
return write(document, new IoDescription(filesystem, directory));
}
// @Override
// public Object getObjectInstance(Object boostedNode, Name name, Context nameCtx, Hashtable, ?> environment) throws Exception {
// return createHtml(boostedNode, environment);
// // ResourceSystem filesystem = Check.notNullWithDefault((environment == null) ? null : environment.get(ResourceSystem.class), "resource system",
// // (output == null) ? null : output.getResourceSystem(), new FileResourceSystem());
// // File directory = IoBoostUtils.getFile(Check.notNullWithDefault((environment == null) ? null : environment.get(File.class), "Target directory file",
// // (environment == null) ? null : environment.get(DocumentationContext.DOCUMENTATION_TARGET_PARAMETER),
// // (output == null) ? null : output.getFile()));
// // BoostedNode document = Check.notNull(boostedNode, "BoostedNode containing the document root");
// // return write(document, new IoDescription(filesystem, directory));
//
// }
public IoDescription getOutput() {
return output;
}
public void setOutput(IoDescription output) {
this.output = output;
}
public Callable getTextTransformer() {
return textTransformer;
}
public void setTextTransformer(Callable textTransformer) {
this.textTransformer = textTransformer;
}
public Callable getTextNodeBuilder() {
return textNodeBuilder;
}
public void setTextNodeBuilder(Callable textNodeBuilder) {
this.textNodeBuilder = textNodeBuilder;
}
public Callable getHtmlHeadAppender() {
return htmlHeadAppender;
}
public void setHtmlHeadAppender(Callable htmlHeadAppender) {
this.htmlHeadAppender = htmlHeadAppender;
}
@Override
protected IoDescription callImpl(Object... parameters) throws Exception {
Object boostedNode = parameters[0];
Hashtable, ?> environment = (Hashtable) parameters[1];
return createHtml(boostedNode, environment);
// return (IoDescription) getObjectInstance(boostedNode, null, null, environment);
}
}