001/* 002 * (C) Copyright 2006-2009 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.webdav.resource; 021 022import static javax.ws.rs.core.Response.Status.OK; 023 024import java.io.IOException; 025import java.net.URI; 026import java.net.URISyntaxException; 027import java.net.URLEncoder; 028 029import javax.servlet.http.HttpServletRequest; 030import javax.ws.rs.GET; 031import javax.ws.rs.PUT; 032import javax.ws.rs.core.Context; 033import javax.ws.rs.core.Response; 034import javax.ws.rs.core.UriInfo; 035import javax.xml.bind.JAXBException; 036import javax.xml.bind.Unmarshaller; 037 038import net.java.dev.webdav.jaxrs.methods.PROPFIND; 039import net.java.dev.webdav.jaxrs.xml.elements.HRef; 040import net.java.dev.webdav.jaxrs.xml.elements.LockEntry; 041import net.java.dev.webdav.jaxrs.xml.elements.LockScope; 042import net.java.dev.webdav.jaxrs.xml.elements.LockType; 043import net.java.dev.webdav.jaxrs.xml.elements.MultiStatus; 044import net.java.dev.webdav.jaxrs.xml.elements.Prop; 045import net.java.dev.webdav.jaxrs.xml.elements.PropFind; 046import net.java.dev.webdav.jaxrs.xml.elements.PropStat; 047import net.java.dev.webdav.jaxrs.xml.elements.Status; 048import net.java.dev.webdav.jaxrs.xml.properties.SupportedLock; 049 050import org.apache.commons.logging.Log; 051import org.apache.commons.logging.LogFactory; 052import org.nuxeo.ecm.core.api.Blob; 053import org.nuxeo.ecm.core.api.Blobs; 054import org.nuxeo.ecm.core.api.DocumentModel; 055import org.nuxeo.ecm.core.api.NuxeoException; 056import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 057import org.nuxeo.ecm.webdav.backend.Backend; 058import org.nuxeo.ecm.webdav.jaxrs.Util; 059 060/** 061 * Resource representing a file-like object in the repository. (I.e. not a folder). 062 */ 063public class FileResource extends ExistingResource { 064 065 private static final Log log = LogFactory.getLog(FileResource.class); 066 067 public FileResource(String path, DocumentModel doc, HttpServletRequest request, Backend backend) { 068 super(path, doc, request, backend); 069 } 070 071 @GET 072 public Object get() { 073 Blob content = null; 074 BlobHolder bh = doc.getAdapter(BlobHolder.class); 075 if (bh != null) { 076 content = bh.getBlob(); 077 } 078 if (content == null) { 079 return Response.ok("").build(); 080 } else { 081 String mimeType = content.getMimeType(); 082 if ("???".equals(mimeType)) { 083 mimeType = "application/octet-stream"; 084 } 085 return Response.ok(content).type(mimeType).build(); 086 } 087 } 088 089 @PUT 090 public Response put() { 091 if (backend.isLocked(doc.getRef()) && !backend.canUnlock(doc.getRef())) { 092 return Response.status(423).build(); 093 } 094 095 try { 096 Blob content = Blobs.createBlob(request.getInputStream()); 097 String contentType = request.getContentType(); 098 if (contentType == null) { 099 contentType = "application/octet-stream"; 100 } 101 content.setMimeType(contentType); 102 content.setFilename(name); 103 104 backend.updateDocument(doc, name, content); 105 try { 106 return Response.created(new URI(URLEncoder.encode(path, "UTF8"))).build(); 107 } catch (URISyntaxException e) { 108 throw new NuxeoException(e); 109 } 110 } catch (IOException e) { 111 log.error("Error during PUT method execution", e); 112 return Response.status(409).build(); 113 } 114 } 115 116 @PROPFIND 117 public Response propfind(@Context UriInfo uriInfo) throws IOException, JAXBException { 118 119 Unmarshaller u = Util.getUnmarshaller(); 120 121 Prop prop = null; 122 if (request.getInputStream() != null && request.getContentLength() > 0) { 123 PropFind propFind; 124 try { 125 propFind = (PropFind) u.unmarshal(request.getInputStream()); 126 } catch (JAXBException e) { 127 return Response.status(400).build(); 128 } 129 prop = propFind.getProp(); 130 } 131 // Util.printAsXml(prop); 132 133 PropStatBuilderExt props = getPropStatBuilderExt(doc, uriInfo); 134 PropStat propStatFound = props.build(); 135 PropStat propStatNotFound = null; 136 if (prop != null) { 137 propStatNotFound = props.notFound(prop); 138 } 139 140 net.java.dev.webdav.jaxrs.xml.elements.Response response; 141 URI uri = uriInfo.getRequestUri(); 142 PropStat filePropStat = new PropStat(new Prop(new SupportedLock(new LockEntry(LockScope.EXCLUSIVE, 143 LockType.WRITE))), new Status(OK)); 144 if (doc.isLocked()) { 145 PropStat lockDiscoveryPropStat = new PropStat(new Prop(getLockDiscovery(doc, uriInfo)), new Status(OK)); 146 if (propStatNotFound != null) { 147 response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null, 148 filePropStat, propStatFound, propStatNotFound, lockDiscoveryPropStat); 149 } else { 150 response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null, 151 filePropStat, propStatFound, lockDiscoveryPropStat); 152 } 153 } else { 154 if (propStatNotFound != null) { 155 response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null, 156 filePropStat, propStatFound, propStatNotFound); 157 } else { 158 response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null, 159 filePropStat, propStatFound); 160 } 161 } 162 163 MultiStatus st = new MultiStatus(response); 164 return Response.status(207).entity(st).build(); 165 } 166 167}