Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow updating mimeType and filename properties
- Use ebucore:filename for premis:hasOriginalName
- Use ebucore:hasMimeType for jcr/fedora:mimeType

Resolves: https://jira.duraspace.org/browse/FCREPO-1532
  • Loading branch information
escowles authored and Andrew Woods committed Jul 16, 2015
1 parent 6e755b2 commit aadf58d
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 23 deletions.
Expand Up @@ -66,6 +66,8 @@
import static org.fcrepo.kernel.RdfLexicon.DIRECT_CONTAINER;
import static org.fcrepo.kernel.RdfLexicon.HAS_CHILD;
import static org.fcrepo.kernel.RdfLexicon.HAS_MEMBER_RELATION;
import static org.fcrepo.kernel.RdfLexicon.HAS_MIME_TYPE;
import static org.fcrepo.kernel.RdfLexicon.HAS_ORIGINAL_NAME;
import static org.fcrepo.kernel.RdfLexicon.HAS_PRIMARY_IDENTIFIER;
import static org.fcrepo.kernel.RdfLexicon.HAS_PRIMARY_TYPE;
import static org.fcrepo.kernel.RdfLexicon.INBOUND_REFERENCES;
Expand Down Expand Up @@ -514,7 +516,35 @@ public void testPatchBinaryDescriptionWithBinaryProperties() throws IOException
}

