Skip to content

Commit

Permalink
Allow users to delete large literal property values.
Browse files Browse the repository at this point in the history
- Large literals that are stored in the binary store are now removeable
via standard means.

Resovles: https://jira.duraspace.org/browse/FCREPO-1561
  • Loading branch information
Bethany Seeger authored and Andrew Woods committed Oct 27, 2015
1 parent 1e4d09d commit 8cceaeb
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 13 deletions.
Expand Up @@ -1965,5 +1965,43 @@ public void testPutReferenceRoot() throws Exception {
assertEquals(CREATED.getStatusCode(), getStatus(response));
}
}
@Test
public void testDeleteLargeLiteralStoredAsBinary() throws IOException {

final String pid = getRandomUniqueId();
createObject(pid);

final Node DC_TITLE = DC_11.title.asNode();
final String location = serverAddress + pid;
final HttpPatch patch = new HttpPatch(location);
final HttpPatch delPatch = new HttpPatch(location);

final String longLiteral = // minimumBinaryInByteSize is currently 40 bytes
"01234567890123456789012345678901234567890123456789" +
"01234567890123456789012345678901234567890123456789" +
"01234567890123456789012345678901234567890123456789" +
"01234567890123456789012345678901234567890123456789";

}
LOGGER.info("BINARY LITERAL TEST");

patch.addHeader("Content-Type", "application/sparql-update");
patch.setEntity(new StringEntity(
"INSERT { <> <" + DC_TITLE + "> \"\"\"" + longLiteral + "\"\"\" } WHERE {}"));

assertEquals("Unable to add property value", NO_CONTENT.getStatusCode(), getStatus(patch));

delPatch.addHeader("Content-Type", "application/sparql-update");
delPatch.setEntity(new StringEntity(
"DELETE WHERE { <> <" + DC_TITLE + "> \"\"\"" + longLiteral + "\"\"\"}"));

// delete that triple, or at least try to.
assertEquals("Unable to complete delete property HTTP request", NO_CONTENT.getStatusCode(),
getStatus(delPatch));

// now test if property exists anymore (it shouldn't).
try (final CloseableGraphStore graph = getGraphStore(getObjMethod(pid))) {
assertFalse("Found the literal we tried to delete!", graph.contains(ANY,createURI(location), DC_TITLE,
createLiteral(longLiteral)));
}
}
}
6 changes: 3 additions & 3 deletions fcrepo-http-api/src/test/resources/test_repository.json
Expand Up @@ -10,9 +10,9 @@
"cacheName" : "FedoraRepository",
"cacheConfiguration" : "${fcrepo.ispn.configuration:config/testing/infinispan-basic.xml}",
"binaryStorage" : {
"type" : "cache",
"dataCacheName" : "FedoraRepositoryBinaryData",
"metadataCacheName" : "FedoraRepositoryMetaData"
"type" : "file",
"minimumBinarySizeInBytes" : 40,
"directory" : "target/test-binaryFileStore"
}
},
"externalSources" : {
Expand Down
Expand Up @@ -17,6 +17,7 @@

import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static org.fcrepo.kernel.api.utils.UncheckedPredicate.uncheck;
import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getReferencePropertyName;
import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.isExternalNode;
import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.isInternalReferenceProperty;
Expand All @@ -27,6 +28,8 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.commons.lang3.StringUtils;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyType;
Expand Down Expand Up @@ -194,37 +197,55 @@ public void removeReferencePlaceholders(final IdentifierConverter<Resource,Fedor
*/
public void removeNodeProperty(final Node node, final String propertyName, final Value valueToRemove)
throws RepositoryException {

LOGGER.debug("Request to remove {}", valueToRemove);
// if the property doesn't exist, we don't need to worry about it.
if (node.hasProperty(propertyName)) {

final Property property = node.getProperty(propertyName);
final String strValueToRemove = valueToRemove.getString();

if (property.isMultiple()) {
final AtomicBoolean remove = new AtomicBoolean();
final Value[] newValues = stream(node.getProperty(propertyName).getValues()).filter(v -> {
if (v.equals(valueToRemove)) {
final Value[] newValues = stream(node.getProperty(propertyName).getValues()).filter(uncheck(v -> {
final String strVal = v.getString();

LOGGER.debug("v is '{}', valueToRemove is '{}'", v, strValueToRemove );
if (strVal.equals(strValueToRemove)) {
remove.set(true);
return false;
}

return true;
}).toArray(Value[]::new);
})).toArray(Value[]::new);

// we only need to update the property if we did anything.
if (remove.get()) {
if (newValues.length == 0) {
LOGGER.debug("Removing property {}", propertyName);
LOGGER.debug("Removing property '{}'", propertyName);
property.remove();
} else {
LOGGER.debug("Removing value {} from property {}", valueToRemove, propertyName);
LOGGER.debug("Removing value '{}' from property '{}'", strValueToRemove, propertyName);
property.setValue(newValues);
}
} else {
LOGGER.debug("Value not removed from property name '{}' (value '{}')", propertyName,
strValueToRemove);
throw new RepositoryException ("Property '" + propertyName + "': Unable to remove value '" +
StringUtils.substring(strValueToRemove, 0, 50) + "...'");
}

} else {
if (property.getValue().equals(valueToRemove)) {
LOGGER.debug("Removing value from property {}", propertyName);

final String strPropVal = property.getValue().getString();

LOGGER.debug("Removing string '{}'", strValueToRemove);
if (StringUtils.equals(strPropVal, strValueToRemove)) {
LOGGER.debug("single value: Removing value from property '{}'", propertyName);
property.remove();
} else {
LOGGER.debug("Value not removed from property name '{}' (property value: '{}';compare value: '{}')",
propertyName, strPropVal, strValueToRemove);
throw new RepositoryException("Property '" + propertyName + "': Unable to remove value '" +
StringUtils.substring(strValueToRemove, 0, 50) + "'");
}
}
}
Expand Down

0 comments on commit 8cceaeb

Please sign in to comment.