You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@clerezza.apache.org by mi...@apache.org on 2010/03/17 11:39:23 UTC

svn commit: r924215 - in /incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content: ./ src/main/java/org/apache/clerezza/platform/content/ src/main/java/org/apache/clerezza/platform/content/hierarchy/ src/main/java/org/a...

Author: mir
Date: Wed Mar 17 10:39:23 2010
New Revision: 924215

URL: http://svn.apache.org/viewvc?rev=924215&view=rev
Log:
CLEREZZA-119: merged with trunk

Added:
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/CollectionTypeHandler.java
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/CollectionTypeHandler.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/WebDavUtils.java
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/WebDavUtils.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/
      - copied from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/COPY.java
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/COPY.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/LOCK.java
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/LOCK.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/MKCOL.java
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/MKCOL.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/MOVE.java
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/MOVE.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/PROPFIND.java
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/PROPFIND.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/PROPPATCH.java
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/PROPPATCH.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/UNLOCK.java
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/webdav/UNLOCK.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/resources/org/apache/clerezza/platform/content/collection.ssp
      - copied unchanged from r924213, incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content/src/main/resources/org/apache/clerezza/platform/content/collection.ssp
Modified:
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/   (props changed)
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/pom.xml
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsHandler.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsTypeHandler.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyNode.java
    incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyUtils.java

Propchange: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Mar 17 10:39:23 2010
@@ -1,5 +1,6 @@
 /incubator/clerezza/issues/CLEREZZA-103/org.apache.clerezza.platform.content:907223-909027
 /incubator/clerezza/issues/CLEREZZA-113/org.apache.clerezza.platform.content:908544-911013
+/incubator/clerezza/issues/CLEREZZA-119/org.apache.clerezza.platform.content:917505-924213
 /incubator/clerezza/issues/CLEREZZA-129/org.apache.clerezza.platform.content:917938-918563
 /incubator/clerezza/issues/CLEREZZA-25/org.apache.clerezza.platform.content:891178-892849
 /incubator/clerezza/issues/CLEREZZA-65/org.apache.clerezza.platform.content:897875-897920

Modified: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/pom.xml
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/pom.xml?rev=924215&r1=924214&r2=924215&view=diff
==============================================================================
--- incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/pom.xml (original)
+++ incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/pom.xml Wed Mar 17 10:39:23 2010
@@ -86,6 +86,10 @@
 			<artifactId>org.apache.clerezza.platform.security</artifactId>
 		</dependency>
 		<dependency>
+			<groupId>org.apache.clerezza</groupId>
+			<artifactId>org.apache.clerezza.platform.typerendering.scalaserverpages</artifactId>
+		</dependency>
+		<dependency>
 			<groupId>junit</groupId>
 			<artifactId>junit</artifactId>
 			<scope>test</scope>

