Skip to content
Snippets Groups Projects
Commit 60aa99d0 authored by Thorsten Vitt's avatar Thorsten Vitt
Browse files

Added rewriting support to the ZIP export

parent 8e39faea
No related branches found
No related tags found
No related merge requests found
......@@ -8,7 +8,6 @@
import java.util.logging.Logger;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
/**
* Represents an entry in an aggregation.
......@@ -59,11 +58,22 @@ protected String getSimpleFileName(final boolean withExtension) {
.getValue()).getSchemeSpecificPart();
if (withExtension)
return FileExtensionMap.getInstance().addExtension(baseName,
getMetadata().getGeneric().getProvided().getFormat());
getFormat());
else
return baseName;
}
public String getFormat() {
return getMetadata().getGeneric().getProvided().getFormat();
}
public Optional<URI> getBase() {
if (getParent().isPresent()) {
return Optional.of(URI.create(getParent().get().getFileName(false).concat("/")));
} else
return Optional.absent();
}
/**
* Returns a {@link File} representing the abstract file name for this
* aggregation entry from the root of the aggregation tree.
......@@ -88,7 +98,7 @@ protected File getFile(final boolean withExtension) {
* @param withExtension TODO
*/
public String getFileName(boolean withExtension) {
return baseURI.relativize(getFile(true).toURI()).toString();
return baseURI.relativize(getFile(withExtension).toURI()).toString();
}
@Override
......
package info.textgrid.services.aggregator.zip;
import info.textgrid._import.ImportObject;
import info.textgrid._import.RewriteMethod;
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 info.textgrid.utils.linkrewriter.ConfigurableXMLRewriter;
import info.textgrid.utils.linkrewriter.ImportMapping;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
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 javax.xml.stream.XMLStreamException;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteStreams;
import com.google.common.io.FileBackedOutputStream;
public class ZipResult implements StreamingOutput {
private final ObjectType rootMetadata;
private final ITextGridRep repository;
private final String sid;
private ImportMapping mapping;
private final static Logger logger = Logger.getLogger(ZipResult.class.getCanonicalName());
public ZipResult(ObjectType rootObject, ITextGridRep repository, String sid) {
this.rootMetadata = rootObject;
......@@ -39,9 +52,60 @@ public void write(OutputStream output) throws IOException,
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);
mapping = new ImportMapping();
addToMapping(mapping, root);
writeAggregation(zip, root);
// now serializing the mapping
zip.putNextEntry(new ZipEntry(".INDEX.imex"));
JAXB.marshal(mapping.toImportSpec(), zip);
zip.closeEntry();
zip.close();
}
// FIXME refactor -> Rewrite library
private static ImmutableMap<String, String> REWRITE_CONFIGS = null;
private static Optional<String> getRewriteConfig(final String contentType) {
if (REWRITE_CONFIGS == null) {
REWRITE_CONFIGS = ImmutableMap.<String, String>builder()
.put("text/tg.aggregation+xml", "internal:textgrid#aggregation")
.put("text/tg.edition+tg.aggregation+xml", "internal:textgrid#aggregation")
.put("text/tg.collection+tg.aggregation+xml", "internal:textgrid#aggregation")
.put("text/xsd+xml", "internal:schema#xsd")
.put("text/linkeditorlinkedfile", "internal:tei#tei")
.put("text/xml", "internal:tei#tei")
.put("application/xhtml+xml", "internal:html#html")
.build();
}
return Optional.fromNullable(REWRITE_CONFIGS.get(contentType));
}
/**
* Recursively adds the entry to the mapping.
* @param mapping
* @param entry
*/
private void addToMapping(ImportMapping mapping, AggregationEntry entry) {
Optional<String> rewriteConfig = getRewriteConfig(entry.getFormat());
ImportObject importObject = new ImportObject();
importObject.setTextgridUri(entry.getTextGridURI().toString());
importObject.setLocalData(entry.getFileName(true));
importObject.setLocalMetadata(entry.getFileName(true).concat(".meta"));
if (rewriteConfig.isPresent()) {
importObject.setRewriteMethod(RewriteMethod.XML);
importObject.setRewriteConfig(rewriteConfig.get());
} else {
importObject.setRewriteMethod(RewriteMethod.NONE);
}
mapping.add(importObject);
if (entry instanceof Aggregation) {
Aggregation aggregation = (Aggregation) entry;
for (AggregationEntry child : aggregation.getChildren()) {
addToMapping(mapping, child);
}
}
}
private void writeAggregation(ZipOutputStream zip, Aggregation root) throws IOException {
writeFile(zip, root);
......@@ -58,10 +122,34 @@ private void writeAggregation(ZipOutputStream zip, Aggregation root) throws IOEx
private void writeFile(ZipOutputStream zip, AggregationEntry aggregationEntry) throws IOException {
writeMetadata(zip, aggregationEntry);
zip.putNextEntry(new ZipEntry(aggregationEntry.getFileName(true)));
ZipEntry zipEntry = new ZipEntry(aggregationEntry.getFileName(true));
ImportObject importObject = mapping.getImportObjectForTextGridURI(aggregationEntry.getTextGridURI().toString());
try {
InputStream content = repository.getContent(aggregationEntry.getTextGridURI(), sid);
ByteStreams.copy(content, zip);
if (importObject.getRewriteMethod().equals(RewriteMethod.XML)) {
ConfigurableXMLRewriter rewriter = new ConfigurableXMLRewriter(mapping, true);
rewriter.configure(URI.create(importObject.getRewriteConfig()));
if (aggregationEntry.getBase().isPresent())
rewriter.setBase(aggregationEntry.getBase().get());
FileBackedOutputStream buffer = new FileBackedOutputStream(1024 * 1024);
try {
rewriter.rewrite(content, buffer);
zip.putNextEntry(zipEntry);
ByteStreams.copy(buffer.getSupplier(), zip);
} catch (XMLStreamException e) {
String errorMsg = MessageFormat.format("Failed to rewrite {0} (error: {1}). Exported with verbatim links instead.", aggregationEntry, e.getMessage());
logger.log(Level.WARNING, errorMsg, e);
zipEntry.setComment(errorMsg);
importObject.setRewriteMethod(RewriteMethod.NONE);
zip.putNextEntry(zipEntry);
ByteStreams.copy(buffer.getSupplier(), zip);
}
}
else {
zip.putNextEntry(zipEntry);
ByteStreams.copy(content, zip);
}
zip.closeEntry();
} catch (Exception e) {
Throwables.propagateIfPossible(e, IOException.class);
......@@ -71,7 +159,18 @@ private void writeFile(ZipOutputStream zip, AggregationEntry aggregationEntry) t
private void writeMetadata(ZipOutputStream zip, AggregationEntry aggregationEntry) throws IOException {
zip.putNextEntry(new ZipEntry(aggregationEntry.getFileName(true).concat(".meta")));
JAXB.marshal(aggregationEntry.getMetadata(), zip);
ConfigurableXMLRewriter rewriter = new ConfigurableXMLRewriter(mapping, true);
rewriter.configure(URI.create("internal:textgrid#metadata"));
if (aggregationEntry.getBase().isPresent())
rewriter.setBase(aggregationEntry.getBase().get());
FileBackedOutputStream buffer = new FileBackedOutputStream(1024*1024);
JAXB.marshal(aggregationEntry.getMetadata(), buffer);
try {
rewriter.rewrite(buffer.getSupplier().getInput(), zip);
} catch (XMLStreamException e) {
logger.log(Level.SEVERE, MessageFormat.format("Error rewriting the metadata of {0}. Should not happen.", aggregationEntry), e);
}
zip.closeEntry();
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment