001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (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 * Gagnavarslan ehf 016 */ 017package org.nuxeo.ecm.webdav.resource; 018 019import static javax.ws.rs.core.Response.Status.OK; 020import static net.java.dev.webdav.jaxrs.xml.properties.ResourceType.COLLECTION; 021 022import java.net.URI; 023import java.util.ArrayList; 024import java.util.Date; 025import java.util.LinkedList; 026import java.util.List; 027 028import javax.servlet.http.HttpServletRequest; 029import javax.ws.rs.DELETE; 030import javax.ws.rs.GET; 031import javax.ws.rs.HEAD; 032import javax.ws.rs.HeaderParam; 033import javax.ws.rs.Produces; 034import javax.ws.rs.core.Context; 035import javax.ws.rs.core.Response; 036import javax.ws.rs.core.UriInfo; 037 038import net.java.dev.webdav.jaxrs.methods.COPY; 039import net.java.dev.webdav.jaxrs.methods.LOCK; 040import net.java.dev.webdav.jaxrs.methods.MKCOL; 041import net.java.dev.webdav.jaxrs.methods.MOVE; 042import net.java.dev.webdav.jaxrs.methods.PROPFIND; 043import net.java.dev.webdav.jaxrs.methods.PROPPATCH; 044import net.java.dev.webdav.jaxrs.methods.UNLOCK; 045import net.java.dev.webdav.jaxrs.xml.elements.ActiveLock; 046import net.java.dev.webdav.jaxrs.xml.elements.Depth; 047import net.java.dev.webdav.jaxrs.xml.elements.HRef; 048import net.java.dev.webdav.jaxrs.xml.elements.LockRoot; 049import net.java.dev.webdav.jaxrs.xml.elements.LockScope; 050import net.java.dev.webdav.jaxrs.xml.elements.LockToken; 051import net.java.dev.webdav.jaxrs.xml.elements.LockType; 052import net.java.dev.webdav.jaxrs.xml.elements.MultiStatus; 053import net.java.dev.webdav.jaxrs.xml.elements.Owner; 054import net.java.dev.webdav.jaxrs.xml.elements.Prop; 055import net.java.dev.webdav.jaxrs.xml.elements.PropStat; 056import net.java.dev.webdav.jaxrs.xml.elements.Status; 057import net.java.dev.webdav.jaxrs.xml.elements.TimeOut; 058import net.java.dev.webdav.jaxrs.xml.properties.CreationDate; 059import net.java.dev.webdav.jaxrs.xml.properties.DisplayName; 060import net.java.dev.webdav.jaxrs.xml.properties.GetContentLength; 061import net.java.dev.webdav.jaxrs.xml.properties.GetContentType; 062import net.java.dev.webdav.jaxrs.xml.properties.GetLastModified; 063import net.java.dev.webdav.jaxrs.xml.properties.LockDiscovery; 064import net.java.dev.webdav.jaxrs.xml.properties.SupportedLock; 065 066import org.apache.commons.lang.StringEscapeUtils; 067import org.nuxeo.ecm.webdav.jaxrs.IsCollection; 068import org.nuxeo.ecm.webdav.jaxrs.IsFolder; 069import org.nuxeo.ecm.webdav.jaxrs.IsHidden; 070 071public class VirtualFolderResource extends AbstractResource { 072 073 private LinkedList<String> rootFolderNames; 074 075 public VirtualFolderResource(String path, HttpServletRequest request, LinkedList<String> rootFolderNames) { 076 super(path, request); 077 this.rootFolderNames = rootFolderNames; 078 } 079 080 @GET 081 @Produces("text/html") 082 public String get() { 083 StringBuilder sb = new StringBuilder(); 084 sb.append("<html><body><p>"); 085 sb.append("Folder listing for "); 086 sb.append(path); 087 sb.append("/"); 088 sb.append("</p>\n<ul>\n"); 089 for (String name : rootFolderNames) { 090 String qname = StringEscapeUtils.escapeHtml(name); 091 sb.append("<li><a href=\""); 092 sb.append(qname); 093 sb.append("/"); // terminating slash 094 sb.append("\">"); 095 sb.append(qname); 096 sb.append("</a></li>\n"); 097 } 098 sb.append("</ul></body>\n"); 099 return sb.toString(); 100 } 101 102 @PROPFIND 103 public Response propfind(@Context UriInfo uriInfo, @HeaderParam("depth") String depth) { 104 105 if (depth == null) { 106 depth = "1"; 107 } 108 109 Date lastModified = new Date(); 110 Date creationDate = new Date(); 111 112 @SuppressWarnings("deprecation") 113 final net.java.dev.webdav.jaxrs.xml.elements.Response response = new net.java.dev.webdav.jaxrs.xml.elements.Response( 114 new HRef(uriInfo.getRequestUri()), null, null, null, new PropStat(new Prop(new DisplayName("nuxeo"), /* 115 * @ 116 * TODO 117 * : 118 * fix 119 * this 120 * . 121 * Hardcoded 122 * root 123 * name 124 */ 125 new LockDiscovery(), new SupportedLock(), new IsFolder("t"), new IsCollection(Integer.valueOf(1)), 126 new IsHidden(Integer.valueOf(0)), new GetContentType("application/octet-stream"), 127 new GetContentLength(0), new CreationDate(creationDate), new GetLastModified(lastModified), 128 COLLECTION), new Status(OK))); 129 130 if (depth.equals("0")) { 131 return Response.status(207).entity(new MultiStatus(response)).build(); 132 } 133 134 List<net.java.dev.webdav.jaxrs.xml.elements.Response> responses = new ArrayList<net.java.dev.webdav.jaxrs.xml.elements.Response>(); 135 responses.add(response); 136 137 for (String name : rootFolderNames) { 138 lastModified = new Date(); 139 creationDate = new Date(); 140 PropStatBuilderExt props = new PropStatBuilderExt(); 141 props.lastModified(lastModified).creationDate(creationDate).displayName(name).status(OK); 142 props.isCollection(); 143 144 PropStat found = props.build(); 145 146 net.java.dev.webdav.jaxrs.xml.elements.Response childResponse; 147 URI childUri = uriInfo.getRequestUriBuilder().path(name).build(); 148 149 childResponse = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(childUri), null, null, null, 150 found); 151 152 responses.add(childResponse); 153 } 154 155 MultiStatus st = new MultiStatus( 156 responses.toArray(new net.java.dev.webdav.jaxrs.xml.elements.Response[responses.size()])); 157 return Response.status(207).entity(st).build(); 158 } 159 160 @DELETE 161 public Response delete() { 162 return Response.status(401).build(); 163 } 164 165 @COPY 166 public Response copy() { 167 return Response.status(401).build(); 168 } 169 170 @MOVE 171 public Response move() { 172 return Response.status(401).build(); 173 } 174 175 @PROPPATCH 176 public Response proppatch() { 177 return Response.status(401).build(); 178 } 179 180 @MKCOL 181 public Response mkcol() { 182 return Response.status(405).build(); 183 } 184 185 @HEAD 186 public Response head() { 187 return Response.status(404).build(); 188 } 189 190 @LOCK 191 public Response lock(@Context UriInfo uriInfo) { 192 Prop prop = new Prop(new LockDiscovery(new ActiveLock(LockScope.EXCLUSIVE, LockType.WRITE, Depth.ZERO, 193 new Owner("Administrator"), new TimeOut(10000L), new LockToken(new HRef("urn:uuid:Administrator")), 194 new LockRoot(new HRef(uriInfo.getRequestUri()))))); 195 196 return Response.ok().entity(prop).header("Lock-Token", "urn:uuid:Administrator").build(); 197 } 198 199 @UNLOCK 200 public Response unlock() { 201 return Response.status(204).build(); 202 } 203 204}