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);


Reply via email to