[Yanel-commits] rev 22297 - in public/yanel/trunk/src: core/java/org/wyona/yanel/core/api/attributes core/java/org/wyona/yanel/servlet resources/file/src/java/org/wyona/yanel/impl/resources resources/xml/src/java/org/wyona/yanel/impl/resources

josias at wyona.com josias at wyona.com
Wed Jan 31 09:24:43 CET 2007


Author: josias
Date: 2007-01-31 09:24:38 +0100 (Wed, 31 Jan 2007)
New Revision: 22297

Modified:
   public/yanel/trunk/src/core/java/org/wyona/yanel/core/api/attributes/VersionableV2.java
   public/yanel/trunk/src/core/java/org/wyona/yanel/servlet/YanelServlet.java
   public/yanel/trunk/src/resources/file/src/java/org/wyona/yanel/impl/resources/NodeResource.java
   public/yanel/trunk/src/resources/xml/src/java/org/wyona/yanel/impl/resources/XMLResource.java
Log:
improved versioning: handle checkin/checkout in yanelservlet to avoid code duplication and to have better protection against un-allowed save requests

Modified: public/yanel/trunk/src/core/java/org/wyona/yanel/core/api/attributes/VersionableV2.java
===================================================================
--- public/yanel/trunk/src/core/java/org/wyona/yanel/core/api/attributes/VersionableV2.java	2007-01-30 20:59:48 UTC (rev 22296)
+++ public/yanel/trunk/src/core/java/org/wyona/yanel/core/api/attributes/VersionableV2.java	2007-01-31 08:24:38 UTC (rev 22297)
@@ -16,6 +16,8 @@
 
 package org.wyona.yanel.core.api.attributes;
 
+import java.util.Date;
+
 import org.wyona.yanel.core.attributes.viewable.View;
 
 /**
@@ -28,7 +30,7 @@
      * @return
      * @throws Exception
      */
-    public String[] getRevisions() throws Exception;
+    public String[] getRevisionNames() throws Exception;
     
     /**
      * Gets the view of a certain revision.
@@ -47,25 +49,44 @@
     public void restore(String revisionName) throws Exception;
     
     /**
-     * Checks out this resource. Noone else will be able to check it out afterwards.
+     * Puts this resource into checked-out state. Noone else will be able to check it out afterwards.
      * @param userID
      * @throws Exception
      */
     public void checkout(String userID) throws Exception;
     
     /**
-     * Checks in this resource, and creates a new revision.
+     * Puts this resource into checked-in state, and creates a new revision.
      * @throws Exception
      */
     public void checkin() throws Exception;
     
     
