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