From 5c4d4e9e1f75de1fa92ffafb6d1e9df1368fbe74 Mon Sep 17 00:00:00 2001
From: Thorsten Vitt <thorsten.vitt@uni-wuerzburg.de>
Date: Sun, 2 Sep 2012 15:28:43 +0000
Subject: [PATCH] Refactored EPUB output to stream the ZIP file and delete the
 temporary directory afterwards

git-svn-id: https://develop.sub.uni-goettingen.de/repos/textgrid/trunk/services/aggregator@13488 7c539038-3410-0410-b1ec-0f2a7bf1c452
---
 pom.xml                                       |   5 +
 .../textgrid/services/aggregator/EPUB.java    |  96 +-----------
 .../services/aggregator/EPUBSerializer.java   | 144 ++++++++++++++++++
 3 files changed, 150 insertions(+), 95 deletions(-)
 create mode 100644 src/main/java/info/textgrid/services/aggregator/EPUBSerializer.java

diff --git a/pom.xml b/pom.xml
index 3151721..b927ddb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -133,6 +133,11 @@
 			<artifactId>link-rewriter-core</artifactId>
 			<version>0.0.4-SNAPSHOT</version>
 		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>2.4</version>
+		</dependency>
 	</dependencies>
 	
 	
diff --git a/src/main/java/info/textgrid/services/aggregator/EPUB.java b/src/main/java/info/textgrid/services/aggregator/EPUB.java
index 65dd3df..931e5cb 100644
--- a/src/main/java/info/textgrid/services/aggregator/EPUB.java
+++ b/src/main/java/info/textgrid/services/aggregator/EPUB.java
@@ -6,24 +6,15 @@
 import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.IoFault;
 import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.MetadataParseFault;
 import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.ObjectNotFoundFault;
-import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.ProtocolNotImplementedFault;
 import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.TGCrudService;
-import info.textgrid.utils.linkrewriter.ConfigurableXMLRewriter;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.URI;
-import java.net.URISyntaxException;
 import java.text.MessageFormat;
-import java.util.Deque;
-import java.util.LinkedList;
-import java.util.Map.Entry;
 import java.util.logging.Logger;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
@@ -32,7 +23,6 @@
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
-import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.stream.StreamSource;
 
 import net.sf.saxon.s9api.Processor;
@@ -41,9 +31,6 @@
 import net.sf.saxon.s9api.XsltExecutable;
 import net.sf.saxon.s9api.XsltTransformer;
 
-import org.xml.sax.SAXException;
-
-import com.google.common.io.ByteStreams;
 import com.google.common.io.Files;
 
 @Path("/epub")