+    /**
+     * Indicates whether this resource is checked out.
+     * @return
+     * @throws Exception
+     */
+    public boolean isCheckedOut() throws Exception;
+    
+    /**
+     * Returns the user id which was supplied when calling checkout()
+     * @return
+     * @throws Exception
+     */
+    public String getCheckoutUserID() throws Exception;
+    
+    /**
+     * Returns the date when this resource was checked out.
+     * @return
+     * @throws Exception
+     */
+    public Date getCheckoutDate() throws Exception;
+    
     /*
      * Methods which could be added to this interface:
      * 
      *
-     * public boolean isCheckedOut() throws Exception;
-     * public String getCheckoutUserID() throws Exception;
      * getDiff(String rev1, String rev2) throws Exception;
      * getHeadRevisionNumber() ?
      * 

Modified: public/yanel/trunk/src/core/java/org/wyona/yanel/servlet/YanelServlet.java
===================================================================
--- public/yanel/trunk/src/core/java/org/wyona/yanel/servlet/YanelServlet.java	2007-01-30 20:59:48 UTC (rev 22296)
+++ public/yanel/trunk/src/core/java/org/wyona/yanel/servlet/YanelServlet.java	2007-01-31 08:24:38 UTC (rev 22297)
@@ -335,7 +335,7 @@
                     if (ResourceAttributeHelper.hasAttributeImplemented(res, "Versionable", "2")) {
                         // retrieve the revisions, but only in the meta usecase (for performance reasons):
                         if (request.getParameter("yanel.resource.meta") != null) {
-                            String[] revisions = ((VersionableV2)res).getRevisions();
+                            String[] revisions = ((VersionableV2)res).getRevisionNames();
                             Element revisionsElement = (Element) resourceElement.appendChild(doc.createElement("revisions"));
                             if (revisions != null) {
                                 for (int i=0; i<revisions.length; i++) {
@@ -353,11 +353,23 @@
                     
                     if (usecase != null && usecase.equals("checkout")) {
                         log.debug("Checkout data ...");
+                        
                         if (ResourceAttributeHelper.hasAttributeImplemented(res, "Versionable", "2")) {
                             // note: this will throw an exception if the document is checked out already
                             // by another user.
                             Identity identity = (Identity) request.getSession().getAttribute("identity");
-                            ((VersionableV2)res).checkout(identity.getUsername());
+                            String userID = identity.getUsername();
+                            VersionableV2 versionable = (VersionableV2)res;
+                            if (versionable.isCheckedOut()) {
+                                String checkoutUserID = versionable.getCheckoutUserID(); 
+                                if (checkoutUserID.equals(userID)) {
+                                    log.warn("Resource " + res.getPath() + " is already checked out by this user: " + checkoutUserID);
+                                } else {
+                                    throw new Exception("Resource is already checked out by another user: " + checkoutUserID);
+                                }
+                            } else {
+                                versionable.checkout(userID);
+                            }
                         }
                         
                         log.warn("Acquire lock has not been implemented yet ...!");
@@ -460,22 +472,12 @@
 
         if (value != null && value.equals("save")) {
             log.debug("Save data ...");
-            save(request, response);
+            save(request, response, false);
             return;
         } else if (value != null && value.equals("checkin")) {
             log.debug("Checkin data ...");
-            save(request, response);
+            save(request, response, true);
 
-            Resource resource = getResource(request, response);
-            if (ResourceAttributeHelper.hasAttributeImplemented(resource, "Versionable", "2")) {
-                try {
-                    ((VersionableV2)resource).checkin();
-                } catch (Exception e) {
-                    log.error(e.getMessage(), e);
-                    throw new ServletException(e.getMessage(), e);
-                }
-            }
-
             log.warn("Release lock has not been implemented yet ...");
             // releaseLock();
             return;
@@ -528,22 +530,12 @@
 
         if (value != null && value.equals("save")) {
             log.debug("Save data ...");
-            save(request, response);
+            save(request, response, false);
             return;
         } else if (value != null && value.equals("checkin")) {
             log.debug("Checkin data ...");
-            save(request, response);
+            save(request, response, true);
             
-            Resource resource = getResource(request, response);
-            if (ResourceAttributeHelper.hasAttributeImplemented(resource, "Versionable", "2")) {
-                try {
-                    ((VersionableV2)resource).checkin();
-                } catch (Exception e) {
-                    log.error(e.getMessage(), e);
-                    throw new ServletException(e.getMessage(), e);
-                }
-            }
-            
             log.warn("Release lock has not been implemented yet ...!");
             // releaseLock();
             return;
@@ -587,7 +579,7 @@
             } else {
                 Resource resource = getResource(request, response);
                 log.error("DEBUG: Client (" + request.getHeader("User-Agent") + ") requests to save a resource: " + resource.getRealm() + ", " + resource.getPath());
-                save(request, response);
+                save(request, response, false);
                 return;
             }
         }
@@ -641,9 +633,31 @@
     /**
      * Save data
      */
