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