Skip to content

Commit

Permalink
added versioning endpoint & tests, but still needs some work on the i…
Browse files Browse the repository at this point in the history
…mplementation layer
  • Loading branch information
fasseg committed May 6, 2013
1 parent 5421391 commit 4e609d2
Show file tree
Hide file tree
Showing 3 changed files with 351 additions and 0 deletions.
184 changes: 184 additions & 0 deletions fcrepo-http-api/src/main/java/org/fcrepo/api/FedoraVersions.java
@@ -0,0 +1,184 @@
package org.fcrepo.api;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Response;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

import org.fcrepo.AbstractResource;
import org.fcrepo.Datastream;
import org.fcrepo.FedoraObject;
import org.fcrepo.jaxb.responses.access.ObjectProfile;
import org.fcrepo.jaxb.responses.management.DatastreamProfile;
import org.fcrepo.jaxb.responses.management.DatastreamProfile.DatastreamStates;
import org.fcrepo.services.DatastreamService;
import org.fcrepo.services.ObjectService;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Path("/rest/{path: .*}/fcr:versions")
public class FedoraVersions extends AbstractResource {

private static final Logger logger = LoggerFactory.getLogger(FedoraVersions.class);

private DateTimeFormatter jcrDateFormat = ISODateTimeFormat.dateTime();

Pattern dspattern = Pattern.compile("/objects/[^/]+?/[^/]+?");


@Autowired
private DatastreamService datastreamService;

@Autowired
private ObjectService objectService;

public void setDatastreamService(DatastreamService datastreamService) {
this.datastreamService = datastreamService;
}

public void setObjectService(ObjectService objectService) {
this.objectService = objectService;
}

@GET
@Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_JSON })
public List<Version> getVersionProfile(@PathParam("path") final List<PathSegment> segments) throws RepositoryException {
final String path = toPath(segments);
final Session sess = getAuthenticatedSession();
// TODO: this shoul dbe done otherwise but the path constraints are forcing this one me atm
Matcher m = dspattern.matcher(path);
if (m.find()) {
/* TODO: this should be moved to datastreamservice */
Datastream ds = datastreamService.getDatastream(sess, path);
Version v = new Version(path, ds.getDsId(), ds.getLabel(), ds.getCreatedDate());
return Arrays.asList(v);
} else {
/* TODO: this should be moved to object service */
FedoraObject obj = objectService.getObject(sess, path);
Version v = new Version(path, obj.getName(), obj.getName(), jcrDateFormat.parseDateTime(obj.getCreated()).toDate());
return Arrays.asList(v);
}

}

@Path("/{id}")
@GET
@Produces({ MediaType.TEXT_XML, MediaType.APPLICATION_XML })
public Response getVersion(@PathParam("path") final List<PathSegment> segments, @PathParam("id") final String id)
throws RepositoryException, IOException {
final String path = toPath(segments);
final Session sess = getAuthenticatedSession();
Matcher m = dspattern.matcher(path);
if (m.find()) {
/* TODO: this should be moved to datastreamservice */
Datastream ds = datastreamService.getDatastream(sess, path);
return Response.ok(getDSProfile(ds)).build();
} else {
/* TODO: this should be moved to objectservice */
return Response.ok(getObjectProfile(objectService.getObject(sess, path))).build();
}
}

private ObjectProfile getObjectProfile(FedoraObject object) throws RepositoryException {
ObjectProfile prof = new ObjectProfile();
prof.objCreateDate = object.getCreated();
prof.objLabel = object.getLabel();
prof.objLastModDate = object.getLastModified();
prof.objSize = object.getSize();
prof.objOwnerId = object.getOwnerId();
prof.objModels = object.getModels();
return prof;
}

/* TODO: this is a duplicate of FedoraDatatstreams.getDSProfile and should be merged into one method */
private DatastreamProfile getDSProfile(final Datastream ds)
throws RepositoryException, IOException {
logger.trace("Executing getDSProfile() with node: " + ds.getDsId());
final DatastreamProfile dsProfile = new DatastreamProfile();
dsProfile.dsID = ds.getDsId();
dsProfile.pid = ds.getObject().getName();
logger.trace("Retrieved datastream " + ds.getDsId() + "'s parent: " +
dsProfile.pid);
dsProfile.dsLabel = ds.getLabel();
logger.trace("Retrieved datastream " + ds.getDsId() + "'s label: " +
ds.getLabel());
dsProfile.dsOwnerId = ds.getOwnerId();
dsProfile.dsChecksumType = ds.getContentDigestType();
dsProfile.dsChecksum = ds.getContentDigest();
dsProfile.dsState = DatastreamStates.A;
dsProfile.dsMIME = ds.getMimeType();
dsProfile.dsSize = ds.getSize();
dsProfile.dsCreateDate = ds.getCreatedDate().toString();
return dsProfile;
}

@XmlRootElement(name = "datastream-version")
@XmlAccessorType(XmlAccessType.FIELD)
public static class Version {

@XmlAttribute(name = "path")
private String path;

@XmlAttribute(name = "name")
private String name;

@XmlAttribute(name = "pid")
private String id;

@XmlAttribute(name = "created")
private Date created;

public Version(String path, String id, String name, Date created) {
super();
this.path = path;
this.name = name;
this.id = id;
this.created = created;
}

private Version() {
super();
}

public String getId() {
return id;
}

public Date getCreated() {
return created;
}

public String getName() {
return name;
}

public String getPath() {
return path;
}
}
}
120 changes: 120 additions & 0 deletions fcrepo-http-api/src/test/java/org/fcrepo/api/FedoraVersionsTest.java
@@ -0,0 +1,120 @@
package org.fcrepo.api;