-    private void save(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+    private void save(HttpServletRequest request, HttpServletResponse response, boolean doCheckin) throws ServletException, IOException {
         log.debug("Save data ...");
 
+        Resource resource = getResource(request, response);
+        if (ResourceAttributeHelper.hasAttributeImplemented(resource, "Versionable", "2")) {
+            try {
+                // check the resource state:
+                Identity identity = (Identity) request.getSession().getAttribute("identity");
+                String userID = identity.getUsername(); 
+                VersionableV2 versionable  = (VersionableV2)resource;
+                if (versionable.isCheckedOut()) {
+                    String checkoutUserID = versionable.getCheckoutUserID(); 
+                    if (!checkoutUserID.equals(userID)) {
+                        throw new Exception("Resource is checked out by another user: " + checkoutUserID);
+                    }
+                } else {
+                    throw new Exception("Resource is not checked out.");
+                }
+
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                throw new ServletException(e.getMessage(), e);
+            }
+        }
+
         InputStream in = request.getInputStream();
         java.io.ByteArrayOutputStream baos  = new java.io.ByteArrayOutputStream();
         byte[] buf = new byte[8192];
@@ -723,7 +737,6 @@
         if (ResourceAttributeHelper.hasAttributeImplemented(res, "Modifiable", "1")) {
             out = ((ModifiableV1) res).getOutputStream(new Path(request.getServletPath()));
             write(memIn, out, request, response);
-            return;
         } else if (ResourceAttributeHelper.hasAttributeImplemented(res, "Modifiable", "2")) {
             try {
                 out = ((ModifiableV2) res).getOutputStream();
@@ -732,7 +745,6 @@
                 } else {
                     ((ModifiableV2) res).write(memIn);
                 }
-                return;
             } catch (Exception e) {
                 log.error(e.getMessage(), e);
                 throw new ServletException(e.getMessage(), e);
@@ -752,8 +764,20 @@
             response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
             PrintWriter w = response.getWriter();
             w.print(sb);
-            return;
         }
+        
+        if (doCheckin) {
+            if (ResourceAttributeHelper.hasAttributeImplemented(resource, "Versionable", "2")) {
+                VersionableV2 versionable  = (VersionableV2)resource;
+                try {
+                    versionable.checkin();
+                } catch (Exception e) {
+                    log.error(e.getMessage(), e);
+                    throw new ServletException("Could not check in resource: " + resource.getPath() 
+                            + " " + e.getMessage(), e);
+                }
+            }
+        }
     }
 
     /**

Modified: public/yanel/trunk/src/resources/file/src/java/org/wyona/yanel/impl/resources/NodeResource.java
===================================================================
--- public/yanel/trunk/src/resources/file/src/java/org/wyona/yanel/impl/resources/NodeResource.java	2007-01-30 20:59:48 UTC (rev 22296)
+++ public/yanel/trunk/src/resources/file/src/java/org/wyona/yanel/impl/resources/NodeResource.java	2007-01-31 08:24:38 UTC (rev 22297)
@@ -41,6 +41,7 @@
 import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Writer;
+import java.util.Date;
 
 import org.apache.log4j.Category;
 
@@ -212,7 +213,7 @@
     /**
      *
      */
-    public String[] getRevisions() throws Exception {
+    public String[] getRevisionNames() throws Exception {
         Revision[] revisions = getRealm().getRepository().getNode(getPath()).getRevisions();
         String[] revisionNames = new String[revisions.length];
         
@@ -223,11 +224,26 @@
     }
     
     public void checkin() throws Exception {
-        getRealm().getRepository().getNode(getPath()).checkin();
+        Node node = getRealm().getRepository().getNode(getPath());
+        node.checkin();
+        /*
+        if (node.isCheckedOut()) {
+            String checkoutUserID = node.getCheckoutUserID(); 
+            if (checkoutUserID.equals(userID)) {
+                node.checkin();
+            } else {
+                throw new Exception("Resource is checked out by another user: " + checkoutUserID);
+            }
+        } else {
+            throw new Exception("Resource is not checked out.");
+        }
+        */
     }
 
     public void checkout(String userID) throws Exception {
-        Node node = getRealm().getRepository().getNode(getPath()); 
+        Node node = getRealm().getRepository().getNode(getPath());
+        node.checkout(userID);
+        /*
         if (node.isCheckedOut()) {
             String checkoutUserID = node.getCheckoutUserID(); 
             if (checkoutUserID.equals(userID)) {
@@ -238,12 +254,29 @@
         } else {
             node.checkout(userID);
         }
+        */
     }
 
     public void restore(String revisionName) throws Exception {
         getRealm().getRepository().getNode(getPath()).restore(revisionName);
     }
 
+    public Date getCheckoutDate() throws Exception {
+        Node node = getRealm().getRepository().getNode(getPath());
+        // return node.getCheckoutDate();
+        return null;
+    }
+
+    public String getCheckoutUserID() throws Exception {
+        Node node = getRealm().getRepository().getNode(getPath());
+        return node.getCheckoutUserID();
+    }
+
+    public boolean isCheckedOut() throws Exception {
+        Node node = getRealm().getRepository().getNode(getPath());
+        return node.isCheckedOut();
+    }
+
     public boolean exists() throws Exception {
         log.warn("Not implemented yet!");
         return true; 

Modified: public/yanel/trunk/src/resources/xml/src/java/org/wyona/yanel/impl/resources/XMLResource.java
===================================================================
--- public/yanel/trunk/src/resources/xml/src/java/org/wyona/yanel/impl/resources/XMLResource.java	2007-01-30 20:59:48 UTC (rev 22296)
+++ public/yanel/trunk/src/resources/xml/src/java/org/wyona/yanel/impl/resources/XMLResource.java	2007-01-31 08:24:38 UTC (rev 22297)
@@ -57,6 +57,7 @@
 import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Writer;
+import java.util.Date;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 
@@ -310,7 +311,7 @@
         return true;
     }
 
-    public String[] getRevisions() throws Exception {
+    public String[] getRevisionNames() throws Exception {
         Revision[] revisions = getRealm().getRepository().getNode(getPath()).getRevisions();
         String[] revisionNames = new String[revisions.length];
         
@@ -321,11 +322,26 @@
     }
     
     public void checkin() throws Exception {
-        getRealm().getRepository().getNode(getPath()).checkin();
+        Node node = getRealm().getRepository().getNode(getPath());
+        node.checkin();
+        /*
+        if (node.isCheckedOut()) {
+            String checkoutUserID = node.getCheckoutUserID(); 
+            if (checkoutUserID.equals(userID)) {
+                node.checkin();
+            } else {
+                throw new Exception("Resource is checked out by another user: " + checkoutUserID);
+            }
+        } else {
+            throw new Exception("Resource is not checked out.");
+        }
+        */
     }
 
     public void checkout(String userID) throws Exception {
-        Node node = getRealm().getRepository().getNode(getPath()); 
+        Node node = getRealm().getRepository().getNode(getPath());
+        node.checkout(userID);
+        /*
         if (node.isCheckedOut()) {
             String checkoutUserID = node.getCheckoutUserID(); 
             if (checkoutUserID.equals(userID)) {
@@ -336,13 +352,30 @@
         } else {
             node.checkout(userID);
         }
+        */
     }
 
     public void restore(String revisionName) throws Exception {
         getRealm().getRepository().getNode(getPath()).restore(revisionName);
     }
 
+    public Date getCheckoutDate() throws Exception {
+        Node node = getRealm().getRepository().getNode(getPath());
+        // return node.getCheckoutDate();
+        return null;
+    }
 
+    public String getCheckoutUserID() throws Exception {
+        Node node = getRealm().getRepository().getNode(getPath());
+        return node.getCheckoutUserID();
+    }
+
+    public boolean isCheckedOut() throws Exception {
+        Node node = getRealm().getRepository().getNode(getPath());
+        return node.isCheckedOut();
+    }
+
+
     public boolean exists() throws Exception {
         log.warn("Not implemented yet!");
         return true; 




More information about the Yanel-commits mailing list