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.util.ArrayList; 027import java.util.List; 028 029import javax.servlet.http.HttpServletRequest; 030import javax.ws.rs.GET; 031import javax.ws.rs.HeaderParam; 032import javax.ws.rs.Produces; 033import javax.ws.rs.core.Context; 034import javax.ws.rs.core.Response; 035import javax.ws.rs.core.UriBuilder; 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.MultiStatus; 043import net.java.dev.webdav.jaxrs.xml.elements.Prop; 044import net.java.dev.webdav.jaxrs.xml.elements.PropFind; 045import net.java.dev.webdav.jaxrs.xml.elements.PropStat; 046import net.java.dev.webdav.jaxrs.xml.elements.Status; 047import net.java.dev.webdav.jaxrs.xml.properties.LockDiscovery; 048import net.java.dev.webdav.jaxrs.xml.properties.SupportedLock; 049 050import org.apache.commons.httpclient.URIException; 051import org.apache.commons.httpclient.util.URIUtil; 052import org.apache.commons.lang.StringEscapeUtils; 053import org.apache.commons.logging.Log; 054import org.apache.commons.logging.LogFactory; 055import org.nuxeo.ecm.core.api.DocumentModel; 056import org.nuxeo.ecm.webdav.backend.Backend; 057import org.nuxeo.ecm.webdav.jaxrs.IsFolder; 058import org.nuxeo.ecm.webdav.jaxrs.Util; 059 060/** 061 * A resource for folder-like objects in the repository. 062 */ 063public class FolderResource extends ExistingResource { 064 065 private static final Log log = LogFactory.getLog(FolderResource.class); 066 067 public FolderResource(String path, DocumentModel doc, HttpServletRequest request, Backend backend) { 068 super(path, doc, request, backend); 069 } 070 071 @GET 072 @Produces("text/html") 073 public String get() { 074 StringBuilder sb = new StringBuilder(); 075 sb.append("<html><body><p>"); 076 sb.append("Folder listing for "); 077 sb.append(path); 078 sb.append("/"); 079 sb.append("</p>\n<ul>\n"); 080 List<DocumentModel> children = backend.getChildren(doc.getRef()); 081 for (DocumentModel child : children) { 082 String name = backend.getDisplayName(child); 083 String qname = StringEscapeUtils.escapeHtml(name); 084 sb.append("<li><a href=\""); 085 sb.append(qname); 086 if (child.isFolder()) { 087 sb.append("/"); 088 } 089 sb.append("\">"); 090 sb.append(qname); 091 sb.append("</a></li>\n"); 092 } 093 sb.append("</ul></body>\n"); 094 return sb.toString(); 095 } 096 097 @PROPFIND 098 public Response propfind(@Context UriInfo uriInfo, @HeaderParam("depth") String depth) throws IOException, 099 JAXBException { 100 101 if (depth == null) { 102 depth = "1"; 103 } 104 105 Unmarshaller u = Util.getUnmarshaller(); 106 107 Prop prop = null; 108 if (request.getInputStream() != null && request.getContentLength() > 0) { 109 PropFind propFind; 110 try { 111 propFind = (PropFind) u.unmarshal(request.getInputStream()); 112 } catch (JAXBException e) { 113 log.error(e); 114 // FIXME: check this is the right response code 115 return Response.status(400).build(); 116 } 117 prop = propFind.getProp(); 118 // Util.printAsXml(prop); 119 } 120 121 final net.java.dev.webdav.jaxrs.xml.elements.Response response; 122 response = createResponse(doc, uriInfo, prop, false); 123 124 if (!doc.isFolder() || depth.equals("0")) { 125 return Response.status(207).entity(new MultiStatus(response)).build(); 126 } 127 128 List<net.java.dev.webdav.jaxrs.xml.elements.Response> responses = new ArrayList<net.java.dev.webdav.jaxrs.xml.elements.Response>(); 129 responses.add(response); 130 131 List<DocumentModel> children = backend.getChildren(doc.getRef()); 132 for (DocumentModel child : children) { 133 net.java.dev.webdav.jaxrs.xml.elements.Response childResponse; 134 childResponse = createResponse(child, uriInfo, prop); 135 136 responses.add(childResponse); 137 } 138 139 MultiStatus st = new MultiStatus( 140 responses.toArray(new net.java.dev.webdav.jaxrs.xml.elements.Response[responses.size()])); 141 // printXml(st); 142 return Response.status(207).entity(st).build(); 143 } 144 145 protected net.java.dev.webdav.jaxrs.xml.elements.Response createResponse(DocumentModel doc, UriInfo uriInfo, 146 Prop prop) throws URIException { 147 return createResponse(doc, uriInfo, prop, true); 148 } 149 150 protected net.java.dev.webdav.jaxrs.xml.elements.Response createResponse(DocumentModel doc, UriInfo uriInfo, 151 Prop prop, boolean append) throws URIException { 152 PropStatBuilderExt props = getPropStatBuilderExt(doc, uriInfo); 153 PropStat propStatFound = props.build(); 154 PropStat propStatNotFound = null; 155 if (prop != null) { 156 propStatNotFound = props.notFound(prop); 157 } 158 159 net.java.dev.webdav.jaxrs.xml.elements.Response response; 160 UriBuilder uriBuilder = uriInfo.getRequestUriBuilder(); 161 if (append) { 162 uriBuilder.path(URIUtil.encodePath(backend.getDisplayName(doc))); 163 } 164 URI uri = uriBuilder.build(); 165 if (doc.isFolder()) { 166 PropStat folderPropStat = new PropStat( 167 new Prop(new LockDiscovery(), new SupportedLock(), new IsFolder("t")), new Status(OK)); 168 if (propStatNotFound != null) { 169 response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null, 170 propStatFound, propStatNotFound, folderPropStat); 171 } else { 172 response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null, 173 propStatFound, folderPropStat); 174 } 175 } else { 176 if (propStatNotFound != null) { 177 response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null, 178 propStatFound, propStatNotFound); 179 } else { 180 response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null, 181 propStatFound); 182 } 183 } 184 return response; 185 } 186 187}