diff --git a/fcrepo-http-api/src/main/java/org/fcrepo/http/api/FedoraNodes.java b/fcrepo-http-api/src/main/java/org/fcrepo/http/api/FedoraNodes.java index efbc447fe3..fe3eac08f5 100644 --- a/fcrepo-http-api/src/main/java/org/fcrepo/http/api/FedoraNodes.java +++ b/fcrepo-http-api/src/main/java/org/fcrepo/http/api/FedoraNodes.java @@ -394,7 +394,7 @@ public Response updateSparql(@PathParam("path") } /** - * Replace triples with triples from a new model + * Create a resource at a specified path, or replace triples with provided RDF. * @param pathList * @param uriInfo * @param requestContentType @@ -411,8 +411,7 @@ public Response createOrReplaceObjectRdf( @HeaderParam("Content-Type") final MediaType requestContentType, final InputStream requestBodyStream, - @Context - final Request request, + @Context final Request request, @Context final HttpServletResponse servletResponse) throws RepositoryException, ParseException, IOException, InvalidChecksumException, URISyntaxException { final String path = toPath(pathList); @@ -425,9 +424,11 @@ public Response createOrReplaceObjectRdf( final MediaType contentType = getSimpleContentType(requestContentType); + final boolean preexisting; if (nodeService.exists(session, path)) { resource = nodeService.getObject(session, path); response = noContent(); + preexisting = true; } else { final MediaType effectiveContentType = requestBodyStream == null || requestContentType == null ? null : contentType; @@ -438,6 +439,7 @@ public Response createOrReplaceObjectRdf( final URI location = new URI(idTranslator.getSubject(resource.getNode().getPath()).getURI()); response = created(location).entity(location.toString()); + preexisting = false; } evaluateRequestPreconditions(request, resource); @@ -455,6 +457,8 @@ public Response createOrReplaceObjectRdf( resource.replaceProperties(graphSubjects, inputModel); + } else if (preexisting) { + return status(SC_CONFLICT).entity("No RDF provided and the resource already exists!").build(); } session.save(); @@ -767,8 +771,11 @@ public Response copyObject(@PathParam("path") final List path, if (destination == null) { return status(SC_BAD_GATEWAY).entity("Destination was not a valid resource path").build(); + } else if (nodeService.exists(session, destination)) { + return status(SC_PRECONDITION_FAILED).entity("Destination resource already exists").build(); } + nodeService.copyObject(session, toPath(path), destination); session.save(); versionService.nodeUpdated(session, destination); @@ -819,6 +826,8 @@ public Response moveObject(@PathParam("path") final List pathList, if (destination == null) { return status(SC_BAD_GATEWAY).entity("Destination was not a valid resource path").build(); + } else if (nodeService.exists(session, destination)) { + return status(SC_PRECONDITION_FAILED).entity("Destination resource already exists").build(); } nodeService.moveObject(session, path, destination); diff --git a/fcrepo-http-api/src/test/java/org/fcrepo/integration/http/api/FedoraNodesIT.java b/fcrepo-http-api/src/test/java/org/fcrepo/integration/http/api/FedoraNodesIT.java index 01c67584f9..fd97919581 100644 --- a/fcrepo-http-api/src/test/java/org/fcrepo/integration/http/api/FedoraNodesIT.java +++ b/fcrepo-http-api/src/test/java/org/fcrepo/integration/http/api/FedoraNodesIT.java @@ -37,6 +37,7 @@ import static javax.ws.rs.core.Response.Status.NOT_MODIFIED; import static javax.ws.rs.core.Response.Status.NO_CONTENT; import static javax.ws.rs.core.Response.Status.OK; +import static javax.ws.rs.core.Response.Status.PRECONDITION_FAILED; import static nu.validator.htmlparser.common.DoctypeExpectation.NO_DOCTYPE_ERRORS; import static nu.validator.htmlparser.common.XmlViolationPolicy.ALLOW; import static org.apache.http.impl.client.cache.CacheConfig.DEFAULT; @@ -213,6 +214,17 @@ public void testIngestWithSlug() throws Exception { getStatus(new HttpGet(location))); } + @Test + public void testIngestWithRepeatedSlug() throws Exception { + final String pid = getRandomUniquePid(); + final HttpPut put = new HttpPut(serverAddress + pid); + assertEquals(201, getStatus(put)); + + final HttpPost method = postObjMethod(""); + method.addHeader("Slug", pid); + assertEquals(409, getStatus(method)); + } + @Test public void testIngestWithBinary() throws Exception { final HttpPost method = postObjMethod(""); @@ -739,6 +751,16 @@ public void testUpdateObjectGraphWithProblems() throws Exception { } + @Test + public void testRepeatedPut() throws Exception { + final String pid = getRandomUniquePid(); + final HttpPut firstPut = new HttpPut(serverAddress + pid); + assertEquals(201, getStatus(firstPut)); + + final HttpPut secondPut = new HttpPut(serverAddress + pid); + assertEquals(409, getStatus(secondPut)); + } + @Test public void testFilteredLDPTypes() throws Exception { final String pid = getRandomUniquePid(); @@ -1049,6 +1071,21 @@ public void testCopy() throws Exception { assertEquals(OK.getStatusCode(), originalResult.getStatusLine().getStatusCode()); } + @Test + public void testCopyDestExists() throws Exception { + + final HttpResponse response1 = createObject(""); + final String location1 = response1.getFirstHeader("Location").getValue(); + final HttpResponse response2 = createObject(""); + final String location2 = response2.getFirstHeader("Location").getValue(); + + final HttpCopy request = new HttpCopy(location1); + request.addHeader("Destination", location2); + final HttpResponse result = client.execute(request); + + assertEquals(PRECONDITION_FAILED.getStatusCode(), result.getStatusLine().getStatusCode()); + } + @Test public void testMove() throws Exception { @@ -1069,6 +1106,21 @@ public void testMove() throws Exception { assertEquals(NOT_FOUND.getStatusCode(), originalResult.getStatusLine().getStatusCode()); } + @Test + public void testMoveDestExists() throws Exception { + + final HttpResponse response1 = createObject(""); + final String location1 = response1.getFirstHeader("Location").getValue(); + final HttpResponse response2 = createObject(""); + final String location2 = response2.getFirstHeader("Location").getValue(); + + final HttpMove request = new HttpMove(location1); + request.addHeader("Destination", location2); + final HttpResponse result = client.execute(request); + + assertEquals(PRECONDITION_FAILED.getStatusCode(), result.getStatusLine().getStatusCode()); + } + @Test public void testMoveWithBadEtag() throws Exception {