package com.wooki.pages.dev;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringBufferInputStream;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.tapestry5.ContentType;
import org.apache.tapestry5.EventConstants;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.StreamResponse;
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.annotations.OnEvent;
import org.apache.tapestry5.internal.services.ArrayEventContext;
import org.apache.tapestry5.internal.services.HeartbeatImpl;
import org.apache.tapestry5.internal.services.RenderQueueImpl;
import org.apache.tapestry5.internal.services.RequestPageCache;
import org.apache.tapestry5.internal.structure.Page;
import org.apache.tapestry5.ioc.LoggerSource;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.services.Environment;
import org.apache.tapestry5.services.Heartbeat;
import org.apache.tapestry5.services.MarkupWriterFactory;
import org.apache.tapestry5.services.Response;
import org.slf4j.Logger;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.wooki.domain.biz.BookManager;
import com.wooki.domain.biz.ChapterManager;
import com.wooki.domain.model.Book;
import com.wooki.domain.model.Chapter;
public class FlyingSaucer
{
@Inject
private BookManager bookManager;
@Inject
private ChapterManager chapterManager;
@Inject
private RequestPageCache pageCache;
@Inject
private TypeCoercer typeCoercer;
@Inject
private LoggerSource loggerSource;
@Inject
private MarkupWriterFactory factory;
@Inject
private Environment environment;
@Inject
@Symbol(SymbolConstants.CHARSET)
private String encoding;
@OnEvent(value = "print")
public Object printFromFull()
{
MarkupWriter writer = factory.newMarkupWriter(new ContentType(encoding));
Page full = pageCache.get("book/full");
full.getRootElement().triggerContextEvent(
EventConstants.ACTIVATE,
new ArrayEventContext(typeCoercer, 1),
null);
String name = "wooki.render." + full.getLogger().getName();
Logger logger = loggerSource.getLogger(name);
try
{
this.environment.push(Heartbeat.class, new HeartbeatImpl());
RenderQueueImpl queue = new RenderQueueImpl(logger);
queue.push(full.getRootElement());
queue.run(writer);
ByteArrayOutputStream dos = new ByteArrayOutputStream();
PrintWriter printWriter = new PrintWriter(dos);
writer.toMarkup(printWriter);
dos.flush();
printWriter.flush();
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(new String(dos.toByteArray())
.getBytes(encoding)));
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(doc, null);
renderer.layout();
final ByteArrayOutputStream os = new ByteArrayOutputStream();
renderer.createPDF(os);
os.close();
return new StreamResponse()
{
public void prepareResponse(Response response)
{
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "max-age=0");
response.setHeader("Content-Disposition", "attachment; filename=wooki.pdf");
}
public InputStream getStream() throws IOException
{
return new ByteArrayInputStream(os.toByteArray());
}
public String getContentType()
{
return "application/pdf";
}
};
}
catch (Exception ex)
{
throw new TapestryException(ex.getMessage(), ex);
}
finally
{
this.environment.pop(Heartbeat.class);
}
}
public Object testFlyingSaucer()
{
Book b = bookManager.findBookBySlugTitle("the-book-of-wooki");
StringBuffer buffer = new StringBuffer();
buffer.append("<html><head><title>").append(b.getTitle()).append("</title>");
buffer
.append(
"<link rel='stylesheet' type='text/css' href='file:/Users/ccordenier/Documents/workspace-tapestry-5.1/wooki/src/main/webapp/static/css/print.css' media='print' />")
.append("</head>");
buffer.append("<body>");
buffer.append("<div style=\"-fs-page-sequence: start; page-break-after: always;\">");
List<Chapter> chapters = chapterManager.listChapters(b.getId());
buffer.append("<div id=\"header\" style=\"position: running(current);\"><span>").append(
b.getTitle()).append("</span></div>");
buffer
.append("<div id=\"title\" style=\"page-break-after: always;\"><h1>")
.append(b.getTitle())
.append(
"</h1><div id=\"meta\"><p id=\"authors\"> By Robin Komiwes, Bruno Verachten and Christophe Cordenier</p><p id=\"revision\">Published 04 february 2010</p></div></div>");
if (chapters != null)
{
// Append abstract
if (chapters.size() > 0)
{
Chapter c = chapters.get(0);
buffer.append("<h2>").append(c.getTitle()).append("</h2>");
String content = chapterManager.getLastPublishedContent(c.getId());
if (content != null)
{
buffer.append(content);
}
// Build Toc
buffer.append("<h2>Table of contents</h2>");
if (chapters.size() > 1)
{
buffer.append("<ol id=\"table-of-contents\">");
for (int i = 1; i < chapters.size(); i++)
{
c = chapters.get(i);
buffer.append("<li><h3><a href=\"#chapter" + i + "\">")
.append(c.getTitle()).append("</a></h3></li>");
}
buffer.append("</ol>");
}
// Append content
for (int i = 1; i < chapters.size(); i++)
{
c = chapters.get(i);
buffer.append("<h2 id=\"chapter" + i + "\">").append(c.getTitle()).append(
"</h2>");
content = chapterManager.getLastPublishedContent(c.getId());
if (content != null)
{
buffer.append(content);
}
}
}
}
buffer.append("</div></body></html>");
// parse our markup into an xml Document
try
{
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new StringBufferInputStream(buffer.toString()));
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(doc, null);
renderer.layout();
final ByteArrayOutputStream os = new ByteArrayOutputStream();
renderer.createPDF(os);
os.close();
return new StreamResponse()
{
public void prepareResponse(Response response)
{
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "max-age=0");
response.setHeader("Content-Disposition", "attachment; filename=wooki.pdf");
}
public InputStream getStream() throws IOException
{
return new ByteArrayInputStream(os.toByteArray());
}
public String getContentType()
{
return "application/pdf";
}
};
}
catch (Exception ex)
{
ex.printStackTrace();
}
return null;
}
}