/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package fedora.soapclient;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.namespace.QName;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.value.StringValue;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import fedora.common.Constants;
import fedora.server.types.gen.DatastreamDef;
import fedora.server.types.gen.FieldSearchQuery;
import fedora.server.types.gen.FieldSearchResult;
import fedora.server.types.gen.MIMETypedStream;
import fedora.server.types.gen.MethodParmDef;
import fedora.server.types.gen.ObjectMethodsDef;
import fedora.server.types.gen.ObjectProfile;
import fedora.server.types.gen.Property;
import fedora.server.types.gen.RepositoryInfo;
import fedora.server.utilities.DateUtility;
import fedora.server.utilities.StreamUtility;
import fedora.utilities.XmlTransformUtility;
/**
* An example of a web-based client that provides a front end to the Fedora
* Access SOAP service. This servlet is designed to provide a "browser centric"
* view of the Fedora Access interface. Return types from the Fedora Access SOAP
* service are translated into a form suitable for viewing with a web browser;
* in other words MIME-typed streams. Applications that can readily handle SOAP
* requests and responses would most likely communicate directly with the Fedora
* Access SOAP service rather than use a java servlet as an intermediary. This
* servlet serves as an example of how to construct a client that uses the
* Fedora Access API via SOAP. </p>
* <p>
* Input parameters for the servlet include:
* </p>
* <ul>
* <li>action_ name of Fedora service which must be one of the following:
* <ol>
* <li>GetDissemination - Gets a dissemination result</li>
* <li>GetDatastreamDissemination - Gets the contents of a datastream in an
* object.</li>
* <li>GetObjectProfile - Gets object profile.</li>
* <li>DescribeRepository - Gets information about the repository server.</li>
* <li>GetObjectHistory - Gets the change history of an object.
* <li>ListMethods - Gets a list of all methods of an object.</li>
* <li>ListDatastreams - Gets a list of all datastreams of an object.</li>
* </ol>
* <li>PID_ - persistent identifier of the digital object</li>
* <li>sDefPID_ - persistent identifier of the Service Definiton object</li>
* <li>dsID_ - identifier of the datastream</li>
* <li>methodName_ - name of the method</li>
* <li>asOfDateTime_ - versioning datetime stamp</li>
* <li>xml_ - boolean switch used in conjunction with ListDatastreams,
* ListMethods, GetObjectProfile, and DescribeRepository that determines whether
* output is formatted as XML or as HTML; value of "true" indicates XML format;
* value of false or omission indicates HTML format.
* <li>userParms - methods may require or provide optional parameters that may
* be input as arguments to the method; these method parameters are entered as
* name/value pairs like the other serlvet parameters.Used in conjunction with
* GetDissemination. (optional)</li>
* </ul>
* <p>
* <i>Note that all servlet parameter names that are implementation specific end
* with the underscore character ("_"). This is done to avoid possible name
* clashes with user-supplied method parameter names. As a general rule,
* user-supplied parameters should never contain names that end with the
* underscore character to prevent possible name conflicts.</i> </ul>
* <p>
* Example URLs
* </p>
* <ol>
* <li>GetDissemination URL syntax:
* <p>
* protocol://hostname:port/soapclient/apia?action_=GetDissemination&PID_=pid&
* sDefPID_=sdefpid&methodName_=methodname[&asOfDateTime_=dateTime][?parmArray]
* </p>
* <p>
* This syntax requests a dissemination of the specified object using the
* specified method of the associated service definition object. The result is
* returned as a MIME-typed stream.
* </p>
* </li>
* <ul>
* <li>protocol - either http or https.</li>
* <li>hostname - required hostname of the Fedora server.</li>
* <li>port - required port number on which the Fedora server is running.</li>
* <li>soapclient - required name of the sample soap client.</li>
* <li>apia - required name of the sample soap client</li>
* <li>GetDissemination - required action name for getting a dissemination
* request.</li>
* <li>pid - required persistent idenitifer of the digital object.</li>
* <li>sdefpid - required persistent identifier of the service definition object
* to which the digital object subscribes.</li>
* <li>methodname - required name of the method to be executed.</li>
* <li>dateTime - optional dateTime value indicating dissemination of a version
* of the digital object at the specified point in time.
* <li>parmArray - optional array of method parameters consisting of name/value
* pairs in the form parm1=value1&parm2=value2...</li>
* </ul>
* <li>GetDatastreamDissemination URL syntax:
* <p>
* protocol://hostname:port/soapclient/apia?action=GetDatastreamDissemination&
* PID_=pid&dsID_=dsid[&asOfDateTime_=dateTime]
* </p>
* <p>
* This syntax requests a datastream dissemination for the specified digital
* object. It is used to return the contents of a datastream.
* </p>
* </li>
* <ul>
* <li>protocol - either http or https.</li>
* <li>hostname - required hostname of the Fedora server.</li>
* <li>port - required port number on which the Fedora server is running.</li>
* <li>soapclient - required name of the sample soap client.</li>
* <li>apia - required name of the sample soap client</li>
* <li>GetDatastreamDissemination - required action name for getting a
* datastream dissemination request.</li>
* <li>pid - required persistent identifier of the digital object.</li>
* <li>dsid - required datastream identifier for the datastream.</li>
* <li>dateTime - optional dateTime value indicating dissemination of a version
* of the digital object at the specified point in time.
* </ul>
* <li>GetObjectProfile URL syntax:
* <p>
* protocol://hostname:port/soapclient/apia?action_=GetObjectProfile&PID_=pid[&
* asOfDateTime_=dateTime][&xml=boolean]
* </p>
* <p>
* This syntax requests an object profile for the specified digital object.
* </p>
* </li>
* <ul>
* <li>protocol - either http or https.</li>
* <li>hostname - required hostname of the Fedora server.</li>
* <li>port - required port number on which the Fedora server is running.</li>
* <li>soapclient - required name of the sample soap client.</li>
* <li>apia - required name of the sample soap client</li>
* <li>GetObjectProfile - required action name for getting an Object Profile
* request.</li>
* <li>pid - required persistent identifier of the digital object.</li>
* <li>dateTime - optional dateTime value indicating dissemination of a version
* of the digital object at the specified point in time.
* </ul>
* <li>GetObjectHistory URL syntax:
* <p>
* protocol://hostname:port/soapclient/apia?action_=GetObjectHistory&PID_=pid[&
* xml_=boolean]
* </p>
* <p>
* This syntax requests an object history for the specified digital object.
* </p>
* </li>
* <ul>
* <li>protocol - either http or https.</li>
* <li>hostname - required hostname of the Fedora server.</li>
* <li>port - required port number on which the Fedora server is running.</li>
* <li>soapclient - required name of the sample soap client.</li>
* <li>apia - required name of the sample soap client</li>
* <li>GetObjectHistory - required action name for getting an object history
* request.</li>
* <li>pid - required persistent identifier of the digital object.</li>
* <li>boolean - 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.</li>
* </ul>
* <li>DescribeRepository URL syntax:
* <p>
* protocol://hostname:port/soapclient/apia?action_=DescribeRepository[&xml_=
* boolean]
* </p>
* <p>
* This syntax requests an object profile for the specified digital object.
* </p>
* </li>
* <ul>
* <li>protocol - either http or https.</li>
* <li>hostname - required hostname of the Fedora server.</li>
* <li>port - required port number on which the Fedora server is running.</li>
* <li>soapclient - required name of the sample soap client.</li>
* <li>apia - required name of the sample soap client</li>
* <li>DescribeRepository - required action name for getting an describe
* repository request.</li>
* <li>boolean - 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.</li>
* </ul>
* <li>ListDatastreams URL syntax:
* <p>
* protocol://hostname:port/soapclient/apia?action_=ListDatastreams&PID_=pid[&
* asOfDateTime_=dateTime][&xml_=boolean]
* </p>
* <p>
* This syntax requests a list of datastreams for the specified digital object.
* </p>
* </li>
* <ul>
* <li>protocol - either http or https.</li>
* <li>hostname - required hostname of the Fedora server.</li>
* <li>port - required port number on which the Fedora server is running.</li>
* <li>soapclient - required name of the sample soap client.</li>
* <li>apia - required name of the sample soap client</li>
* <li>ListDatastreams - required action name for getting a list datastreams
* request.</li>
* <li>pid - required persistent identifier of the digital object.</li>
* <li>dateTime - optional dateTime value indicating dissemination of a version
* of the digital object at the specified point in time.
* <li>boolean - 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.</li>
* </ul>
* <li>ListMethods URL syntax:
* <p>
* protocol://hostname:port/soapclient/apia?action_=ListMethods&PID_=pid[&
* asOfDateTime_=ateTime][xml_=boolean]
* </p>
* <p>
* This syntax requests a list of methods for the specified digital object.
* </p>
* </li>
* <ul>
* <li>protocol - either http or https.</li>
* <li>hostname - required hostname of the Fedora server.</li>
* <li>port - required port number on which the Fedora server is running.</li>
* <li>soapclient - required name of the sample soap client.</li>
* <li>apia - required name of the sample soap client</li>
* <li>ListMethods - required action name for getting a list methods request.</li>
* <li>pid - required persistent identifier of the digital object.</li>
* <li>dateTime - optional dateTime value indicating dissemination of a version
* of the digital object at the specified point in time.
* <li>boolean - 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.</li>
* </ul>
* </ol>
*
* @author Ross Wayland
*/
public class FedoraAccessSoapServlet
extends HttpServlet
implements Constants {
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";
/** GetDissemination service name. */
private static final String GET_DISSEMINATION = "GetDissemination";
/** GetDatastreamDissemination service name. */
private static final String GET_DATASTREAM_DISSEMINATION =
"GetDatastreamDissemination";
/** ListMethods service name. */
private static final String LIST_METHODS = "ListMethods";
/** GetObjectProfile service name. */
private static final String GET_OBJECT_PROFILE = "GetObjectProfile";
/** GetObjectProfile service name. */
private static final String GET_OBJECT_HISTORY = "GetObjectHistory";
/** DescribeRepository service name. */
private static final String DESCRIBE_REPOSITORY = "DescribeRepository";
/** ListDatastreams service name. */
private static final String LIST_DATASTREAMS = "ListDatastreams";
/** Properties file for soap client */
private static final String soapClientPropertiesFile =
"WEB-INF/soapclient.properties";
/** URI of Fedora Access SOAP service. */
private static String FEDORA_ACCESS_ENDPOINT = null;
/** Servlet mapping for this servlet */
private static String SOAP_CLIENT_SERVLET_PATH = null;
/** Servlet mapping for MethodParmResolverServlet */
private static String METHOD_PARM_RESOLVER_SERVLET_PATH = null;
/** User-supplied method parameters from servlet URL. */
private Hashtable<String, String> h_userParms = null;
/** Host name of the Fedora server * */
private static String fedoraServerHost = null;
/** Port number on which the Fedora server is running. * */
private static String fedoraServerPort = null;
/** The application server context which the Fedora server is running in * */
private static String fedoraAppServerContext = null;
/** Authenticated username to connect to Fedora server * */
private static String fedoraServerUsername = null;
/** Authenitcated user password to connecto to Fedora server * */
private static String fedoraServerPassword = null;
/** Protocol to use in connecting to Fedora server * */
private static String fedoraServerProtocol;
/**
* <p>
* Process Fedora Access Request. Parse and validate the servlet input
* parameters and then execute the specified request by calling the
* appropriate Fedora Access SOAP service.
* </p>
*
* @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 occurs with an input or output operation.
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String asOfDateTime = null;
Date versDateTime = null;
String action = null;
String sDefPID = null;
String methodName = null;
String PID = null;
String dsID = null;
Property[] userParms = null;
boolean xml = false;
h_userParms = new Hashtable<String, String>();
String requestURL = request.getRequestURL().toString();
if (!fedoraServerProtocol.equals(request.getRequestURL().toString()
.substring(0, requestURL.indexOf(":")))) {
response
.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"The protocol specified in the SoapClient "
+ "properties file specifies the Fedora server protocol is: \""
+ fedoraServerProtocol
+ "\". The protocol "
+ "of this request is: \""
+ request
.getRequestURL()
.toString()
.substring(0,
requestURL
.indexOf(":"))
+ "\". "
+ "The protocol of the initiating request must match that specified for the Fedora server. Either change "
+ "the protocol of the initiating request or change the protocol specified in the SoapClient properties "
+ "file so that the protocols agree.");
}
// Get servlet input parameters.
Enumeration<?> URLParms = request.getParameterNames();
while (URLParms.hasMoreElements()) {
String parm =
URLDecoder.decode((String) URLParms.nextElement(), "UTF-8");
if (parm.equals("action_")) {
action = request.getParameter(parm);
} else if (parm.equals("PID_")) {
PID = URLDecoder.decode(request.getParameter(parm), "UTF-8");
} else if (parm.equals("sDefPID_")) {
sDefPID =
URLDecoder.decode(request.getParameter(parm), "UTF-8");
} else if (parm.equals("dsID_")) {
dsID = URLDecoder.decode(request.getParameter(parm), "UTF-8");
} else if (parm.equals("methodName_")) {
methodName =
URLDecoder.decode(request.getParameter(parm), "UTF-8");
} else if (parm.equals("asOfDateTime_")) {
asOfDateTime = request.getParameter(parm);
versDateTime = DateUtility.convertStringToDate(asOfDateTime);
} else if (parm.equals("xml_")) {
xml = new Boolean(request.getParameter(parm)).booleanValue();
} else {
// Any remaining parameters are assumed to be user-supplied
// method
// parameters. Place user-supplied parameters in hashtable for
// easier access.
h_userParms.put(parm, URLDecoder.decode(request
.getParameter(parm), "UTF-8"));
}
}
// API-A interface requires user-supplied parameters to be of type
// Property[]; create Property[] from hashtable of user parameters.
int userParmCounter = 0;
if (!h_userParms.isEmpty()) {
userParms = new Property[h_userParms.size()];
for (Enumeration<String> e = h_userParms.keys(); e
.hasMoreElements();) {
Property userParm = new Property();
userParm.setName(e.nextElement());
userParm.setValue(h_userParms.get(userParm.getName()));
userParms[userParmCounter] = userParm;
userParmCounter++;
}
}
// Validate servlet URL parameters to verify that all parameters
// required
// by the servlet are present and to verify that any other user-supplied
// parameters are valid for the request.
if (isValidURLParms(action,
PID,
sDefPID,
dsID,
methodName,
versDateTime,
h_userParms,
response)) {
if (action.equals(GET_DISSEMINATION)) {
ServletOutputStream out = response.getOutputStream();
ByteArrayInputStream dissemResult = null;
try {
// Call Fedora Access SOAP service to request dissemination.
MIMETypedStream dissemination = null;
dissemination =
getDissemination(PID,
sDefPID,
methodName,
userParms,
asOfDateTime);
if (dissemination != null) {
// Dissemination found. Output the mime-typed stream.
//
// Note that what is returned by the Fedora Access SOAP
// service is
// a data structure. In a browser-based environment, it
// makes more
// sense to return something that is "browser-friendly"
// so the
// returned datastructure is written back to the serlvet
// response.
// In a nonbrowser-based environment, one would use the
// returned
// data structure directly and most likely forgo this
// transformation step.
//
if (dissemination
.getMIMEType()
.equalsIgnoreCase("application/fedora-redirect")) {
// A MIME type of application/fedora-redirect
// signals that the
// MIMETypedStream returned from the dissemination
// is a special
// Fedora-specific MIME type. In this case, teh
// Fedora server
// will not proxy the stream, but instead perform a
// simple
// redirect to the URL contained within the body of
// the
// MIMETypedStream. This special MIME type is used
// primarily
// for streaming media.
BufferedReader br =
new BufferedReader(new InputStreamReader(new ByteArrayInputStream(dissemination
.getStream())));
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
response.sendRedirect(sb.toString());
} else {
response
.setContentType(dissemination.getMIMEType());
Property[] headerArray = dissemination.getHeader();
if (headerArray != null) {
for (int i = 0; i < headerArray.length; i++) {
if (headerArray[i].getName() != null
&& !headerArray[i]
.getName()
.equalsIgnoreCase("content-type")) {
response.addHeader(headerArray[i]
.getName(), headerArray[i]
.getValue());
// System.out.println("THIS WAS ADDED TO
// FEDORASOAPSERVLET RESPONSE HEADER
// FROM ORIGINATING PROVIDER
// "+headerArray[i].getName()+" :
// "+headerArray[i].getValue());
}
}
}
int byteStream = 0;
dissemResult =
new ByteArrayInputStream(dissemination
.getStream());
byte[] buffer = new byte[255];
while ((byteStream = dissemResult.read(buffer)) != -1) {
out.write(buffer, 0, byteStream);
}
out.flush();
buffer = null;
}
} else {
// Dissemination request returned nothing.
String message =
"[FedoraAccessSoapServlet] No Dissemination "
+ "result returned. See server logs for additional info";
System.err.println(message);
showURLParms(action,
PID,
sDefPID,
methodName,
asOfDateTime,
userParms,
response,
message);
}
} catch (Exception e) {
// FIXME!! Needs more refined Exception handling.
e.printStackTrace();
String message =
"[FedoraAccessSoapServlet] No Dissemination "
+ "result returned. Exception: "
+ e.getClass().getName() + " Reason: "
+ e.getMessage()
+ " See server logs for additional info";
System.err.println(message);
showURLParms(action,
PID,
sDefPID,
methodName,
asOfDateTime,
userParms,
response,
message);
} finally {
try {
if (dissemResult != null) {
dissemResult.close();
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName()
+ " \". Reason: " + th.getMessage();
throw new ServletException(message);
}
}
} else if (action.equals(GET_DATASTREAM_DISSEMINATION)) {
ServletOutputStream out = response.getOutputStream();
ByteArrayInputStream dissemResult = null;
try {
// Call Fedora Access SOAP service to request dissemination.
MIMETypedStream dsDissemination = null;
dsDissemination =
getDatastreamDissemination(PID, dsID, asOfDateTime);
if (dsDissemination != null) {
// Dissemination found. Output the mime-typed stream.
//
// Note that what is returned by the Fedora Access SOAP
// service is
// a data structure. In a browser-based environment, it
// makes more
// sense to return something that is "browser-friendly"
// so the
// returned datastructure is written back to the serlvet
// response.
// In a nonbrowser-based environment, one would use the
// returned
// data structure directly and most likely forgo this
// transformation step.
//
response.setContentType(dsDissemination.getMIMEType());
Property[] headerArray = dsDissemination.getHeader();
if (headerArray != null) {
for (int i = 0; i < headerArray.length; i++) {
if (headerArray[i].getName() != null
&& !headerArray[i]
.getName()
.equalsIgnoreCase("content-type")) {
response
.addHeader(headerArray[i].getName(),
headerArray[i]
.getValue());
// System.out.println("THIS WAS ADDED TO
// FEDORASOAPSERVLET RESPONSE HEADER FROM
// ORIGINATING PROVIDER
// "+headerArray[i].getName()+" :
// "+headerArray[i].getValue());
}
}
}
int byteStream = 0;
dissemResult =
new ByteArrayInputStream(dsDissemination
.getStream());
byte[] buffer = new byte[255];
while ((byteStream = dissemResult.read(buffer)) != -1) {
out.write(buffer, 0, byteStream);
}
out.flush();
buffer = null;
} else {
// Dissemination request returned nothing.
String message =
"[FedoraAccessSoapServlet] No Datastream Dissemination "
+ "result returned. See server logs for additional info";
System.err.println(message);
showURLParms(action,
PID,
dsID,
methodName,
asOfDateTime,
userParms,
response,
message);
}
} catch (Exception e) {
String message =
"[FedoraAccessSoapServlet] An error has occured in "
+ "accessing the Fedora Access Subsystem. The error was \" "
+ e.getClass().getName() + " \". Reason: "
+ e.getMessage()
+ " Input Request was: \""
+ request.getRequestURL().toString();
// logger.logWarning(message);
response
.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response
.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
message);
e.printStackTrace();
} finally {
try {
if (dissemResult != null) {
dissemResult.close();
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName()
+ " \". Reason: " + th.getMessage();
throw new ServletException(message);
}
}
} else if (action.equals(LIST_METHODS)) {
ObjectMethodsDef[] objMethDefArray = null;
PipedWriter pw = new PipedWriter();
PipedReader pr = new PipedReader(pw);
OutputStreamWriter out = null;
try {
pw = new PipedWriter();
pr = new PipedReader(pw);
objMethDefArray = listMethods(PID, asOfDateTime);
if (objMethDefArray != null) {
// Object Methods found.
// Deserialize ObjectmethodsDef datastructure into XML
new ObjectMethodDefSerializerThread(PID,
objMethDefArray,
versDateTime,
pw).start();
if (xml) {
// Return results as raw XML
response.setContentType(CONTENT_TYPE_XML);
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();
// int bytestream = 0;
// while ( (bytestream = pr.read()) >= 0)
// {
// out.write(bytestream);
// }
// out.flush();
} else {
// Transform results into an html table
response.setContentType(CONTENT_TYPE_HTML);
out =
new OutputStreamWriter(response
.getOutputStream(), "UTF-8");
TransformerFactory factory =
XmlTransformUtility.getTransformerFactory();
Templates template =
factory
.newTemplates(new StreamSource(getServletContext()
.getRealPath("WEB-INF/xsl/listMethods.xslt")));
Transformer transformer = template.newTransformer();
transformer
.setParameter("title_",
new StringValue("Fedora Digital Object"));
transformer
.setParameter("subtitle_",
new StringValue("Object Methods View"));
transformer
.setParameter("soapClientServletPath",
new StringValue(SOAP_CLIENT_SERVLET_PATH));
transformer
.setParameter("soapClientMethodParmResolverServletPath",
new StringValue(METHOD_PARM_RESOLVER_SERVLET_PATH));
transformer.setParameter("fedora",
fedoraAppServerContext);
transformer.transform(new StreamSource(pr),
new StreamResult(out));
}
out.flush();
} else {
// Object Methods Definition request returned nothing.
String message =
"[FedoraAccessSoapServlet] No Object Method "
+ "Definitions returned.";
System.out.println(message);
showURLParms(action,
PID,
"",
"",
asOfDateTime,
new Property[0],
response,
message);
// response.setStatus(HttpServletResponse.SC_NO_CONTENT);
// response.sendError(response.SC_NO_CONTENT, message);
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName() + " \". Reason: "
+ th.getMessage();
System.out.println(message);
th.printStackTrace();
System.out.println(message);
showURLParms(action,
PID,
"",
"",
asOfDateTime,
new Property[0],
response,
message);
// response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
// response.sendError(response.SC_INTERNAL_SERVER_ERROR,
// message);
} finally {
try {
if (pr != null) {
pr.close();
}
if (out != null) {
out.close();
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName()
+ " \". Reason: " + th.getMessage();
throw new ServletException(message);
}
}
} else if (action.equals(LIST_DATASTREAMS)) {
DatastreamDef[] datastreamDefArray = null;
PipedWriter pw = new PipedWriter();
PipedReader pr = new PipedReader(pw);
OutputStreamWriter out = null;
try {
pw = new PipedWriter();
pr = new PipedReader(pw);
datastreamDefArray = listDatastreams(PID, asOfDateTime);
if (datastreamDefArray != null) {
// Object Methods found.
// Deserialize ObjectmethodsDef datastructure into XML
new DatastreamDefSerializerThread(PID,
datastreamDefArray,
versDateTime,
pw).start();
if (xml) {
// Return results as raw XML
response.setContentType(CONTENT_TYPE_XML);
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();
// int bytestream = 0;
// while ( (bytestream = pr.read()) >= 0)
// {
// out.write(bytestream);
// }
// out.flush();
} else {
// Transform results into an html table
response.setContentType(CONTENT_TYPE_HTML);
out =
new OutputStreamWriter(response
.getOutputStream(), "UTF-8");
TransformerFactory factory =
XmlTransformUtility.getTransformerFactory();
Templates template =
factory
.newTemplates(new StreamSource(getServletContext()
.getRealPath("WEB-INF/xsl/listDatastreams.xslt")));
Transformer transformer = template.newTransformer();
transformer
.setParameter("title_",
new StringValue("Fedora Digital Object"));
transformer
.setParameter("subtitle_",
new StringValue("List Methods"));
transformer
.setParameter("soapClientServletPath",
new StringValue(SOAP_CLIENT_SERVLET_PATH));
transformer
.setParameter("soapClientMethodParmResolverServletPath",
new StringValue(METHOD_PARM_RESOLVER_SERVLET_PATH));
transformer.transform(new StreamSource(pr),
new StreamResult(out));
}
out.flush();
} else {
// Datastream Definition request returned nothing.
String message =
"[FedoraAccessSoapServlet] No Datastream "
+ "Definitions returned.";
System.out.println(message);
showURLParms(action,
PID,
"",
"",
asOfDateTime,
new Property[0],
response,
message);
// response.setStatus(HttpServletResponse.SC_NO_CONTENT);
// response.sendError(response.SC_NO_CONTENT, message);
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName() + " \". Reason: "
+ th.getMessage();
System.out.println(message);
th.printStackTrace();
System.out.println(message);
showURLParms(action,
PID,
"",
"",
asOfDateTime,
new Property[0],
response,
message);
// response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
// response.sendError(response.SC_INTERNAL_SERVER_ERROR,
// message);
} finally {
try {
if (pr != null) {
pr.close();
}
if (out != null) {
out.close();
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName()
+ " \". Reason: " + th.getMessage();
throw new ServletException(message);
}
}
} else if (action.equals(GET_OBJECT_PROFILE)) {
ObjectProfile objProfile = null;
PipedWriter pw = new PipedWriter();
PipedReader pr = new PipedReader(pw);
OutputStreamWriter out = null;
try {
// out = response.getOutputStream();
pw = new PipedWriter();
pr = new PipedReader(pw);
objProfile = getObjectProfile(PID, asOfDateTime);
if (objProfile != null) {
// Object Profile found.
// Deserialize ObjectProfile datastructure into XML
new ProfileSerializerThread(PID,
objProfile,
versDateTime,
pw).start();
if (xml) {
// Return results as raw XML
response.setContentType(CONTENT_TYPE_XML);
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();
// int bytestream = 0;
// while ( (bytestream = pr.read()) >= 0)
// {
// out.write(bytestream);
// }
// 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(getServletContext()
.getRealPath("WEB-INF/xsl/viewObjectProfile.xslt"));
TransformerFactory factory =
XmlTransformUtility.getTransformerFactory();
Templates template =
factory
.newTemplates(new StreamSource(xslFile));
Transformer transformer = template.newTransformer();
transformer
.setParameter("title_",
new StringValue("Fedora Digital Object"));
transformer
.setParameter("subtitle_",
new StringValue("Object Profile View"));
transformer
.setParameter("soapClientServletPath",
new StringValue(SOAP_CLIENT_SERVLET_PATH));
transformer
.setParameter("soapClientMethodParmResolverServletPath",
new StringValue(METHOD_PARM_RESOLVER_SERVLET_PATH));
transformer.setParameter("fedora",
fedoraAppServerContext);
transformer.transform(new StreamSource(pr),
new StreamResult(out));
}
out.flush();
} else {
// No Object Profile returned
String message =
"[FedoraAccessSoapServlet] No Object Profile returned.";
System.out.println(message);
showURLParms(action,
PID,
"",
"",
asOfDateTime,
new Property[0],
response,
message);
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName() + " \". Reason: "
+ th.getMessage();
System.out.println(message);
th.printStackTrace();
System.out.println(message);
showURLParms(action,
PID,
"",
"",
asOfDateTime,
new Property[0],
response,
message);
// response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
// response.sendError(response.SC_INTERNAL_SERVER_ERROR,
// message);
} finally {
try {
if (pr != null) {
pr.close();
}
if (out != null) {
out.close();
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName()
+ " \". Reason: " + th.getMessage();
throw new ServletException(message);
}
}
} else if (action.equals(DESCRIBE_REPOSITORY)) {
RepositoryInfo repositoryInfo = null;
PipedWriter pw = new PipedWriter();
PipedReader pr = new PipedReader(pw);
OutputStreamWriter out = null;
try {
pw = new PipedWriter();
pr = new PipedReader(pw);
repositoryInfo = describeRepository();
if (repositoryInfo != null) {
// Repository Info found.
// Deserialize RepositoryInfo datastructure into XML
new ReposInfoSerializerThread(repositoryInfo, pw)
.start();
if (xml) {
// Return results as raw XML
response.setContentType(CONTENT_TYPE_XML);
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(getServletContext()
.getRealPath("WEB-INF/xsl/viewRepositoryInfo.xslt"));
TransformerFactory factory =
XmlTransformUtility.getTransformerFactory();
Templates template =
factory
.newTemplates(new StreamSource(xslFile));
Transformer transformer = template.newTransformer();
transformer.setParameter("title_",
new StringValue("Fedora"));
transformer
.setParameter("subtitle_",
new StringValue("Describe Repository View"));
transformer
.setParameter("soapClientServletPath",
new StringValue(SOAP_CLIENT_SERVLET_PATH));
transformer
.setParameter("soapClientMethodParmResolverServletPath",
new StringValue(METHOD_PARM_RESOLVER_SERVLET_PATH));
transformer.transform(new StreamSource(pr),
new StreamResult(out));
}
out.flush();
} else {
// No Repository Info returned
String message =
"[FedoraAccessSoapServlet] No Repository Info returned.";
System.out.println(message);
showURLParms(action,
"",
"",
"",
null,
new Property[0],
response,
message);
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName() + " \". Reason: "
+ th.getMessage();
System.out.println(message);
th.printStackTrace();
System.out.println(message);
showURLParms(action,
"",
"",
"",
null,
new Property[0],
response,
message);
// response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
// response.sendError(response.SC_INTERNAL_SERVER_ERROR,
// message);
} finally {
try {
if (pr != null) {
pr.close();
}
if (out != null) {
out.close();
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName()
+ " \". Reason: " + th.getMessage();
throw new ServletException(message);
}
}
} else if (action.equals(GET_OBJECT_HISTORY)) {
String[] objectHistory = null;
PipedWriter pw = new PipedWriter();
PipedReader pr = new PipedReader(pw);
OutputStreamWriter out = null;
try {
pw = new PipedWriter();
pr = new PipedReader(pw);
objectHistory = getObjectHistory(PID);
if (objectHistory.length > 0) {
// Object History found.
// Deserialize Object History datastructure into XML
new ObjectHistorySerializerThread(PID,
objectHistory,
pw).start();
if (xml) {
// Return results as raw XML
response.setContentType(CONTENT_TYPE_XML);
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(getServletContext()
.getRealPath("WEB-INF/xsl/viewObjectHistory.xslt"));
TransformerFactory factory =
XmlTransformUtility.getTransformerFactory();
Templates template =
factory
.newTemplates(new StreamSource(xslFile));
Transformer transformer = template.newTransformer();
transformer.setParameter("title_",
new StringValue("Fedora"));
transformer
.setParameter("subtitle_",
new StringValue("Object History View"));
transformer
.setParameter("soapClientServletPath",
new StringValue(SOAP_CLIENT_SERVLET_PATH));
transformer
.setParameter("soapClientMethodParmResolverServletPath",
new StringValue(METHOD_PARM_RESOLVER_SERVLET_PATH));
transformer.transform(new StreamSource(pr),
new StreamResult(out));
}
out.flush();
} else {
// No Repository Info returned
String message =
"[FedoraAccessSoapServlet] No Object History returned.";
System.out.println(message);
showURLParms(action,
"",
"",
"",
null,
new Property[0],
response,
message);
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName() + " \". Reason: "
+ th.getMessage();
System.out.println(message);
th.printStackTrace();
System.out.println(message);
showURLParms(action,
PID,
"",
"",
null,
new Property[0],
response,
message);
} finally {
try {
if (pr != null) {
pr.close();
}
if (out != null) {
out.close();
}
} catch (Throwable th) {
String message =
"[FedoraAccessSoapServlet] An error has occured. "
+ " The error was a \" "
+ th.getClass().getName()
+ " \". Reason: " + th.getMessage();
throw new ServletException(message);
}
}
} else {
// Action not recognized
String message =
"[FedoraAccessSoapServlet] Requested action not recognized.";
System.out.println(message);
showURLParms(action,
PID,
"",
"",
asOfDateTime,
new Property[0],
response,
message);
}
}
}
/**
* <p>
* A Thread to serialize a DatastreamDef object into XML.
* </p>
*/
public class DatastreamDefSerializerThread
extends Thread {
private PipedWriter pw = null;
private String PID = null;
private DatastreamDef[] dsDefs = null;
private Date versDateTime = null;
/**
* <p>
* Constructor for ProfileSerializeThread.
* </p>
*
* @param PID
* The persistent identifier of the specified digital object.
* @param dsDefs
* An array of DatastreamDefs.
* @param versDateTime
* The version datetime stamp of the request.
* @param pw
* A PipedWriter to which the serialization info is written.
*/
public DatastreamDefSerializerThread(String PID,
DatastreamDef[] dsDefs,
Date versDateTime,
PipedWriter pw) {
this.pw = pw;
this.PID = PID;
this.dsDefs = dsDefs;
this.versDateTime = versDateTime;
}
/**
* <p>
* This method executes the thread.
* </p>
*/
@Override
public void run() {
if (pw != null) {
try {
pw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
pw.write("<objectDatastreams pid=\"" + PID + "\"");
if (versDateTime != null) {
pw.write(" asOfDateTime=\"");
pw.write(DateUtility.convertDateToString(versDateTime));
pw.write("\"");
}
final String baseURL =
fedoraServerProtocol + "://" + fedoraServerHost
+ ":" + fedoraServerPort + "/"
+ fedoraAppServerContext + "/";
pw.write(" baseURL=\"" + baseURL + "\"");
pw.write(" xmlns:xsi=\"" + XSI.uri + "\"");
pw.write(" xsi:schemaLocation=\"" + ACCESS.uri);
pw.write(" " + OBJ_DATASTREAMS1_0.xsdLocation + "\">");
// DatastreamDef SERIALIZATION
for (DatastreamDef element : dsDefs) {
pw.write(" <datastream " + "dsid=\""
+ StreamUtility.enc(element.getID()) + "\" "
+ "label=\""
+ StreamUtility.enc(element.getLabel()) + "\" "
+ "mimeType=\""
+ StreamUtility.enc(element.getMIMEType())
+ "\" />");
}
pw.write("</objectDatastreams>");
pw.flush();
pw.close();
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
} finally {
try {
if (pw != null) {
pw.close();
}
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
}
}
}
}
}
/**
* <p>
* A Thread to serialize an ObjectMethodDef object into XML.
* </p>
*/
public class ObjectMethodDefSerializerThread
extends Thread {
private PipedWriter pw = null;
private String PID = null;
private ObjectMethodsDef[] methodDefs = null;
private Date versDateTime = null;
/**
* <p>
* Constructor for ProfileSerializeThread.
* </p>
*
* @param PID
* The persistent identifier of the specified digital object.
* @param methodDefs
* An array of ObjectMethodsDefs.
* @param versDateTime
* The version datetime stamp of the request.
* @param pw
* A PipedWriter to which the serialization info is written.
*/
public ObjectMethodDefSerializerThread(String PID,
ObjectMethodsDef[] methodDefs,
Date versDateTime,
PipedWriter pw) {
this.pw = pw;
this.PID = PID;
this.methodDefs = methodDefs;
this.versDateTime = versDateTime;
}
/**
* <p>
* This method executes the thread.
* </p>
*/
@Override
public void run() {
if (pw != null) {
try {
pw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
pw.write("<objectMethods");
pw.write(" pid=\"" + PID + "\"");
if (versDateTime != null) {
pw.write(" asOfDateTime=\"");
pw.write(DateUtility.convertDateToString(versDateTime));
pw.write("\"");
}
pw.write(" baseURL=\""
+ StreamUtility.enc(fedoraServerProtocol) + "://"
+ StreamUtility.enc(fedoraServerHost) + ":"
+ StreamUtility.enc(fedoraServerPort) + "/"
+ fedoraAppServerContext + "/\"");
pw.write(" xmlns:xsi=\"" + XSI.uri + "\" ");
pw.write(" xsi:schemaLocation=\"" + ACCESS.uri);
pw.write(" " + OBJ_METHODS1_0.xsdLocation + "\">");
// ObjectMethodsDef SERIALIZATION
String nextSdef = "null";
String currentSdef = "";
for (int i = 0; i < methodDefs.length; i++) {
currentSdef = methodDefs[i].getServiceDefinitionPID();
if (!currentSdef.equalsIgnoreCase(nextSdef)) {
if (i != 0) {
pw.write("</sDef>");
}
pw.write("<sDef pid=\""
+ StreamUtility.enc(methodDefs[i]
.getServiceDefinitionPID())
+ "\" >");
}
pw.write("<method name=\""
+ StreamUtility.enc(methodDefs[i]
.getMethodName()) + "\" >");
MethodParmDef[] methodParms =
methodDefs[i].getMethodParmDefs();
for (MethodParmDef element : methodParms) {
pw.write("<methodParm parmName=\""
+ StreamUtility.enc(element.getParmName())
+ "\" parmDefaultValue=\""
+ StreamUtility.enc(element
.getParmDefaultValue())
+ "\" parmRequired=\""
+ element.isParmRequired()
+ "\" parmLabel=\""
+ StreamUtility.enc(element.getParmLabel())
+ "\" >");
if (element.getParmDomainValues().length > 0) {
pw.write("<methodParmDomain>");
for (int k = 0; k < element
.getParmDomainValues().length; k++) {
pw.write("<methodParmValue>"
+ StreamUtility.enc(element
.getParmDomainValues()[k])
+ "</methodParmValue>");
}
pw.write("</methodParmDomain>");
}
pw.write("</methodParm>");
}
pw.write("</method>");
nextSdef = currentSdef;
}
pw.write("</sDef>");
pw.write("</objectMethods>");
pw.flush();
pw.close();
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
} finally {
try {
if (pw != null) {
pw.close();
}
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
}
}
}
}
}
/**
* <p>
* A Thread to serialize an ObjectProfile object into XML.
* </p>
*/
public class ProfileSerializerThread
extends Thread {
private PipedWriter pw = null;
private String PID = null;
private ObjectProfile objProfile = null;
private Date versDateTime = null;
/**
* <p>
* Constructor for ProfileSerializeThread.
* </p>
*
* @param PID
* The persistent identifier of the specified digital object.
* @param objProfile
* An object profile data structure.
* @param versDateTime
* The version datetime stamp of the request.
* @param pw
* A PipedWriter to which the serialization info is written.
*/
public ProfileSerializerThread(String PID,
ObjectProfile objProfile,
Date versDateTime,
PipedWriter pw) {
this.pw = pw;
this.PID = PID;
this.objProfile = objProfile;
this.versDateTime = versDateTime;
}
/**
* <p>
* This method executes the thread.
* </p>
*/
@Override
public void run() {
if (pw != null) {
try {
pw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
pw.write("<objectProfile");
pw.write(" pid=\"" + StreamUtility.enc(PID) + "\"");
if (versDateTime != null) {
DateUtility.convertDateToString(versDateTime);
pw.write(" dateTime=\""
+ DateUtility.convertDateToString(versDateTime)
+ "\"");
}
pw.write(" xmlns:xsi=\"" + XSI.uri + "\""
+ " xsi:schemaLocation=\""
+ OBJ_PROFILE1_0.namespace.uri + " "
+ OBJ_PROFILE1_0.xsdLocation + "\">");
// PROFILE FIELDS SERIALIZATION
pw.write("<objLabel>" + objProfile.getObjLabel()
+ "</objLabel>");
String cDate = objProfile.getObjCreateDate();
pw.write("<objCreateDate>" + cDate + "</objCreateDate>");
String mDate = objProfile.getObjLastModDate();
pw.write("<objLastModDate>" + mDate + "</objLastModDate>");
pw.write("<objDissIndexViewURL>"
+ objProfile.getObjDissIndexViewURL()
+ "</objDissIndexViewURL>");
pw.write("<objItemIndexViewURL>"
+ objProfile.getObjItemIndexViewURL()
+ "</objItemIndexViewURL>");
pw.write("</objectProfile>");
pw.flush();
pw.close();
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
} finally {
try {
if (pw != null) {
pw.close();
}
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
}
}
}
}
}
/**
* <p>
* A Thread to serialize a RepositoryInfo object into XML.
* </p>
*/
public class ReposInfoSerializerThread
extends Thread {
private PipedWriter pw = null;
private RepositoryInfo repositoryInfo = null;
/**
* <p>
* Constructor for ReposInfoSerializeThread.
* </p>
*
* @param repositoryInfo
* A repository info data structure.
* @param pw
* A PipedWriter to which the serialization info is written.
*/
public ReposInfoSerializerThread(RepositoryInfo repositoryInfo,
PipedWriter pw) {
this.pw = pw;
this.repositoryInfo = repositoryInfo;
}
/**
* <p>
* This method executes the thread.
* </p>
*/
@Override
public void run() {
if (pw != null) {
try {
pw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
pw.write("<fedoraRepository " + " xmlns:xsd=\""
+ XML_XSD.uri + "\"" + " xmlns:xsi=\"" + XSI.uri
+ "\"" + " xsi:schemaLocation=\"" + ACCESS.uri
+ " " + REPO_DESC1_0.xsdLocation + "\">");
// REPOSITORY INFO FIELDS SERIALIZATION
pw.write("<repositoryName>"
+ repositoryInfo.getRepositoryName()
+ "</repositoryName>");
pw.write("<repositoryBaseURL>"
+ repositoryInfo.getRepositoryBaseURL()
+ "</repositoryBaseURL>");
pw.write("<repositoryVersion>"
+ repositoryInfo.getRepositoryVersion()
+ "</repositoryVersion>");
pw.write("<repositoryPID>");
pw.write(" <PID-namespaceIdentifier>"
+ repositoryInfo.getRepositoryPIDNamespace()
+ "</PID-namespaceIdentifier>");
pw.write(" <PID-delimiter>" + ":" + "</PID-delimiter>");
pw.write(" <PID-sample>" + repositoryInfo.getSamplePID()
+ "</PID-sample>");
String[] retainPIDs = repositoryInfo.getRetainPIDs();
for (String element : retainPIDs) {
pw.write(" <retainPID>" + element + "</retainPID>");
}
pw.write("</repositoryPID>");
pw.write("<repositoryOAI-identifier>");
pw.write(" <OAI-namespaceIdentifier>"
+ repositoryInfo.getOAINamespace()
+ "</OAI-namespaceIdentifier>");
pw.write(" <OAI-delimiter>" + ":" + "</OAI-delimiter>");
pw.write(" <OAI-sample>"
+ repositoryInfo.getSampleOAIIdentifier()
+ "</OAI-sample>");
pw.write("</repositoryOAI-identifier>");
pw.write("<sampleSearch-URL>"
+ repositoryInfo.getSampleSearchURL()
+ "</sampleSearch-URL>");
pw.write("<sampleAccess-URL>"
+ repositoryInfo.getSampleAccessURL()
+ "</sampleAccess-URL>");
pw.write("<sampleOAI-URL>"
+ repositoryInfo.getSampleOAIURL()
+ "</sampleOAI-URL>");
String[] emails = repositoryInfo.getAdminEmailList();
for (String element : emails) {
pw.write("<adminEmail>" + element + "</adminEmail>");
}
pw.write("</fedoraRepository>");
pw.flush();
pw.close();
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
} finally {
try {
if (pw != null) {
pw.close();
}
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
}
}
}
}
}
/**
* <p>
* A Thread to serialize an ObjectHistory object into XML.
* </p>
*/
public class ObjectHistorySerializerThread
extends Thread {
private PipedWriter pw = null;
private String PID = null;
private String[] objectHistoryArray = new String[0];
/**
* <p>
* Constructor for SerializeThread.
* </p>
*
* @param PID
* The persistent identifier of the specified digital object.
* @param objectHistoryArray
* An array of method definitions.
* @param pw
* A PipedWriter to which the serialization info is written.
*/
public ObjectHistorySerializerThread(String PID,
String[] objectHistoryArray,
PipedWriter pw) {
this.pw = pw;
this.PID = PID;
this.objectHistoryArray = objectHistoryArray;
}
/**
* <p>
* This method executes the thread.
* </p>
*/
@Override
public void run() {
if (pw != null) {
try {
pw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
pw.write("<fedoraObjectHistory" + " pid=\"" + PID + "\""
+ " xmlns:xsd=\"" + XML_XSD.uri + "\""
+ " xmlns:xsi=\"" + XSI.uri + "\""
+ " xsi:schemaLocation=\"" + ACCESS.uri + " "
+ OBJ_HISTORY1_0.xsdLocation + "\">");
for (String element : objectHistoryArray) {
pw.write("<objectChangeDate>" + element
+ "</objectChangeDate>");
}
pw.write("</fedoraObjectHistory>");
pw.flush();
pw.close();
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
} finally {
try {
if (pw != null) {
pw.close();
}
} catch (IOException ioe) {
System.err.println("WriteThread IOException: "
+ ioe.getMessage());
}
}
}
}
}
/**
* <p>
* For now, treat a HTTP POST request just like a GET request.
* </p>
*
* @param request
* The servet request.
* @param response
* The servlet response.
* @throws ServletException
* If thrown by <code>doGet</code>.
* @throws IOException
* If thrown by <code>doGet</code>.
* @throws ServletException
* If an error occurs that effects the servlet's basic operation.
*/
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
* <p>
* Gets a list of Service Definition object PIDs for the specified digital
* object by invoking the appropriate Fedora Access SOAP service.
* </p>
*
* @param PID
* The persistent identifier of the digital object.
* @return An array of timestamps indicating when an object component
* changed.
* @throws Exception
* If an error occurs in communicating with the Fedora Access SOAP
* service.
*/
public String[] getObjectHistory(String PID) throws Exception {
Service service = new Service();
Call call = (Call) service.createCall();
call.setUsername(fedoraServerUsername);
call.setPassword(fedoraServerPassword);
call.setTargetEndpointAddress(new URL(FEDORA_ACCESS_ENDPOINT));
call.setOperationName(new QName(API.uri, GET_OBJECT_HISTORY));
String[] objectHistory = (String[]) call.invoke(new Object[] {PID});
return objectHistory;
}
/**
* <p>
* Gets a MIME-typed bytestream containing the result of a dissemination by
* invoking the appropriate Fedora Access SOAP service.
*
* @param PID
* The persistent identifier of the digital object.
* @param sDefPID
* The persistent identifier of the Service Definition object.
* @param methodName
* The name of the method.
* @param asOfDateTime
* The version datetime stamp of the digital object.
* @param userParms
* An array of user-supplied method parameters and values.
* @return A MIME-typed stream containing the dissemination result.
* @throws Exception
* If an error occurs in communicating with the Fedora Access SOAP
* service.
*/
public MIMETypedStream getDissemination(String PID,
String sDefPID,
String methodName,
Property[] userParms,
String asOfDateTime)
throws Exception {
// Generate a call to the Fedora SOAP service requesting the
// GetDissemination method
MIMETypedStream dissemination = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setUsername(fedoraServerUsername);
call.setPassword(fedoraServerPassword);
call.setTargetEndpointAddress(new URL(FEDORA_ACCESS_ENDPOINT));
call.setOperationName(new QName(API.uri, GET_DISSEMINATION));
QName qn = new QName(TYPES.uri, "MIMETypedStream");
QName qn2 = new QName(TYPES.uri, "Property");
// Any Fedora-defined types required by the SOAP service must be
// registered
// prior to invocation so the SOAP service knows the appropriate
// serializer/deserializer to use for these types.
call
.registerTypeMapping(MIMETypedStream.class,
qn,
new BeanSerializerFactory(MIMETypedStream.class,
qn),
new BeanDeserializerFactory(MIMETypedStream.class,
qn));
call
.registerTypeMapping(fedora.server.types.gen.Property.class,
qn2,
new BeanSerializerFactory(Property.class,
qn2),
new BeanDeserializerFactory(Property.class,
qn2));
dissemination =
(MIMETypedStream) call.invoke(new Object[] {PID, sDefPID,
methodName, userParms, asOfDateTime});
return dissemination;
}
public MIMETypedStream getDatastreamDissemination(String PID,
String dsID,
String asOfDateTime)
throws Exception {
// Generate a call to the Fedora SOAP service requesting the
// GetDissemination method
MIMETypedStream dsDissemination = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setUsername(fedoraServerUsername);
call.setPassword(fedoraServerPassword);
call.setTargetEndpointAddress(new URL(FEDORA_ACCESS_ENDPOINT));
call.setOperationName(new QName(API.uri, GET_DATASTREAM_DISSEMINATION));
QName qn = new QName(TYPES.uri, "MIMETypedStream");
// Any Fedora-defined types required by the SOAP service must be
// registered
// prior to invocation so the SOAP service knows the appropriate
// serializer/deserializer to use for these types.
call
.registerTypeMapping(MIMETypedStream.class,
qn,
new BeanSerializerFactory(MIMETypedStream.class,
qn),
new BeanDeserializerFactory(MIMETypedStream.class,
qn));
dsDissemination =
(MIMETypedStream) call.invoke(new Object[] {PID, dsID,
asOfDateTime});
return dsDissemination;
}
/**
* <p>
* Gets a list of all method definitions for the specified object by
* invoking the appropriate Fedora Access SOAP service.
* </p>
*
* @param PID
* The persistent identifier for the digital object.
* @param asOfDateTime
* The versioning datetime stamp.
* @return An array of object method definitions.
* @throws Exception
* If an error occurs in communicating with the Fedora Access SOAP
* service.
*/
public ObjectMethodsDef[] listMethods(String PID, String asOfDateTime)
throws Exception {
ObjectMethodsDef[] objMethDefArray = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setUsername(fedoraServerUsername);
call.setPassword(fedoraServerPassword);
call.setOperationName(new QName(API.uri, LIST_METHODS));
QName qn = new QName(TYPES.uri, "ObjectMethodsDef");
QName qn2 = new QName(TYPES.uri, "MethodParmDef");
call.setTargetEndpointAddress(new URL(FEDORA_ACCESS_ENDPOINT));
// Any Fedora-defined types required by the SOAP service must be
// registered
// prior to invocation so the SOAP service knows the appropriate
// serializer/deserializer to use for these types.
call
.registerTypeMapping(ObjectMethodsDef.class,
qn,
new BeanSerializerFactory(ObjectMethodsDef.class,
qn),
new BeanDeserializerFactory(ObjectMethodsDef.class,
qn));
call
.registerTypeMapping(MethodParmDef.class,
qn2,
new BeanSerializerFactory(MethodParmDef.class,
qn2),
new BeanDeserializerFactory(MethodParmDef.class,
qn2));
objMethDefArray =
(ObjectMethodsDef[]) call.invoke(new Object[] {PID,
asOfDateTime});
return objMethDefArray;
}
/**
* <p>
* Gets a list of all datastream for the specified object by invoking the
* appropriate Fedora Access SOAP service.
* </p>
*
* @param PID
* The persistent identifier of the digital object.
* @param asOfDateTime
* The versioning datetime stamp.
* @return An array of datastream definitions.
* @throws Exception
* If an error occurs in communicating with the Fedora Access SOAP
* service.
*/
public DatastreamDef[] listDatastreams(String PID, String asOfDateTime)
throws Exception {
DatastreamDef[] datastreamDefArray = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setUsername(fedoraServerUsername);
call.setPassword(fedoraServerPassword);
call.setOperationName(new QName(API.uri, LIST_DATASTREAMS));
QName qn = new QName(TYPES.uri, "DatastreamDef");
call.setTargetEndpointAddress(new URL(FEDORA_ACCESS_ENDPOINT));
// Any Fedora-defined types required by the SOAP service must be
// registered
// prior to invocation so the SOAP service knows the appropriate
// serializer/deserializer to use for these types.
call
.registerTypeMapping(DatastreamDef.class,
qn,
new BeanSerializerFactory(DatastreamDef.class,
qn),
new BeanDeserializerFactory(DatastreamDef.class,
qn));
datastreamDefArray =
(DatastreamDef[]) call.invoke(new Object[] {PID, asOfDateTime});
return datastreamDefArray;
}
/**
* <p>
* Gets a object profile for the specified object by invoking the
* appropriate Fedora Access SOAP service.
* </p>
*
* @param PID
* The persistent identifier for the digital object.
* @param asOfDateTime
* The versioning datetime stamp.
* @return An object profile data structure.
* @throws Exception
* If an error occurs in communicating with the Fedora Access SOAP
* service.
*/
public ObjectProfile getObjectProfile(String PID, String asOfDateTime)
throws Exception {
ObjectProfile objProfile = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setUsername(fedoraServerUsername);
call.setPassword(fedoraServerPassword);
call.setOperationName(new QName(API.uri, GET_OBJECT_PROFILE));
QName qn = new QName(TYPES.uri, "ObjectProfile");
call.setTargetEndpointAddress(new URL(FEDORA_ACCESS_ENDPOINT));
// Any Fedora-defined types required by the SOAP service must be
// registered
// prior to invocation so the SOAP service knows the appropriate
// serializer/deserializer to use for these types.
call
.registerTypeMapping(ObjectProfile.class,
qn,
new BeanSerializerFactory(ObjectProfile.class,
qn),
new BeanDeserializerFactory(ObjectProfile.class,
qn));
objProfile =
(ObjectProfile) call.invoke(new Object[] {PID, asOfDateTime});
return objProfile;
}
/**
* <p>
* Gets repository information for the server by invoking the appropriate
* Fedora Access SOAP service.
* </p>
*
* @return A repository information data structure.
* @throws Exception
* If an error occurs in communicating with the Fedora Access SOAP
* service.
*/
public RepositoryInfo describeRepository() throws Exception {
RepositoryInfo repositoryInfo = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setUsername(fedoraServerUsername);
call.setPassword(fedoraServerPassword);
call.setOperationName(new QName(API.uri, DESCRIBE_REPOSITORY));
QName qn = new QName(TYPES.uri, "RepositoryInfo");
call.setTargetEndpointAddress(new URL(FEDORA_ACCESS_ENDPOINT));
// Any Fedora-defined types required by the SOAP service must be
// registered
// prior to invocation so the SOAP service knows the appropriate
// serializer/deserializer to use for these types.
call
.registerTypeMapping(RepositoryInfo.class,
qn,
new BeanSerializerFactory(RepositoryInfo.class,
qn),
new BeanDeserializerFactory(RepositoryInfo.class,
qn));
repositoryInfo = (RepositoryInfo) call.invoke(new Object[] {});
return repositoryInfo;
}
/**
* <p>
* Lists the specified fields of each object matching the given criteria.
* </p>
*
* @param resultFields
* the names of the fields to return
* @param maxResults
* the maximum number of results to return at a time
* @param query
* the query
* @return the specified fields of each object matching the given criteria.
* @throws Exception
* If an error occurs in communicating with the Fedora Access SOAP
* service.
*/
public FieldSearchResult findObjects(String[] resultFields,
int maxResults,
FieldSearchQuery query)
throws Exception {
FieldSearchResult fieldSearchResult = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setUsername(fedoraServerUsername);
call.setPassword(fedoraServerPassword);
call.setOperationName(new QName(API.uri, DESCRIBE_REPOSITORY));
QName qn = new QName(TYPES.uri, "FieldSearchResult");
QName qn2 = new QName(TYPES.uri, "FieldSearchQuery");
call.setTargetEndpointAddress(new URL(FEDORA_ACCESS_ENDPOINT));
// Any Fedora-defined types required by the SOAP service must be
// registered
// prior to invocation so the SOAP service knows the appropriate
// serializer/deserializer to use for these types.
call
.registerTypeMapping(FieldSearchResult.class,
qn,
new BeanSerializerFactory(FieldSearchResult.class,
qn),
new BeanDeserializerFactory(FieldSearchResult.class,
qn));
call
.registerTypeMapping(FieldSearchQuery.class,
qn2,
new BeanSerializerFactory(FieldSearchQuery.class,
qn2),
new BeanDeserializerFactory(FieldSearchQuery.class,
qn2));
fieldSearchResult =
(FieldSearchResult) call.invoke(new Object[] {resultFields,
new Integer(maxResults), query});
return fieldSearchResult;
}
/**
* <p>
* Resumes an in-progress listing of object fields.
* </p>
*
* @param sessionToken
* the token of the session in which the remaining results can be
* obtained
* @return the remaining specified fields of each object matching the given
* criteria.
* @throws Exception
* If an error occurs in communicating with the Fedora Access SOAP
* service.
*/
public FieldSearchResult resumeFindObjects(String sessionToken)
throws Exception {
FieldSearchResult fieldSearchResult = null;
Service service = new Service();
Call call = (Call) service.createCall();
call.setUsername(fedoraServerUsername);
call.setPassword(fedoraServerPassword);
call.setOperationName(new QName(API.uri, DESCRIBE_REPOSITORY));
QName qn = new QName(TYPES.uri, "FieldSearchResult");
call.setTargetEndpointAddress(new URL(FEDORA_ACCESS_ENDPOINT));
// Any Fedora-defined types required by the SOAP service must be
// registered
// prior to invocation so the SOAP service knows the appropriate
// serializer/deserializer to use for these types.
call
.registerTypeMapping(FieldSearchResult.class,
qn,
new BeanSerializerFactory(FieldSearchResult.class,
qn),
new BeanDeserializerFactory(FieldSearchResult.class,
qn));
fieldSearchResult =
(FieldSearchResult) call.invoke(new Object[] {sessionToken});
return fieldSearchResult;
}
/**
* <p>
* Initialize servlet.
* </p>
*
* @throws ServletException
* If the servet cannot be initialized.
*/
@Override
public void init() throws ServletException {
try {
System.out
.println("Realpath Properties File: "
+ getServletContext()
.getRealPath(soapClientPropertiesFile));
FileInputStream fis =
new FileInputStream(getServletContext()
.getRealPath(soapClientPropertiesFile));
Properties p = new Properties();
p.load(fis);
FEDORA_ACCESS_ENDPOINT = p.getProperty("fedoraEndpoint");
SOAP_CLIENT_SERVLET_PATH = p.getProperty("soapClientServletPath");
METHOD_PARM_RESOLVER_SERVLET_PATH =
p.getProperty("soapClientMethodParmResolverServletPath");
fedoraServerUsername = p.getProperty("fedoraServerUsername");
fedoraServerPassword = p.getProperty("fedoraServerPassword");
System.out.println("FedoraEndpoint: " + FEDORA_ACCESS_ENDPOINT);
System.out.println("soapClientServletPath: "
+ SOAP_CLIENT_SERVLET_PATH);
System.out.println("soapClientMethodParmResolverServletPath: "
+ METHOD_PARM_RESOLVER_SERVLET_PATH);
System.out.println("fedoraServerUsername: " + fedoraServerUsername);
System.out.println("fedoraServerPassword: " + fedoraServerPassword);
// Locations of the internal Fedora XML schemas are local to the
// Fedora server so it is
// the Fedora server hostname and port number are extracted from the
// FEDORA_ACCESS_ENDPOINT string for easier access within the
// servlet.
int i = FEDORA_ACCESS_ENDPOINT.indexOf(":", 8);
int j = FEDORA_ACCESS_ENDPOINT.indexOf("/", i);
int k = FEDORA_ACCESS_ENDPOINT.indexOf(":");
fedoraServerHost = FEDORA_ACCESS_ENDPOINT.substring(k + 3, i);
fedoraServerPort = FEDORA_ACCESS_ENDPOINT.substring(i + 1, j);
fedoraServerProtocol = FEDORA_ACCESS_ENDPOINT.substring(0, k);
fedoraAppServerContext = p.getProperty("fedoraAppServerContext");
System.out.println("fedoraServerHost: " + fedoraServerHost);
System.out.println("fedoraServerPort: " + fedoraServerPort);
System.out.println("fedoraServerProtocol: " + fedoraServerProtocol);
} catch (Throwable th) {
String message =
"[FedoraSOAPServlet] An error has occurred. "
+ "The error was a \"" + th.getClass().getName()
+ "\" . The " + "Reason: \"" + th.getMessage()
+ "\" .";
throw new ServletException(message);
}
}
/**
* <p>
* Cleans up servlet resources.
* </p>
*/
@Override
public void destroy() {
}
/**
* <p>
* Validates required servlet URL parameters. Different parameters are
* required based on the requested action.
* </p>
*
* @param action
* The Fedora service to be executed
* @param PID
* The persistent identifier of the Digital Object.
* @param sDefPID
* The persistent identifier of the Service Definition object.
* @param methodName
* The method name.
* @param versDateTime
* The version datetime stamp of the digital object.
* @param h_userParms
* A hashtabe of user-supplied method parameters.
* @param response
* The servlet response.
* @return True if required parameters are valid; false otherwise.
* @throws IOException
* If an error occurrs with an input or output operation.
*/
private boolean isValidURLParms(String action,
String PID,
String sDefPID,
String dsID,
String methodName,
Date versDateTime,
Hashtable<String, String> h_userParms,
HttpServletResponse response)
throws IOException {
// Check for missing parameters required either by the servlet or the
// requested Fedora Access SOAP service.
boolean isValid = true;
ServletOutputStream out = response.getOutputStream();
String versDate = DateUtility.convertDateToString(versDateTime);
StringBuffer html = new StringBuffer();
if (action != null && action.equals(GET_DISSEMINATION)) {
if (PID == null || sDefPID == null || methodName == null) {
// Dissemination requires PID, sDefPID, and methodName;
// asOfDateTime is optional.
response.setContentType(CONTENT_TYPE_HTML);
html.append("<html>");
html.append("<head>");
html.append("<title>FedoraAccessSOAPServlet</title>");
html.append("</head>");
html.append("<body>");
html.append("<p><font size='+1' color='red'>"
+ "Required parameter missing "
+ "in Dissemination Request:</font></p>");
html.append("<table cellpadding='5'>");
html.append("<tr>");
html.append("<td><font color='red'>action_</font></td>");
html.append("<td> = </td>");
html.append("<td>" + action + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>PID_</font></td>");
html.append("<td> = </td>");
html.append("<td>" + PID + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>sDefPID_</font></td>");
html.append("<td> = </td><td>" + sDefPID + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>methodName_</font></td>");
html.append("<td> = </td>");
html.append("<td>" + methodName + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>asOfDateTime_</font></td>");
html.append("<td> = </td>");
html.append("<td>" + versDate + "</td>");
html.append("<td><font color='green'>(OPTIONAL)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
html.append("<tr>");
html.append("<td colspan='5'><font size='+1' color='blue'>"
+ "Other Parameters Found:</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
for (Enumeration<String> e = h_userParms.keys(); e
.hasMoreElements();) {
String name = e.nextElement();
html.append("<tr>");
html.append("<td><font color='red'>" + name
+ "</font></td>");
html.append("<td>= </td>");
html.append("<td>" + h_userParms.get(name) + "</td>");
html.append("</tr>");
}
html.append("</table>");
html.append("</body>");
html.append("</html>");
out.println(html.toString());
isValid = false;
}
// FIXME!! Validation for any user-supplied parameters not
// implemented.
} else if (action != null
&& action.equals(GET_DATASTREAM_DISSEMINATION)) {
if (PID == null || dsID == null) {
response.setContentType(CONTENT_TYPE_HTML);
html.append("<html>");
html.append("<head>");
html.append("<title>FedoraAccessSOAPServlet</title>");
html.append("</head>");
html.append("<body>");
html.append("<p><font size='+1' color='red'>"
+ "Required parameter missing in " + action
+ " Request:</font></p>");
html.append("<table cellpadding='5'>");
html.append("<tr>");
html.append("<td><font color='red'>action_</td>");
html.append("<td> = </td>");
html.append("<td>" + action + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>PID_</td>");
html.append("<td> = </td>");
html.append("<td>" + PID + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>dsID_</td>");
html.append("<td> = </td>");
html.append("<td>" + PID + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>asOfDateTime_</td>");
html.append("<td> = </td>");
html.append("<td>" + versDate + "</td>");
html.append("<td><font color='green'>(OPTIONAL)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
html.append("<tr>");
html.append("<td colspan='5'><font size='+1' color='blue'>"
+ "Other Parameters Found:</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
for (Enumeration<String> e = h_userParms.keys(); e
.hasMoreElements();) {
String name = e.nextElement();
html.append("<tr>");
html.append("<td><font color='red'>" + name
+ "</font></td>");
html.append("<td>= </td>");
html.append("<td>" + h_userParms.get(name) + "</td>");
html.append("</tr>");
}
html.append("</table>");
html.append("</body>");
html.append("</html>");
out.println(html.toString());
isValid = false;
}
} else if (action != null
&& (action.equals(LIST_DATASTREAMS)
|| action.equals(LIST_METHODS) || action
.equals(GET_OBJECT_PROFILE))) {
if (PID == null) {
response.setContentType(CONTENT_TYPE_HTML);
html.append("<html>");
html.append("<head>");
html.append("<title>FedoraAccessSOAPServlet</title>");
html.append("</head>");
html.append("<body>");
html.append("<p><font size='+1' color='red'>"
+ "Required parameter missing in " + action
+ " Request:</font></p>");
html.append("<table cellpadding='5'>");
html.append("<tr>");
html.append("<td><font color='red'>action_</td>");
html.append("<td> = </td>");
html.append("<td>" + action + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>PID_</td>");
html.append("<td> = </td>");
html.append("<td>" + PID + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>asOfDateTime_</td>");
html.append("<td> = </td>");
html.append("<td>" + versDate + "</td>");
html.append("<td><font color='green'>(OPTIONAL)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
html.append("<tr>");
html.append("<td colspan='5'><font size='+1' color='blue'>"
+ "Other Parameters Found:</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
for (Enumeration<String> e = h_userParms.keys(); e
.hasMoreElements();) {
String name = e.nextElement();
html.append("<tr>");
html.append("<td><font color='red'>" + name
+ "</font></td>");
html.append("<td>= </td>");
html.append("<td>" + h_userParms.get(name) + "</td>");
html.append("</tr>");
}
html.append("</table>");
html.append("</body>");
html.append("</html>");
out.println(html.toString());
isValid = false;
}
} else if (action != null && action.equals(GET_OBJECT_HISTORY)) {
System.out.println("action: " + action + " PID: " + PID
+ "isValid: " + isValid);
if (PID == null) {
// GetObjectHistory requires PID;
// xml is optional.
response.setContentType(CONTENT_TYPE_HTML);
html.append("<html>");
html.append("<head>");
html.append("<title>FedoraAccessSOAPServlet</title>");
html.append("</head>");
html.append("<body>");
html.append("<p><font size='+1' color='red'>"
+ "Required parameter missing in " + action
+ " Request:</font></p>");
html.append("<table cellpadding='5'>");
html.append("<tr>");
html.append("<td><font color='red'>action_</td>");
html.append("<td> = </td>");
html.append("<td>" + action + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>PID_</td>");
html.append("<td> = </td>");
html.append("<td>" + PID + "</td>");
html.append("<td><font color='blue'>(REQUIRED)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>asOfDateTime_</td>");
html.append("<td> = </td>");
html.append("<td>" + versDate + "</td>");
html.append("<td><font color='green'>(OPTIONAL)</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
html.append("<tr>");
html.append("<td colspan='5'><font size='+1' color='blue'>"
+ "Other Parameters Found:</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
for (Enumeration<String> e = h_userParms.keys(); e
.hasMoreElements();) {
String name = e.nextElement();
html.append("<tr>");
html.append("<td><font color='red'>" + name
+ "</font></td>");
html.append("<td>= </td>");
html.append("<td>" + h_userParms.get(name) + "</td>");
html.append("</tr>");
}
html.append("</table>");
html.append("</body>");
html.append("</html>");
out.println(html.toString());
isValid = false;
}
} else if (action != null
&& action.equalsIgnoreCase(DESCRIBE_REPOSITORY)) {
System.out
.println("Validated DESCRIBE_REPOSITORY as good request w/no parms");
isValid = true;
} else {
System.out.println("action: " + action + " PID: " + PID
+ " isValid: " + isValid);
System.out.println("Unknown API-A request encountered.");
// Unknown Fedora service has been requested.
response.setContentType(CONTENT_TYPE_HTML);
html.append("<html>");
html.append("<head>");
html.append("<title>FedoraAccessSOAPServlet</title>");
html.append("</head>");
html.append("<body>");
html.append("<p><font size='+1' color='red'>Invalid 'action' "
+ "parameter specified in Servlet Request: action= "
+ action + "<p>");
html.append("<br></br><font color='blue'>Reserved parameters "
+ "in Request:</font>");
html.append("<table cellpadding='5'>");
html.append("<tr>");
html.append("<td><font color='red'>action_</td>");
html.append("<td> = </td>");
html.append("<td>" + action + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>PID_</td>");
html.append("<td> = </td>");
html.append("<td>" + PID + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>sDefPID_</td>");
html.append("<td> = </td>");
html.append("<td>" + sDefPID + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>methodName_</td>");
html.append("<td> = </td>");
html.append("<td>" + methodName + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>asOfDateTime_</td>");
html.append("<td> = </td>");
html.append("<td>" + versDate + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
html.append("<tr>");
html.append("<td colspan='5'><font size='+1' color='blue'>"
+ "Other Parameters Found:</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
for (Enumeration<String> e = h_userParms.keys(); e
.hasMoreElements();) {
String name = e.nextElement();
html.append("<tr>");
html.append("<td><font color='red'>" + name + "</font></td>");
html.append("<td>= </td>");
html.append("<td>" + h_userParms.get(name) + "</td>");
html.append("</tr>");
}
html.append("</table>");
html.append("</body>");
html.append("</html>");
out.println(html.toString());
isValid = false;
}
return isValid;
}
/**
* <p>
* Displays a list of the servlet input parameters. This method is generally
* called when a service request returns no data. Usually this is a result
* of an incorrect spelling of either a required URL parameter or in one of
* the user-supplied parameters. The output from this method can be used to
* help verify the URL parameters sent to the servlet and hopefully fix the
* problem.
* </p>
*
* @param action
* The Fedora service requested.
* @param PID
* The persistent identifier of the digital object.
* @param sDefPID
* The persistent identifier of the Service Definition object.
* @param methodName
* the name of the method.
* @param asOfDateTime
* The version datetime stamp of the digital object.
* @param userParms
* An array of user-supplied method parameters and values.
* @param response
* The servlet response.
* @param message
* The message text to include at the top of the output page.
* @throws IOException
* If an error occurrs with an input or output operation.
*/
private void showURLParms(String action,
String PID,
String sDefPID,
String methodName,
String asOfDateTime,
Property[] userParms,
HttpServletResponse response,
String message) throws IOException {
ServletOutputStream out = response.getOutputStream();
response.setContentType(CONTENT_TYPE_HTML);
// Display servlet input parameters
StringBuffer html = new StringBuffer();
html.append("<html>");
html.append("<head>");
html.append("<title>FedoraAccessSOAPServlet</title>");
html.append("</head>");
html.append("<body>");
html.append("<br></br><font size='+2'>" + message + "</font>");
html.append("<br></br><font color='red'>Request Parameters</font>");
html.append("<br></br>");
html.append("<table cellpadding='5'>");
html.append("<tr>");
html.append("<td><font color='red'>action_</font></td>");
html.append("<td> = </td>");
html.append("<td>" + action + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>PID_</font></td>");
html.append("<td> = </td>");
html.append("<td>" + PID + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>sDefPID_</font></td>");
html.append("<td> = </td>");
html.append("<td>" + sDefPID + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>methodName_</font></td>");
html.append("<td> = </td>");
html.append("<td>" + methodName + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td><font color='red'>asOfDateTime_</font></td>");
html.append("<td> = </td>");
html.append("<td>" + asOfDateTime + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
html.append("<tr>");
html.append("<td colspan='5'><font size='+1' color='blue'>"
+ "Other Parameters Found:</font></td>");
html.append("</tr>");
html.append("<tr>");
html.append("</tr>");
// List user-supplied parameters if any
if (userParms != null) {
for (Property element : userParms) {
html.append("<tr>");
html.append("<td><font color='red'>" + element.getName()
+ "</font></td>");
html.append("<td> = </td>");
html.append("<td>" + element.getValue() + "</td>");
html.append("</tr>");
}
}
html.append("</table>");
html.append("</body></html>");
out.println(html.toString());
System.err.println("REQUEST Returned NO Data");
}
}