001/* 002 * (C) Copyright 2006-2009 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Stefane Fermigier 018 */ 019package org.nuxeo.ecm.webdav.resource; 020 021import java.io.IOException; 022import java.net.URI; 023import java.net.URISyntaxException; 024 025import javax.servlet.http.HttpServletRequest; 026import javax.ws.rs.DELETE; 027import javax.ws.rs.HEAD; 028import javax.ws.rs.PUT; 029import javax.ws.rs.WebApplicationException; 030import javax.ws.rs.core.Response; 031 032import net.java.dev.webdav.jaxrs.methods.COPY; 033import net.java.dev.webdav.jaxrs.methods.MKCOL; 034import net.java.dev.webdav.jaxrs.methods.MOVE; 035import net.java.dev.webdav.jaxrs.methods.PROPFIND; 036import net.java.dev.webdav.jaxrs.methods.PROPPATCH; 037 038import org.nuxeo.ecm.core.api.Blob; 039import org.nuxeo.ecm.core.api.Blobs; 040import org.nuxeo.ecm.webdav.backend.Backend; 041 042/** 043 * Resource for an unknown (ie non-existing) object. Used so that PUT / MKCOL requests can actually created a document / 044 * folder. Other requests will end up with a 404 error. 045 */ 046public class UnknownResource extends AbstractResource { 047 048 private static final String DS_STORE = ".DS_Store"; 049 050 protected Backend backend; 051 052 public UnknownResource(String path, HttpServletRequest request, Backend backend) { 053 super(path, request); 054 this.backend = backend; 055 } 056 057 /** 058 * PUT over a non-existing resource: create a new file resource. 059 */ 060 @PUT 061 public Response put() throws IOException, URISyntaxException { 062 063 // Special case: ignore some Mac OS X files. 064 // ._ files cannot easily be skipped as the Finder requires them on creation 065 // We only forbid .DS_Store creation for now. 066 if (DS_STORE.equals(name)) { 067 throw new WebApplicationException(Response.Status.CONFLICT); 068 } 069 070 ensureParentExists(); 071 String contentType = request.getContentType(); 072 if (contentType == null) { 073 contentType = "application/octet-stream"; 074 } 075 Blob content = Blobs.createBlob(request.getInputStream(), contentType, null); 076 content.setFilename(name); 077 backend.createFile(parentPath, name, content); 078 backend.saveChanges(); 079 return Response.created(new URI(request.getRequestURI())).build(); 080 } 081 082 /** 083 * MKCOL over a non-existing resource: create a new folder resource. 084 */ 085 @MKCOL 086 public Response mkcol() throws IOException, URISyntaxException { 087 ensureParentExists(); 088 backend.createFolder(parentPath, name); 089 backend.saveChanges(); 090 return Response.created(new URI(request.getRequestURI())).build(); 091 } 092 093 // All these methods should raise an error 404 094 095 @DELETE 096 public Response delete() { 097 throw new WebApplicationException(Response.Status.NOT_FOUND); 098 } 099 100 @COPY 101 public Response copy() { 102 throw new WebApplicationException(Response.Status.NOT_FOUND); 103 } 104 105 @MOVE 106 public Response move() { 107 throw new WebApplicationException(Response.Status.NOT_FOUND); 108 } 109 110 @PROPFIND 111 public Response propfind() { 112 throw new WebApplicationException(Response.Status.NOT_FOUND); 113 } 114 115 @PROPPATCH 116 public Response proppatch() { 117 throw new WebApplicationException(Response.Status.NOT_FOUND); 118 } 119 120 @HEAD 121 public Response head() { 122 throw new WebApplicationException(Response.Status.NOT_FOUND); 123 } 124 125 // Utility 126 127 private void ensureParentExists() { 128 if (!backend.exists(parentPath)) { 129 throw new WebApplicationException(Response.Status.CONFLICT); 130 } 131 } 132 133}