From 8e39faea546d348fa7d5930f9ceeb258cf073e31 Mon Sep 17 00:00:00 2001 From: Thorsten Vitt <thorsten.vitt@uni-wuerzburg.de> Date: Mon, 27 May 2013 12:02:16 +0000 Subject: [PATCH] Actually return a ZIP. This version does not have any fancy features yet, i.e. neither link rewriting nor cool file names git-svn-id: https://develop.sub.uni-goettingen.de/repos/textgrid/trunk/services/aggregator@14098 7c539038-3410-0410-b1ec-0f2a7bf1c452 --- .../aggregator/tree/AggregationEntry.java | 17 ++-- .../textgrid/services/aggregator/zip/ZIP.java | 28 ++++--- .../services/aggregator/zip/ZipResult.java | 78 +++++++++++++++++++ 3 files changed, 109 insertions(+), 14 deletions(-) create mode 100644 src/main/java/info/textgrid/services/aggregator/zip/ZipResult.java diff --git a/src/main/java/info/textgrid/services/aggregator/tree/AggregationEntry.java b/src/main/java/info/textgrid/services/aggregator/tree/AggregationEntry.java index d545aa1..de94117 100644 --- a/src/main/java/info/textgrid/services/aggregator/tree/AggregationEntry.java +++ b/src/main/java/info/textgrid/services/aggregator/tree/AggregationEntry.java @@ -16,6 +16,8 @@ public class AggregationEntry { private static Logger logger = Logger.getLogger("info.textgrid.services.aggregator.tree"); + + private static URI baseURI = new File(".").toURI().normalize(); private final ObjectType metadata; @@ -70,10 +72,10 @@ protected String getSimpleFileName(final boolean withExtension) { * if true, append a content type specific extension to the last * component of the path. */ - protected File getFileName(final boolean withExtension) { + protected File getFile(final boolean withExtension) { Optional<Aggregation> parent = getParent(); if (parent.isPresent()) - return new File(parent.get().getFileName(false), + return new File(parent.get().getFile(false), getSimpleFileName(withExtension)); else return new File(getSimpleFileName(withExtension)); @@ -82,10 +84,11 @@ protected File getFileName(final boolean withExtension) { /** * Returns a {@link File} representing the abstract file name for this * aggregation entry from the root of the aggregation tree. Equivalent to - * {@code {@linkplain #getFileName(boolean) getFileName(true)}}. + * {@code {@linkplain #getFile(boolean) getFileName(true)}}. + * @param withExtension TODO */ - public File getFileName() { - return getFileName(true); + public String getFileName(boolean withExtension) { + return baseURI.relativize(getFile(true).toURI()).toString(); } @Override @@ -100,4 +103,8 @@ public String toString() { } } + public URI getTextGridURI() { + return URI.create(getMetadata().getGeneric().getGenerated().getTextgridUri().getValue()); + } + } diff --git a/src/main/java/info/textgrid/services/aggregator/zip/ZIP.java b/src/main/java/info/textgrid/services/aggregator/zip/ZIP.java index 4bbc49d..cf68add 100644 --- a/src/main/java/info/textgrid/services/aggregator/zip/ZIP.java +++ b/src/main/java/info/textgrid/services/aggregator/zip/ZIP.java @@ -13,6 +13,8 @@ import info.textgrid.services.aggregator.tree.AggregationTreeFactory; import java.net.URI; +import java.text.MessageFormat; +import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletContext; @@ -21,8 +23,11 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.StreamingOutput; import org.apache.cxf.jaxrs.model.wadl.Description; @@ -40,8 +45,8 @@ public ZIP(final ITextGridRep repository) { @GET @Path(value = "/{object}") - @Produces(value = "text/html") - public Response get( + @Produces(value = "application/zip") + public StreamingOutput get( @Description("The TextGrid URI of the TEI document or aggregation to transform") @PathParam("object") final URI uri, @Description("Session ID to access protected resources") @@ -51,21 +56,26 @@ public Response get( final MetadataContainerType container = crud.readMetadata(sid, null, uri.toString()); final ObjectType rootObject = container.getObject(); - Aggregation tree = AggregationTreeFactory.create(rootObject, repository, sid); + final String format = rootObject.getGeneric().getProvided().getFormat(); + if (!format.contains("aggregation")) { + logger.log(Level.SEVERE, "The requested object {0} is a {1}, not an aggregation, and thus cannot be aggregated.", new Object[] {uri,format}); + throw new WebApplicationException(javax.ws.rs.core.Response + .status(Status.BAD_REQUEST) + .entity(MessageFormat.format( + "The requested object {0} is a {1}, not an aggregation, and thus cannot be aggregated.", uri, + format)).build()); + } - StringBuilder output = new StringBuilder("Following stuff (+meta) would be zipped:\n\n"); - appendLS(tree, output); - - return Response.ok().entity(output.toString()).type("text/plain").build(); + return new ZipResult(rootObject, repository, sid); } private void appendLS(Aggregation aggregation, StringBuilder output) { - output.append(aggregation.getFileName()).append(":\n"); + output.append(aggregation.getFileName(true)).append(":\n"); for(AggregationEntry child : aggregation.getChildren()) if (child instanceof Aggregation) appendLS((Aggregation) child, output); else - output.append(' ').append(child.getFileName()).append('\n'); + output.append(' ').append(child.getFileName(true)).append('\n'); } } diff --git a/src/main/java/info/textgrid/services/aggregator/zip/ZipResult.java b/src/main/java/info/textgrid/services/aggregator/zip/ZipResult.java new file mode 100644 index 0000000..c42dcba --- /dev/null +++ b/src/main/java/info/textgrid/services/aggregator/zip/ZipResult.java @@ -0,0 +1,78 @@ +package info.textgrid.services.aggregator.zip; + +import info.textgrid.namespaces.metadata.core._2010.ObjectType; +import info.textgrid.services.aggregator.ITextGridRep; +import info.textgrid.services.aggregator.tree.Aggregation; +import info.textgrid.services.aggregator.tree.AggregationEntry; +import info.textgrid.services.aggregator.tree.AggregationTreeFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.MessageFormat; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.StreamingOutput; +import javax.xml.bind.JAXB; + +import com.google.common.base.Throwables; +import com.google.common.io.ByteStreams; + +public class ZipResult implements StreamingOutput { + + private final ObjectType rootMetadata; + private final ITextGridRep repository; + private final String sid; + + public ZipResult(ObjectType rootObject, ITextGridRep repository, String sid) { + this.rootMetadata = rootObject; + this.repository = repository; + this.sid = sid; + } + + @Override + public void write(OutputStream output) throws IOException, + WebApplicationException { + ZipOutputStream zip = new ZipOutputStream(output); + zip.setComment(MessageFormat.format("# Exported from TextGrid -- www.textgrid.de\nRoot aggregation: {0}", rootMetadata.getGeneric().getGenerated().getTextgridUri().getValue())); + + Aggregation root = AggregationTreeFactory.create(rootMetadata, repository, sid); + writeAggregation(zip, root); + zip.close(); + } + + private void writeAggregation(ZipOutputStream zip, Aggregation root) throws IOException { + writeFile(zip, root); + zip.putNextEntry(new ZipEntry(root.getFileName(false).concat("/"))); + zip.closeEntry(); + + for (AggregationEntry child : root.getChildren()) { + if (child instanceof Aggregation) + writeAggregation(zip, (Aggregation) child); + else + writeFile(zip, child); + } + } + + private void writeFile(ZipOutputStream zip, AggregationEntry aggregationEntry) throws IOException { + writeMetadata(zip, aggregationEntry); + zip.putNextEntry(new ZipEntry(aggregationEntry.getFileName(true))); + try { + InputStream content = repository.getContent(aggregationEntry.getTextGridURI(), sid); + ByteStreams.copy(content, zip); + zip.closeEntry(); + } catch (Exception e) { + Throwables.propagateIfPossible(e, IOException.class); + throw new WebApplicationException(e); + } + } + + private void writeMetadata(ZipOutputStream zip, AggregationEntry aggregationEntry) throws IOException { + zip.putNextEntry(new ZipEntry(aggregationEntry.getFileName(true).concat(".meta"))); + JAXB.marshal(aggregationEntry.getMetadata(), zip); + zip.closeEntry(); + } + +} -- GitLab