
demo-soapclient.DemoSOAPClient Maven / Gradle / Ivy
Show all versions of fcrepo-client Show documentation
package demo.soapclient;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.MalformedURLException;
import java.rmi.RemoteException;
import java.util.StringTokenizer;
import java.util.HashMap;
import javax.xml.rpc.ServiceException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import fedora.client.FedoraClient;
import fedora.server.management.FedoraAPIM;
import fedora.server.access.FedoraAPIA;
import fedora.server.types.gen.DatastreamDef;
import fedora.server.types.gen.MethodParmDef;
import fedora.server.types.gen.MIMETypedStream;
import fedora.server.types.gen.ObjectMethodsDef;
import fedora.server.types.gen.ObjectProfile;
import fedora.server.types.gen.RepositoryInfo;
import fedora.server.types.gen.Property;
/**
*
* Title: DemoSOAPClient
* Description: A simple example on how to write a SOAP client that
* makes calls to the Fedora SOAP interfaces (API-A and API-M).
*
* -----------------------------------------------------------------------------
*
* License and Copyright: The contents of this file are subject to the
* Mozilla Public License Version 1.1 (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.mozilla.org/MPL/.
*
* 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 © 2002-2004 by The
* Rector and Visitors of the University of Virginia and Cornell University.
* All rights reserved.
*
* -----------------------------------------------------------------------------
*
* @author [email protected]
*/
public class DemoSOAPClient {
private static FedoraAPIM APIM;
private static FedoraAPIA APIA;
private static HashMap s_repoInfo=new HashMap();
public DemoSOAPClient(String protocol, String host, int port, String user, String pass)
throws Exception {
// Use the FedoraClient utility to get SOAP stubs.
// These SOAP stubs enable the client to connect to a Fedora repository
// via the API-A and API-M web service interfaces.
String baseURL = protocol + "://" + host + ":" + port + "/fedora";
FedoraClient fc = new FedoraClient(baseURL, user, pass);
APIA=fc.getAPIA();
APIM=fc.getAPIM();
}
public RepositoryInfo describeRepository()
throws RemoteException {
// make the SOAP call on API-A using the connection stub
RepositoryInfo repoinfo = APIA.describeRepository();
// print results
System.out.println("SOAP Request: describeRepository...");
System.out.println("SOAP Response: repository version = " + repoinfo.getRepositoryVersion());
System.out.println("SOAP Response: repository name = " + repoinfo.getRepositoryName());
System.out.println("SOAP Response: repository pid namespace = " + repoinfo.getRepositoryPIDNamespace());
System.out.println("SOAP Response: repository default export = " + repoinfo.getDefaultExportFormat());
System.out.println("SOAP Response: repository base URL = " + repoinfo.getRepositoryBaseURL());
System.out.println("SOAP Response: repository OAI namespace = " + repoinfo.getOAINamespace());
System.out.println("SOAP Response: repository sample OAI identifier = " + repoinfo.getSampleOAIIdentifier());
System.out.println("SOAP Response: repository sample OAI URL = " + repoinfo.getSampleOAIURL());
System.out.println("SOAP Response: repository sample access URL = " + repoinfo.getSampleAccessURL());
System.out.println("SOAP Response: repository sample search URL = " + repoinfo.getSampleSearchURL());
System.out.println("SOAP Response: repository sample PID = " + repoinfo.getSamplePID());
return repoinfo;
}
public String ingest(InputStream ingestStream, String ingestFormat, String logMessage)
throws RemoteException, IOException {
// prep
ByteArrayOutputStream out=new ByteArrayOutputStream();
pipeStream(ingestStream, out, 4096);
// make the SOAP call on API-M using the connection stub
String pid = APIM.ingest(out.toByteArray(), ingestFormat, logMessage);
System.out.println("SOAP Request: ingest...");
System.out.println("SOAP Response: pid = " + pid);
return pid;
}
public String addDatastream(String pid, String dsID, String[] altIDs, String dsLabel,
boolean versionable, String dsMIME, String formatURI,
String dsLocation, String dsControlGroup, String dsState,
String checksumType, String checksum, String logMessage)
throws RemoteException {
// make the SOAP call on API-M using the connection stub
String datastreamID = APIM.addDatastream(
pid, dsID, altIDs, dsLabel, versionable, dsMIME, formatURI,
dsLocation, dsControlGroup, dsState, checksumType, checksum, logMessage);
System.out.println("SOAP Request: addDatastream...");
System.out.println("SOAP Response: datastreamID = " + datastreamID);
return datastreamID;
}
public String modifyDatastreamByReference(String pid, String dsID, String[] altIDs, String dsLabel,
String dsMIME, String formatURI, String dsLocation,
String checksumType, String checksum,
String logMessage, boolean force)
throws RemoteException {
// make the SOAP call on API-M using the connection stub
String datastreamID = APIM.modifyDatastreamByReference(
pid, dsID, altIDs, dsLabel, dsMIME,
formatURI, dsLocation, checksumType, checksum, logMessage, force);
System.out.println("SOAP Request: modifyDatastreamByReference...");
System.out.println("SOAP Response: datastreamID = " + datastreamID);
return datastreamID;
}
public String[] purgeDatastream(String pid, String dsID, String startDate, String endDate,
String logMessage, boolean force)
throws RemoteException {
// make the SOAP call on API-M using the connection stub
String[] dateTimeStamps = APIM.purgeDatastream(
pid, dsID, startDate, endDate, logMessage, force);
System.out.println("SOAP Request: purgeDatastream...");
return dateTimeStamps;
}
public String purgeObject(String pid, String logMessage, boolean force)
throws RemoteException {
// make the SOAP call on API-M using the connection stub
String purgeDateTime = APIM.purgeObject(pid, logMessage, force);
System.out.println("SOAP Request: purgeObject...");
System.out.println("SOAP Response: purge dateTime = " + purgeDateTime);
return purgeDateTime;
}
public byte[] export(String pid, String format, String exportContext, OutputStream outStream)
throws RemoteException, IOException {
// make the SOAP call on API-M
byte[] objectXML = APIM.export(pid, format, exportContext);
// serialize the object XML to the specified output stream
try {
// use Xerces to pretty print the xml, assuming it's well formed
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc=builder.parse(new ByteArrayInputStream(objectXML));
OutputFormat fmt=new OutputFormat("XML", "UTF-8", true);
fmt.setIndent(2);
fmt.setLineWidth(120);
fmt.setPreserveSpace(false);
XMLSerializer ser=new XMLSerializer(outStream, fmt);
ser.serialize(doc);
} catch (Exception e) {
System.out.println("Error on export while serializing object XML." +
e.getClass().getName() + " : " + e.getMessage());
} finally {
outStream.close();
}
// print results
System.out.println("SOAP Request: export...");
System.out.println("SOAP Response: see result serialized in XML export file.");
return objectXML;
}
public byte[] getObjectXML(String pid)
throws RemoteException {
// make the SOAP call on API-M
byte[] objectXML = APIM.getObjectXML(pid);
// print results
return objectXML;
}
/**
* Copies the contents of an InputStream to an OutputStream, then closes
* both.
*
* @param in The source stream.
* @param out The target stram.
* @param bufSize Number of bytes to attempt to copy at a time.
* @throws IOException If any sort of read/write error occurs on either
* stream.
*/
public static void pipeStream(InputStream in, OutputStream out, int bufSize)
throws IOException {
try {
byte[] buf = new byte[bufSize];
int len;
while ( ( len = in.read( buf ) ) > 0 ) {
out.write( buf, 0, len );
}
} finally {
try {
in.close();
out.close();
} catch (IOException e) {
System.err.println("WARNING: Could not close stream.");
}
}
}
public static void main(String[] args) {
try {
if (args.length==5) {
if (!args[0].equals("http") && !args[0].equals("https")) {
throw new Exception("Protocol must be either \"http\" or \"https\". Value specified was: \""+args[0]+"\".");
}
System.out.println("\n");
System.out.println("Protocol: " + args[0]);
System.out.println("Host: " + args[1]);
System.out.println("Port: " + args[2]);
System.out.println("Username: " + args[3]);
System.out.println("Password: " + args[4] + "\n");
// Instantiate the demo client.
// This will set up connection stubs for making SOAP requests on API-A and API-M
DemoSOAPClient caller = new DemoSOAPClient(args[0],
args[1], new Integer(args[2]).intValue(),
args[3], args[4]);
//**************************************************************
//******** STEP 1 : get info about the repository
//**************************************************************
System.out.println("\nTest describeRepository..........................................");
RepositoryInfo repoinfo = caller.describeRepository();
//**************************************************************
// ******** STEP 2 purge test objects if they already exist
//**************************************************************
String purgeDate=null;
try {
purgeDate = caller.purgeObject(
"test:100", // the object pid
"purge object", // an optional log message about the change
false); // do not force changes that break ref integrity
} catch (Exception e) {
System.out.println("Hack...just ignore failures since objects may not exist yet." + e.getMessage());
}
try {
purgeDate = caller.purgeObject(
"test:28", // the object pid
"purge object", // an optional log message about the change
false); // do not force changes that break ref integrity
} catch (Exception e) {
System.out.println("Hack...just ignore failures since objects may not exist yet." + e.getMessage());
}
try {
purgeDate = caller.purgeObject(
"test:27", // the object pid
"purge object", // an optional log message about the change
false); // do not force changes that break ref integrity
} catch (Exception e) {
System.out.println("Hack...just ignore failures since objects may not exist yet." + e.getMessage());
}
//**************************************************************
//******** STEP 3: ingest the test objects
//**************************************************************
FileInputStream inStream=null;
String ingestPID=null;
System.out.println("\nTest ingest......................................................");
File ingestFile=new File("TestIngestFiles/bdef_test_27.xml");
try {
inStream=new FileInputStream(ingestFile);
} catch (IOException ioe) {
System.out.println("Error on ingest file inputstream: " + ioe.getMessage());
ioe.printStackTrace();
}
ingestPID = caller.ingest(inStream, "foxml1.0", "ingest of test bdef");
System.out.println("Finished test ingest of bdef object: " + ingestPID);
System.out.println("\nTest ingest......................................................");
ingestFile=new File("TestIngestFiles/bmech_test_28.xml");
inStream=null;
try {
inStream=new FileInputStream(ingestFile);
} catch (IOException ioe) {
System.out.println("Error on ingest file inputstream: " + ioe.getMessage());
ioe.printStackTrace();
}
ingestPID = caller.ingest(inStream, "foxml1.0", "ingest of test bmech");
System.out.println("Finished test ingest of bmech object: " + ingestPID);
System.out.println("\nTest ingest......................................................");
ingestFile=new File("TestIngestFiles/obj_test_100.xml");
inStream=null;
try {
inStream=new FileInputStream(ingestFile);
} catch (IOException ioe) {
System.out.println("Error on ingest file inputstream: " + ioe.getMessage());
ioe.printStackTrace();
}
ingestPID = caller.ingest(inStream, "foxml1.0", "ingest of test object");
System.out.println("Finished test ingest of data object: " + ingestPID);
//**************************************************************
//******** STEP 4: add a datastream to the object
//**************************************************************
System.out.println("\nTest add datastream..............................................");
String[] altIDs = new String[] {"id1", "id2", "id3"};
String datastreamID = caller.addDatastream(
ingestPID, // the object pid
"MY-DS", // user-assigned datastream name or id
altIDs,
"Add my test datastream", // user-assigned label
true, // in version 2.0 always set datastream versioning to true
"image/gif", // mime type of the datastream content
"info:fedora/format/myformat", // an optional format URI
"http://www.cs.cornell.edu/payette/images/sjcomp.gif", // URL for content
"E", // type E for External Referenced Datastream
"A", // datastream state is A for Active
null, // datastream checksumType
null, // datastream checksum
"added new datastream MY-DS"); // log message
//**************************************************************
//******** STEP 5: modify a datastream
//**************************************************************
// modify the datastream using null to indicate which attributes should stay the same.
System.out.println("\nFirst test of modify datastream .................................");
String modDSID = caller.modifyDatastreamByReference(
ingestPID, // the object pid
"MY-DS", // user-assigned datastream name or id
null, // altIDs (no change)
"modify-1 of my test datastream", // new user-assigned label
null, // MIME type (no change)
null, // new formatURI (no change)
null, // new URL for content (no change)
null, // new checksumType
null, // new checksum
"first modify to change label only", // an optional log message about the change
false); // do not force changes that break ref integrity
//**************************************************************
//******** STEP 6: modify a datastream again
//**************************************************************
// again, modify the datastream and test setting attributes to empty strings.
// NOTE: attempt to set system required attribute to empty will default to no change.
System.out.println("\nSecond test of modify datastream.................................");
modDSID = caller.modifyDatastreamByReference(
ingestPID, // the object pid
"MY-DS", // user-assigned datastream name or id
new String[0], // altIDs (empty array)
"", // new user-assigned label
"", // MIME type (empty)
"", // new formatURI (empty)
"", // new URL for content (no change since required field cannot be emptied)
null, // new checksumType
null, // new checksum
"second modify to empty all non-required fields", // an optional log message about the change
false); // do not force changes that break ref integrity
//**************************************************************
//******** STEP 7: purge a datastream
//**************************************************************
System.out.println("\nTest of purge datastream.........................................");
String[] dateTimeStamps = caller.purgeDatastream(
ingestPID, // the object pid
"MY-DS", // user-assigned datastream name or id
"",
"", // end date to purge versions before (null/empty to purge all versions)
"purge datastream", // an optional log message about the change
false); // do not force changes that break ref integrity
//**************************************************************
//******** STEP 8: export the demo object
//**************************************************************
System.out.println("\nTest of export object............................................");
File exportFile = new File("demo-export.xml");
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(exportFile);
} catch (IOException ioe) {
System.out.println("Error on export output stream: " + ioe.getMessage());
ioe.printStackTrace();
}
byte[] objectXML = caller.export(ingestPID, "foxml1.0", null, outStream);
//**************************************************************
//******** NOW TEST API-A METHODS
//**************************************************************
//**************************************************************
//******** STEP 9: listDatastreams for demo object demo:11
//**************************************************************
System.out.println("\nTest of listDatastream...........................................");
listDatastreams();
//**************************************************************
//******** STEP 10: listMethods for demo object demo:11
//**************************************************************
System.out.println("\nTest of listMethods..............................................");
listMethods();
//**************************************************************
//******** STEP 11: get the object profile for demo object demo:11
//**************************************************************
System.out.println("\nTest of getObjectProfile.........................................");
getObjectProfile();
//**************************************************************
//******** STEP 12: get several datastreams from various demo objects
//**************************************************************
System.out.println("\nTest of getDatastreamDissemination...............................");
getDatastreamDissemination();
//**************************************************************
//******** STEP 13: get several disseminations from various demo objects
//**************************************************************
System.out.println("\nTest of getDissemination.........................................");
getDissemination();
//**************************************************************
//******** STEP 14: get object history the demo object demo:11
//**************************************************************
System.out.println("\nTest of getObjectHistory.........................................");
getObjectHistory();
} else {
System.out.println("Number of arguments must be equal to 5.");
System.out.println("Usage: run-demo-soapclient protocol host port username password");
System.out.println("Demo soapclient requires that demo objects are already ingested in repository \n");
}
} catch (Exception e) {
System.out.println("Exception in main: " + e.getMessage());
e.printStackTrace();
}
}
public static void listDatastreams() throws Exception {
DatastreamDef[] dsDefs = APIA.listDatastreams("demo:11", null);
System.out.println("SOAP Request: listDatastreams...");
System.out.println("SOAP Response: see results below.");
verifyDatastreamDefs(dsDefs, "SOAP Response: listDatastream: ");
}
public static void listMethods() throws Exception {
ObjectMethodsDef[] methodDefs = APIA.listMethods("demo:11", null);
System.out.println("SOAP Request: listMethods...");
System.out.println("SOAP Response: see results below.");
verifyObjectMethods(methodDefs, "SOAP Response: listMethods: ");
}
public static void getDatastreamDissemination() throws Exception {
// test for DC datastream
MIMETypedStream ds = null;
ds = APIA.getDatastreamDissemination("demo:11", "DC", null);
System.out.println("SOAP Request: getDatastreamDissemination for DC datastream of demo object demo:11...");
String dsXML = new String(ds.getStream(), "UTF-8");
System.out.println("SOAP Response: GetDatastreamDissemination Object:demo:11 Datastream:DC succeeded.");
System.out.println("SOAP Response: DC datastream contents: \n"+dsXML);
// test for type X datastream
ds = APIA.getDatastreamDissemination("demo:11", "TECH1", null);
System.out.println("\nSOAP Request: getDatastreamDissemination for TECH1 datastream of demo object demo:11...");
dsXML = new String(ds.getStream(), "UTF-8");
System.out.println("SOAP Response: GetDatastreamDissemination Object:demo:11 Datastream:TECH1 succeeded.");
System.out.println("SOAP Response: TECH1 datastream contents: \n"+dsXML);
// test for type E datastream
ds = APIA.getDatastreamDissemination("demo:11", "DS1", null);
System.out.println("\nSOAP Request: getDatastreamDissemination for DS1 datastream of demo object demo:11...");
System.out.println("SOAP Response: GetDatastreamDissemination Object:demo:11 Datastream:DS1 succeeded.");
System.out.println("SOAP Response: DS1 datastream contents: BINARY DATA "+ds);
// test for type R datastream
ds = APIA.getDatastreamDissemination("demo:30", "DS1", null);
System.out.println("\nSOAP Request: getDatastreamDissemination for DS1 datastream of demo object demo:30...");
System.out.println("SOAP Response: GetDatastreamDissemination Object:demo:30 Datastream:DS1 succeeded.");
System.out.println("SOAP Response: DS1 datastream contents: BINARY DATA "+ds);
// test for type M datastream
ds = APIA.getDatastreamDissemination("demo:5", "DS1", null);
System.out.println("\nSOAP Request: getDatastreamDissemination for DS1 datastream of demo object demo:5...");
System.out.println("SOAP Response: GetDatastreamDissemination Object:demo:5 Datastream:DS1 succeeded.");
System.out.println("SOAP Response: DS1 datastream contents: BINARY DATA "+ds);
}
public static void getObjectProfile() throws Exception {
ObjectProfile profile = APIA.getObjectProfile("demo:11", null);
System.out.println("SOAP Request: getObjectProfile for demo object demo:11...");
System.out.println("SOAP Response: PID: "+profile.getPid());
System.out.println("SOAP Response: ObjectType: "+profile.getObjType());
System.out.println("SOAP Response: ObjectLabel: "+profile.getObjLabel());
System.out.println("SOAP Response: CreateDate: "+profile.getObjCreateDate());
System.out.println("SOAP Response: LastModDate: "+profile.getObjLastModDate());
System.out.println("SOAP Response: ContentModel: "+profile.getObjContentModel());
System.out.println("SOAP Response: DissIndexViewURL: "+profile.getObjDissIndexViewURL());
System.out.println("SOAP Response: ItemIndexViewURL: "+profile.getObjItemIndexViewURL());
}
public static void getObjectHistory() throws Exception {
String[] timestamps = APIA.getObjectHistory("demo:11");
System.out.println("SOAP Request: getObjectHistory for demo object demo:11...");
for (int i=0; i