Skip to content

Commit

Permalink
Added setContent() methods to Datastream and factored DatastreamServi…
Browse files Browse the repository at this point in the history
…ce to use them
  • Loading branch information
ajs6f committed Feb 28, 2013
1 parent b114512 commit b0c9d90
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 35 deletions.
48 changes: 47 additions & 1 deletion fcrepo-kernel/src/main/java/org/fcrepo/Datastream.java
Expand Up @@ -7,6 +7,7 @@
import static org.fcrepo.utils.FedoraTypesUtils.value2string;
import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
import static org.modeshape.jcr.api.JcrConstants.JCR_DATA;
import static org.modeshape.jcr.api.JcrConstants.NT_RESOURCE;

import java.io.InputStream;
import java.util.Date;
Expand All @@ -19,13 +20,20 @@
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.version.VersionException;

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

/**
* Abstraction for a Fedora datastream backed by a JCR node.
*
* @author ajs6f
*
*/
public class Datastream {
public class Datastream extends JcrTools {

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

Node node;

Expand All @@ -49,6 +57,44 @@ public InputStream getContent() throws RepositoryException {
.getStream();
}

/**
* Sets the content of this Datastream.
*
* @param content
* @throws RepositoryException
*/
public void setContent(InputStream content) throws RepositoryException {
final Node contentNode =
findOrCreateChild(node, 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 requester 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 asynchronous method that we
* develop later.
*/
Property dataProperty =
contentNode.setProperty(JCR_DATA, node.getSession()
.getValueFactory().createBinary(content));
logger.debug("Created data property at path: " + dataProperty.getPath());

}

public void setContent(InputStream content, String mimeType)
throws RepositoryException {
setContent(content);
node.setProperty("fedora:contentType", mimeType);
}

/**
* @return The size in bytes of content associated with this datastream.
* @throws RepositoryException
Expand Down
Expand Up @@ -5,10 +5,8 @@
import static org.fcrepo.utils.FedoraJcrTypes.DC_IDENTIFER;
import static org.fcrepo.utils.FedoraJcrTypes.FEDORA_DATASTREAM;
import static org.fcrepo.utils.FedoraJcrTypes.FEDORA_OWNED;
import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
import static org.modeshape.jcr.api.JcrConstants.JCR_DATA;
import static org.fcrepo.utils.FedoraJcrTypes.FEDORA_OWNERID;
import static org.modeshape.jcr.api.JcrConstants.NT_FILE;
import static org.modeshape.jcr.api.JcrConstants.NT_RESOURCE;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -19,7 +17,6 @@
import javax.inject.Inject;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
Expand Down Expand Up @@ -54,38 +51,10 @@ public static Node createDatastreamNode(final Session session,

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 requester 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 asynchronous 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);

new Datastream(ds).setContent(requestBodyStream,contentType);
ds.addMixin(FEDORA_OWNED);
ds.setProperty("fedora:ownerId", session.getUserID());
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..
Expand Down
Expand Up @@ -15,6 +15,8 @@ public class FedoraJcrTypes {

public static final String FEDORA_OWNED = "fedora:owned";

public static final String FEDORA_OWNERID = "fedora:ownerId";

public static final String DC_TITLE = "dc:title";

public static final String DC_IDENTIFER = "dc:identifier";
Expand Down

0 comments on commit b0c9d90

Please sign in to comment.