@@ -107,93 +94,12 @@ public Response get(@PathParam("object") final URI uri) {
 			transformer.setSource(new StreamSource(corpus));
 			transformer.transform();
 
-			// Finally, create the ZIP file.
-			// FIXME first as a file
-			final File zipFile = new File(workingDir, "ebook.epub");
-			final ZipOutputStream zip = new ZipOutputStream(
-					new FileOutputStream(zipFile));
-			try {
-
-				// first entry is the uncompressed mimetype marker
-				new MimeTypeEntry("application/epub+zip").writeTo(zip);
-
-				// now filtered filesystem structure. FIXME add rewriting +
-				// images
-				final File mimeTypeFile = new File(workingDir, "mimetype");
-				final URI base = workingDir.toURI();
-				final File opsDir = new File(workingDir, "OPS");
-				final URI ops = opsDir.toURI();
-				final OPFManifest manifest = new OPFManifest(new File(opsDir,
-						"content.opf"));
-				final ConfigurableXMLRewriter xhtmlRewriter = new ConfigurableXMLRewriter(
-						manifest.getImportMapping(), true);
-				xhtmlRewriter.configure(URI.create("internal:html#html"));
-				final ConfigurableXMLRewriter opfRewriter = new ConfigurableXMLRewriter(
-						manifest.getImportMapping(), true);
-				opfRewriter.configure(URI.create("internal:epub#opf"));
-
-				final Deque<File> queue = new LinkedList<File>();
-				queue.push(workingDir);
-				while (!queue.isEmpty()) {
-					final File directory = queue.pop();
-
-					for (final File child : directory.listFiles()) {
-						// filter stuff we don't want:
-						if (child.equals(mimeTypeFile) || child.equals(corpus)
-								|| child.equals(zipFile))
-							continue;
-
-						String name = base.relativize(child.toURI()).getPath();
-						if (child.isDirectory()) {
-							queue.push(child);
-							if (!name.endsWith("/"))
-								name = name.concat("/");
-							zip.putNextEntry(new ZipEntry(name));
-						} else {
-							zip.putNextEntry(new ZipEntry(name));
-
-							if (Files.getFileExtension(name).equals("html"))
-								xhtmlRewriter.rewrite(
-										new FileInputStream(child), zip);
-							else if (Files.getFileExtension(name).equals("opf"))
-								opfRewriter.rewrite(new FileInputStream(child),
-										zip);
-							else
-								Files.copy(child, zip);
-							zip.closeEntry();
-						}
-					}
-				}
-
-				// now we need to add those files that are referenced by
-				// absolute URI in the manifest
-				for (final Entry<URI, String> externalItem : manifest.externalItems.entrySet()) {
-					final String pseudoFileName = base.relativize(new File(opsDir, manifest.getFileName(externalItem.getKey().toString())).toURI()).getPath();
-					zip.putNextEntry(new ZipEntry(pseudoFileName));
-					ByteStreams.copy(repository.getContent(externalItem.getKey()), zip);
-					zip.closeEntry();
-				}
-			} catch (final SAXException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (final URISyntaxException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (final XMLStreamException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (final ProtocolNotImplementedFault e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} finally {
-				zip.close();
-			}
 			return RESTUtils
 					.attachmentResponse(
 							rootObject.getGeneric().getProvided().getTitle()
 							.get(0)
 							+ ".epub").type("application/epub+zip")
-							.entity(zipFile).build();
+							.entity(new EPUBSerializer(workingDir, repository, corpus)).build();
 
 			// return Response.ok().type("text/plain").entity("Done, see " +
 			// workingDir).build();
diff --git a/src/main/java/info/textgrid/services/aggregator/EPUBSerializer.java b/src/main/java/info/textgrid/services/aggregator/EPUBSerializer.java
new file mode 100644
index 0000000..c4f749b
--- /dev/null
+++ b/src/main/java/info/textgrid/services/aggregator/EPUBSerializer.java
@@ -0,0 +1,144 @@
+package info.textgrid.services.aggregator;
+
+import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.AuthFault;
+import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.IoFault;
+import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.MetadataParseFault;
+import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.ObjectNotFoundFault;
+import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.ProtocolNotImplementedFault;
+import info.textgrid.utils.linkrewriter.ConfigurableXMLRewriter;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.Map.Entry;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.StreamingOutput;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.cxf.helpers.FileUtils;
+import org.xml.sax.SAXException;
+
+import com.google.common.io.ByteStreams;
+import com.google.common.io.Files;
+
+class EPUBSerializer implements StreamingOutput {
+
+	private final File workingDir;
+	private final ITextGridRep repository;
+	private final File corpus;
+
+
+
+	public EPUBSerializer(final File workingDir, final ITextGridRep repository, final File corpus) {
+		super();
+		this.workingDir = workingDir;
+		this.repository = repository;
+		this.corpus = corpus;
+	}
+
+
+
+	@Override
+	public void write(final OutputStream output) throws IOException,
+	WebApplicationException {
+		final ZipOutputStream zip = new ZipOutputStream(output);
+		try {
+
+			// first entry is the uncompressed mimetype marker
+			new MimeTypeEntry("application/epub+zip").writeTo(zip);
+
+			// now filtered filesystem structure. FIXME add rewriting +
+			// images
+			final File mimeTypeFile = new File(workingDir, "mimetype");
+			final URI base = workingDir.toURI();
+			final File opsDir = new File(workingDir, "OPS");
+			final URI ops = opsDir.toURI();
+			final OPFManifest manifest = new OPFManifest(new File(opsDir,
+					"content.opf"));
+			final ConfigurableXMLRewriter xhtmlRewriter = new ConfigurableXMLRewriter(
+					manifest.getImportMapping(), true);
+			xhtmlRewriter.configure(URI.create("internal:html#html"));
+			final ConfigurableXMLRewriter opfRewriter = new ConfigurableXMLRewriter(
+					manifest.getImportMapping(), true);
+			opfRewriter.configure(URI.create("internal:epub#opf"));
+
+			final Deque<File> queue = new LinkedList<File>();
+			queue.push(workingDir);
+			while (!queue.isEmpty()) {
+				final File directory = queue.pop();
+
+				for (final File child : directory.listFiles()) {
+					// filter stuff we don't want:
+					if (child.equals(mimeTypeFile) || child.equals(corpus))
+						continue;
+
+					String name = base.relativize(child.toURI()).getPath();
+					if (child.isDirectory()) {
+						queue.push(child);
+						if (!name.endsWith("/"))
+							name = name.concat("/");
+						zip.putNextEntry(new ZipEntry(name));
+					} else {
+						zip.putNextEntry(new ZipEntry(name));
+
+						if (Files.getFileExtension(name).equals("html"))
+							xhtmlRewriter.rewrite(
+									new FileInputStream(child), zip);
+						else if (Files.getFileExtension(name).equals("opf"))
+							opfRewriter.rewrite(new FileInputStream(child),
+									zip);
+						else
+							Files.copy(child, zip);
+						zip.closeEntry();
+					}
+				}
+			}
+
+			// now we need to add those files that are referenced by
+			// absolute URI in the manifest
+			for (final Entry<URI, String> externalItem : manifest.externalItems.entrySet()) {
+				final String pseudoFileName = base.relativize(new File(opsDir, manifest.getFileName(externalItem.getKey().toString())).toURI()).getPath();
+				zip.putNextEntry(new ZipEntry(pseudoFileName));
+				ByteStreams.copy(repository.getContent(externalItem.getKey()), zip);
+				zip.closeEntry();
+			}
+		} catch (final SAXException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final URISyntaxException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final XMLStreamException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final ProtocolNotImplementedFault e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final ObjectNotFoundFault e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final MetadataParseFault e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final IoFault e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final AuthFault e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} finally {
+			zip.close();
+			FileUtils.removeDir(workingDir);
+		}
+
+	}
+
+}
-- 
GitLab