/* 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.server.management; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import fedora.server.Context; import fedora.server.errors.ServerException; import fedora.server.journal.JournalConstants; import fedora.server.storage.types.Datastream; import fedora.server.storage.types.RelationshipTuple; /** * A generic management delegate for use in Journal unit testing. Each method * call generates a {@link Call} object which is added to a list of calls for * later inspection. The method then returns some plausible result value if * required. * * @author Firstname Lastname */ public class MockManagementDelegate implements ManagementDelegate { // ---------------------------------------------------------------------- // Mocking infrastructure // ---------------------------------------------------------------------- /** * A data class that holds the information from a method call: method name * and method arguments. */ public static class Call { private final String methodName; private final Object[] methodArgs; public Call(String methodName, Object... methodArgs) { this.methodName = methodName; this.methodArgs = methodArgs; } public String getMethodName() { return methodName; } public Object[] getMethodArgs() { return methodArgs; } @Override public String toString() { return "Call[" + methodName + ", " + Arrays.deepToString(methodArgs) + "]"; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null) { return false; } if (!Call.class.equals(obj.getClass())) { return false; } Call that = (Call) obj; return methodName.equals(that.methodName) && equalArgs(methodArgs, that.methodArgs); } private boolean equalArgs(Object[] args1, Object[] args2) { if (args1.length != args2.length) { return false; } for (int i = 0; i < args1.length; i++) { if (args1[i] instanceof InputStream && args2[i] instanceof InputStream) { // Input streams are considered equal, even if different types, // and without testing the contents. continue; } else if (args1[i] instanceof Object[] && args2[i] instanceof Object[]) { // Arrays are compared for equal members, not identical members. if (Arrays.deepEquals((Object[]) args1[i], (Object[]) args2[i])) { continue; } } else if (args1[i].equals(args2[i])) { continue; } return false; } return true; } @Override public int hashCode() { return methodName.hashCode() ^ Arrays.asList(methodArgs).hashCode(); } } private final List<Call> calls = new ArrayList<Call>(); public void reset() { calls.clear(); } public int getCallCount() { return calls.size(); } public List<Call> getCalls() { return new ArrayList<Call>(calls); } // ---------------------------------------------------------------------- // Mocked methods // ---------------------------------------------------------------------- public String addDatastream(Context context, String pid, String dsID, String[] altIDs, String dsLabel, boolean versionable, String MIMEType, String formatURI, String location, String controlGroup, String dsState, String checksumType, String checksum, String logMessage) throws ServerException { calls.add(new Call(JournalConstants.METHOD_ADD_DATASTREAM, context, pid, dsID, altIDs, dsLabel, versionable, MIMEType, formatURI, location, controlGroup, dsState, checksumType, checksum, logMessage)); return dsID; } public boolean adminPing(Context context) throws ServerException { calls.add(new Call("adminPing", context)); return true; } public boolean addRelationship(Context context, String subject, String relationship, String object, boolean isLiteral, String datatype) throws ServerException { calls.add(new Call(JournalConstants.METHOD_ADD_RELATIONSHIP, context, subject, relationship, object, isLiteral, datatype)); return true; } public String compareDatastreamChecksum(Context context, String pid, String dsID, Date asOfDateTime) throws ServerException { calls.add(new Call("compareDatastreamChecksum", context, pid, dsID, asOfDateTime)); return "bogusChecksum"; } public InputStream export(Context context, String pid, String format, String exportContext, String encoding) throws ServerException { calls.add(new Call("export", context, pid, format, exportContext, encoding)); return new ByteArrayInputStream(new byte[0]); } public Datastream getDatastream(Context context, String pid, String datastreamID, Date asOfDateTime) throws ServerException { calls.add(new Call("getDatastream", context, pid, datastreamID, asOfDateTime)); return null; } public Datastream[] getDatastreamHistory(Context context, String pid, String datastreamID) throws ServerException { calls.add(new Call("getDatastreamHistory", context, pid, datastreamID)); return new Datastream[0]; } public Datastream[] getDatastreams(Context context, String pid, Date asOfDateTime, String dsState) throws ServerException { calls.add(new Call("getDatastreams", context, pid, asOfDateTime, dsState)); return new Datastream[0]; } public String[] getNextPID(Context context, int numPIDs, String namespace) throws ServerException { calls.add(new Call("getNextPID", context, numPIDs, namespace)); String[] result = new String[numPIDs]; for (int i = 0; i < result.length; i++) { result[i] = "sillyPID_" + i; } return result; } public InputStream getObjectXML(Context context, String pid, String encoding) { calls.add(new Call("getObjectXML", context, pid, encoding)); return new ByteArrayInputStream(new byte[0]); } public RelationshipTuple[] getRelationships(Context context, String subject, String relationship) throws ServerException { calls.add(new Call("getRelationships", context, subject, relationship)); return new RelationshipTuple[0]; } public InputStream getTempStream(String id) throws ServerException { calls.add(new Call("getTempStream", id)); return new ByteArrayInputStream(new byte[0]); } public String ingest(Context context, InputStream serialization, String logMessage, String format, String encoding, boolean newPid) throws ServerException { calls.add(new Call(JournalConstants.METHOD_INGEST, context, serialization, logMessage, format, encoding, newPid)); return "Ingest:" + getCallCount(); } public Date modifyDatastreamByReference(Context context, String pid, String datastreamID, String[] altIDs, String dsLabel, String mimeType, String formatURI, String dsLocation, String checksumType, String checksum, String logMessage, boolean force) throws ServerException { calls .add(new Call(JournalConstants.METHOD_MODIFY_DATASTREAM_BY_REFERENCE, context, pid, datastreamID, altIDs, dsLabel, mimeType, formatURI, dsLocation, checksumType, checksum, logMessage, force)); return new Date(111111L); } public Date modifyDatastreamByValue(Context context, String pid, String datastreamID, String[] altIDs, String dsLabel, String mimeType, String formatURI, InputStream dsContent, String checksumType, String checksum, String logMessage, boolean force) throws ServerException { calls.add(new Call(JournalConstants.METHOD_MODIFY_DATASTREAM_BY_VALUE, context, pid, datastreamID, altIDs, dsLabel, mimeType, formatURI, dsContent, checksumType, checksum, logMessage, force)); return new Date(222222L); } public Date modifyObject(Context context, String pid, String state, String label, String ownerId, String logMessage) throws ServerException { calls.add(new Call(JournalConstants.METHOD_MODIFY_OBJECT, context, pid, state, label, ownerId, logMessage)); return new Date(10000L); } public Date[] purgeDatastream(Context context, String pid, String datastreamID, Date startDT, Date endDT, String logMessage, boolean force) throws ServerException { calls.add(new Call(JournalConstants.METHOD_PURGE_DATASTREAM, context, pid, datastreamID, startDT, endDT, logMessage, force)); return new Date[0]; } public Date purgeObject(Context context, String pid, String logMessage, boolean force) throws ServerException { calls.add(new Call(JournalConstants.METHOD_PURGE_OBJECT, context, pid, logMessage, force)); return new Date(654L); } public boolean purgeRelationship(Context context, String subject, String relationship, String object, boolean isLiteral, String datatype) throws ServerException { calls.add(new Call(JournalConstants.METHOD_PURGE_RELATIONSHIP, context, subject, relationship, object, isLiteral, datatype)); return false; } public String putTempStream(Context context, InputStream in) throws ServerException { calls .add(new Call(JournalConstants.METHOD_PUT_TEMP_STREAM, context, in)); return "tempStreamId"; } public Date setDatastreamState(Context context, String pid, String dsID, String dsState, String logMessage) throws ServerException { calls.add(new Call(JournalConstants.METHOD_SET_DATASTREAM_STATE, context, pid, dsID, dsState, logMessage)); return new Date(3000000L); } public Date setDatastreamVersionable(Context context, String pid, String dsID, boolean versionable, String logMessage) throws ServerException { calls.add(new Call(JournalConstants.METHOD_SET_DATASTREAM_VERSIONABLE, context, pid, dsID, versionable, logMessage)); return new Date(234234L); } // ---------------------------------------------------------------------- // Un-implemented methods // ---------------------------------------------------------------------- }