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 java.io.IOException;
025import java.io.UnsupportedEncodingException;
026import java.net.URISyntaxException;
027
028import javax.servlet.http.HttpServletRequest;
029import javax.ws.rs.GET;
030import javax.ws.rs.HeaderParam;
031import javax.ws.rs.OPTIONS;
032import javax.ws.rs.Path;
033import javax.ws.rs.PathParam;
034import javax.ws.rs.Produces;
035import javax.ws.rs.WebApplicationException;
036import javax.ws.rs.core.Context;
037import javax.ws.rs.core.Response;
038import javax.ws.rs.core.UriInfo;
039import javax.xml.bind.JAXBException;
040
041import net.java.dev.webdav.jaxrs.methods.PROPFIND;
042
043import org.apache.commons.logging.Log;
044import org.apache.commons.logging.LogFactory;
045import org.nuxeo.ecm.core.api.Blob;
046import org.nuxeo.ecm.core.api.DocumentModel;
047import org.nuxeo.ecm.core.api.DocumentNotFoundException;
048import org.nuxeo.ecm.core.api.NuxeoException;
049import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
050import org.nuxeo.ecm.core.api.security.SecurityConstants;
051import org.nuxeo.ecm.webdav.backend.Backend;
052import org.nuxeo.ecm.webdav.backend.BackendHelper;
053
054//path is set at the servlet level, see the deployment-fragment file
055@Path("")
056public class RootResource {
057
058    private static final Log log = LogFactory.getLog(RootResource.class);
059
060    private HttpServletRequest request;
061
062    public RootResource(@Context HttpServletRequest request) {
063        log.debug(request.getMethod() + " " + request.getRequestURI());
064        this.request = request;
065    }
066
067    @GET
068    @Produces("text/html")
069    public Object getRoot() {
070        Object resource = findResource("");
071        if (resource instanceof FolderResource) {
072            return ((FolderResource) resource).get();
073        } else {
074            return ((VirtualFolderResource) findResource("")).get();
075        }
076    }
077
078    @OPTIONS
079    public Object getRootOptions() {
080        Object resource = findResource("");
081        if (resource instanceof FolderResource) {
082            return ((FolderResource) resource).options();
083        } else {
084            return ((VirtualFolderResource) findResource("")).options();
085        }
086    }
087
088    @PROPFIND
089    public Object getRootPropfind(@Context UriInfo uriInfo, @HeaderParam("depth") String depth)
090            throws IOException, JAXBException, URISyntaxException {
091        Object resource = findResource("");
092        if (resource instanceof FolderResource) {
093            return ((FolderResource) resource).propfind(uriInfo, depth);
094        } else {
095            return ((VirtualFolderResource) findResource("")).propfind(uriInfo, depth);
096        }
097    }
098
099    @Path("{path:.+}")
100    public Object findResource(@PathParam("path") String path) {
101        try {
102            path = new String(path.getBytes(), "UTF-8");
103        } catch (UnsupportedEncodingException e) {
104            throw new NuxeoException(e);
105        }
106
107        Backend backend = BackendHelper.getBackend(path, request);
108
109        if (backend == null) {
110            throw new WebApplicationException(Response.Status.NOT_FOUND);
111        }
112
113        if (backend.isVirtual()) {
114            return new VirtualFolderResource(path, request, backend.getVirtualFolderNames());
115        }
116
117        DocumentModel doc = null;
118        try {
119            doc = backend.getDocument(path);
120        } catch (DocumentNotFoundException e) {
121            log.error("Error during resolving path: " + path, e);
122            throw new WebApplicationException(Response.Status.CONFLICT);
123        }
124
125        if (doc == null) {
126            return new UnknownResource(path, request, backend);
127        }
128
129        // Send 401 error if not authorised to read.
130        if (!backend.hasPermission(doc.getRef(), SecurityConstants.READ)) {
131            throw new WebApplicationException(Response.Status.UNAUTHORIZED);
132        }
133
134        if (doc.isFolder()) {
135            return new FolderResource(getDocumentPath(doc), doc, request, backend);
136        } else {
137            return new FileResource(getDocumentPath(doc), doc, request, backend);
138        }
139    }
140
141    private String getDocumentPath(DocumentModel source) {
142        if (source.isFolder()) {
143            return source.getPathAsString();
144        } else {
145            BlobHolder bh = source.getAdapter(BlobHolder.class);
146            if (bh != null) {
147                Blob blob = bh.getBlob();
148                if (blob != null) {
149                    return blob.getFilename();
150                }
151            }
152            return String.valueOf(source.getPropertyValue("dc:title"));
153        }
154    }
155
156}