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.text.StringEscapeUtils; 069import org.nuxeo.ecm.webdav.EscapeUtils; 070import org.nuxeo.ecm.webdav.jaxrs.IsCollection; 071import org.nuxeo.ecm.webdav.jaxrs.IsFolder; 072import org.nuxeo.ecm.webdav.jaxrs.IsHidden; 073 074public class VirtualFolderResource extends AbstractResource { 075 076 private LinkedList<String> rootFolderNames; 077 078 public VirtualFolderResource(String path, HttpServletRequest request, LinkedList<String> rootFolderNames) { 079 super(path, request); 080 this.rootFolderNames = rootFolderNames; 081 } 082 083 @GET 084 @Produces("text/html") 085 public String get() { 086 StringBuilder sb = new StringBuilder(); 087 sb.append("<html><body><p>"); 088 sb.append("Folder listing for "); 089 sb.append(StringEscapeUtils.escapeHtml4(path)); 090 sb.append("/"); 091 sb.append("</p>\n<ul>\n"); 092 for (String name : rootFolderNames) { 093 sb.append("<li><a href=\""); 094 sb.append(StringEscapeUtils.escapeHtml4(EscapeUtils.encodePath(name))); 095 sb.append("/"); // terminating slash 096 sb.append("\">"); 097 sb.append(StringEscapeUtils.escapeHtml4(name)); 098 sb.append("</a></li>\n"); 099 } 100 sb.append("</ul></body>\n"); 101 return sb.toString(); 102 } 103 104 @PROPFIND 105 @Produces({ "application/xml", "text/xml" }) 106 public Response propfind(@Context UriInfo uriInfo, @HeaderParam("depth") String depth) { 107 108 if (depth == null) { 109 depth = "1"; 110 } 111 112 Date lastModified = new Date(); 113 Date creationDate = new Date(); 114 115 @SuppressWarnings("deprecation") 116 final net.java.dev.webdav.jaxrs.xml.elements.Response response = new net.java.dev.webdav.jaxrs.xml.elements.Response( 117 new HRef(uriInfo.getRequestUri()), null, null, null, new PropStat(new Prop(new DisplayName("nuxeo"), /* 118 * @ 119 * TODO 120 * : 121 * fix 122 * this 123 * . 124 * Hardcoded 125 * root 126 * name 127 */ 128 new LockDiscovery(), new SupportedLock(), new IsFolder("t"), new IsCollection(Integer.valueOf(1)), 129 new IsHidden(Integer.valueOf(0)), new GetContentType("application/octet-stream"), 130 new GetContentLength(0), new CreationDate(creationDate), new GetLastModified(lastModified), 131 COLLECTION), new Status(OK))); 132 133 if (depth.equals("0")) { 134 return Response.status(207).entity(new MultiStatus(response)).build(); 135 } 136 137 List<net.java.dev.webdav.jaxrs.xml.elements.Response> responses = new ArrayList<net.java.dev.webdav.jaxrs.xml.elements.Response>(); 138 responses.add(response); 139 140 for (String name : rootFolderNames) { 141 lastModified = new Date(); 142 creationDate = new Date(); 143 PropStatBuilderExt props = new PropStatBuilderExt(); 144 props.lastModified(lastModified).creationDate(creationDate).displayName(name).status(OK); 145 props.isCollection(); 146 147 PropStat found = props.build(); 148 149 net.java.dev.webdav.jaxrs.xml.elements.Response childResponse; 150 URI childUri = uriInfo.getRequestUriBuilder().path(name).build(); 151 152 childResponse = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(childUri), null, null, null, 153 found); 154 155 responses.add(childResponse); 156 } 157 158 MultiStatus st = new MultiStatus( 159 responses.toArray(new net.java.dev.webdav.jaxrs.xml.elements.Response[responses.size()])); 160 return Response.status(207).entity(st).build(); 161 } 162 163 @DELETE 164 public Response delete() { 165 return Response.status(401).build(); 166 } 167 168 @COPY 169 public Response copy() { 170 return Response.status(401).build(); 171 } 172 173 @MOVE 174 public Response move() { 175 return Response.status(401).build(); 176 } 177 178 @PROPPATCH 179 public Response proppatch() { 180 return Response.status(401).build(); 181 } 182 183 @MKCOL 184 public Response mkcol() { 185 return Response.status(405).build(); 186 } 187 188 @HEAD 189 public Response head() { 190 return Response.status(404).build(); 191 } 192 193 @LOCK 194 @Produces({ "application/xml", "text/xml" }) 195 public Response lock(@Context UriInfo uriInfo) { 196 Prop prop = new Prop(new LockDiscovery(new ActiveLock(LockScope.EXCLUSIVE, LockType.WRITE, Depth.ZERO, 197 new Owner("Administrator"), new TimeOut(10000L), new LockToken(new HRef("urn:uuid:Administrator")), 198 new LockRoot(new HRef(uriInfo.getRequestUri()))))); 199 200 return Response.ok().entity(prop).header("Lock-Token", "urn:uuid:Administrator").build(); 201 } 202 203 @UNLOCK 204 @Produces({ "application/xml", "text/xml" }) 205 public Response unlock() { 206 return Response.status(204).build(); 207 } 208 209}