@Test
public void testPatchWithBlankNode() throws IOException {
public void testPatchBinaryNameAndType() throws Exception {
final String pid = getRandomUniqueId();

createDatastream(pid, "x", "some content");

final String location = serverAddress + pid + "/x/fcr:metadata";
final HttpPatch patch = new HttpPatch(location);
patch.addHeader("Content-Type", "application/sparql-update");
final BasicHttpEntity e = new BasicHttpEntity();
final String sparql = "INSERT DATA { <" + serverAddress + pid + "/x> <" + HAS_MIME_TYPE + "> \"text/plain\""
+ " . <" + serverAddress + pid + "/x> <" + HAS_ORIGINAL_NAME + "> \"x.txt\" }";
e.setContent(new ByteArrayInputStream(sparql.getBytes()));
patch.setEntity(e);
final HttpResponse response = client.execute(patch);
assertEquals(NO_CONTENT.getStatusCode(), response.getStatusLine()
.getStatusCode());

final GraphStore graphStore = getGraphStore(new HttpGet(location));
assertTrue(graphStore.contains(ANY, createURI(serverAddress + pid + "/x"),
HAS_MIME_TYPE.asNode(), createLiteral("text/plain")));
assertTrue(graphStore.contains(ANY, createURI(serverAddress + pid + "/x"),
HAS_ORIGINAL_NAME.asNode(), createLiteral("x.txt")));
assertFalse("Should not contain old mime type property",
graphStore.contains(ANY, createURI(serverAddress + pid + "/x"),
createURI(REPOSITORY_NAMESPACE + "mimeType"), ANY));
}

@Test
public void testPatchWithBlankNode() throws Exception {
final String id = getRandomUniqueId();
createObjectAndClose(id);

Expand Down
Expand Up @@ -49,10 +49,11 @@
import java.util.Collection;

import static com.codahale.metrics.MetricRegistry.name;
import static org.fcrepo.kernel.FedoraJcrTypes.HAS_MIME_TYPE;
import static org.fcrepo.kernel.FedoraJcrTypes.FILENAME;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isFedoraBinary;
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.JCR_MIME_TYPE;
import static org.slf4j.LoggerFactory.getLogger;

/**
Expand Down Expand Up @@ -151,11 +152,11 @@ public void setContent(final InputStream content, final String contentType,
}

if (contentType != null) {
contentNode.setProperty(JCR_MIME_TYPE, contentType);
contentNode.setProperty(HAS_MIME_TYPE, contentType);
}

if (originalFileName != null) {
contentNode.setProperty(PREMIS_FILE_NAME, originalFileName);
contentNode.setProperty(FILENAME, originalFileName);
}

LOGGER.debug("Created content node at path: {}", contentNode.getPath());
Expand Down Expand Up @@ -243,8 +244,8 @@ public URI getContentDigest() {
@Override
public String getMimeType() {
try {
if (hasProperty(JCR_MIME_TYPE)) {
return getProperty(JCR_MIME_TYPE).getString();
if (hasProperty(HAS_MIME_TYPE)) {
return getProperty(HAS_MIME_TYPE).getString();
}
return "application/octet-stream";
} catch (final RepositoryException e) {
Expand All @@ -259,8 +260,8 @@ public String getMimeType() {
@Override
public String getFilename() {
try {
if (hasProperty(PREMIS_FILE_NAME)) {
return getProperty(PREMIS_FILE_NAME).getString();
if (hasProperty(FILENAME)) {
return getProperty(FILENAME).getString();
}
return node.getParent().getName();
} catch (final RepositoryException e) {
Expand Down
Expand Up @@ -106,13 +106,17 @@ public abstract class FedoraTypesUtils implements FedoraJcrTypes {
}
});

/**
* Check if a property is intentionally suppressed.
*/
private static Predicate<Property> isSuppressedProperty = uncheck(p -> p.getName().equals("jcr:mimeType"));

/**
* Check whether a property is an internal property that should be suppressed
* from external output.
*/
public static Predicate<Property> isInternalProperty = p -> isBinaryContentProperty.test(p) ||
isProtectedAndShouldBeHidden.test(p);

isProtectedAndShouldBeHidden.test(p) || isSuppressedProperty.test(p);


/**
Expand Down
Expand Up @@ -26,6 +26,7 @@
<rdfs = 'http://www.w3.org/2000/01/rdf-schema#'>
<premis = 'http://www.loc.gov/premis/rdf/v1#'>
<ldp = 'http://www.w3.org/ns/ldp#'>
<ebucore = 'http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#'>

/*
* A fedora namespace for properties a user may set on a node that may
Expand Down
Expand Up @@ -285,9 +285,9 @@ public void testChecksumBlobs() throws RepositoryException, InvalidChecksumExcep

binaryService.findOrCreate(session, pid + "/testRepositoryContent").setContent(
new ByteArrayInputStream("01234567890123456789012345678901234567890123456789".getBytes()),
"application/octet-stream",
null,
"text/plain",
null,
"numbers.txt",
null
);

Expand All @@ -303,6 +303,11 @@ public void testChecksumBlobs() throws RepositoryException, InvalidChecksumExcep
fixityResults.contains(null,
HAS_MESSAGE_DIGEST,
createResource("urn:sha1:9578f951955d37f20b601c26591e260c1e5389bf")));

assertEquals("Expected to find mime type",
ds.getNode().getProperty("ebucore:hasMimeType").getString(), "text/plain");
assertEquals("Expected to find file name",
ds.getNode().getProperty("ebucore:filename").getString(), "numbers.txt");
} finally {
session.logout();
}
Expand Down
Expand Up @@ -15,7 +15,7 @@
*/
package org.fcrepo.integration.kernel.impl.services;

import static org.fcrepo.kernel.FedoraJcrTypes.PREMIS_FILE_NAME;
import static org.fcrepo.kernel.FedoraJcrTypes.FILENAME;
import static org.jgroups.util.Util.assertEquals;
import static org.jgroups.util.Util.assertTrue;
import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
Expand Down Expand Up @@ -92,7 +92,7 @@ public void testCreateDatastreamNodeWithfilename() throws Exception {

assertTrue(session.getRootNode().hasNode("testDatastreamNode"));
assertEquals("xyz.jpg", session.getNode("/testDatastreamNode").getNode(JCR_CONTENT)
.getProperty(PREMIS_FILE_NAME).getString());
.getProperty(FILENAME).getString());
session.logout();
}

Expand Down
Expand Up @@ -50,7 +50,7 @@
import static org.mockito.MockitoAnnotations.initMocks;
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.JCR_MIME_TYPE;
import static org.fcrepo.kernel.FedoraJcrTypes.HAS_MIME_TYPE;

/**
* <p>DatastreamImplTest class.</p>
Expand Down Expand Up @@ -172,7 +172,7 @@ public void testSetContentWithFilename() throws RepositoryException,
when(mockContent.getProperty(JCR_DATA)).thenReturn(mockData);
when(mockData.getBinary()).thenReturn(mockBin);
testObj.setContent(mockStream, null, null, "xyz", null);
verify(mockContent).setProperty(PREMIS_FILE_NAME, "xyz");
verify(mockContent).setProperty(FILENAME, "xyz");
}

@Test(expected = InvalidChecksumException.class)
Expand Down Expand Up @@ -220,10 +220,10 @@ public void testGetMimeType() throws RepositoryException {
getContentNodeMock(mockContent, 8);
when(mockDsNode.getNode(JCR_CONTENT)).thenReturn(mockContent);
when(mockDsNode.hasNode(JCR_CONTENT)).thenReturn(true);
when(mockContent.hasProperty(JCR_MIME_TYPE)).thenReturn(true);
when(mockContent.hasProperty(HAS_MIME_TYPE)).thenReturn(true);

final Property mockProperty = mock(Property.class);
when(mockContent.getProperty(JCR_MIME_TYPE)).thenReturn(mockProperty);
when(mockContent.getProperty(HAS_MIME_TYPE)).thenReturn(mockProperty);
when(mockProperty.getString()).thenReturn("application/x-mime-type");
assertEquals("application/x-mime-type", testObj.getMimeType());
}
Expand All @@ -239,7 +239,7 @@ public void testGetMimeTypeWithDefault() throws RepositoryException {
getContentNodeMock(mockContent, 8);
when(mockDsNode.getNode(JCR_CONTENT)).thenReturn(mockContent);
when(mockDsNode.hasNode(JCR_CONTENT)).thenReturn(true);
when(mockContent.hasProperty(JCR_MIME_TYPE)).thenReturn(false);
when(mockContent.hasProperty(HAS_MIME_TYPE)).thenReturn(false);

assertEquals("application/octet-stream", testObj.getMimeType());
}
Expand Down
Expand Up @@ -54,7 +54,9 @@ public interface FedoraJcrTypes {

String JCR_CREATEDBY = "jcr:createdBy";

String PREMIS_FILE_NAME = "premis:hasOriginalName";
String FILENAME = "ebucore:filename";

String HAS_MIME_TYPE = "ebucore:hasMimeType";

String CONTENT_SIZE = "premis:hasSize";

Expand Down
8 changes: 5 additions & 3 deletions fcrepo-kernel/src/main/java/org/fcrepo/kernel/RdfLexicon.java
Expand Up @@ -54,6 +54,8 @@ public final class RdfLexicon {

public static final String JCR_NT_NAMESPACE = "http://www.jcp.org/jcr/nt/1.0";

public static final String EBUCORE_NAMESPACE = "http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#";

/**
* Fedora configuration namespace "fedora-config", used for user-settable
* configuration properties.
Expand Down Expand Up @@ -240,12 +242,12 @@ public final class RdfLexicon {
public static final Property HAS_CONTENT_LOCATION_VALUE =
createProperty(PREMIS_NAMESPACE + "hasContentLocationValue");
public static final Property HAS_MIME_TYPE =
createProperty(REPOSITORY_NAMESPACE + "mimeType");
createProperty(EBUCORE_NAMESPACE + "hasMimeType");
public static final Property HAS_ORIGINAL_NAME =
createProperty(PREMIS_NAMESPACE + "hasOriginalName");
createProperty(EBUCORE_NAMESPACE + "filename");

public static final Set<Property> contentProperties = of(HAS_CONTENT_LOCATION, HAS_CONTENT_LOCATION_VALUE,
HAS_MIME_TYPE, HAS_ORIGINAL_NAME, HAS_SIZE);
HAS_SIZE);


// VERSIONING
Expand Down

0 comments on commit aadf58d

Please sign in to comment.