From 4f1ad3a46c227bd25b96123e7522d717554bd8e2 Mon Sep 17 00:00:00 2001
From: Thorsten Vitt <thorsten.vitt@uni-wuerzburg.de>
Date: Fri, 7 Sep 2012 19:56:58 +0000
Subject: [PATCH] Merge branch 'pdf', including the 'configurable repo' branch

Conflicts:
	src/main/java/info/textgrid/services/aggregator/EPUB.java
	src/test/java/info/textgrid/services/aggregator/EPUBTest.java

git-svn-id: https://develop.sub.uni-goettingen.de/repos/textgrid/trunk/services/aggregator@13522 7c539038-3410-0410-b1ec-0f2a7bf1c452
---
 pom.xml                                       |   2 +-
 .../textgrid/services/aggregator/EPUB.java    |   5 +-
 .../services/aggregator/EPUB.java.orig        | 168 ++++++++++++++++++
 .../services/aggregator/ITextGridRep.java     |  15 +-
 .../textgrid/services/aggregator/PDF.java     | 156 ++++++++++++++++
 .../services/aggregator/RESTUtils.java        |   4 +-
 .../services/aggregator/TEICorpus.java        |   7 +-
 .../aggregator/TextGridRepProvider.java       |  55 +++++-
 src/main/webapp/WEB-INF/beans.xml             |  39 +++-
 .../services/aggregator/EPUBTest.java         |   2 +-
 .../services/aggregator/EPUBTest.java.orig    |  22 +++
 .../services/aggregator/TEICorpusTest.java    |  16 +-
 .../textgrid/services/aggregator/TestPDF.java |  17 ++
 13 files changed, 487 insertions(+), 21 deletions(-)
 create mode 100644 src/main/java/info/textgrid/services/aggregator/EPUB.java.orig
 create mode 100644 src/main/java/info/textgrid/services/aggregator/PDF.java
 create mode 100644 src/test/java/info/textgrid/services/aggregator/EPUBTest.java.orig
 create mode 100644 src/test/java/info/textgrid/services/aggregator/TestPDF.java

diff --git a/pom.xml b/pom.xml
index b927ddb..6a8d623 100644
--- a/pom.xml
+++ b/pom.xml
@@ -157,7 +157,7 @@
 							<configuration>
 								<port>13000</port>
 								<path>/aggregator</path>
-								<useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader>
+								<useSeparateTomcatClassLoader>false</useSeparateTomcatClassLoader>
 							</configuration>
 						</execution>
 					</executions>
