java.fedora.server.access.DescribeRepositoryServlet Maven / Gradle / Ivy
/*
* -----------------------------------------------------------------------------
*
* License and Copyright: The contents of this file are subject to the
* Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of
* the License at
* http://www.fedora-commons.org/licenses.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The entire file consists of original code.
* Copyright © 2008 Fedora Commons, Inc.
*
Copyright © 2002-2007 The Rector and Visitors of the University of
* Virginia and Cornell University
* All rights reserved.
*
* -----------------------------------------------------------------------------
*/
package fedora.server.access;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.net.URLDecoder;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.util.Enumeration;
import java.util.Properties;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import org.apache.log4j.Logger;
import fedora.common.Constants;
import fedora.server.Context;
import fedora.server.ReadOnlyContext;
import fedora.server.Server;
import fedora.server.errors.InitializationException;
import fedora.server.errors.GeneralException;
import fedora.server.errors.ServerException;
import fedora.server.errors.StreamIOException;
import fedora.server.errors.authorization.AuthzException;
import fedora.server.errors.servletExceptionExtensions.InternalError500Exception;
import fedora.server.errors.servletExceptionExtensions.RootException;
/**
*
* Title: DescribeRepositoryServlet.java
*
*
* Description: Implements the "describeRepository" functionality of the
* Fedora Access LITE (API-A-LITE) interface using a java servlet front end. The
* syntax defined by API-A-LITE has for getting a description of the repository
* has the following binding:
*
* - describeRepository URL syntax:
* protocol://hostname:port/fedora/describe[?xml=BOOLEAN] This syntax requests
* information about the repository. The xml parameter determines the type of
* output returned. If the parameter is omitted or has a value of "false", a
* MIME-typed stream consisting of an html table is returned providing a
* browser-savvy means of viewing the object profile. If the value specified is
* "true", then a MIME-typed stream consisting of XML is returned.
*
* - protocol - either http or https.
* - hostname - required hostname of the Fedora server.
* - port - required port number on which the Fedora server is running.
* - fedora - required name of the Fedora access service.
* - describe - required verb of the Fedora service.
* - xml - an optional parameter indicating the requested output format. A
* value of "true" indicates a return type of text/xml; the absence of the xml
* parameter or a value of "false" indicates format is to be text/html.
*
*
* @author [email protected]
* @version $Id: DescribeRepositoryServlet.java,v 1.27 2005/05/04 11:59:20 rlw
* Exp $
*/
public class DescribeRepositoryServlet extends HttpServlet {
/** Logger for this class. */
private static final Logger LOG = Logger.getLogger(
DescribeRepositoryServlet.class.getName());
private static final long serialVersionUID = 1L;
/** Content type for html. */
private static final String CONTENT_TYPE_HTML = "text/html; charset=UTF-8";
/** Content type for xml. */
private static final String CONTENT_TYPE_XML = "text/xml; charset=UTF-8";
/** Instance of the Fedora server. */
private static Server s_server = null;
/** Instance of the access subsystem. */
private static Access s_access = null;
/** Instance of URLDecoder */
private URLDecoder decoder = new URLDecoder();
/** HTTP protocol * */
private static String HTTP = "http";
/** HTTPS protocol * */
private static String HTTPS = "https";
/** Configured Fedora server hostname */
private static String fedoraServerHost = null;
String ACTION_LABEL = "describe repository";
/**
*
* Process Fedora Access Request. Parse and validate the servlet input
* parameters and then execute the specified request.
*
*
* @param request
* The servlet request.
* @param response
* servlet The servlet response.
* @throws ServletException
* If an error occurs that effects the servlet's basic
* operation.
* @throws IOException
* If an error occurrs with an input or output operation.
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
boolean xml = false;
LOG.debug("Got request: " + request.getRequestURL().toString()
+ "?" + request.getQueryString());
// Check for xml parameter.
for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
String name = URLDecoder.decode((String) e.nextElement(), "UTF-8");
if (name.equalsIgnoreCase("xml")) {
xml = new Boolean(request.getParameter(name)).booleanValue();
}
}
Context context = ReadOnlyContext.getContext(
Constants.HTTP_REQUEST.REST.uri, request);
try {
describeRepository(context, xml, response);
} catch (AuthzException ae) {
throw RootException.getServletException(ae, request, ACTION_LABEL,
new String[0]);
} catch (Throwable th) {
throw new InternalError500Exception("", th, request, ACTION_LABEL,
"", new String[0]);
}
}
public void describeRepository(Context context, boolean xml,
HttpServletResponse response) throws ServerException {
OutputStreamWriter out = null;
RepositoryInfo repositoryInfo = null;
PipedWriter pw = null;
PipedReader pr = null;
try {
pw = new PipedWriter();
pr = new PipedReader(pw);
repositoryInfo = s_access.describeRepository(context);
if (repositoryInfo != null) {
// Repository info obtained.
// Serialize the RepositoryInfo object into XML
new ReposInfoSerializerThread(context, repositoryInfo, pw)
.start();
if (xml) {
// Return results as raw XML
response.setContentType(CONTENT_TYPE_XML);
// Insures stream read from PipedReader correctly translates
// utf-8
// encoded characters to OutputStreamWriter.
out = new OutputStreamWriter(response.getOutputStream(),
"UTF-8");
int bufSize = 4096;
char[] buf = new char[bufSize];
int len = 0;
while ((len = pr.read(buf, 0, bufSize)) != -1) {
out.write(buf, 0, len);
}
out.flush();
} else {
// Transform results into an html table
response.setContentType(CONTENT_TYPE_HTML);
out = new OutputStreamWriter(response.getOutputStream(),
"UTF-8");
File xslFile = new File(s_server.getHomeDir(),
"access/viewRepositoryInfo.xslt");
TransformerFactory factory = TransformerFactory
.newInstance();
Templates template = factory.newTemplates(new StreamSource(
xslFile));
Transformer transformer = template.newTransformer();
Properties details = template.getOutputProperties();
transformer.transform(new StreamSource(pr),
new StreamResult(out));
}
out.flush();
} else {
// Describe request returned nothing.
LOG.error("No repository info returned");
}
} catch (AuthzException ae) {
throw ae;
} catch (Throwable th) {
String msg = "Error describing repository";
LOG.error(msg, th);
throw new GeneralException(msg, th);
} finally {
try {
if (pr != null)
pr.close();
if (out != null)
out.close();
} catch (Throwable th) {
String message = "[DescribeRepositoryServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName()
+ " \". Reason: " + th.getMessage();
throw new StreamIOException(message);
}
}
}
/**
*
* A Thread to serialize an ObjectProfile object into XML.
*
*
*/
public class ReposInfoSerializerThread extends Thread {
private PipedWriter pw = null;
private RepositoryInfo repositoryInfo = null;
private String fedoraServerProtocol = null;
private String fedoraServerPort = null;
/**
*
* Constructor for ReposInfoSerializerThread.
*
*
* @param repositoryInfo
* A repository info data structure.
* @param pw
* A PipedWriter to which the serialization info is written.
*/
public ReposInfoSerializerThread(Context context,
RepositoryInfo repositoryInfo, PipedWriter pw) {
this.pw = pw;
this.repositoryInfo = repositoryInfo;
fedoraServerPort = context
.getEnvironmentValue(Constants.HTTP_REQUEST.SERVER_PORT.uri);
if (Constants.HTTP_REQUEST.SECURE.uri.equals(context
.getEnvironmentValue(Constants.HTTP_REQUEST.SECURITY.uri))) {
fedoraServerProtocol = HTTPS;
} else if (Constants.HTTP_REQUEST.INSECURE.uri.equals(context
.getEnvironmentValue(Constants.HTTP_REQUEST.SECURITY.uri))) {
fedoraServerProtocol = HTTP;
}
}
/**
*
* This method executes the thread.
*
*/
public void run() {
if (pw != null) {
try {
pw.write("");
pw
.write("");
// REPOSITORY INFO FIELDS SERIALIZATION
pw.write("" + repositoryInfo.repositoryName
+ " ");
pw.write(""
+ repositoryInfo.repositoryBaseURL
+ " ");
pw.write(""
+ repositoryInfo.repositoryVersion
+ " ");
pw.write("");
pw.write(" "
+ repositoryInfo.repositoryPIDNamespace
+ " ");
pw.write(" " + ":" + " ");
pw.write(" " + repositoryInfo.samplePID
+ " ");
String[] retainPIDs = repositoryInfo.retainPIDs;
for (int i = 0; i < retainPIDs.length; i++) {
pw.write(" " + retainPIDs[i]
+ " ");
}
pw.write(" ");
pw.write("");
pw.write(" "
+ repositoryInfo.OAINamespace
+ " ");
pw.write(" " + ":" + " ");
pw.write(" "
+ repositoryInfo.sampleOAIIdentifer
+ " ");
pw.write(" ");
pw.write(""
+ repositoryInfo.sampleSearchURL
+ " ");
pw.write(""
+ repositoryInfo.sampleAccessURL
+ " ");
pw.write("" + repositoryInfo.sampleOAIURL
+ " ");
String[] emails = repositoryInfo.adminEmailList;
for (int i = 0; i < emails.length; i++) {
pw.write("" + emails[i] + " ");
}
pw.write(" ");
pw.flush();
pw.close();
} catch (IOException ioe) {
LOG.error("WriteThread IOException", ioe);
} finally {
try {
if (pw != null)
pw.close();
} catch (IOException ioe) {
LOG.error("WriteThread IOException", ioe);
}
}
}
}
}
/**
*
* For now, treat a HTTP POST request just like a GET request.
*
*
* @param request
* The servet request.
* @param response
* The servlet response.
* @throws ServletException
* If thrown by doGet
.
* @throws IOException
* If thrown by doGet
.
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
*
* Initialize servlet.
*
*
* @throws ServletException
* If the servet cannot be initialized.
*/
public void init() throws ServletException {
try {
s_server = Server.getInstance(new File(Constants.FEDORA_HOME),
false);
s_access = (Access) s_server
.getModule("fedora.server.access.Access");
fedoraServerHost = s_server.getParameter("fedoraServerHost");
} catch (InitializationException ie) {
throw new ServletException("Unable to get Fedora Server instance."
+ ie.getMessage());
}
}
/**
*
* Cleans up servlet resources.
*
*/
public void destroy() {
}
private Server getServer() {
return s_server;
}
}