/*
* (C) Copyright 2006-2009 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Nuxeo - initial API and implementation
*
* $Id$
*/
package org.nuxeo.ecm.webdav.resource;
import static javax.ws.rs.core.Response.Status.OK;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import net.java.dev.webdav.jaxrs.methods.PROPFIND;
import net.java.dev.webdav.jaxrs.xml.elements.HRef;
import net.java.dev.webdav.jaxrs.xml.elements.MultiStatus;
import net.java.dev.webdav.jaxrs.xml.elements.Prop;
import net.java.dev.webdav.jaxrs.xml.elements.PropFind;
import net.java.dev.webdav.jaxrs.xml.elements.PropStat;
import net.java.dev.webdav.jaxrs.xml.elements.Status;
import net.java.dev.webdav.jaxrs.xml.properties.LockDiscovery;
import net.java.dev.webdav.jaxrs.xml.properties.SupportedLock;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.webdav.backend.Backend;
import org.nuxeo.ecm.webdav.jaxrs.IsFolder;
import org.nuxeo.ecm.webdav.jaxrs.Util;
/**
* A resource for folder-like objects in the repository.
*/
public class FolderResource extends ExistingResource {
private static final Log log = LogFactory.getLog(FolderResource.class);
public FolderResource(String path, DocumentModel doc, HttpServletRequest request, Backend backend) {
super(path, doc, request, backend);
}
@GET
@Produces("text/html")
public String get() {
StringBuilder sb = new StringBuilder();
sb.append("<html><body><p>");
sb.append("Folder listing for ");
sb.append(path);
sb.append("/");
sb.append("</p>\n<ul>\n");
List<DocumentModel> children = backend.getChildren(doc.getRef());
for (DocumentModel child : children) {
String name = backend.getDisplayName(child);
String qname = StringEscapeUtils.escapeHtml(name);
sb.append("<li><a href=\"");
sb.append(qname);
if (child.isFolder()) {
sb.append("/");
}
sb.append("\">");
sb.append(qname);
sb.append("</a></li>\n");
}
sb.append("</ul></body>\n");
return sb.toString();
}
@PROPFIND
public Response propfind(@Context UriInfo uriInfo, @HeaderParam("depth") String depth) throws IOException,
JAXBException {
if (depth == null) {
depth = "1";
}
Unmarshaller u = Util.getUnmarshaller();
Prop prop = null;
if (request.getInputStream() != null && request.getContentLength() > 0) {
PropFind propFind;
try {
propFind = (PropFind) u.unmarshal(request.getInputStream());
} catch (JAXBException e) {
log.error(e);
// FIXME: check this is the right response code
return Response.status(400).build();
}
prop = propFind.getProp();
// Util.printAsXml(prop);
}
final net.java.dev.webdav.jaxrs.xml.elements.Response response;
response = createResponse(doc, uriInfo, prop, false);
if (!doc.isFolder() || depth.equals("0")) {
return Response.status(207).entity(new MultiStatus(response)).build();
}
List<net.java.dev.webdav.jaxrs.xml.elements.Response> responses = new ArrayList<net.java.dev.webdav.jaxrs.xml.elements.Response>();
responses.add(response);
List<DocumentModel> children = backend.getChildren(doc.getRef());
for (DocumentModel child : children) {
net.java.dev.webdav.jaxrs.xml.elements.Response childResponse;
childResponse = createResponse(child, uriInfo, prop);
responses.add(childResponse);
}
MultiStatus st = new MultiStatus(
responses.toArray(new net.java.dev.webdav.jaxrs.xml.elements.Response[responses.size()]));
// printXml(st);
return Response.status(207).entity(st).build();
}
protected net.java.dev.webdav.jaxrs.xml.elements.Response createResponse(DocumentModel doc, UriInfo uriInfo,
Prop prop) throws URIException {
return createResponse(doc, uriInfo, prop, true);
}
protected net.java.dev.webdav.jaxrs.xml.elements.Response createResponse(DocumentModel doc, UriInfo uriInfo,
Prop prop, boolean append) throws URIException {
PropStatBuilderExt props = getPropStatBuilderExt(doc, uriInfo);
PropStat propStatFound = props.build();
PropStat propStatNotFound = null;
if (prop != null) {
propStatNotFound = props.notFound(prop);
}
net.java.dev.webdav.jaxrs.xml.elements.Response response;
UriBuilder uriBuilder = uriInfo.getRequestUriBuilder();
if (append) {
uriBuilder.path(URIUtil.encodePath(backend.getDisplayName(doc)));
}
URI uri = uriBuilder.build();
if (doc.isFolder()) {
PropStat folderPropStat = new PropStat(
new Prop(new LockDiscovery(), new SupportedLock(), new IsFolder("t")), new Status(OK));
if (propStatNotFound != null) {
response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null,
propStatFound, propStatNotFound, folderPropStat);
} else {
response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null,
propStatFound, folderPropStat);
}
} else {
if (propStatNotFound != null) {
response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null,
propStatFound, propStatNotFound);
} else {
response = new net.java.dev.webdav.jaxrs.xml.elements.Response(new HRef(uri), null, null, null,
propStatFound);
}
}
return response;
}
}