Modified: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsHandler.java
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsHandler.java?rev=924215&r1=924214&r2=924215&view=diff
==============================================================================
--- incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsHandler.java (original)
+++ incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsHandler.java Wed Mar 17 10:39:23 2010
@@ -44,7 +44,8 @@ public interface DiscobitsHandler {
 
 	/**
 	 * Removes InfoDiscoBits (aka binary contents), other DiscoBits and
-	 * the context of the specified node.
+	 * the context of the specified node. If it is in a hierarchy then it
+	 * will be removed also form its container.
 	 * 
 	 * @param node
 	 */

Modified: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsTypeHandler.java
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsTypeHandler.java?rev=924215&r1=924214&r2=924215&view=diff
==============================================================================
--- incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsTypeHandler.java (original)
+++ incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/DiscobitsTypeHandler.java Wed Mar 17 10:39:23 2010
@@ -18,12 +18,21 @@
  */
 package org.apache.clerezza.platform.content;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.net.URISyntaxException;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import java.util.Set;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
+import javax.ws.rs.HttpMethod;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Produces;
 import javax.ws.rs.WebApplicationException;
@@ -34,7 +43,24 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.ext.RuntimeDelegate;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import org.apache.clerezza.jaxrs.utils.RedirectUtil;
+import org.apache.clerezza.platform.content.WebDavUtils.PropertyMap;
+import org.apache.clerezza.platform.content.hierarchy.CollectionNode;
+import org.apache.clerezza.platform.content.hierarchy.HierarchyNode;
 import org.apache.clerezza.platform.content.hierarchy.HierarchyService;
+import org.apache.clerezza.platform.content.hierarchy.HierarchyUtils;
+import org.apache.clerezza.platform.content.hierarchy.IllegalMoveException;
+import org.apache.clerezza.platform.content.hierarchy.NodeAlreadyExistsException;
+import org.apache.clerezza.platform.content.hierarchy.NodeDoesNotExistException;
+import org.apache.clerezza.platform.content.hierarchy.UnknownRootExcetpion;
+import org.apache.clerezza.platform.content.webdav.MKCOL;
+import org.apache.clerezza.platform.content.webdav.MOVE;
+import org.apache.clerezza.platform.content.webdav.PROPFIND;
+import org.apache.clerezza.platform.content.webdav.PROPPATCH;
 
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Property;
@@ -46,10 +72,16 @@ import org.apache.felix.scr.annotations.
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.clerezza.platform.graphprovider.content.ContentGraphProvider;
+import org.apache.clerezza.platform.typehandlerspace.OPTIONS;
 import org.apache.clerezza.platform.typehandlerspace.SupportedTypes;
 import org.apache.clerezza.rdf.core.MGraph;
 import org.apache.clerezza.rdf.core.UriRef;
 import org.apache.clerezza.rdf.utils.GraphNode;
+import org.apache.clerezza.web.fileserver.util.MediaTypeGuesser;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.wymiwyg.wrhapi.HeaderName;
 
 /**
  * This Class allows getting and putting content structured using the
@@ -58,7 +90,7 @@ import org.apache.clerezza.rdf.utils.Gra
  * Is an implementation of DiscobitsHandler and additionally registers as
  * TypeHanlder to allow HTTP GET and PUT.
  *
- * @author reto, tho
+ * @author reto, tho, agron, mir
  */
 @Component
 @Services({
@@ -76,10 +108,10 @@ public class DiscobitsTypeHandler extend
 		implements DiscobitsHandler {
 
 	@Reference
-	private ContentGraphProvider cgProvider;
+	protected ContentGraphProvider cgProvider;
 
 	@Reference
-	private HierarchyService hierarchyService;
+	protected HierarchyService hierarchyService;
 	
 	private static final Logger logger = LoggerFactory.getLogger(DiscobitsTypeHandler.class);
 
@@ -106,12 +138,20 @@ public class DiscobitsTypeHandler extend
 			if (mGraph.filter(uri, null, null).hasNext() ||
 					mGraph.filter(null, null, uri).hasNext()) {
 				return graphNode;
+			} else {
+				UriRef slashedUri = new UriRef(uri.getUnicodeString()+"/");
+				if (mGraph.filter(slashedUri, null, null).hasNext() ||
+					mGraph.filter(null, null, slashedUri).hasNext()) {
+					RedirectUtil.createSeeOtherResponse(
+							slashedUri.getUnicodeString(), uriInfo);
+				}
 			}
 		}
 		throw new WebApplicationException(RuntimeDelegate.getInstance()
 				.createResponseBuilder().status(Status.NOT_FOUND)
 				.entity("Sorry, we know nothing about this resource.").build());
 	}
+
 	
 	/**
 	 * Creates an <code>InfoDiscoBit</code> at the specified location
@@ -126,17 +166,337 @@ public class DiscobitsTypeHandler extend
 			final List<String> contentTypeHeaders = headers.getRequestHeader(HttpHeaders.CONTENT_TYPE);
 			if (contentTypeHeaders == null) {
 				logger.warn("Content-Type not specified");
-				throw new WebApplicationException(RuntimeDelegate.getInstance()
-					.createResponseBuilder().status(Status.BAD_REQUEST)
-					.entity("Content-Type not specified").build());
+				String guessedContentType = MediaTypeGuesser.getInstance().guessTypeForName(
+						uriInfo.getAbsolutePath().toString()).toString();
+				contentType = guessedContentType == null ?
+					MediaType.APPLICATION_OCTET_STREAM : guessedContentType;
+			} else {
+				contentType = contentTypeHeaders.get(0);
 			}
-			contentType = contentTypeHeaders.get(0);
+			
 		}
+	
 		final UriRef infoDiscoBitUri = new UriRef(uriInfo.getAbsolutePath().toString());
 		put(infoDiscoBitUri, MediaType.valueOf(contentType), data);
 		return Response.status(Status.CREATED).build();
 	}
 
+	/**
+	 * Creates a new collection at the specified uri
+	 *
+	 * @param uriInfo
+	 * @return
+	 * <ul>
+	 *	<li>201 "Created" response if method succeeded
+	 *	<li>405 "Method Not Allowed" response if collection already exists
+	 * </ul>
+	 */
+	@MKCOL
+	public Object mkcol(@Context UriInfo uriInfo) {
+		UriRef nodeUri = new UriRef(uriInfo.getAbsolutePath().toString());
+		if (!nodeUri.getUnicodeString().endsWith("/")) {
+			nodeUri = new UriRef(nodeUri.getUnicodeString() + "/");
+		}
+		try {
+			hierarchyService.createCollectionNode(nodeUri);
+		} catch (NodeAlreadyExistsException e) {
+			logger.debug("Collection \""
+					+ nodeUri.getUnicodeString() + "\" already exists.");
+			return Response.status(405) // Method Not Allowed
+					.entity("Collection \"" + nodeUri.getUnicodeString()
+					+ "\" already exists.").build();
+		}
+		return Response.created(uriInfo.getAbsolutePath()).build();
+	}
+
+	/**
+	 * Finds all properties of a hierarchy node and returns them in a
+	 * {@link DOMSource}
+	 *
+	 * @param uriInfo
+	 * @param headers {@link HttpHeaders}
+	 * @param body {@link DOMSource} containing the requested properties, can be null
+	 * @return
+	 * <ul>
+	 *	<li>207 "Multistatus" response if method succeeded
+	 *	<li>404 "Not Found" response if the hierarchy node was not found
+	 *	<li>400 "Bad Request" response if the body is malformed
+	 * </ul>
+	 */
+	@PROPFIND
+	@Consumes({"application/xml", "text/xml", "*/*"})
+	@Produces({"application/xml", "text/xml", "*/*"})
+	public Response propfind(@Context UriInfo uriInfo,
+			@Context HttpHeaders headers, DOMSource body) {
+		final UriRef nodeUri = new UriRef(uriInfo.getAbsolutePath().toString());
+		if (!nodeAtUriExists(nodeUri)) {
+			return checkIfCollectionExistsAndRedirectIfSo(nodeUri, uriInfo);
+		}
+			Map<UriRef, PropertyMap> result;
+			try {
+				String depthHeader = WebDavUtils.getHeaderAsString(headers, "Depth");
+				if (depthHeader == null) {
+					depthHeader = WebDavUtils.infinite;
+				}
+				HierarchyNode node = hierarchyService.getHierarchyNode(nodeUri);
+				if (body != null) {
+					Document requestDoc = WebDavUtils.sourceToDocument(body);
+					Node propfindNode = WebDavUtils.getNode(requestDoc, WebDavUtils.propfind);
+					Node requestNode = WebDavUtils.getFirstChild(propfindNode);
+					String requestType = requestNode.getLocalName();
+					if (requestType.equalsIgnoreCase(WebDavUtils.allprop)) {
+						result = getAllProps(node, depthHeader);
+					} else if (requestType.equalsIgnoreCase(WebDavUtils.prop)) {
+						result = getPropsByName(requestNode, node, depthHeader);
+					} else if (requestType.equalsIgnoreCase(WebDavUtils.propname)) {
+						result = getPropNames(node, depthHeader);
+					} else {
+						return Response.status(Status.BAD_REQUEST).build();
+					}
+				} else {
+					// returns all properties
+					result = getAllProps(node, depthHeader);
+				}
+				Document responseDoc = WebDavUtils.createResponseDoc(result);
+				return Response.status(207).entity(new DOMSource(responseDoc)).type(
+						MediaType.APPLICATION_XML_TYPE).build();
+			} catch (NodeDoesNotExistException e) {
+				return Response.status(Status.NOT_FOUND).entity(
+						e.getMessage()).build();
+			} catch (TransformerFactoryConfigurationError e) {
+				return Response.status(Status.BAD_REQUEST).build();
+			} catch (TransformerException e) {
+				return Response.status(Status.BAD_REQUEST).build();
+			} catch (ParserConfigurationException e) {
+				throw new RuntimeException(e);
+			} catch(UnknownRootExcetpion ex) {
+				return Response.status(Status.BAD_REQUEST).build();
+			}
+	}
+
+	Map<UriRef, PropertyMap> getPropNames(HierarchyNode node, String depthHeader) {
+		Map<UriRef, PropertyMap> result = new HashMap<UriRef, PropertyMap>();
+		WebDavUtils.addNodeProperties(result, null, null, node, false);
+		return result;
+	}
+
+	Map<UriRef, PropertyMap> getPropsByName(Node requestNode, HierarchyNode node,
+			String depthHeader) {
+		Map<UriRef, PropertyMap> result;
+		NodeList children = requestNode.getChildNodes();
+		result = WebDavUtils.getPropsByName(children, node, "0", true);
+		return result;
+	}
+
+	Map<UriRef, PropertyMap> getAllProps(HierarchyNode node, String depthHeader) {
+		HashMap<UriRef, PropertyMap> result = new HashMap<UriRef, PropertyMap>();
+		WebDavUtils.addNodeProperties(result, null, null, node, true);
+		return result;
+	}
+
+	/**
+	 * @param uriInfo
+	 * @param body {@link DOMSource} containing properties which should be set
+	 * or deleted
+	 * @return
+	 * <ul>
+	 *	<li>207 "Multistatus" response if method succeeded
+	 *	<li>404 "Not Found" response if the hierarchy node was not found
+	 *	<li>400 "Bad Request" response if the body is malformed
+	 * </ul>
+	 */
+	@PROPPATCH
+	@Consumes({"application/xml", "text/xml", "*/*"})
+	@Produces({"application/xml", "text/xml", "*/*"})
+	public Response proppatch(@Context UriInfo uriInfo, DOMSource body) {
+		UriRef nodeUri = new UriRef(uriInfo.getAbsolutePath().toString());
+		if (!nodeAtUriExists(nodeUri)) {
+			return checkIfCollectionExistsAndRedirectIfSo(nodeUri, uriInfo);
+		}
+		try {
+			Document requestDoc = WebDavUtils.sourceToDocument(body);
+			HierarchyNode node = hierarchyService.getHierarchyNode(nodeUri);
+			NodeList propsToSet = null;
+			NodeList propsToRemove = null;
+			Node proppatchNode = WebDavUtils.getNode(requestDoc, WebDavUtils.proppatch);
+			NodeList childNodes = proppatchNode.getChildNodes();
+			for (int i = 0; i < childNodes.getLength(); i++) {
+				Node child = childNodes.item(i);
+				String localName = child.getLocalName();
+				if (localName != null) {
+					if (localName.equals(WebDavUtils.set)) {
+						propsToSet = child.getFirstChild().getChildNodes();
+					} else if (localName.equals(WebDavUtils.remove)) {
+						propsToRemove = child.getFirstChild().getChildNodes();
+					}
+				}
+			}
+			Document responseDoc = WebDavUtils.modifyProperties(node, propsToSet, propsToRemove);
+			return Response.status(207).entity(new DOMSource(responseDoc)).type(
+					MediaType.APPLICATION_XML_TYPE).build();
+		} catch (NodeDoesNotExistException e) {
+			return Response.status(Status.NOT_FOUND).entity(
+					e.getMessage()).build();
+		}catch (ParserConfigurationException ex) {
+			throw new RuntimeException(ex);
+		} catch (TransformerFactoryConfigurationError ex) {
+			return Response.status(Status.BAD_REQUEST).build();
+		} catch (TransformerException ex) {
+			return Response.status(Status.BAD_REQUEST).build();
+		} catch(UnknownRootExcetpion ex) {
+			return Response.status(Status.BAD_REQUEST).build();
+		}
+	}
+
+	/**
+	 * Moves or renames a hierarchy node
+	 *
+	 * @param uriInfo
+	 * @param headers
+	 * @return
+	 * <ul>
+	 *  <li>201 "Created" response if method succeeded
+	 *  <li>412 "Precondition Failed" response if the destination URL is already
+	 *	mapped to a resource
+	 *  <li>404 "Not Found" response if the hierarchy node was not found
+	 *  <li>403 "Forbidden" response if the source and destination resources are the same
+	 *  <li>400 "Bad Request" if no "Destination" header was found
+	 * </ul>
+	 */
+	@MOVE
+	public Response move(@Context UriInfo uriInfo, @Context HttpHeaders headers) {
+		final UriRef nodeUri = new UriRef(uriInfo.getAbsolutePath().toString());
+		if (!nodeAtUriExists(nodeUri)) {
+			return checkIfCollectionExistsAndRedirectIfSo(nodeUri, uriInfo);
+		}
+		HierarchyNode targetNode;
+		String overwriteHeader = null;
+		CollectionNode newParentCollection = null;
+		try {
+			targetNode = hierarchyService.getHierarchyNode(nodeUri);
+			/* ignored at the moment */
+			overwriteHeader = WebDavUtils.getHeaderAsString(headers, "Overwrite");
+			if (overwriteHeader == null) {
+				overwriteHeader = "F";
+			}
+			String newCollectionString = WebDavUtils.getHeaderAsString(headers,
+					"Destination");
+			if (newCollectionString != null) {				
+				UriRef newParentUri = HierarchyUtils.extractParentCollectionUri(
+						new UriRef(newCollectionString));
+				newParentCollection = hierarchyService
+						.getCollectionNode(newParentUri);
+				targetNode.move(newParentCollection, HierarchyUtils.getName(
+						new UriRef(newCollectionString)), newParentCollection
+						.getMembers().size());
+				return Response.created(new java.net.URI(newCollectionString))
+						.build();
+			} else {
+				logger.error("empty Destination header!");
+				return Response.status(Status.BAD_REQUEST).build();
+			}
+		} catch (URISyntaxException e) {
+			return Response.status(Status.BAD_REQUEST).build();
+		} catch (NodeDoesNotExistException e) {
+			return Response.status(Status.NOT_FOUND).build();
+		} catch (NodeAlreadyExistsException e) {
+			if (overwriteHeader.equals("F")) {
+				return Response.status(Status.PRECONDITION_FAILED).build();
+			} else if (overwriteHeader.equals("T")) {
+				try {
+					String name = HierarchyUtils.getName(nodeUri);
+					hierarchyService.getHierarchyNode(
+							new UriRef(newParentCollection.getNode().
+							getUnicodeString() + name)).delete();
+					return this.move(uriInfo, headers);
+				} catch (NodeDoesNotExistException ex) {
+					throw new RuntimeException(e);
+				} catch (UnknownRootExcetpion ex) {
+					throw new RuntimeException(ex);
+				}
+			} else {
+				return Response.status(Status.BAD_REQUEST).build();
+			}
+		} catch (IllegalMoveException e) {
+			return Response.status(Status.FORBIDDEN).build();
+		} catch (UnknownRootExcetpion ex) {
+			return Response.status(Status.BAD_REQUEST).build();
+		}
+	}
+
+	/**
+	 * Deletes a hierarchy node
+	 *
+	 * @param uriInfo
+	 * @return
+	 * <ul>
+	 *	<li>200 "OK" response if method succeeded
+	 *	<li>404 "Not Found" response if the hierarchy node was not found
+	 * </ul>
+	 */
+	@DELETE
+	public Response delete(@Context UriInfo uriInfo) {
+		final UriRef nodeUri = new UriRef(uriInfo.getAbsolutePath().toString());
+		if (!nodeAtUriExists(nodeUri)) {
+			return checkIfCollectionExistsAndRedirectIfSo(nodeUri, uriInfo);
+		}
+		UriRef hierarchyNodeUri = new UriRef(uriInfo.getAbsolutePath().toString());
+		HierarchyNode hierarchyNode;
+		try {
+			hierarchyNode = hierarchyService.getHierarchyNode(hierarchyNodeUri);
+		} catch (NodeDoesNotExistException e) {
+			return Response.status(Status.NOT_FOUND).entity(
+					uriInfo.getAbsolutePath()).build();
+		} catch (UnknownRootExcetpion ex) {
+			return Response.status(Status.NOT_FOUND).entity(
+					uriInfo.getAbsolutePath()).build();
+		}
+		hierarchyNode.delete();
+		return Response.ok().build();
+	}
+
+	/**
+	 * @param uriInfo
+	 * @return
+	 * <ul>
+	 *	<li>200 "OK" response with an "Allow" and a "DAV" header. The "Allow"
+	 * header contains all the possible HTTP methods that can be executed on the
+	 * resource and the "DAV" header shows if the resource is WebDAV enabled
+	 *	<li>404 "Not Found" response if the resource was not found
+	 * </ul>
+	 */
+	@OPTIONS
+	public Response options(@Context UriInfo uriInfo) {
+		final UriRef nodeUri = new UriRef(uriInfo.getAbsolutePath().toString());
+		if (!nodeAtUriExists(nodeUri)) {
+			return checkIfCollectionExistsAndRedirectIfSo(nodeUri, uriInfo);
+		}
+			Response.ResponseBuilder builder = Response.ok();
+			builder.header(HeaderName.DAV.toString(), "1");
+			Set<String> allow = new HashSet<String>();
+			Method[] methods = this.getClass().getMethods();
+			for (Method method : methods) {
+				for (Annotation annotation : method.getAnnotations()) {
+					HttpMethod httpMethod = annotation.annotationType().getAnnotation(HttpMethod.class);
+					if (httpMethod != null) {
+						allow.add(httpMethod.value());
+					}
+				}
+			}
+			if (allow.isEmpty()) {
+				builder.header(HeaderName.ALLOW.toString(), "");
+			} else {
+				final Iterator<String> iterator = allow.iterator();
+				final StringBuffer buffer = new StringBuffer(iterator.next());
+				while (iterator.hasNext()) {
+					buffer.append(", ");
+					buffer.append(iterator.next());
+				}
+				builder.header(HeaderName.ALLOW.toString(), buffer.toString());
+			}
+			return builder.build();
+	}
+
 	protected void bindMetaDataGenerator(MetaDataGenerator generator) {
 		metaDataGenerators.add(generator);
 	}
@@ -158,5 +518,27 @@ public class DiscobitsTypeHandler extend
 	@Override
 	protected HierarchyService getHierarchyService() {
 		return hierarchyService;
+	}	
+
+	private boolean nodeAtUriExists(UriRef nodeUri) {
+		MGraph mGraph = getMGraph();
+		return mGraph.filter(nodeUri, null, null).hasNext()
+				|| mGraph.filter(null, null, nodeUri).hasNext();
+	}
+
+	private Response checkIfCollectionExistsAndRedirectIfSo(UriRef nodeUri,
+			UriInfo uriInfo) {
+		UriRef slashedUri = new UriRef(nodeUri.getUnicodeString() + "/");
+		if (collectionExists(slashedUri)) {
+			return RedirectUtil.createSeeOtherResponse(
+					slashedUri.getUnicodeString(), uriInfo);
+		}
+		return Response.status(Status.NOT_FOUND).build();
+	}
+	
+	private boolean collectionExists(UriRef slashedUri) {
+		MGraph mGraph = getMGraph();
+		return mGraph.filter(slashedUri, null, null).hasNext() ||
+				mGraph.filter(null, null, slashedUri).hasNext();
 	}
 }

Modified: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyNode.java
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyNode.java?rev=924215&r1=924214&r2=924215&view=diff
==============================================================================
--- incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyNode.java (original)
+++ incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyNode.java Wed Mar 17 10:39:23 2010
@@ -85,6 +85,7 @@ public class HierarchyNode extends Graph
 	/**
 	 * Moves this node into the specified parent collection at the specified
 	 * position pos.
+	 *
 	 * @param newParentCollection the collection into which this node should be moved
 	 * @param pos the member position of the moved node in the members list of
 	 * the new parent collection.
@@ -93,7 +94,7 @@ public class HierarchyNode extends Graph
 	 * @throws IllegalMoveException is thrown if the move operation is not allowed
 	 * @return the HierarchyNode at the new location
 	 */
-	public HierarchyNode move(CollectionNode newParentCollection, int pos) 
+	public HierarchyNode move(CollectionNode newParentCollection, int pos)
 			throws NodeAlreadyExistsException, IllegalMoveException {
 		return this.move(newParentCollection, null, pos);
 	}

Modified: incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyUtils.java
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyUtils.java?rev=924215&r1=924214&r2=924215&view=diff
==============================================================================
--- incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyUtils.java (original)
+++ incubator/clerezza/trunk/org.apache.clerezza.parent/org.apache.clerezza.platform.content/src/main/java/org/apache/clerezza/platform/content/hierarchy/HierarchyUtils.java Wed Mar 17 10:39:23 2010
@@ -25,14 +25,14 @@ import org.apache.clerezza.rdf.core.UriR
  *
  * @author mir
  */
-class HierarchyUtils {
+public class HierarchyUtils {
 
 	/**
 	 * Extracts the URI of the parent collection from the specified URI.
 	 * @param nodeUri
 	 * @return URI of the parent collection of the specified URI
 	 */
-	static UriRef extractParentCollectionUri(UriRef nodeUri) {
+	public static UriRef extractParentCollectionUri(UriRef nodeUri) {
 		String uri = nodeUri.getUnicodeString();
 		if (uri.endsWith("/")) {
 			uri = uri.substring(0, uri.length() - 1);
@@ -52,8 +52,7 @@ class HierarchyUtils {
 			throw new IllegalArgumentException(uri + " does not end with a slash");
 		}
 	}
-
-	static String getName(UriRef uri) {
+	public static String getName(UriRef uri) {
 		String uriString = uri.getUnicodeString();
 		if (uriString.endsWith("/")) {
 			uriString = uriString.substring(0, uriString.length() - 1);