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.google.common.annotations.VisibleForTesting; 051import org.apache.jena.rdf.model.ResourceFactory; 052 053/** 054 * CRUD operations on Fedora Nodes 055 * 056 * @author cbeer 057 */ 058@Scope("request") 059@Path("/{path: .*}") 060public class FedoraNodes extends ContentExposingResource { 061 062 private static final Logger LOGGER = getLogger(FedoraNodes.class); 063 064 @Context protected Request request; 065 @Context protected HttpServletResponse servletResponse; 066 @Context protected UriInfo uriInfo; 067 068 @PathParam("path") protected String externalPath; 069 070 protected FedoraResource resource; 071 072 /** 073 * Default JAX-RS entry point 074 */ 075 public FedoraNodes() { 076 super(); 077 } 078 079 /** 080 * Create a new FedoraNodes instance for a given path 081 * @param externalPath the external path 082 */ 083 @VisibleForTesting 084 public FedoraNodes(final String externalPath) { 085 this.externalPath = externalPath; 086 } 087 088 089 /** 090 * Run these actions after initializing this resource 091 */ 092 @PostConstruct 093 public void postConstruct() { 094 setUpJMSInfo(uriInfo, headers); 095 } 096 097 /** 098 * @deprecated 099 * Copies an object from one path to another 100 * @param destinationUri the destination uri 101 * @throws URISyntaxException if uri syntax exception occurred 102 * @return the response 103 */ 104 @COPY 105 @Deprecated 106 public Response copyObject(@HeaderParam("Destination") final String destinationUri) 107 throws URISyntaxException { 108 109 try { 110 final String source = translator().asString(translator().toDomain(externalPath)); 111 112 if (!nodeService.exists(session.getFedoraSession(), source)) { 113 throw new ClientErrorException("The source path does not exist", CONFLICT); 114 } 115 116 final String destination = translator().asString(ResourceFactory.createResource(destinationUri)); 117 118 if (destination == null) { 119 throw new ServerErrorException("Destination was not a valid resource path", BAD_GATEWAY); 120 } else if (nodeService.exists(session.getFedoraSession(), destination)) { 121 throw new ClientErrorException("Destination resource already exists", PRECONDITION_FAILED); 122 } 123 124 LOGGER.info("Copy from '{}' to '{}'", source, destination); 125 nodeService.copyObject(session.getFedoraSession(), source, destination); 126 session.commit(); 127 128 return created(new URI(destinationUri)).build(); 129 } catch (final RepositoryRuntimeException e) { 130 final Throwable cause = e.getCause(); 131 132 if (cause instanceof ItemExistsException) { 133 134 throw new ClientErrorException("Destination resource already exists", PRECONDITION_FAILED, e); 135 136 } else if (cause instanceof PathNotFoundException) { 137 138 throw new ClientErrorException("There is no node that will serve as the parent of the copied item", 139 CONFLICT, e); 140 } else { 141 throw e; 142 } 143 } 144 145 } 146 147 /** 148 * @deprecated 149 * Moves an object from one path to another 150 * @param destinationUri the destination uri 151 * @throws URISyntaxException if uri syntax exception occurred 152 * @return the response 153 */ 154 @MOVE 155 @Deprecated 156 public Response moveObject(@HeaderParam("Destination") final String destinationUri) 157 throws URISyntaxException { 158 159 try { 160 161 final String source = toPath(translator(), externalPath); 162 163 if (!nodeService.exists(session.getFedoraSession(), source)) { 164 throw new ClientErrorException("The source path does not exist", CONFLICT); 165 } 166 167 168 evaluateRequestPreconditions(request, servletResponse, resource(), session); 169 170 final String destination = translator().asString(ResourceFactory.createResource(destinationUri)); 171 172 if (destination == null) { 173 throw new ServerErrorException("Destination was not a valid resource path", BAD_GATEWAY); 174 } else if (nodeService.exists(session.getFedoraSession(), destination)) { 175 throw new ClientErrorException("Destination resource already exists", PRECONDITION_FAILED); 176 } 177 178 LOGGER.info("Move from '{}' to '{}'", source, destination); 179 nodeService.moveObject(session.getFedoraSession(), source, destination); 180 session.commit(); 181 return created(new URI(destinationUri)).build(); 182 } catch (final RepositoryRuntimeException e) { 183 final Throwable cause = e.getCause(); 184 185 if (cause instanceof ItemExistsException) { 186 throw new ClientErrorException("Destination resource already exists", PRECONDITION_FAILED, e); 187 } else if (cause instanceof PathNotFoundException) { 188 throw new ClientErrorException("There is no node that will serve as the parent of the moved item", 189 CONFLICT, e); 190 } else { 191 throw e; 192 } 193 } 194 } 195 196 @Override 197 protected void addResourceHttpHeaders(final FedoraResource resource) { 198 throw new UnsupportedOperationException(); 199 } 200 201 @Override 202 protected String externalPath() { 203 return externalPath; 204 } 205 206}