diff --git a/src/main/java/info/textgrid/services/aggregator/EPUB.java b/src/main/java/info/textgrid/services/aggregator/EPUB.java
index 5c5a01d..f2290f7 100644
--- a/src/main/java/info/textgrid/services/aggregator/EPUB.java
+++ b/src/main/java/info/textgrid/services/aggregator/EPUB.java
@@ -41,7 +41,7 @@
 public class EPUB {
 	private static final String TEI_TO_EPUB_XSL = "/usr/share/xml/tei/stylesheet/epub/tei-to-epub.xsl";
 
-	private final ITextGridRep repository = TextGridRepProvider.getInstance();
+	private ITextGridRep repository = TextGridRepProvider.getInstance();
 
 	final Logger logger = Logger.getLogger("info.textgrid.services.aggregator.EPUB");
 
@@ -49,7 +49,8 @@ public class EPUB {
 
 	private final Processor xsltProcessor;
 
-	public EPUB() {
+	public EPUB(final ITextGridRep repository) {
+		this.repository = repository;
 		xsltProcessor = new Processor(false);
 		final XsltCompiler xsltCompiler = xsltProcessor.newXsltCompiler();
 		try {
diff --git a/src/main/java/info/textgrid/services/aggregator/EPUB.java.orig b/src/main/java/info/textgrid/services/aggregator/EPUB.java.orig
new file mode 100644
index 0000000..cefacda
--- /dev/null
+++ b/src/main/java/info/textgrid/services/aggregator/EPUB.java.orig
@@ -0,0 +1,168 @@
+package info.textgrid.services.aggregator;
+
+import info.textgrid.namespaces.metadata.core._2010.MetadataContainerType;
+import info.textgrid.namespaces.metadata.core._2010.ObjectType;
+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.namespaces.middleware.tgcrud.services.tgcrudservice.TGCrudService;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.text.MessageFormat;
+import java.util.logging.Logger;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+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.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.xml.transform.stream.StreamSource;
+
+import net.sf.saxon.s9api.Processor;
+import net.sf.saxon.s9api.SaxonApiException;
+import net.sf.saxon.s9api.XsltCompiler;
+import net.sf.saxon.s9api.XsltExecutable;
+import net.sf.saxon.s9api.XsltTransformer;
+
+import com.google.common.io.Files;
+import com.google.common.io.InputSupplier;
+
+@Path("/epub")
+public class EPUB {
+<<<<<<< HEAD
+	private static final String TEI_TO_EPUB_XSL = "/usr/share/xml/tei/stylesheet/epub/tei-to-epub.xsl";
+
+	private final ITextGridRep repository = TextGridRepProvider.getInstance();
+=======
+	private final ITextGridRep repository;
+>>>>>>> pdf
+
+	final Logger logger = Logger.getLogger("info.textgrid.services.aggregator.EPUB");
+
+	private XsltExecutable teiToEpub;
+
+	private final Processor xsltProcessor;
+
+	public EPUB(final ITextGridRep repository) {
+		this.repository = repository;
+		xsltProcessor = new Processor(false);
+		final XsltCompiler xsltCompiler = xsltProcessor.newXsltCompiler();
+		try {
+			teiToEpub = xsltCompiler.compile(new StreamSource(TEI_TO_EPUB_XSL));
+		} catch (final SaxonApiException e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	@GET
+	@Path(value = "/{object}")
+	@Produces(value = "application/epub+zip")
+	public Response get(@PathParam("object") final URI uri,
+			@QueryParam("stylesheet") final URI xsluri) {
+		logger.fine("EPUB called for root object: " + uri);
+		final TGCrudService crud = repository.getCRUDService();
+		try {
+			final MetadataContainerType container = crud.readMetadata(null,
+					null, uri.toString());
+			final ObjectType rootObject = container.getObject();
+			final String mimeType = rootObject.getGeneric().getProvided()
+					.getFormat();
+			final boolean aggregation = mimeType.contains("aggregation");
+			if (!aggregation && !mimeType.matches("^text/.*xml.*")) {
+				final String errorMsg = "The EPUB export can only convert aggregations or XML documents to EPUB, however, the document {0} you referred to has the MIME type {1}.";
+				logger.warning("Failing with: " + errorMsg);
+				return Response.status(Status.UNSUPPORTED_MEDIA_TYPE)
+						.entity(MessageFormat.format(errorMsg, uri, mimeType))
+						.type("text/plain").build();
+			}
+
+			final File workingDir = Files.createTempDir();
+			logger.fine("Using " + workingDir + " to build the E-Book");
+
+			final File corpus = new File(workingDir, "corpus.xml");
+			if (aggregation) {
+				// First, use the aggregator to create a TEI corpus file to build on
+				final TEICorpusSerializer corpusSerializer = new TEICorpusSerializer(
+						rootObject, true);
+				final FileOutputStream corpusOutput = new FileOutputStream(corpus);
+				corpusSerializer.write(corpusOutput);
+				corpusOutput.close();
+			} else {
+				final InputStream tei = repository.getContent(uri);
+				Files.copy(new InputSupplier<InputStream>() {
+
+					@Override
+					public InputStream getInput() throws IOException {
+						return tei;
+					}
+				}, corpus);
+			}
+
+			// Now, run the EPUB stylesheet
+			// TODO cache the saxon stuff
+			final XsltTransformer transformer;
+			if (xsluri == null)
+				transformer = teiToEpub.load();
+			else {
+				logger.info("Loading stylesheet from " + xsluri);
+				final StreamSource xsltSource = new StreamSource(xsluri.toURL().openStream());
+				final XsltExecutable xsltExecutable = xsltProcessor.newXsltCompiler().compile(xsltSource);
+				transformer = xsltExecutable.load();
+			}
+			transformer.setDestination(xsltProcessor.newSerializer(new File(
+					workingDir, "output.xml")));
+			transformer.setSource(new StreamSource(corpus));
+			transformer.transform();
+
+			return RESTUtils
+					.attachmentResponse(
+							rootObject.getGeneric().getProvided().getTitle()
+							.get(0)
+							+ ".epub").type("application/epub+zip")
+							.entity(new EPUBSerializer(workingDir, repository, corpus)).build();
+
+			// return Response.ok().type("text/plain").entity("Done, see " +
+			// workingDir).build();
+		} 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();
+		} catch (final FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final WebApplicationException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final SaxonApiException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (final ProtocolNotImplementedFault e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return Response.noContent().build();
+
+	}
+
+}
diff --git a/src/main/java/info/textgrid/services/aggregator/ITextGridRep.java b/src/main/java/info/textgrid/services/aggregator/ITextGridRep.java
index 6916746..1dd50e6 100644
--- a/src/main/java/info/textgrid/services/aggregator/ITextGridRep.java
+++ b/src/main/java/info/textgrid/services/aggregator/ITextGridRep.java
@@ -1,6 +1,7 @@
 package info.textgrid.services.aggregator;
 
 import info.textgrid.middleware.tgsearch.client.SearchClient;
+import info.textgrid.namespaces.metadata.core._2010.ObjectType;
 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;
@@ -14,6 +15,8 @@
 
 import javax.ws.rs.WebApplicationException;
 
+import com.google.common.io.InputSupplier;
+
 public interface ITextGridRep {
 
 	public SearchClient getPublicSearchClient();
@@ -22,8 +25,18 @@ public interface ITextGridRep {
 
 	public String getConfValue(final String key) throws WebApplicationException;
 
-	public abstract InputStream getContent(final URI uri)
+	public abstract InputStream getContent(final URI uri, String sid)
 			throws ObjectNotFoundFault, MetadataParseFault, IoFault,
 			ProtocolNotImplementedFault, AuthFault, IOException;
 
+	public InputStream getContent(final URI uri) throws ObjectNotFoundFault, MetadataParseFault, IoFault, ProtocolNotImplementedFault, AuthFault, IOException;
+
+	public abstract TGOSupplier<InputStream> read(final URI uri, final String sid)
+			throws WebApplicationException;
+
+	public interface TGOSupplier<T> extends InputSupplier<T> {
+		public ObjectType getMetadata();
+	}
+
+
 }
\ No newline at end of file
diff --git a/src/main/java/info/textgrid/services/aggregator/PDF.java b/src/main/java/info/textgrid/services/aggregator/PDF.java
new file mode 100644
index 0000000..d44c616
--- /dev/null
+++ b/src/main/java/info/textgrid/services/aggregator/PDF.java
@@ -0,0 +1,156 @@
+package info.textgrid.services.aggregator;
+
+import info.textgrid._import.RewriteMethod;
+import info.textgrid.services.aggregator.ITextGridRep.TGOSupplier;
+import info.textgrid.utils.linkrewriter.ConfigurableXMLRewriter;
+import info.textgrid.utils.linkrewriter.ImportMapping;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+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.Response;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.stream.StreamSource;
+
+import net.sf.saxon.s9api.Processor;
+import net.sf.saxon.s9api.SaxonApiException;
+import net.sf.saxon.s9api.XsltCompiler;
+import net.sf.saxon.s9api.XsltExecutable;
+import net.sf.saxon.s9api.XsltTransformer;
+
+import org.apache.commons.io.FileUtils;
+
+import com.google.common.io.FileBackedOutputStream;
+import com.google.common.io.Files;
+
+@Path("/pdf")
+public class PDF {
+
+	final Logger logger = Logger.getLogger("info.textgrid.services.aggregator");
+	private XsltExecutable teiToLatex;
+	private final Processor xsltProcessor;
+	private final ITextGridRep repository;
+
+	public PDF(final ITextGridRep repository) {
+		this.repository = repository;
+		xsltProcessor = new Processor(false);
+		final XsltCompiler xsltCompiler = xsltProcessor.newXsltCompiler();
+		try {
+			teiToLatex = xsltCompiler.compile(new StreamSource(
+					"/usr/share/xml/tei/stylesheet/latex2/tei.xsl"));
+		} catch (final SaxonApiException e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	@GET
+	@Path("/{uri}")
+	@Produces("application/pdf")
+	public Response get(@PathParam("uri") final URI uri,
+			@QueryParam("sid") final String sid) {
+		final File workingDir = Files.createTempDir();
+		try {
+
+			// First step: Rewrite with a non-initalized mapping to a temporary
+			// buffer
+			// to collect the undefined references
+			final ImportMapping mapping = new ImportMapping();
+			final ConfigurableXMLRewriter rewriter = new ConfigurableXMLRewriter(
+					mapping, true);
+			rewriter.configure(URI.create("internal:tei#tei"));
+			rewriter.recordMissingReferences();
+			final FileBackedOutputStream buffer = new FileBackedOutputStream(
+					1024 * 1024);
+			final TGOSupplier<InputStream> textSupplier = repository.read(uri, sid);
+			rewriter.rewrite(textSupplier.getInput(), buffer);
+
+			// now download the missing references if applicable, add
+			// them to the mapping
+			final Set<String> linkedURIs = rewriter.getMissingReferences();
+			for (final String missingReference : linkedURIs) {
+				final URI missingURI = URI.create(missingReference);
+				if (missingURI.isAbsolute()
+						&& (missingURI.getScheme().equals("textgrid") || missingURI
+								.getScheme().equals("hdl"))
+								&& mapping
+								.getImportObjectForTextGridURI(missingReference) == null) {
+					final TGOSupplier<InputStream> supplier = repository.read(
+							missingURI, sid);
+					final String format = supplier.getMetadata().getGeneric()
+							.getProvided().getFormat();
+					String fileName = null;
+					if (format.equals("image/jpeg"))
+						fileName = missingURI.getSchemeSpecificPart()
+						.replace('.', '-').concat(".jpg");
+					else if (format.equals("image/png"))
+						fileName = missingURI.getSchemeSpecificPart()
+						.replace('.', '-').concat(".png");
+					else if (format.equals("image/tiff"))
+						fileName = missingURI.getSchemeSpecificPart()
+						.replace('.', '-').concat(".tif");
+					else if (format.equals("application/pdf"))
+						fileName = missingURI.getSchemeSpecificPart()
+						.replace('.', '-').concat(".pdf");
+					if (fileName != null) {
+						mapping.add(missingReference, fileName, null,
+								RewriteMethod.NONE);
+						Files.copy(supplier, new File(workingDir, fileName));
+					}
+				}
+			}
+
+			// finally, rewrite again, this time using the mapping
+			final File teiFile = new File(workingDir, "data.xml");
+			final FileOutputStream teiStream = new FileOutputStream(teiFile);
+			rewriter.rewrite(buffer.getSupplier().getInput(), teiStream);
+			teiStream.close();
+			buffer.close();
+
+			// now generate the TeX
+			final XsltTransformer transformer = teiToLatex.load();
+			final File tex = new File(workingDir, "data.tex");
+			transformer.setDestination(xsltProcessor.newSerializer(tex));
+			transformer.setSource(new StreamSource(teiFile));
+			transformer.transform();
+
+			final Process latexProcess = Runtime
+					.getRuntime()
+					.exec("pdflatex -no-shell-escape -interaction nonstopmode data.tex",
+							null, workingDir);
+			latexProcess.waitFor();
+
+			final Response response = RESTUtils
+					.attachmentResponse(
+							textSupplier.getMetadata().getGeneric()
+							.getProvided().getTitle().get(0)
+							.concat(".pdf"))
+							.type("application/pdf")
+							.entity(new FileInputStream(
+									new File(workingDir, "data.pdf"))).build();
+			FileUtils.deleteDirectory(workingDir);
+			return response;
+
+		} catch (final IOException e) {
+			throw new WebApplicationException(e);
+		} catch (final SaxonApiException e1) {
+			throw new WebApplicationException(e1);
+		} catch (final InterruptedException e1) {
+			throw new WebApplicationException(e1);
+		} catch (final XMLStreamException e1) {
+			throw new WebApplicationException(e1);
+		}
+	}
+
+}
diff --git a/src/main/java/info/textgrid/services/aggregator/RESTUtils.java b/src/main/java/info/textgrid/services/aggregator/RESTUtils.java
index d13be5d..d820c1a 100644
--- a/src/main/java/info/textgrid/services/aggregator/RESTUtils.java
+++ b/src/main/java/info/textgrid/services/aggregator/RESTUtils.java
@@ -9,8 +9,8 @@ public class RESTUtils {
 	public static ResponseBuilder addAttachmentFilename(final ResponseBuilder builder, final String fileName) {
 		final String asciiFileName = fileName.replaceAll("[^A-Za-z0-9.-]", "_");
 		final String extendedNameSpec = "UTF-8''" + UriBuilder.fromPath(fileName).build().toASCIIString();
-		builder.header("Content-Disposition", "attachment; filename*=\"" + extendedNameSpec + "\" ");
-		builder.header("Content-Disposition", " filename=\"" + asciiFileName + "\" " );
+		builder.header("Content-Disposition", "attachment; filename*=\"" + extendedNameSpec + "\"; " +
+				/*		builder.header("Content-Disposition", */ " filename=\"" + asciiFileName + "\" " );
 		return builder;
 	}
 
diff --git a/src/main/java/info/textgrid/services/aggregator/TEICorpus.java b/src/main/java/info/textgrid/services/aggregator/TEICorpus.java
index 61101bd..977e21c 100644
--- a/src/main/java/info/textgrid/services/aggregator/TEICorpus.java
+++ b/src/main/java/info/textgrid/services/aggregator/TEICorpus.java
@@ -51,10 +51,15 @@
 @Path("/teicorpus")
 public class TEICorpus {
 
-	private final ITextGridRep repository = TextGridRepProvider.getInstance();
+	private final ITextGridRep repository;
 
 	final Logger logger = Logger.getLogger("info.textgrid.services.aggregator");
 
+	public TEICorpus(final ITextGridRep repository) {
+		this.repository = repository;
+	}
+
+
 	@GET
 	@Path(value="/{aggregation}")
 	@Produces("text/xml")
diff --git a/src/main/java/info/textgrid/services/aggregator/TextGridRepProvider.java b/src/main/java/info/textgrid/services/aggregator/TextGridRepProvider.java
index 2dd81aa..2740804 100644
--- a/src/main/java/info/textgrid/services/aggregator/TextGridRepProvider.java
+++ b/src/main/java/info/textgrid/services/aggregator/TextGridRepProvider.java
@@ -4,6 +4,7 @@
 import info.textgrid.middleware.confclient.ConfservClientConstants;
 import info.textgrid.middleware.tgsearch.client.SearchClient;
 import info.textgrid.namespaces.metadata.core._2010.MetadataContainerType;
+import info.textgrid.namespaces.metadata.core._2010.ObjectType;
 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;
@@ -21,6 +22,7 @@
 
 import javax.activation.DataHandler;
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response.Status;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.ws.BindingProvider;
 import javax.xml.ws.Holder;
@@ -34,7 +36,15 @@ public class TextGridRepProvider implements ITextGridRep {
 	private ConfservClient confservClient;
 	private TGCrudService crud;
 	private SearchClient publicSearchClient;
-	private static final String CONF_ENDPOINT = "https://www.textgridlab.org/1.0/confserv";
+	private String CONF_ENDPOINT = "https://www.textgridlab.org/1.0/confserv";
+	public String getCONF_ENDPOINT() {
+		return CONF_ENDPOINT;
+	}
+
+	public void setCONF_ENDPOINT(final String cONF_ENDPOINT) {
+		CONF_ENDPOINT = cONF_ENDPOINT;
+	}
+
 	private static final ITextGridRep instance = new TextGridRepProvider();
 
 	@Override
@@ -68,14 +78,53 @@ public TGCrudService getCRUDService() {
 	}
 
 	@Override
-	public InputStream getContent(final URI uri) throws ObjectNotFoundFault, MetadataParseFault, IoFault, ProtocolNotImplementedFault, AuthFault, IOException {
+	public InputStream getContent(final URI uri, final String sid) throws ObjectNotFoundFault, MetadataParseFault, IoFault, ProtocolNotImplementedFault, AuthFault, IOException {
 		final TGCrudService crudService = getCRUDService();
 		final Holder<MetadataContainerType> mdHolder = new Holder<MetadataContainerType>();
 		final Holder<DataHandler> dHolder = new Holder<DataHandler>();
-		crudService.read(null, null, uri.toString(), mdHolder, dHolder);
+		crudService.read(sid, null, uri.toString(), mdHolder, dHolder);
 		return dHolder.value.getInputStream();
 	}
 
+	@Override
+	public TGOSupplier<InputStream> read(final URI uri, final String sid) throws WebApplicationException {
+		final TGCrudService crudService = getCRUDService();
+		final Holder<MetadataContainerType> mdHolder = new Holder<MetadataContainerType>();
+		final Holder<DataHandler> dHolder = new Holder<DataHandler>();
+		try {
+			crudService.read(sid, null, uri.toString(), mdHolder, dHolder);
+
+
+			return new TGOSupplier<InputStream>() {
+
+				@Override
+				public InputStream getInput() throws IOException {
+					return dHolder.value.getInputStream();
+				}
+
+				@Override
+				public ObjectType getMetadata() {
+					return mdHolder.value.getObject();
+				}
+			};
+		} catch (final ObjectNotFoundFault e) {
+			throw new WebApplicationException(e, Status.NOT_FOUND);
+		} catch (final MetadataParseFault e) {
+			throw new WebApplicationException(e);
+		} catch (final IoFault e) {
+			throw new WebApplicationException(e);
+		} catch (final ProtocolNotImplementedFault e) {
+			throw new WebApplicationException(e, Status.BAD_REQUEST);
+		} catch (final AuthFault e) {
+			throw new WebApplicationException(e, Status.FORBIDDEN);
+		}
+	}
+
+	@Override
+	public InputStream getContent(final URI uri) throws ObjectNotFoundFault, MetadataParseFault, IoFault, ProtocolNotImplementedFault, AuthFault, IOException {
+		return getContent(uri, null);
+	}
+
 	@Override
 	public SearchClient getPublicSearchClient() {
 		if (publicSearchClient == null)
diff --git a/src/main/webapp/WEB-INF/beans.xml b/src/main/webapp/WEB-INF/beans.xml
index 32ba3b5..75eedd9 100644
--- a/src/main/webapp/WEB-INF/beans.xml
+++ b/src/main/webapp/WEB-INF/beans.xml
@@ -17,13 +17,27 @@ http://cxf.apache.org/schemas/jaxrs.xsd">
   <context:annotation-config/>
   <bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"/>
   <bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"/>
+  
+  <bean id="stable-repo" class="info.textgrid.services.aggregator.TextGridRepProvider">
+  	<property name="CONF_ENDPOINT" value="https://www.textgridlab.org/1.0/confserv"/>
+  </bean>
+  <bean id="dev-repo" class="info.textgrid.services.aggregator.TextGridRepProvider">
+  	<property name="CONF_ENDPOINT" value="https://www.textgridlab.org/dev/confserv"/>
+  </bean>
 
 
    <jaxrs:server id="services" address="/">
     <jaxrs:serviceBeans>
       <!-- bean class="info.textgrid.services.aggregator.HelloWorld" /-->
-      <bean class="info.textgrid.services.aggregator.TEICorpus" scope="singleton" />
-      <bean class="info.textgrid.services.aggregator.EPUB" scope="singleton" />
+      <bean class="info.textgrid.services.aggregator.TEICorpus" scope="singleton">
+      	<constructor-arg ref="stable-repo"/>
+      </bean>
+      <bean class="info.textgrid.services.aggregator.EPUB" scope="singleton">
+      	<constructor-arg ref="stable-repo"/>
+      </bean>
+      <bean class="info.textgrid.services.aggregator.PDF" scope="singleton">
+      	<constructor-arg ref="stable-repo"/>
+      </bean>
     </jaxrs:serviceBeans>
     <jaxrs:providers>
         <!-- bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/-->
@@ -31,5 +45,26 @@ http://cxf.apache.org/schemas/jaxrs.xsd">
     </jaxrs:providers>
     
     </jaxrs:server>
+    
+    <jaxrs:server id="services-dev" address="/dev">
+	<jaxrs:serviceBeans>
+		<!-- bean class="info.textgrid.services.aggregator.HelloWorld" / -->
+		<bean class="info.textgrid.services.aggregator.TEICorpus" scope="singleton">
+			<constructor-arg ref="dev-repo" />
+		</bean>
+		<bean class="info.textgrid.services.aggregator.EPUB" scope="singleton">
+			<constructor-arg ref="dev-repo" />
+		</bean>
+		<bean class="info.textgrid.services.aggregator.PDF" scope="singleton">
+			<constructor-arg ref="dev-repo" />
+		</bean>
+	</jaxrs:serviceBeans>
+	<jaxrs:providers>
+		<!-- bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/ -->
+		<bean class="org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper" />
+	</jaxrs:providers>
+
+</jaxrs:server>
+    
 
 </beans>
diff --git a/src/test/java/info/textgrid/services/aggregator/EPUBTest.java b/src/test/java/info/textgrid/services/aggregator/EPUBTest.java
index be21305..05aae13 100644
--- a/src/test/java/info/textgrid/services/aggregator/EPUBTest.java
+++ b/src/test/java/info/textgrid/services/aggregator/EPUBTest.java
@@ -10,7 +10,7 @@ public class EPUBTest {
 
 	@Test
 	public void testGet() {
-		final EPUB epub = new EPUB();
+		final EPUB epub = new EPUB(TextGridRepProvider.getInstance());
 		final Response response = epub.get(URI.create("textgrid:jfst.0"), null);
 	}
 
diff --git a/src/test/java/info/textgrid/services/aggregator/EPUBTest.java.orig b/src/test/java/info/textgrid/services/aggregator/EPUBTest.java.orig
new file mode 100644
index 0000000..6175be4
--- /dev/null
+++ b/src/test/java/info/textgrid/services/aggregator/EPUBTest.java.orig
@@ -0,0 +1,22 @@
+package info.textgrid.services.aggregator;
+
+import java.net.URI;
+
+import javax.ws.rs.core.Response;
+
+import org.junit.Test;
+
+public class EPUBTest {
+
+	@Test
+	public void testGet() {
+<<<<<<< HEAD
+		final EPUB epub = new EPUB();
+		final Response response = epub.get(URI.create("textgrid:jfst.0"), null);
+=======
+		final EPUB epub = new EPUB(TextGridRepProvider.getInstance());
+		final Response response = epub.get(URI.create("textgrid:jfst.0"));
+>>>>>>> pdf
+	}
+
+}
diff --git a/src/test/java/info/textgrid/services/aggregator/TEICorpusTest.java b/src/test/java/info/textgrid/services/aggregator/TEICorpusTest.java
index 3830a20..233194f 100644
--- a/src/test/java/info/textgrid/services/aggregator/TEICorpusTest.java
+++ b/src/test/java/info/textgrid/services/aggregator/TEICorpusTest.java
@@ -22,27 +22,27 @@ public class TEICorpusTest {
 
 	@Before
 	public void setUp() throws Exception {
-		teiCorpus = new TEICorpus();
+		teiCorpus = new TEICorpus(TextGridRepProvider.getInstance());
 	}
 
 	@Test(expected = WebApplicationException.class)
 	public void testGet404() throws URISyntaxException {
-		Response response = teiCorpus.get(URI.create("textgrid:doesnotexist"),
+		final Response response = teiCorpus.get(URI.create("textgrid:doesnotexist"),
 				true, false);
 		Assert.assertEquals(404, response.getStatus());
 	}
 
 	@Test
 	public void testGet() throws URISyntaxException, WebApplicationException,
-			IOException {
-		Response response = teiCorpus.get(URI.create("textgrid:jmzg.0"), true,
+	IOException {
+		final Response response = teiCorpus.get(URI.create("textgrid:jmzg.0"), true,
 				false);
-		Object entity = response.getEntity();
-		ByteArrayOutputStream output = new ByteArrayOutputStream();
+		final Object entity = response.getEntity();
+		final ByteArrayOutputStream output = new ByteArrayOutputStream();
 		((StreamingOutput) entity).write(output);
-		InputStream inputStream = getClass().getClassLoader()
+		final InputStream inputStream = getClass().getClassLoader()
 				.getResourceAsStream("gedichte-anakreons-corpus.xml");
-		String expected = IOUtils.toString(inputStream, "UTF-8");
+		final String expected = IOUtils.toString(inputStream, "UTF-8");
 		Assert.assertEquals(expected, output.toString("UTF-8"));
 	}
 
diff --git a/src/test/java/info/textgrid/services/aggregator/TestPDF.java b/src/test/java/info/textgrid/services/aggregator/TestPDF.java
new file mode 100644
index 0000000..7e2bb58
--- /dev/null
+++ b/src/test/java/info/textgrid/services/aggregator/TestPDF.java
@@ -0,0 +1,17 @@
+package info.textgrid.services.aggregator;
+
+import java.net.URI;
+
+import javax.ws.rs.core.Response;
+
+import org.junit.Test;
+
+public class TestPDF {
+
+	@Test
+	public void testGet() {
+		final PDF pdf = new PDF(TextGridRepProvider.getInstance());
+		final Response response = pdf.get(URI.create("textgrid:h4jw.0"), "OeXTtXQpyAmzAWbcIYNV9kn27Dj8lk78KZUF1MGXYsULozHkMEPJsQcLYGZ9jQ91346833336381705");
+	}
+
+}
-- 
GitLab