Skip to content

Commit

Permalink
Merge pull request #5 from futures/model-services
Browse files Browse the repository at this point in the history
object and datastream creation services
  • Loading branch information
cbeer committed Feb 12, 2013
2 parents 03ee283 + 5449c78 commit 41ae108
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 50 deletions.
@@ -0,0 +1,78 @@
package org.fcrepo.services;

import org.modeshape.jcr.api.JcrTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Calendar;

import static org.modeshape.jcr.api.JcrConstants.*;


public class DatastreamService {

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

@Inject
private Repository repo;

private JcrTools jcrTools = new JcrTools();

public Node createDatastreamNode(final Session session, final String dsPath, final MediaType contentType, final InputStream requestBodyStream) throws RepositoryException, IOException {

final Node ds = jcrTools.findOrCreateNode(session, dsPath, NT_FILE);
ds.addMixin("fedora:datastream");

final Node contentNode = jcrTools.findOrCreateChild(ds, JCR_CONTENT,
NT_RESOURCE);
logger.debug("Created content node at path: " + contentNode.getPath());
/*
* This next line of code deserves explanation. If we chose for the
* simpler line:
*
* Property dataProperty = contentNode.setProperty(JCR_DATA,
* requestBodyStream);
*
* then the JCR would not block on the stream's completion, and we would
* return to the requestor before the mutation to the repo had actually
* completed. So instead we use createBinary(requestBodyStream), because
* its contract specifies:
*
* "The passed InputStream is closed before this method returns either
* normally or because of an exception."
*
* which lets us block and not return until the job is done! The simpler
* code may still be useful to us for an asychronous method that we
* develop later.
*/
Property dataProperty = contentNode.setProperty(JCR_DATA, session
.getValueFactory().createBinary(requestBodyStream));
logger.debug("Created data property at path: " + dataProperty.getPath());

ds.setProperty("fedora:contentType", contentType.toString());

ds.addMixin("fedora:owned");
ds.setProperty("fedora:ownerId", session.getUserID());

if(!ds.hasProperty("fedora:created")) {
ds.setProperty("fedora:created", Calendar.getInstance());
}
ds.setProperty("jcr:lastModified", Calendar.getInstance());

// TODO: I guess we should also have the PID + DSID..
ds.setProperty("dc:identifier", new String[] { ds.getIdentifier(), ds.getParent().getName() + "/" + ds.getName() });

return ds;
}
}
39 changes: 39 additions & 0 deletions fcrepo-kernel/src/main/java/org/fcrepo/services/ObjectService.java
@@ -0,0 +1,39 @@
package org.fcrepo.services;


import org.modeshape.jcr.api.JcrTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import java.util.Calendar;

import static javax.ws.rs.core.Response.created;

public class ObjectService {

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

@Inject
private Repository repo;

private JcrTools jcrTools = new JcrTools();

public Node createObjectNode(Session session, String path) throws RepositoryException {
final Node obj = jcrTools.findOrCreateNode(session, path, "nt:folder");
obj.addMixin("fedora:object");
obj.addMixin("fedora:owned");
obj.setProperty("fedora:ownerId", session.getUserID());
obj.setProperty("jcr:lastModified", Calendar.getInstance());
obj.setProperty("dc:identifier", new String[]{obj.getIdentifier(), obj.getName()});

return obj;
}


}
Expand Up @@ -42,6 +42,7 @@
import org.fcrepo.jaxb.responses.DatastreamProfile;
import org.fcrepo.jaxb.responses.ObjectDatastreams;
import org.fcrepo.jaxb.responses.ObjectDatastreams.Datastream;
import org.fcrepo.services.DatastreamService;
import org.modeshape.jcr.api.Binary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -194,50 +195,10 @@ private URI addDatastreamNode(final String pid, final String dsPath,

Long oldObjectSize = getObjectSize(session.getNode("/objects/" + pid));
logger.debug("Attempting to add datastream node at path: " + dsPath);
Boolean created = false;
if (!session.nodeExists(dsPath)) {
created = true;
}

final Node ds = jcrTools.findOrCreateNode(session, dsPath, NT_FILE);
ds.addMixin("fedora:datastream");
final Node contentNode = jcrTools.findOrCreateChild(ds, JCR_CONTENT,
NT_RESOURCE);
logger.debug("Created content node at path: " + contentNode.getPath());
/*
* This next line of code deserves explanation. If we chose for the
* simpler line:
*
* Property dataProperty = contentNode.setProperty(JCR_DATA,
* requestBodyStream);
*
* then the JCR would not block on the stream's completion, and we would
* return to the requestor before the mutation to the repo had actually
* completed. So instead we use createBinary(requestBodyStream), because
* its contract specifies:
*
* "The passed InputStream is closed before this method returns either
* normally or because of an exception."
*
* which lets us block and not return until the job is done! The simpler
* code may still be useful to us for an asychronous method that we
* develop later.
*/
Property dataProperty = contentNode.setProperty(JCR_DATA, session
.getValueFactory().createBinary(requestBodyStream));
logger.debug("Created data property at path: " + dataProperty.getPath());

ds.setProperty("fedora:contentType", contentType.toString());

ds.addMixin("fedora:owned");
ds.setProperty("fedora:ownerId", "Fedo Radmin");
if (created) {
ds.setProperty("fedora:created", Calendar.getInstance());
}
ds.setProperty("jcr:lastModified", Calendar.getInstance());
boolean created = session.nodeExists(dsPath);

// TODO: I guess we should also have the PID + DSID..
ds.setProperty("dc:identifier", new String[] { ds.getIdentifier() });
Node ds = new DatastreamService().createDatastreamNode(session, dsPath, contentType, requestBodyStream);

session.save();
if (created) {
Expand Down
Expand Up @@ -10,7 +10,6 @@
import static org.fcrepo.jaxb.responses.ObjectProfile.ObjectStates.A;

import java.io.IOException;
import java.util.Calendar;

import javax.jcr.*;
import javax.jcr.nodetype.NodeType;
Expand All @@ -24,6 +23,7 @@

import org.fcrepo.AbstractResource;
import org.fcrepo.jaxb.responses.ObjectProfile;
import org.fcrepo.services.ObjectService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -67,13 +67,8 @@ public Response ingest(@PathParam("pid") final String pid)
final Session session = repo.login();

if (session.hasPermission("/objects/" + pid, "add_node")) {
final Node obj = jcrTools.findOrCreateNode(session, "/objects/"
+ pid, "nt:folder");
obj.addMixin("fedora:object");
obj.addMixin("fedora:owned");
obj.setProperty("fedora:ownerId", "Fedo Radmin");
obj.setProperty("jcr:lastModified", Calendar.getInstance());
obj.setProperty("dc:identifier", new String[] { obj.getIdentifier(), pid });
final Node obj = new ObjectService().createObjectNode(session, "/objects/" + pid);

session.save();
/*
* we save before updating the repo size because the act of
Expand Down

0 comments on commit 41ae108

Please sign in to comment.