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