import static org.fcrepo.test.util.PathSegmentImpl.createPathList;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.junit.Assert.*;

import java.util.List;

import javax.jcr.LoginException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;

import org.fcrepo.Datastream;
import org.fcrepo.FedoraObject;
import org.fcrepo.api.FedoraVersions.Version;
import org.fcrepo.jaxb.responses.management.DatastreamProfile;
import org.fcrepo.services.DatastreamService;
import org.fcrepo.services.ObjectService;
import org.fcrepo.session.SessionFactory;
import org.fcrepo.test.util.TestHelpers;
import org.fcrepo.utils.FedoraJcrTypes;
import org.fcrepo.utils.FedoraTypesUtils;
import org.junit.Before;
import org.junit.Test;

import com.google.common.base.Predicate;

public class FedoraVersionsTest {

FedoraVersions fedoraVersions;

ObjectService mockObjects;

DatastreamService mockDatastreams;

Session mockSession;

FedoraObject mockObject;


@Before
public void setUp() throws LoginException, RepositoryException {
mockObjects = mock(ObjectService.class);
mockDatastreams = mock(DatastreamService.class);
fedoraVersions = new FedoraVersions();
mockSession = mock(Session.class);
final SessionFactory mockSessions = mock(SessionFactory.class);
when(mockSessions.getSession()).thenReturn(mockSession);
when(mockSessions.getSession(any(SecurityContext.class),any(HttpServletRequest.class))).thenReturn(mockSession);
fedoraVersions.setSessionFactory(mockSessions);
fedoraVersions.setUriInfo(TestHelpers.getUriInfoImpl());
fedoraVersions.setObjectService(mockObjects);
fedoraVersions.setDatastreamService(mockDatastreams);

mockObject = mock(FedoraObject.class);
}

@Test
public void testGetObjectVersion() throws Exception {
String path = "objects/fedoradatastreamtest1";

when(mockObject.getCreated()).thenReturn("2013-05-06T15:21:27.480+02:00");
when(mockObject.getName()).thenReturn(path);
when(mockObject.getLabel()).thenReturn(path);
when(mockObject.getLastModified()).thenReturn("2013-05-06T15:22:27.480+02:00");
when(mockObject.getOwnerId()).thenReturn("testOwner");
when(mockObject.getModels()).thenReturn(null);
when(mockObject.getSize()).thenReturn(1291l);
when(mockObjects.getObject(mockSession, "/" + path)).thenReturn(mockObject);

fedoraVersions.getVersion(createPathList(path),path);

verify(mockObjects).getObject(mockSession, "/" + path);
}

@Test
public void testGetDatastreamVersion() throws Exception {
String path = "objects/fedoradatastreamtest1/ds1";
String pid = "testobj";
String dsid = "ds1";
String content ="emptem";
Datastream mockds = TestHelpers.mockDatastream(pid, dsid, content);

when(mockDatastreams.getDatastream(mockSession, "/" + path)).thenReturn(mockds);

Response resp = fedoraVersions.getVersion(createPathList(path),path);

verify(mockDatastreams).getDatastream(mockSession, "/" + path);
assertTrue(resp.getStatus() == 200);
assertTrue(resp.getEntity() instanceof DatastreamProfile);
}

@Test
public void testGetDatastreamVersionProfile() throws Exception{
String path = "objects/fedoradatastreamtest1/ds1";
String pid = "testobj";
String dsid = "ds1";
String content ="emptem";
Datastream mockds = TestHelpers.mockDatastream(pid, dsid, content);

when(mockDatastreams.getDatastream(mockSession, "/" + path)).thenReturn(mockds);

List<Version> versions = fedoraVersions.getVersionProfile(createPathList(path));

verify(mockDatastreams).getDatastream(mockSession, "/" + path);
assertTrue(versions.size() == 1);
Version v = versions.get(0);
assertTrue(v.getCreated() != null);
assertTrue(v.getId() == dsid);
}

}
@@ -0,0 +1,47 @@
package org.fcrepo.integration.api;

import static org.junit.Assert.assertEquals;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.junit.Test;

public class FedoraVersionsIT extends AbstractResourceIT{
@Test
public void testGetObjectVersionProfile() throws Exception {
execute(postObjMethod("FedoraDatastreamsTest1"));
final HttpGet method = new HttpGet(serverAddress +
"objects/FedoraDatastreamsTest1/fcr:versions");
HttpResponse resp = execute(method);
assertEquals(200, resp.getStatusLine().getStatusCode());
}

@Test
public void testGetDatastreamVersionProfile() throws Exception {
execute(postObjMethod("FedoraDatastreamsTest1"));

HttpPost postDs = postDSMethod("FedoraDatastreamsTest1","ds1","foo");
execute(postDs);
assertEquals(201, getStatus(postDs));

final HttpGet getVersion = new HttpGet(serverAddress +
"objects/FedoraDatastreamsTest1/ds1/fcr:versions");
HttpResponse resp =execute(getVersion);
assertEquals(200, resp.getStatusLine().getStatusCode());
}

@Test
public void testGetDatastreamVersion() throws Exception {
execute(postObjMethod("FedoraDatastreamsTest1"));

HttpPost postDs = postDSMethod("FedoraDatastreamsTest1","ds1","foo");
execute(postDs);
assertEquals(201, getStatus(postDs));

final HttpGet getVersion = new HttpGet(serverAddress +
"objects/FedoraDatastreamsTest1/ds1/fcr:versions/lastVersion");
HttpResponse resp =execute(getVersion);
assertEquals(200, resp.getStatusLine().getStatusCode());
}
}

0 comments on commit 4e609d2

Please sign in to comment.