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 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.webdav.resource;
023
024import static javax.ws.rs.core.Response.Status.OK;
025
026import java.io.IOException;
027import java.net.URI;
028import java.net.URISyntaxException;
029import java.net.URLEncoder;
030
031import javax.servlet.http.HttpServletRequest;
032import javax.ws.rs.GET;
033import javax.ws.rs.PUT;
034import javax.ws.rs.core.Context;
035import javax.ws.rs.core.Response;
036import javax.ws.rs.core.UriInfo;
037import javax.xml.bind.JAXBException;
038import javax.xml.bind.Unmarshaller;
039
040import net.java.dev.webdav.jaxrs.methods.PROPFIND;
041import net.java.dev.webdav.jaxrs.xml.elements.HRef;
042import net.java.dev.webdav.jaxrs.xml.elements.LockEntry;
043import net.java.dev.webdav.jaxrs.xml.elements.LockScope;
044import net.java.dev.webdav.jaxrs.xml.elements.LockType;
045import net.java.dev.webdav.jaxrs.xml.elements.MultiStatus;
046import net.java.dev.webdav.jaxrs.xml.elements.Prop;
047import net.java.dev.webdav.jaxrs.xml.elements.PropFind;
048import net.java.dev.webdav.jaxrs.xml.elements.PropStat;
049import net.java.dev.webdav.jaxrs.xml.elements.Status;
050import net.java.dev.webdav.jaxrs.xml.properties.SupportedLock;
051
052import org.apache.commons.logging.Log;
053import org.apache.commons.logging.LogFactory;
054import org.nuxeo.ecm.core.api.Blob;
055import org.nuxeo.ecm.core.api.Blobs;
056import org.nuxeo.ecm.core.api.DocumentModel;
057import org.nuxeo.ecm.core.api.NuxeoException;
058import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
059import org.nuxeo.ecm.webdav.backend.Backend;
060import org.nuxeo.ecm.webdav.jaxrs.Util;
061
062/**
063 * Resource representing a file-like object in the repository. (I.e. not a folder).
064 */
065public class FileResource extends ExistingResource {
066
067    private static final Log log = LogFactory.getLog(FileResource.class);
068
069    public FileResource(String path, DocumentModel doc, HttpServletRequest request, Backend backend) {
070        super(path, doc, request, backend);
071    }
072
073    @GET
074    public Object get() {
075        Blob content = null;
076        BlobHolder bh = doc.getAdapter(BlobHolder.class);
077        if (bh != null) {
078            content = bh.getBlob();
079        }
080        if (content == null) {
081            return Response.ok("").build();
082        } else {
083            String mimeType = content.getMimeType();
084            if ("???".equals(mimeType)) {
085                mimeType = "application/octet-stream";
086            }
087            return Response.ok(content).type(mimeType).build();
088        }
089    }
090
091    @PUT
092    public Response put() {
093        if (backend.isLocked(doc.getRef()) && !backend.canUnlock(doc.getRef())) {
094            return Response.status(423).build();
095        }
096
097        try {
098            Blob content = Blobs.createBlob(request.getInputStream());
099            String contentType = request.getContentType();
100            if (contentType == null) {
101                contentType = "application/octet-stream";
102            }
103            content.setMimeType(contentType);
104            content.setFilename(name);
105
106            backend.updateDocument(doc, name, content);
107            try {
108                return Response.created(new URI(URLEncoder.encode(path, "UTF8"))).build();
109            } catch (URISyntaxException e) {
110                throw new NuxeoException(e);
111            }
112        } catch (IOException e) {
113            log.error("Error during PUT method execution", e);
114            return Response.status(409).build();
115        }
116    }
117
118    @PROPFIND
119    public Response propfind(@Context UriInfo uriInfo) throws IOException, JAXBException {
120
121        Unmarshaller u = Util.getUnmarshaller();
122
123        Prop prop = null;
124        if (request.getInputStream() != null && request.getContentLength() > 0) {
125            PropFind propFind;
126            try {
127                propFind = (PropFind) u.unmarshal(request.getInputStream());
128            } catch (JAXBException e) {
129                return Response.status(400).build();
130            }
131            prop = propFind.getProp();
132        }
133        // Util.printAsXml(prop);
134
135        PropStatBuilderExt props = getPropStatBuilderExt(doc, uriInfo);
136        PropStat propStatFound = props.build();
137        PropStat propStatNotFound = null;
138        if (prop != null) {
139            propStatNotFound = props.notFound(prop);
140        }
141
142        net.java.dev.webdav.jaxrs.xml.elements.Response response;
143        URI uri = uriInfo.getRequestUri();
144        PropStat filePropStat = new PropStat(new Prop(new SupportedLock(new LockEntry(LockScope.EXCLUSIVE,
145                LockType.WRITE))), new Status(OK));
146        if (doc.isLocked()) {
147            PropStat lockDiscoveryPropStat = new PropStat(new Prop(getLockDiscovery(doc, uriInfo)), new Status(OK));
148            if (propStatNotFound != null) {
149                response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null,
150                        filePropStat, propStatFound, propStatNotFound, lockDiscoveryPropStat);
151            } else {
152                response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null,
153                        filePropStat, propStatFound, lockDiscoveryPropStat);
154            }
155        } else {
156            if (propStatNotFound != null) {
157                response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null,
158                        filePropStat, propStatFound, propStatNotFound);
159            } else {
160                response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null,
161                        filePropStat, propStatFound);
162            }
163        }
164
165        MultiStatus st = new MultiStatus(response);
166        return Response.status(207).entity(st).build();
167    }
168
169}