001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.http.api; 019 020import static javax.ws.rs.core.Response.Status.BAD_GATEWAY; 021import static javax.ws.rs.core.Response.Status.CONFLICT; 022import static javax.ws.rs.core.Response.Status.PRECONDITION_FAILED; 023import static javax.ws.rs.core.Response.created; 024import static org.slf4j.LoggerFactory.getLogger; 025 026import java.net.URI; 027import java.net.URISyntaxException; 028 029import javax.annotation.PostConstruct; 030import javax.jcr.ItemExistsException; 031import javax.jcr.PathNotFoundException; 032import javax.servlet.http.HttpServletResponse; 033import javax.ws.rs.ClientErrorException; 034import javax.ws.rs.HeaderParam; 035import javax.ws.rs.Path; 036import javax.ws.rs.PathParam; 037import javax.ws.rs.ServerErrorException; 038import javax.ws.rs.core.Context; 039import javax.ws.rs.core.Request; 040import javax.ws.rs.core.Response; 041import javax.ws.rs.core.UriInfo; 042 043import org.fcrepo.http.commons.domain.COPY; 044import org.fcrepo.http.commons.domain.MOVE; 045import org.fcrepo.kernel.api.models.FedoraResource; 046import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 047import org.slf4j.Logger; 048import org.springframework.context.annotation.Scope; 049 050import com.codahale.metrics.annotation.Timed; 051import com.google.common.annotations.VisibleForTesting; 052import org.apache.jena.rdf.model.ResourceFactory; 053 054/** 055 * CRUD operations on Fedora Nodes 056 * 057 * @author cbeer 058 */ 059@Scope("request") 060@Path("/{path: .*}") 061public class FedoraNodes extends ContentExposingResource { 062 063 private static final Logger LOGGER = getLogger(FedoraNodes.class); 064 065 @Context protected Request request; 066 @Context protected HttpServletResponse servletResponse; 067 @Context protected UriInfo uriInfo; 068 069 @PathParam("path") protected String externalPath; 070 071 protected FedoraResource resource; 072 073 /** 074 * Default JAX-RS entry point 075 */ 076 public FedoraNodes() { 077 super(); 078 } 079 080 /** 081 * Create a new FedoraNodes instance for a given path 082 * @param externalPath the external path 083 */ 084 @VisibleForTesting 085 public FedoraNodes(final String externalPath) { 086 this.externalPath = externalPath; 087 } 088 089 090 /** 091 * Run these actions after initializing this resource 092 */ 093 @PostConstruct 094 public void postConstruct() { 095 setUpJMSInfo(uriInfo, headers); 096 } 097 098 /** 099 * @deprecated 100 * Copies an object from one path to another 101 * @param destinationUri the destination uri 102 * @throws URISyntaxException if uri syntax exception occurred 103 * @return the response 104 */ 105 @COPY 106 @Timed 107 @Deprecated 108 public Response copyObject(@HeaderParam("Destination") final String destinationUri) 109 throws URISyntaxException { 110 111 try { 112 final String source = translator().asString(translator().toDomain(externalPath)); 113 114 if (!nodeService.exists(session.getFedoraSession(), source)) { 115 throw new ClientErrorException("The source path does not exist", CONFLICT); 116 } 117 118 final String destination = translator().asString(ResourceFactory.createResource(destinationUri)); 119 120 if (destination == null) { 121 throw new ServerErrorException("Destination was not a valid resource path", BAD_GATEWAY); 122 } else if (nodeService.exists(session.getFedoraSession(), destination)) { 123 throw new ClientErrorException("Destination resource already exists", PRECONDITION_FAILED); 124 } 125 126 LOGGER.info("Copy from '{}' to '{}'", source, destination); 127 nodeService.copyObject(session.getFedoraSession(), source, destination); 128 session.commit(); 129 130 return created(new URI(destinationUri)).build(); 131 } catch (final RepositoryRuntimeException e) { 132 final Throwable cause = e.getCause(); 133 134 if (cause instanceof ItemExistsException) { 135 136 throw new ClientErrorException("Destination resource already exists", PRECONDITION_FAILED, e); 137 138 } else if (cause instanceof PathNotFoundException) { 139 140 throw new ClientErrorException("There is no node that will serve as the parent of the copied item", 141 CONFLICT, e); 142 } else { 143 throw e; 144 } 145 } 146 147 } 148 149 /** 150 * @deprecated 151 * Moves an object from one path to another 152 * @param destinationUri the destination uri 153 * @throws URISyntaxException if uri syntax exception occurred 154 * @return the response 155 */ 156 @MOVE 157 @Timed 158 @Deprecated 159 public Response moveObject(@HeaderParam("Destination") final String destinationUri) 160 throws URISyntaxException { 161 162 try { 163 164 final String source = toPath(translator(), externalPath); 165 166 if (!nodeService.exists(session.getFedoraSession(), source)) { 167 throw new ClientErrorException("The source path does not exist", CONFLICT); 168 } 169 170 171 evaluateRequestPreconditions(request, servletResponse, resource(), session); 172 173 final String destination = translator().asString(ResourceFactory.createResource(destinationUri)); 174 175 if (destination == null) { 176 throw new ServerErrorException("Destination was not a valid resource path", BAD_GATEWAY); 177 } else if (nodeService.exists(session.getFedoraSession(), destination)) { 178 throw new ClientErrorException("Destination resource already exists", PRECONDITION_FAILED); 179 } 180 181 LOGGER.info("Move from '{}' to '{}'", source, destination); 182 nodeService.moveObject(session.getFedoraSession(), source, destination); 183 session.commit(); 184 return created(new URI(destinationUri)).build(); 185 } catch (final RepositoryRuntimeException e) { 186 final Throwable cause = e.getCause(); 187 188 if (cause instanceof ItemExistsException) { 189 throw new ClientErrorException("Destination resource already exists", PRECONDITION_FAILED, e); 190 } else if (cause instanceof PathNotFoundException) { 191 throw new ClientErrorException("There is no node that will serve as the parent of the moved item", 192 CONFLICT, e); 193 } else { 194 throw e; 195 } 196 } 197 } 198 199 @Override 200 protected void addResourceHttpHeaders(final FedoraResource resource) { 201 throw new UnsupportedOperationException(); 202 } 203 204 @Override 205 protected String externalPath() { 206 return externalPath; 207 } 208 209}