You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by an...@apache.org on 2006/11/13 18:44:17 UTC

svn commit: r474413 [1/3] - in /lenya/trunk/src: impl/java/org/apache/lenya/cms/publication/ impl/test/org/apache/lenya/cms/rc/ java/org/apache/lenya/cms/cocoon/acting/ java/org/apache/lenya/cms/cocoon/components/modules/input/ java/org/apache/lenya/cm...

Author: andreas
Date: Mon Nov 13 09:44:15 2006
New Revision: 474413

URL: http://svn.apache.org/viewvc?view=rev&rev=474413
Log:
Refactored revision control to use sources instead of files, added support for revisions to Document- and LenyaSourceFactory

Added:
    lenya/trunk/src/java/org/apache/lenya/cms/repository/ContentHolder.java
    lenya/trunk/src/java/org/apache/lenya/cms/repository/History.java
    lenya/trunk/src/java/org/apache/lenya/cms/repository/Revision.java
    lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/LinkTarget.java
    lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeHistory.java
    lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeMetaDataHandler.java
    lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java
    lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRevision.java
Modified:
    lenya/trunk/src/impl/java/org/apache/lenya/cms/publication/DocumentImpl.java
    lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RCMLTest.java
    lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RevisionControllerTest.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/DiscoverCheckoutAction.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckinAction.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutAction.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutTestAction.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/RevisionControllerAction.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/DocumentInfoModule.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/PageEnvelopeModule.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/flow/FlowHelperImpl.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/generation/LenyaMetaDataGenerator.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/RepositorySource.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/SourceUtil.java
    lenya/trunk/src/java/org/apache/lenya/cms/publication/Document.java
    lenya/trunk/src/java/org/apache/lenya/cms/publication/PublicationException.java
    lenya/trunk/src/java/org/apache/lenya/cms/rc/RCML.java
    lenya/trunk/src/java/org/apache/lenya/cms/rc/RevisionController.java
    lenya/trunk/src/java/org/apache/lenya/cms/repository/Node.java
    lenya/trunk/src/java/org/apache/lenya/cms/repository/RepositoryItem.java
    lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/source/DocumentSourceFactory.java
    lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/LinkRewritingTransformer.java
    lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/LinkResolver.java
    lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/LinkResolverImpl.java
    lenya/trunk/src/modules-core/sitemanagement/java/src/org/apache/lenya/cms/site/usecases/Overview.java
    lenya/trunk/src/modules-core/sitemanagement/java/src/org/apache/lenya/cms/site/usecases/Revisions.java
    lenya/trunk/src/modules-core/sitemanagement/java/src/org/apache/lenya/cms/site/usecases/Rollback.java
    lenya/trunk/src/modules-core/sitemanagement/java/src/org/apache/lenya/cms/site/usecases/SiteOverview.java
    lenya/trunk/src/modules-core/sitemanagement/usecases/tab/revisions.jx
    lenya/trunk/src/modules/repository/java/src/org/apache/lenya/cms/repo/adapter/RepoNode.java
    lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java
    lenya/trunk/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeMetaData.java
    lenya/trunk/src/modules/webdav/java/src/org/apache/lenya/cms/usecases/webdav/FilePropfind.java
    lenya/trunk/src/modules/webdav/java/src/org/apache/lenya/cms/usecases/webdav/Propfind.java
    lenya/trunk/src/modules/xhtml/sitemap.xmap
    lenya/trunk/src/pubs/blog/java/src/org/apache/cocoon/generation/BlogGenerator.java
    lenya/trunk/src/pubs/blog/java/src/org/apache/cocoon/generation/BlogOverviewGenerator.java

Modified: lenya/trunk/src/impl/java/org/apache/lenya/cms/publication/DocumentImpl.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/impl/java/org/apache/lenya/cms/publication/DocumentImpl.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/impl/java/org/apache/lenya/cms/publication/DocumentImpl.java (original)
+++ lenya/trunk/src/impl/java/org/apache/lenya/cms/publication/DocumentImpl.java Mon Nov 13 09:44:15 2006
@@ -19,6 +19,7 @@
 package org.apache.lenya.cms.publication;
 
 import java.io.File;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -173,8 +174,12 @@
     /**
      * @see org.apache.lenya.cms.publication.Document#getLastModified()
      */
-    public Date getLastModified() {
-        return new Date(getFile().lastModified());
+    public long getLastModified() throws DocumentException {
+        try {
+            return getRepositoryNode().getLastModified();
+        } catch (RepositoryException e) {
+            throw new DocumentException(e);
+        }
     }
 
     public File getFile() {
@@ -591,5 +596,9 @@
             this.area = new AreaImpl(this.manager, getFactory(), getPublication(), getArea());
         }
         return this.area;
+    }
+
+    public InputStream getInputStream() throws RepositoryException {
+        return getRepositoryNode().getInputStream();
     }
 }

Modified: lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RCMLTest.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RCMLTest.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RCMLTest.java (original)
+++ lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RCMLTest.java Mon Nov 13 09:44:15 2006
@@ -23,15 +23,14 @@
 import java.io.PrintWriter;
 import java.util.Date;
 
-import junit.framework.TestCase;
-
 import org.w3c.dom.Document;
+import org.apache.lenya.ac.impl.AbstractAccessControlTest;
 import org.apache.lenya.xml.DocumentHelper;
 
 /**
  * RCML Test
  */
-public class RCMLTest extends TestCase {
+public class RCMLTest extends AbstractAccessControlTest {
 
 	/**
 	 * <code>co</code> Checkout
@@ -66,7 +65,8 @@
 		}
 
 		try {
-			RCML rcml = new RCML(args[0], args[1], args[2]);
+            org.apache.lenya.cms.publication.Document doc = null;
+			RCML rcml = doc.getRepositoryNode().getRcml();
 			rcml.checkOutIn(RCML.co, "michi", new Date().getTime(), false);
 
 			(new PrintWriter(System.out)).print(this.document);

Modified: lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RevisionControllerTest.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RevisionControllerTest.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RevisionControllerTest.java (original)
+++ lenya/trunk/src/impl/test/org/apache/lenya/cms/rc/RevisionControllerTest.java Mon Nov 13 09:44:15 2006
@@ -23,21 +23,15 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 
-import junit.framework.TestCase;
+import org.apache.lenya.ac.impl.AbstractAccessControlTest;
+import org.apache.lenya.cms.publication.Document;
 
 /**
  * Revision Controller test
  */
-public class RevisionControllerTest extends TestCase {
-    /**
-     * Constructor.
-     * @param test The test to execute.
-     */
-    public RevisionControllerTest(String test) {
-        super(test);
-    }
+public class RevisionControllerTest extends AbstractAccessControlTest {
 
-    public static void testRevisionController() {
+    public void testRevisionController() {
         
         String[] args = { "", "", "", "" };
         
@@ -52,13 +46,16 @@
             return;
         }
 
+        Document doc1 = null;
+        Document doc2 = null;
+        
         String identityS = args[0];
         String source = args[1];
         String identityD = args[2];
         String destination = args[3];
-        RevisionController rc = new RevisionController(null, null, null);
+        RevisionController rc = new RevisionController();
         try {
-            rc.reservedCheckOut(source, identityS);
+            rc.reservedCheckOut(doc1.getRepositoryNode(), identityS);
         } catch (FileNotFoundException e) // No such source file
             {
             System.out.println(e.toString());
@@ -78,7 +75,7 @@
         }
 
         try {
-            rc.reservedCheckIn(destination, identityD, true, true);
+            rc.reservedCheckIn(doc2.getRepositoryNode(), identityD, true, true);
         } catch (FileReservedCheckInException e) {
             System.out.println(e.toString());
         } catch (Exception e) {

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/DiscoverCheckoutAction.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/DiscoverCheckoutAction.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/DiscoverCheckoutAction.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/DiscoverCheckoutAction.java Mon Nov 13 09:44:15 2006
@@ -42,10 +42,10 @@
         super.act(redirector, resolver, objectModel, src, parameters);
 
         HashMap actionMap = new HashMap();
-        final RCMLEntry entry =getRc().getRCML(getFilename()).getLatestEntry();
+        final RCMLEntry entry = getNode().getRcml().getLatestEntry();
 
         if ((entry != null) && (entry.getType() == RCML.co) ) {
-            actionMap.put("filename", getFilename());
+            actionMap.put("filename", getNode().getSourceURI());
             actionMap.put("user", entry.getIdentity());
             return actionMap;
         }

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckinAction.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckinAction.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckinAction.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckinAction.java Mon Nov 13 09:44:15 2006
@@ -51,10 +51,10 @@
         getLogger().debug("Backup: " + backup);
 
         try {
-            getRc().reservedCheckIn(getFilename(), getUsername(), backup, true);
+            getRc().reservedCheckIn(getNode(), getUsername(), backup, true);
         } catch (FileReservedCheckInException e) {
             actionMap.put("exception", "fileReservedCheckInException");
-            actionMap.put("filename", getFilename());
+            actionMap.put("filename", getNode().getSourceURI());
             actionMap.put("checkType", e.getTypeString());
             actionMap.put("user", e.getUsername());
             actionMap.put("date", e.getDate());
@@ -63,9 +63,9 @@
             return actionMap;
         } catch (Exception e) {
             actionMap.put("exception", "genericException");
-            actionMap.put("filename", getFilename());
+            actionMap.put("filename", getNode().getSourceURI());
             actionMap.put("message", e.getMessage());
-            getLogger().warn("The document " + getFilename() + " couldn't be checked in");
+            getLogger().warn("The document " + getNode().getSourceURI() + " couldn't be checked in");
 
             return actionMap;
         }

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutAction.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutAction.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutAction.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutAction.java Mon Nov 13 09:44:15 2006
@@ -44,10 +44,10 @@
 
         //check out
         try {
-            getLogger().debug(".act(): Filename: " + getFilename());
+            getLogger().debug(".act(): Node: " + getNode().getSourceURI());
             getLogger().debug(".act(): Username: " + getUsername());
 
-            if (getFilename() == null) {
+            if (getNode() == null) {
                 throw new Exception("Filename is null");
             }
 
@@ -55,22 +55,22 @@
                 throw new Exception("Username is null");
             }
 
-            getRc().reservedCheckOut(getFilename(), getUsername());
+            getRc().reservedCheckOut(getNode(), getUsername());
         } catch (FileReservedCheckOutException e) {
             actionMap.put("exception", "fileReservedCheckOutException");
-            actionMap.put("filename", getFilename());
+            actionMap.put("filename", getNode().getSourceURI());
             actionMap.put("user", e.getCheckOutUsername());
             actionMap.put("date", e.getCheckOutDate());
             getLogger().warn(
-                    "Document " + getFilename() + " already checked-out by "
+                    "Node " + getNode().getSourceURI() + " already checked-out by "
                             + e.getCheckOutUsername() + " since " + e.getCheckOutDate());
 
             return actionMap;
         } catch (Exception e) {
             actionMap.put("exception", "genericException");
-            actionMap.put("filename", getFilename());
+            actionMap.put("filename", getNode().getSourceURI());
             actionMap.put("message", "" + e.getMessage());
-            getLogger().error("The document " + getFilename() + " couldn't be checked out: ", e);
+            getLogger().error("The node " + getNode().getSourceURI() + " couldn't be checked out: ", e);
 
             return actionMap;
         }

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutTestAction.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutTestAction.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutTestAction.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/ReservedCheckoutTestAction.java Mon Nov 13 09:44:15 2006
@@ -48,25 +48,25 @@
         HashMap actionMap = new HashMap();
 
         try {
-            RCMLEntry entry =getRc().getRCML(getFilename()).getLatestEntry();
+            RCMLEntry entry = getNode().getRcml().getLatestEntry();
 
 			if ((entry == null) || (entry.getType() != RCML.co) || !entry.getIdentity().equals(getUsername())) {
 				//check out
-	            getRc().reservedCheckOut(getFilename(),getUsername());   
+	            getRc().reservedCheckOut(getNode(), getUsername());   
 			}
 		} catch (FileReservedCheckOutException e) {
 			actionMap.put("exception", "fileReservedCheckOutException");
-			actionMap.put("filename", getFilename());
+			actionMap.put("filename", getNode().getSourceURI());
 			actionMap.put("user", e.getCheckOutUsername());
 			actionMap.put("date", e.getCheckOutDate());
-			getLogger().warn("Document " + getFilename() + " already checked-out by " + e.getCheckOutUsername() + " since " + e.getCheckOutDate());
+			getLogger().warn("Node " + getNode().getSourceURI() + " already checked-out by " + e.getCheckOutUsername() + " since " + e.getCheckOutDate());
 
 			return actionMap;
 		} catch (Exception e) {
 			actionMap.put("exception", "genericException");
-			actionMap.put("filename", getFilename());
+			actionMap.put("filename", getNode().getSourceURI());
 			actionMap.put("message", e.getMessage());
-			getLogger().error(".act(): The document " + getFilename() + " couldn't be checked out: ", e);
+			getLogger().error(".act(): The node " + getNode().getSourceURI() + " couldn't be checked out: ", e);
 
 			return actionMap;
 		}

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/RevisionControllerAction.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/RevisionControllerAction.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/RevisionControllerAction.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/acting/RevisionControllerAction.java Mon Nov 13 09:44:15 2006
@@ -40,6 +40,7 @@
 import org.apache.lenya.cms.publication.PublicationUtil;
 import org.apache.lenya.cms.rc.RCEnvironment;
 import org.apache.lenya.cms.rc.RevisionController;
+import org.apache.lenya.cms.repository.Node;
 import org.apache.lenya.cms.repository.RepositoryUtil;
 
 /**
@@ -53,7 +54,7 @@
     private String backupDirectory = null;
     private RevisionController rc = null;
     private String username = null;
-    private String filename = null;
+    private Node node = null;
 
     /**
      * @see org.apache.cocoon.acting.Action#act(org.apache.cocoon.environment.Redirector,
@@ -117,8 +118,7 @@
         this.backupDirectory = publicationPath + File.separator + this.backupDirectory;
 
         // Initialize Revision Controller
-        this.rc = new RevisionController(this.rcmlDirectory, this.backupDirectory, publicationPath);
-        getLogger().debug("revision controller" + this.rc);
+        this.rc = new RevisionController();
 
         // /Initialize Revision Controller
         // Get session
@@ -159,15 +159,12 @@
             }
 
             Document srcDoc = map.get(publication, document.getArea(), documentid, language);
-            File newFile = srcDoc.getFile();
-            this.filename = newFile.getCanonicalPath();
+            this.node = srcDoc.getRepositoryNode();
 
         } else {
-            this.filename = document.getFile().getCanonicalPath();
+            this.node = document.getRepositoryNode();
         }
 
-        this.filename = this.filename.substring(publicationPath.length());
-
         this.username = null;
 
         if (identity != null) {
@@ -185,11 +182,11 @@
     }
 
     /**
-     * Get the filename.
-     * @return the filename
+     * Get the node.
+     * @return the node
      */
-    protected String getFilename() {
-        return this.filename;
+    protected Node getNode() {
+        return this.node;
     }
 
     /**

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/DocumentInfoModule.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/DocumentInfoModule.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/DocumentInfoModule.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/DocumentInfoModule.java Mon Nov 13 09:44:15 2006
@@ -141,7 +141,7 @@
             if (attribute.equals(RESOURCE_TYPE)) {
                 value = document.getResourceType().getName();
             } else if (attribute.equals(LAST_MODIFIED)) {
-                value = this.dateFormat.format(document.getLastModified());
+                value = this.dateFormat.format(new Date(document.getLastModified()));
             } else if (attribute.equals(MIME_TYPE)) {
                 value = document.getMimeType();
             } else if (attribute.equals(CONTENT_LENGTH)) {

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/PageEnvelopeModule.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/PageEnvelopeModule.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/PageEnvelopeModule.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/components/modules/input/PageEnvelopeModule.java Mon Nov 13 09:44:15 2006
@@ -120,7 +120,7 @@
                 } else if (name.equals(PageEnvelope.DOCUMENT_LANGUAGES_CSV)) {
                     value = StringUtils.join(document.getLanguages(), ',');
                 } else if (name.equals(PageEnvelope.DOCUMENT_LASTMODIFIED)) {
-                    Date date = document.getLastModified();
+                    Date date = new Date(document.getLastModified());
                     value = new SimpleDateFormat(DATE_FORMAT).format(date);
                 } else if (name.equals(PageEnvelope.DOCUMENT_TYPE)) {
                     ResourceType resourceType = document.getResourceType();

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/flow/FlowHelperImpl.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/flow/FlowHelperImpl.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/flow/FlowHelperImpl.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/flow/FlowHelperImpl.java Mon Nov 13 09:44:15 2006
@@ -20,7 +20,6 @@
 
 package org.apache.lenya.cms.cocoon.flow;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.Enumeration;
 import java.util.Map;
@@ -44,8 +43,8 @@
 import org.apache.lenya.cms.publication.PublicationUtil;
 import org.apache.lenya.cms.publication.util.DocumentHelper;
 import org.apache.lenya.cms.rc.FileReservedCheckInException;
-import org.apache.lenya.cms.rc.RCEnvironment;
 import org.apache.lenya.cms.rc.RevisionController;
+import org.apache.lenya.cms.repository.Node;
 import org.apache.lenya.cms.repository.RepositoryUtil;
 import org.apache.lenya.cms.repository.Session;
 import org.apache.lenya.cms.workflow.WorkflowUtil;
@@ -162,16 +161,7 @@
      */
     public RevisionController getRevisionController(FOM_Cocoon cocoon)
             throws PageEnvelopeException, IOException {
-        final Publication publication = getPageEnvelope(cocoon).getPublication();
-        final String publicationPath = publication.getDirectory().getCanonicalPath();
-        final RCEnvironment rcEnvironment = RCEnvironment.getInstance(publication.getServletContext()
-                .getCanonicalPath());
-        String rcmlDirectory = rcEnvironment.getRCMLDirectory();
-        rcmlDirectory = publicationPath + File.separator + rcmlDirectory;
-        String backupDirectory = rcEnvironment.getBackupDirectory();
-        backupDirectory = publicationPath + File.separator + backupDirectory;
-
-        return new RevisionController(rcmlDirectory, backupDirectory, publicationPath);
+        return new RevisionController();
     }
 
     /**
@@ -184,12 +174,8 @@
                 .getSession()
                 .getAttribute(Identity.class.getName());
         final PageEnvelope pageEnvelope = getPageEnvelope(cocoon);
-        final Publication publication = getPageEnvelope(cocoon).getPublication();
-        final String filename = pageEnvelope.getDocument()
-                .getFile()
-                .getCanonicalPath()
-                .substring(publication.getDirectory().getCanonicalPath().length());
-        getRevisionController(cocoon).reservedCheckIn(filename,
+        Node node = pageEnvelope.getDocument().getRepositoryNode();
+        getRevisionController(cocoon).reservedCheckIn(node,
                 identity.getUser().getId(),
                 backup,
                 true);

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/generation/LenyaMetaDataGenerator.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/generation/LenyaMetaDataGenerator.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/generation/LenyaMetaDataGenerator.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/generation/LenyaMetaDataGenerator.java Mon Nov 13 09:44:15 2006
@@ -212,7 +212,7 @@
     public SourceValidity getValidity() {
         long lastModified;
         try {
-            lastModified = document.getLastModified().getTime();
+            lastModified = document.getLastModified();
         } catch (Exception e) {
             getLogger().error("Error determining last modification date", e);
             return null;

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/RepositorySource.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/RepositorySource.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/RepositorySource.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/RepositorySource.java Mon Nov 13 09:44:15 2006
@@ -38,11 +38,13 @@
 import org.apache.excalibur.source.SourceException;
 import org.apache.excalibur.source.SourceNotFoundException;
 import org.apache.excalibur.source.impl.AbstractSource;
+import org.apache.lenya.cms.repository.ContentHolder;
 import org.apache.lenya.cms.repository.Node;
 import org.apache.lenya.cms.repository.NodeFactory;
 import org.apache.lenya.cms.repository.RepositoryException;
 import org.apache.lenya.cms.repository.RepositoryManager;
 import org.apache.lenya.cms.repository.Session;
+import org.apache.lenya.util.Query;
 
 /**
  * Repository source.
@@ -52,7 +54,7 @@
 public class RepositorySource extends AbstractSource implements ModifiableTraversableSource {
 
     private ServiceManager manager;
-    private Node node;
+    private ContentHolder content;
     private Session session;
     private Logger logger;
     protected static final String SCHEME = "lenya";
@@ -101,7 +103,31 @@
         try {
             factory = (NodeFactory) this.manager.lookup(NodeFactory.ROLE);
             factory.setSession(session);
-            this.node = (Node) session.getRepositoryItem(factory, uri);
+            
+            String sourceUri;
+            int revisionNumber = -1;
+            
+            int questionMarkIndex = uri.indexOf("?");
+            if (questionMarkIndex > -1) {
+                sourceUri = uri.substring(0, questionMarkIndex);
+                Query query = new Query(uri.substring(questionMarkIndex + 1));
+                String revisionString = query.getValue("rev", null);
+                if (revisionString != null) {
+                    revisionNumber = Integer.valueOf(revisionString).intValue();
+                }
+            }
+            else {
+                sourceUri = uri;
+            }
+            
+            if (revisionNumber == -1) {
+                this.content = (ContentHolder) session.getRepositoryItem(factory, sourceUri);
+            }
+            else {
+                Node node = (Node) session.getRepositoryItem(factory, sourceUri);
+                this.content = node.getHistory().getRevision(revisionNumber);
+            }
+            
         } catch (Exception e) {
             throw new SourceException("Creating repository node failed: ", e);
         } finally {
@@ -115,7 +141,12 @@
      * @return The repository node which is accessed by this source.
      */
     public Node getNode() {
-        return this.node;
+        
+        if (!(this.content instanceof Node)) {
+            throw new RuntimeException("This operation can only be invoked on nodes, not on revisions.");
+        }
+        
+        return (Node) this.content;
     }
 
     protected Logger getLogger() {
@@ -127,7 +158,7 @@
      */
     public OutputStream getOutputStream() throws IOException {
         try {
-            return this.node.getOutputStream();
+            return getNode().getOutputStream();
         } catch (RepositoryException e) {
             throw new RuntimeException(e);
         }
@@ -140,7 +171,7 @@
         RepositoryManager repoManager = null;
         try {
             repoManager = (RepositoryManager) this.manager.lookup(RepositoryManager.ROLE);
-            repoManager.delete(this.node);
+            repoManager.delete(getNode());
         } catch (Exception e) {
             throw new RuntimeException(e);
         } finally {
@@ -168,7 +199,7 @@
      */
     public boolean exists() {
         try {
-            if (this.node.exists()) {
+            if (getContent().exists()) {
                 return true;
             } else {
                 return isCollection();
@@ -188,7 +219,7 @@
             throw new SourceNotFoundException("The source [" + getURI() + "] does not exist!");
         }
         try {
-            return this.node.getInputStream();
+            return getContent().getInputStream();
         } catch (RepositoryException e) {
             throw new RuntimeException(e);
         }
@@ -234,13 +265,17 @@
         transformer.transform(new DOMSource(edoc), new StreamResult(pos));
 
     }
+    
+    protected ContentHolder getContent() {
+        return this.content;
+    }
 
     /**
      * @see org.apache.excalibur.source.Source#getContentLength()
      */
     public long getContentLength() {
         try {
-            return this.node.getContentLength();
+            return getContent().getContentLength();
         } catch (RepositoryException e) {
             throw new RuntimeException(e);
         }
@@ -251,7 +286,7 @@
      */
     public long getLastModified() {
         try {
-            return this.node.getLastModified();
+            return getContent().getLastModified();
         } catch (RepositoryException e) {
             throw new RuntimeException(e);
         }
@@ -262,7 +297,7 @@
      */
     public String getMimeType() {
         try {
-            return this.node.getMimeType();
+            return getContent().getMimeType();
         } catch (RepositoryException e) {
             throw new RuntimeException(e);
         }
@@ -307,7 +342,7 @@
      */
     public Collection getChildren() {
         try {
-            Collection children = this.node.getChildren();
+            Collection children = getNode().getChildren();
             java.util.Iterator iterator = children.iterator();
             java.util.Vector newChildren = new java.util.Vector();
             while (iterator.hasNext()) {
@@ -328,7 +363,7 @@
      */
     public boolean isCollection() {
         try {
-            return this.node.isCollection();
+            return getNode().isCollection();
         } catch (RepositoryException e) {
             throw new RuntimeException(e);
         }

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/SourceUtil.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/SourceUtil.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/SourceUtil.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/SourceUtil.java Mon Nov 13 09:44:15 2006
@@ -50,20 +50,22 @@
 
     /**
      * <p>
-     * Copies one Source to another using a source buffer i.e. the source Source is buffered before
-     * it is copied to its final destination.
+     * Copies one Source to another using a source buffer i.e. the source Source
+     * is buffered before it is copied to its final destination.
      * </p>
      * <p>
-     * The optional buffering is sometimes useful, if the source Source somehow depends on the
-     * destination Source. This situation may occur e.g. if source Source is a Cocoon pipeline.
+     * The optional buffering is sometimes useful, if the source Source somehow
+     * depends on the destination Source. This situation may occur e.g. if
+     * source Source is a Cocoon pipeline.
      * </p>
      * <p>
-     * <em>NOTE:</em> o.a.e..s.SourceUtil.copy does not close streams on an exception!!
+     * <em>NOTE:</em> o.a.e..s.SourceUtil.copy does not close streams on an
+     * exception!!
      * </p>
      * @param source
      * @param destination
-     * @param useBuffer If true, the source data will be read into a buffer before it is written to
-     *            the final destination.
+     * @param useBuffer If true, the source data will be read into a buffer
+     *        before it is written to the final destination.
      * @throws IOException If an error occures.
      */
     public static void copy(Source source, ModifiableSource destination, boolean useBuffer)
@@ -97,8 +99,8 @@
      * @param resolver The SourceResolver to use for lookin up Sources.
      * @param sourceUri The source to be copied.
      * @param destUri The URI to copy to.
-     * @param useBuffer If true, the source Source is buffered before copied to the final
-     *            destination.
+     * @param useBuffer If true, the source Source is buffered before copied to
+     *        the final destination.
      * @throws IOException If an error occures.
      * @throws SourceException If the destination is not modifiable.
      * @see #copy(Source, ModifiableSource, boolean)
@@ -329,6 +331,35 @@
     }
 
     /**
+     * Returns the last modification date of a source.
+     * @param sourceUri The source URI.
+     * @param manager The service manager.
+     * @return A long value.
+     * @throws ServiceException if an error occurs.
+     * @throws MalformedURLException if an error occurs.
+     * @throws IOException if an error occurs.
+     */
+    public static long getLastModified(String sourceUri, ServiceManager manager)
+            throws ServiceException, MalformedURLException, IOException {
+        SourceResolver resolver = null;
+        Source source = null;
+        try {
+
+            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+            source = resolver.resolveURI(sourceUri);
+
+            return source.getLastModified();
+        } finally {
+            if (resolver != null) {
+                if (source != null) {
+                    resolver.release(source);
+                }
+                manager.release(resolver);
+            }
+        }
+    }
+
+    /**
      * Checks out a repository source.
      * @param sourceUri The source URI.
      * @param manager The service manager.
@@ -464,6 +495,62 @@
 
         } catch (Exception e) {
             throw new RuntimeException(e);
+        } finally {
+            if (resolver != null) {
+                if (source != null) {
+                    resolver.release(source);
+                }
+                manager.release(resolver);
+            }
+        }
+    }
+
+    /**
+     * @param sourceUri The source URI.
+     * @param manager The service manager.
+     * @return A content length.
+     * @throws ServiceException
+     * @throws MalformedURLException
+     * @throws IOException
+     */
+    public static long getContentLength(String sourceUri, ServiceManager manager)
+            throws ServiceException, MalformedURLException, IOException {
+        SourceResolver resolver = null;
+        Source source = null;
+        try {
+
+            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+            source = resolver.resolveURI(sourceUri);
+
+            return source.getContentLength();
+        } finally {
+            if (resolver != null) {
+                if (source != null) {
+                    resolver.release(source);
+                }
+                manager.release(resolver);
+            }
+        }
+    }
+
+    /**
+     * @param sourceUri The source URI.
+     * @param manager The service manager.
+     * @return A mime type.
+     * @throws ServiceException
+     * @throws IOException
+     * @throws MalformedURLException
+     */
+    public static String getMimeType(String sourceUri, ServiceManager manager)
+            throws ServiceException, MalformedURLException, IOException {
+        SourceResolver resolver = null;
+        Source source = null;
+        try {
+
+            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+            source = resolver.resolveURI(sourceUri);
+
+            return source.getMimeType();
         } finally {
             if (resolver != null) {
                 if (source != null) {

Modified: lenya/trunk/src/java/org/apache/lenya/cms/publication/Document.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/publication/Document.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/publication/Document.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/publication/Document.java Mon Nov 13 09:44:15 2006
@@ -114,7 +114,7 @@
      * Returns the date of the last modification of this document.
      * @return A date denoting the date of the last modification.
      */
-    Date getLastModified();
+    long getLastModified() throws DocumentException;
 
     /**
      * Returns the area this document belongs to.

Modified: lenya/trunk/src/java/org/apache/lenya/cms/publication/PublicationException.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/publication/PublicationException.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/publication/PublicationException.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/publication/PublicationException.java Mon Nov 13 09:44:15 2006
@@ -20,10 +20,12 @@
 
 package org.apache.lenya.cms.publication;
 
+import org.apache.lenya.cms.repository.RepositoryException;
+
 /**
  * Publication Exception
  */
-public class PublicationException extends Exception {
+public class PublicationException extends RepositoryException {
 
     /**
 	 * 

Modified: lenya/trunk/src/java/org/apache/lenya/cms/rc/RCML.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/rc/RCML.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/rc/RCML.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/rc/RCML.java Mon Nov 13 09:44:15 2006
@@ -20,141 +20,37 @@
 
 package org.apache.lenya.cms.rc;
 
-import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Vector;
 
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.apache.lenya.xml.DocumentHelper;
-import org.apache.lenya.xml.NamespaceHelper;
-import org.apache.xpath.XPathAPI;
-import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXParseException;
-
 /**
  * Handle with the RCML file
  */
-public class RCML {
-    private static Logger log = Logger.getLogger(RCML.class);
+public interface RCML {
 
     /**
      * <code>co</code> Checkout
      */
-    public static final short co = 0;
+    short co = 0;
     /**
      * <code>ci</code> Checkin
      */
-    public static final short ci = 1;
-
-    private File rcmlFile;
-    private Document document = null;
-    private boolean dirty = false;
-    private int maximalNumberOfEntries = 5;
-
-    private static Map ELEMENTS = new HashMap();
-    protected static final String ELEMENT_CHECKIN = "CheckIn";
-    protected static final String ELEMENT_CHECKOUT = "CheckOut";
-    protected static final String ELEMENT_BACKUP = "Backup";
-
-    {
-        ELEMENTS.put(new Short(ci), ELEMENT_CHECKIN);
-        ELEMENTS.put(new Short(co), ELEMENT_CHECKOUT);
-    }
-
-    /**
-     * Creates a new RCML object.
-     */
-    public RCML() {
-        this.maximalNumberOfEntries = 10;
-        this.maximalNumberOfEntries = (2 * this.maximalNumberOfEntries) + 1;
-    }
-
-    /**
-     * create a RCML-File if no one exists already
-     * @param rcmlDirectory The rcml directory.
-     * @param filename The path of the file from the publication (e.g. for file with absolute path
-     *            home/...//lenya/pubs/{publication id}/content/authoring/foo/bar.xml the filename
-     *            is content/authoring/foo/bar.xml)
-     * @param rootDirectory The publication directory
-     * @throws Exception if an error occurs
-     */
-    public RCML(String rcmlDirectory, String filename, String rootDirectory) throws Exception {
-        this();
-        this.rcmlFile = new File(rcmlDirectory, filename + ".rcml");
-
-        if (!this.rcmlFile.isFile()) {
-            // The rcml file does not yet exist, so we create it now...
-            //
-            File dataFile = new File(rootDirectory, filename);
-            long lastModified = 0;
-
-            if (dataFile.isFile()) {
-                lastModified = dataFile.lastModified();
-            }
-
-            initDocument();
-
-            // Create a "fake" checkin entry so it looks like the
-            // system checked the document in. We use the filesystem
-            // modification date as checkin time.
-            //
-            checkOutIn(RCML.ci, RevisionController.systemUsername, lastModified, false);
-
-            File parent = new File(this.rcmlFile.getParent());
-            parent.mkdirs();
-
-            write();
-        } else {
-            try {
-                this.document = DocumentHelper.readDocument(this.rcmlFile);
-            } catch (SAXParseException e) {
-                throw new RevisionControlException("Could not read RC file ["
-                        + this.rcmlFile.getAbsolutePath() + "]");
-            }
-        }
-    }
+    short ci = 1;
 
     /**
      * initialise the RCML-document. Delete all entries
      * @throws ParserConfigurationException
      */
-    public void initDocument() throws ParserConfigurationException {
-        this.document = DocumentHelper.createDocument(null, "XPSRevisionControl", null);
-    }
-
-    /**
-     * Call the methode write, if the document is dirty
-     * 
-     * @throws IOException if an error occurs
-     * @throws Exception if an error occurs
-     */
-    protected void finalize() throws IOException, Exception {
-        if (this.isDirty()) {
-            log.debug("RCML.finalize(): calling write()");
-            write();
-        }
-    }
+    public void initDocument() throws ParserConfigurationException ;
 
     /**
      * Write the xml RCML-document in the RCML-file.
      * @throws IOException if an error occurs
      * @throws Exception if an error occurs
      */
-    public void write() throws Exception {
-        if (this.document == null) {
-            throw new IllegalStateException("The XML for RC file [" + this.rcmlFile + "] is null!");
-        }
-        DocumentHelper.writeDocument(this.document, this.rcmlFile);
-        clearDirty();
-    }
+    public void write() throws Exception;
 
     /**
      * Write a new entry for a check out or a check in the RCML-File made by the user with identity
@@ -167,211 +63,56 @@
      * @throws Exception if an error occurs
      */
     public void checkOutIn(short type, String identity, long time, boolean backup)
-            throws IOException, Exception {
-        
-        if (identity == null) {
-            throw new IllegalArgumentException("The identity must not be null!");
-        }
-
-        if (type != co && type != ci) {
-            throw new IllegalArgumentException("ERROR: " + this.getClass().getName()
-                    + ".checkOutIn(): No such type");
-        }
-
-        NamespaceHelper helper = new NamespaceHelper(null, "", this.document);
-
-        Element identityElement = helper.createElement("Identity", identity);
-        Element timeElement = helper.createElement("Time", "" + time);
-
-        String elementName = (String) ELEMENTS.get(new Short(type));
-        Element checkOutElement = helper.createElement(elementName);
-
-        checkOutElement.appendChild(identityElement);
-        checkOutElement.appendChild(timeElement);
-
-        if (type == ci) {
-            int version = 0;
-            CheckInEntry latestEntry = getLatestCheckInEntry();
-            if (latestEntry != null) {
-                version = latestEntry.getVersion();
-            }
-            version++;
-            Element versionElement = helper.createElement("Version", "" + version);
-            checkOutElement.appendChild(versionElement);
-        }
-
-        if (backup) {
-            Element backupElement = helper.createElement(ELEMENT_BACKUP);
-            checkOutElement.appendChild(backupElement);
-        }
-
-        Element root = this.document.getDocumentElement();
-        root.insertBefore(checkOutElement, root.getFirstChild());
-
-        setDirty();
-
-        // If this is a checkout, we write back the changed state
-        // to the file immediately because otherwise another
-        // process might read the file and think there is no open
-        // checkout (as it is only visible in our private DOM tree
-        // at this time).
-        //
-        // If, however, this is a checkin, we do not yet write it
-        // out because then another process might again check it
-        // out immediately and manipulate the file contents
-        // *before* our caller has finished writing back the
-        // changed data to the destination file. We therefore rely
-        // on either our caller invoking the write() method when
-        // finished or the garbage collector calling the finalize()
-        // method.
-        //
-        if (type == co) {
-            write();
-        }
-    }
+            throws Exception;
 
     /**
      * get the latest check out
      * @return CheckOutEntry The entry of the check out
      * @throws Exception if an error occurs
      */
-    public CheckOutEntry getLatestCheckOutEntry() throws Exception {
-        Element parent = this.document.getDocumentElement();
-        Node identity = null;
-        Node time = null;
-        String rcIdentity = null;
-
-        identity = XPathAPI.selectSingleNode(parent,
-                "/XPSRevisionControl/CheckOut[1]/Identity/text()");
-        time = XPathAPI.selectSingleNode(parent, "/XPSRevisionControl/CheckOut[1]/Time/text()");
-
-        if (identity == null && time == null) {
-            // No checkout at all
-            return null;
-        }
-        rcIdentity = identity.getNodeValue();
-        long rcTime = new Long(time.getNodeValue()).longValue();
-
-        return new CheckOutEntry(rcIdentity, rcTime);
-    }
+    public CheckOutEntry getLatestCheckOutEntry() throws Exception;
 
     /**
      * get the latest check in
      * @return CheckInEntry The entry of the check in
      * @throws Exception if an error occurs
      */
-    public CheckInEntry getLatestCheckInEntry() throws Exception {
-        Element parent = this.document.getDocumentElement();
-
-        Node identity = XPathAPI.selectSingleNode(parent,
-                "/XPSRevisionControl/CheckIn[1]/Identity/text()");
-        Node time = XPathAPI.selectSingleNode(parent, "/XPSRevisionControl/CheckIn[1]/Time/text()");
-        Node versionNode = XPathAPI.selectSingleNode(parent,
-                "/XPSRevisionControl/CheckIn[1]/Version/text()");
-
-        if (identity == null && time == null) {
-            // No checkout at all
-            return null;
-        }
-        String rcIdentity = identity.getNodeValue();
-        long rcTime = new Long(time.getNodeValue()).longValue();
-        int version = 0;
-        if (versionNode != null) {
-            version = new Integer(versionNode.getNodeValue()).intValue();
-        }
-
-        return new CheckInEntry(rcIdentity, rcTime, version);
-    }
+    public CheckInEntry getLatestCheckInEntry() throws Exception;
 
     /**
      * get the latest entry (a check out or check in)
      * @return RCMLEntry The entry of the check out/in
      * @throws Exception if an error occurs
      */
-    public RCMLEntry getLatestEntry() throws Exception {
-        CheckInEntry cie = getLatestCheckInEntry();
-        CheckOutEntry coe = getLatestCheckOutEntry();
-
-        if ((cie != null) && (coe != null)) {
-            if (cie.getTime() > coe.getTime()) {
-                return cie;
-            }
-            return coe;
-        }
-
-        if (cie != null) {
-            return cie;
-        }
-        return coe;
-    }
+    public RCMLEntry getLatestEntry() throws Exception;
 
     /**
      * get all check in and check out
      * @return Vector of all check out and check in entries in this RCML-file
      * @throws Exception if an error occurs
      */
-    public Vector getEntries() throws Exception {
-        Element parent = this.document.getDocumentElement();
-        NodeList entries = XPathAPI.selectNodeList(parent,
-                "/XPSRevisionControl/CheckOut|/XPSRevisionControl/CheckIn");
-        Vector RCMLEntries = new Vector();
-
-        for (int i = 0; i < entries.getLength(); i++) {
-            Element elem = (Element) entries.item(i);
-            String time = elem.getElementsByTagName("Time").item(0).getFirstChild().getNodeValue();
-            String identity = elem.getElementsByTagName("Identity")
-                    .item(0)
-                    .getFirstChild()
-                    .getNodeValue();
-
-            if (elem.getTagName().equals("CheckOut")) {
-                RCMLEntries.add(new CheckOutEntry(identity, new Long(time).longValue()));
-            } else {
-                NodeList versionElements = elem.getElementsByTagName("Version");
-                int version = 0;
-                if (versionElements.getLength() > 0) {
-                    String versionString = versionElements.item(0).getFirstChild().getNodeValue();
-                    version = new Integer(versionString).intValue();
-                }
-
-                RCMLEntries.add(new CheckInEntry(identity, new Long(time).longValue(), version));
-            }
-        }
-
-        return RCMLEntries;
-    }
+    public Vector getEntries() throws Exception;
 
     /**
      * get all backup entries
      * @return Vector of all entries in this RCML-file with a backup
      * @throws Exception if an error occurs
      */
-    public Vector getBackupEntries() throws Exception {
-        Element parent = this.document.getDocumentElement();
-        NodeList entries = XPathAPI.selectNodeList(parent, "/XPSRevisionControl/CheckOut["
-                + ELEMENT_BACKUP + "]|/XPSRevisionControl/CheckIn[" + ELEMENT_BACKUP + "]");
-        Vector RCMLEntries = new Vector();
-
-        for (int i = 0; i < entries.getLength(); i++) {
-            Element elem = (Element) entries.item(i);
-            String time = elem.getElementsByTagName("Time").item(0).getFirstChild().getNodeValue();
-            String identity = elem.getElementsByTagName("Identity")
-                    .item(0)
-                    .getFirstChild()
-                    .getNodeValue();
-
-            NodeList versionElements = elem.getElementsByTagName("Version");
-            int version = 0;
-            if (versionElements.getLength() > 0) {
-                String versionString = versionElements.item(0).getFirstChild().getNodeValue();
-                version = new Integer(versionString).intValue();
-            }
-
-            RCMLEntries.add(new CheckInEntry(identity, new Long(time).longValue(), version));
-        }
+    public Vector getBackupEntries() throws Exception;
+    
+    /**
+     * Creates a backup.
+     * @param time The time.
+     * @throws RevisionControlException
+     */
+    public void makeBackup(long time) throws RevisionControlException;
 
-        return RCMLEntries;
-    }
+    /**
+     * Restores a backup.
+     * @param time The time.
+     * @throws RevisionControlException
+     */
+    public void restoreBackup(long time) throws RevisionControlException;
 
     /**
      * Prune the list of entries and delete the corresponding backups. Limit the number of entries
@@ -379,118 +120,49 @@
      * @param backupDir The backup directory
      * @throws Exception if an error occurs
      */
-    public void pruneEntries(String backupDir) throws Exception {
-        Element parent = this.document.getDocumentElement();
-        NodeList entries = XPathAPI.selectNodeList(parent,
-                "/XPSRevisionControl/CheckOut|/XPSRevisionControl/CheckIn");
-
-        for (int i = this.maximalNumberOfEntries; i < entries.getLength(); i++) {
-            Element current = (Element) entries.item(i);
-
-            // remove the backup file associated with this entry
-            String time = current.getElementsByTagName("Time")
-                    .item(0)
-                    .getFirstChild()
-                    .getNodeValue();
-            File backupFile = new File(backupDir + "/" + time + ".bak");
-            backupFile.delete();
-            // remove the entry from the list
-            current.getParentNode().removeChild(current);
-        }
-    }
+    public void pruneEntries() throws Exception;
 
     /**
      * Get a clone document
      * @return org.w3c.dom.Document The clone document
      * @throws Exception if an error occurs
      */
-    public org.w3c.dom.Document getDOMDocumentClone() throws Exception {
-        Document documentClone = DocumentHelper.createDocument(null, "dummy", null);
-        documentClone.removeChild(documentClone.getDocumentElement());
-        documentClone.appendChild(documentClone.importNode(this.document.getDocumentElement(), true));
-
-        return documentClone;
-    }
+    public org.w3c.dom.Document getDOMDocumentClone() throws Exception;
 
     /**
      * Check if the document is dirty
      * @return boolean dirty
      */
-    public boolean isDirty() {
-        return this.dirty;
-    }
-
-    /**
-     * Set the value dirty to true
-     */
-    protected void setDirty() {
-        this.dirty = true;
-    }
-
-    /**
-     * Set the value dirty to false
-     */
-    protected void clearDirty() {
-        this.dirty = false;
-    }
+    public boolean isDirty();
 
     /**
      * Delete the latest check in
      * @throws Exception if an error occurs
      */
-    public void deleteFirstCheckIn() throws Exception {
-        Node root = this.document.getDocumentElement();
-        Node firstCheckIn = XPathAPI.selectSingleNode(root, "/XPSRevisionControl/CheckIn[1]");
-        root.removeChild(firstCheckIn);
-        root.removeChild(root.getFirstChild()); // remove EOL (end of line)
-        setDirty();
-    }
+    public void deleteFirstCheckIn() throws Exception;
 
     /**
      * Delete the latest check in
      * @throws Exception if an error occurs
      */
-    public void deleteFirstCheckOut() throws Exception {
-        Node root = this.document.getDocumentElement();
-        Node firstCheckIn = XPathAPI.selectSingleNode(root, "/XPSRevisionControl/CheckOut[1]");
-        root.removeChild(firstCheckIn);
-        root.removeChild(root.getFirstChild()); // remove EOL (end of line)
-        setDirty();
-    }
+    public void deleteFirstCheckOut() throws Exception;
 
     /**
      * get the time's value of the backups
      * @return String[] the times
      * @throws Exception if an error occurs
      */
-    public String[] getBackupsTime() throws Exception {
-        Node root = this.document.getDocumentElement();
-        NodeList entries = XPathAPI.selectNodeList(root, "/XPSRevisionControl/CheckIn");
-
-        ArrayList times = new ArrayList();
-
-        for (int i = 0; i < entries.getLength(); i++) {
-            Element elem = (Element) entries.item(i);
-            String time = elem.getElementsByTagName("Time").item(0).getFirstChild().getNodeValue();
-            NodeList backupNodes = elem.getElementsByTagName(ELEMENT_BACKUP);
-            if (backupNodes != null && backupNodes.getLength() > 0) {
-                times.add(time);
-            }
-        }
-        return (String[]) times.toArray(new String[times.size()]);
-
-    }
+    public String[] getBackupsTime() throws Exception;
 
     /**
      * delete the rcml file and the directory if this one is empty
      * @return boolean true, if the file was deleted
      */
-    public boolean delete() {
-        File directory = this.rcmlFile.getParentFile();
-        boolean deleted = this.rcmlFile.delete();
-        if (directory.exists() && directory.isDirectory() && directory.listFiles().length == 0) {
-            directory.delete();
-        }
-        return deleted;
-    }
+    public boolean delete();
+    
+    /**
+     * Delete all revisions.
+     * @throws RevisionControlException if an error occurs.
+     */
+    void deleteRevisions() throws RevisionControlException;
 }

Modified: lenya/trunk/src/java/org/apache/lenya/cms/rc/RevisionController.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/rc/RevisionController.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/rc/RevisionController.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/rc/RevisionController.java Mon Nov 13 09:44:15 2006
@@ -20,13 +20,10 @@
 
 package org.apache.lenya.cms.rc;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.util.Date;
 
+import org.apache.lenya.cms.repository.Node;
 import org.apache.log4j.Logger;
 
 /**
@@ -43,52 +40,20 @@
      */
     public static final String systemUsername = "System";
 
-    private String rcmlDir = null;
-    private String rootDir = null;
-    private String backupDir = null;
-
     /**
      * Creates a new RevisionController object.
-     * 
-     * @param rcmlDirectory The directory for the RCML files
-     * @param backupDirectory The directory for the backup versions
-     * @param rootDirectory The publication directory
-     */
-    public RevisionController(String rcmlDirectory, String backupDirectory, String rootDirectory) {
-        this.rcmlDir = rcmlDirectory;
-        this.backupDir = backupDirectory;
-        this.rootDir = rootDirectory;
-    }
-
-    /**
-     * Shows Configuration
-     * @return String The rcml directory, the backup directory, the publication directory
-     */
-    public String toString() {
-        return "rcmlDir=" + this.rcmlDir + " , rcbakDir=" + this.backupDir + " , rootDir="
-                + this.rootDir;
-    }
-
-    /**
-     * Get the RCML File for the file source
-     * @param source The path of the file from the publication.
-     * @return RCML The corresponding RCML file.
-     * @throws FileNotFoundException if an error occurs
-     * @throws IOException if an error occurs
-     * @throws Exception if an error occurs
      */
-    public RCML getRCML(String source) throws FileNotFoundException, IOException, Exception {
-        return new RCML(this.rcmlDir, source, this.rootDir);
+    public RevisionController() {
     }
 
     /**
      * Returns the latest version of a source.
-     * @param source The path of the file from the publication.
+     * @param node The node to control.
      * @return A version number.
      * @throws Exception if an error occurs.
      */
-    public int getLatestVersion(String source) throws Exception {
-        RCML rcml = new RCML(this.rcmlDir, source, this.rootDir);
+    public int getLatestVersion(Node node) throws Exception {
+        RCML rcml = node.getRcml();
         CheckInEntry entry = rcml.getLatestCheckInEntry();
         int version = 0;
         if (entry != null) {
@@ -100,19 +65,13 @@
     /**
      * Try to make a reserved check out of the file source for a user with identity
      * 
-     * @param source The filename of the file to check out
+     * @param node The node to check out
      * @param identity The identity of the user
-     * @return File File to check out
      * @throws Exception if an error occurs
      */
-    public File reservedCheckOut(String source, String identity) throws Exception {
+    public void reservedCheckOut(Node node, String identity) throws Exception {
 
-        File file = new File(this.rootDir + source);
-        /*
-         * if (!file.isFile()) { throw new FileNotFoundException(file.getAbsolutePath()); }
-         */
-
-        RCML rcml = new RCML(this.rcmlDir, source, this.rootDir);
+        RCML rcml = node.getRcml();
 
         RCMLEntry entry = rcml.getLatestEntry();
 
@@ -127,23 +86,21 @@
 
         if ((entry != null) && (entry.getType() != RCML.ci)
                 && !entry.getIdentity().equals(identity)) {
-            throw new FileReservedCheckOutException(this.rootDir + source, rcml);
+            throw new FileReservedCheckOutException(node.getSourceURI(), rcml);
         }
 
         rcml.checkOutIn(RCML.co, identity, new Date().getTime(), false);
-
-        return file;
     }
 
     /**
      * Checks if a source can be checked out.
-     * @param source The source.
+     * @param node The node.
      * @param identity The identity who requests checking out.
      * @return A boolean value.
      * @throws Exception when something went wrong.
      */
-    public boolean canCheckOut(String source, String identity) throws Exception {
-        RCML rcml = new RCML(this.rcmlDir, source, this.rootDir);
+    public boolean canCheckOut(Node node, String identity) throws Exception {
+        RCML rcml = node.getRcml();
 
         RCMLEntry entry = rcml.getLatestEntry();
 
@@ -163,12 +120,12 @@
     }
 
     /**
-     * @param source A source.
-     * @return If the source is checked out.
+     * @param node A node.
+     * @return If the node is checked out.
      * @throws Exception if an error occurs.
      */
-    public boolean isCheckedOut(String source) throws Exception {
-        RCML rcml = new RCML(this.rcmlDir, source, this.rootDir);
+    public boolean isCheckedOut(Node node) throws Exception {
+        RCML rcml = node.getRcml();
 
         RCMLEntry entry = rcml.getLatestEntry();
 
@@ -187,7 +144,7 @@
      * Try to make a reserved check in of the file destination for a user with identity. A backup
      * copy can be made.
      * 
-     * @param destination The file we want to check in
+     * @param node The node to control.
      * @param identity The identity of the user
      * @param backup if true, a backup will be created, else no backup will be made.
      * @param newVersion If true, a new version will be created.
@@ -198,130 +155,74 @@
      *                because it is already checked out by someone other ...)
      * @exception Exception if other problems occur
      */
-    public long reservedCheckIn(String destination, String identity, boolean backup,
+    public long reservedCheckIn(Node node, String identity, boolean backup,
             boolean newVersion) throws FileReservedCheckInException, Exception {
-        FileInputStream in = null;
-        FileOutputStream out = null;
 
         RCML rcml;
         long time = new Date().getTime();
 
-        try {
-            rcml = new RCML(this.rcmlDir, destination, this.rootDir);
-
-            CheckOutEntry coe = rcml.getLatestCheckOutEntry();
-            CheckInEntry cie = rcml.getLatestCheckInEntry();
+        rcml = node.getRcml();
 
-            // If there has never been a checkout for this object
-            // *or* if the user attempting the checkin right now
-            // is the system itself, we will skip any checks and proceed
-            // right away to the actual checkin.
-            // In all other cases we enforce the revision control
-            // rules inside this if clause:
-            //
-            if (!((coe == null) || identity.equals(RevisionController.systemUsername))) {
-                /*
-                 * Possible cases and rules:
-                 * 
-                 * 1.) we were able to read the latest checkin and it is later than latest checkout
-                 * (i.e. there is no open checkout to match this checkin, an unusual case) 1.1.)
-                 * identity of latest checkin is equal to current user -> checkin allowed, same user
-                 * may check in repeatedly 1.2.) identity of latest checkin is not equal to current
-                 * user -> checkin rejected, may not overwrite the revision which another user
-                 * checked in previously 2.) there was no checkin or the latest checkout is later
-                 * than latest checkin (i.e. there is an open checkout) 2.1.) identity of latest
-                 * checkout is equal to current user -> checkin allowed, user checked out and may
-                 * check in again (the most common case) 2.2.) identity of latest checkout is not
-                 * equal to current user -> checkin rejected, may not check in while another user is
-                 * working on this document
-                 *  
-                 */
-                if ((cie != null) && (cie.getTime() > coe.getTime())) {
-                    // We have case 1
-                    if (!cie.getIdentity().equals(identity)) {
-                        // Case 1.2., abort...
-                        //
-                        throw new FileReservedCheckInException(this.rootDir + destination, rcml);
-                    }
-                } else {
-                    // Case 2
-                    if (!coe.getIdentity().equals(identity)) {
-                        // Case 2.2., abort...
-                        //
-                        throw new FileReservedCheckInException(this.rootDir + destination, rcml);
-                    }
-                }
-            }
+        CheckOutEntry coe = rcml.getLatestCheckOutEntry();
+        CheckInEntry cie = rcml.getLatestCheckInEntry();
 
-            File originalFile = new File(this.rootDir, destination);
-
-            if (backup && originalFile.isFile()) {
-                File backupFile = new File(this.backupDir, destination + ".bak." + time);
-                File parent = new File(backupFile.getParent());
-
-                if (!parent.isDirectory()) {
-                    parent.mkdirs();
-                }
-
-                log.debug("Backup: copy " + originalFile.getAbsolutePath() + " to "
-                        + backupFile.getAbsolutePath());
-
-                in = new FileInputStream(originalFile.getAbsolutePath());
-                out = new FileOutputStream(backupFile.getAbsolutePath());
-                byte[] buffer = new byte[512];
-                int length;
-
-                while ((length = in.read(buffer)) != -1) {
-                    out.write(buffer, 0, length);
+        // If there has never been a checkout for this object
+        // *or* if the user attempting the checkin right now
+        // is the system itself, we will skip any checks and proceed
+        // right away to the actual checkin.
+        // In all other cases we enforce the revision control
+        // rules inside this if clause:
+        //
+        if (!((coe == null) || identity.equals(RevisionController.systemUsername))) {
+            /*
+             * Possible cases and rules:
+             * 
+             * 1.) we were able to read the latest checkin and it is later than latest checkout
+             * (i.e. there is no open checkout to match this checkin, an unusual case) 1.1.)
+             * identity of latest checkin is equal to current user -> checkin allowed, same user
+             * may check in repeatedly 1.2.) identity of latest checkin is not equal to current
+             * user -> checkin rejected, may not overwrite the revision which another user
+             * checked in previously 2.) there was no checkin or the latest checkout is later
+             * than latest checkin (i.e. there is an open checkout) 2.1.) identity of latest
+             * checkout is equal to current user -> checkin allowed, user checked out and may
+             * check in again (the most common case) 2.2.) identity of latest checkout is not
+             * equal to current user -> checkin rejected, may not check in while another user is
+             * working on this document
+             *  
+             */
+            if ((cie != null) && (cie.getTime() > coe.getTime())) {
+                // We have case 1
+                if (!cie.getIdentity().equals(identity)) {
+                    // Case 1.2., abort...
+                    //
+                    throw new FileReservedCheckInException(node.getSourceURI(), rcml);
                 }
-            }
-
-            if (newVersion) {
-                rcml.checkOutIn(RCML.ci, identity, time, backup);
             } else {
-                rcml.deleteFirstCheckOut();
+                // Case 2
+                if (!coe.getIdentity().equals(identity)) {
+                    // Case 2.2., abort...
+                    //
+                    throw new FileReservedCheckInException(node.getSourceURI(), rcml);
+                }
             }
-            rcml.pruneEntries(this.backupDir);
-            rcml.write();
-
-        } catch (final FileNotFoundException e) {
-            log.error("File not found" + e.toString());
-        } catch (final IOException e) {
-            log.error("IO error " + e.toString());
-        } finally {
-            if (in != null)
-                in.close();
-            if (out != null)
-                out.close();
         }
-        return time;
-    }
+        
+        rcml.makeBackup(time);
 
-    /**
-     * Get the absolute path of a backup version
-     * @param time The time of the backup
-     * @param filename The path of the file from the {publication}
-     * @return String The absolute path of the backup version
-     */
-    public String getBackupFilename(long time, String filename) {
-        File backup = new File(this.backupDir, filename + ".bak." + time);
-        return backup.getAbsolutePath();
-    }
+        if (newVersion) {
+            rcml.checkOutIn(RCML.ci, identity, time, backup);
+        } else {
+            rcml.deleteFirstCheckOut();
+        }
+        rcml.pruneEntries();
+        rcml.write();
 
-    /**
-     * Get the file of a backup version
-     * @param time The time of the backup
-     * @param filename The path of the file from the {publication}
-     * @return File The file of the backup version
-     */
-    public File getBackupFile(long time, String filename) {
-        File backup = new File(this.backupDir, filename + ".bak." + time);
-        return backup;
+        return time;
     }
 
     /**
      * Rolls back to the given point in time.
-     * @param destination File which will be rolled back
+     * @param node The node which will be rolled back
      * @param identity The identity of the user
      * @param backupFlag If true, a backup of the current version will be made before the rollback
      * @param time The time point of the desired version
@@ -331,57 +232,22 @@
      * @exception FileNotFoundException if a file couldn't be found
      * @exception Exception if another problem occurs
      */
-    public long rollback(String destination, String identity, boolean backupFlag, long time)
-            throws FileReservedCheckInException, FileReservedCheckOutException,
-            FileNotFoundException, Exception {
-
-        FileInputStream in = null;
-        FileOutputStream out = null;
+    public long rollback(Node node, String identity, boolean backupFlag, long time)
+            throws Exception {
 
-        try {
-            // Make sure the old version exists
-            File backup = new File(this.backupDir, destination + ".bak." + time);
-            File current = new File(this.rootDir, destination);
-
-            if (!backup.isFile()) {
-                throw new FileNotFoundException(backup.getAbsolutePath());
-            }
+        // Make sure the old version exists
+        RCML rcml = node.getRcml();
 
-            if (!current.isFile()) {
-                throw new FileNotFoundException(current.getAbsolutePath());
-            }
-
-            // Try to check out current version
-            reservedCheckOut(destination, identity);
-
-            // Now roll back to the old state
-            in = new FileInputStream(backup.getAbsolutePath());
-            out = new FileOutputStream(current.getAbsolutePath());
-            byte[] buffer = new byte[512];
-            int length;
-
-            while ((length = in.read(buffer)) != -1) {
-                out.write(buffer, 0, length);
-            }
-        } catch (FileNotFoundException e) {
-            log.error("File not found " + e.toString());
-        } catch (IOException e) {
-            log.error("IO error " + e.toString());
-        } catch (Exception e) {
-            log.error("Exception " + e.toString());
-        } finally {
-            if (in != null)
-                in.close();
-            if (out != null)
-                out.close();
-        }
+        // Try to check out current version
+        reservedCheckOut(node, identity);
+        rcml.restoreBackup(time);
 
         // Try to check back in, this might cause
         // a backup of the current version to be created if
         // desired by the user.
         //XXX:  what is the use of a backup if doc isn't versioned, can't rollback?
         //long newtime = reservedCheckIn(destination, identity, backupFlag, false);
-        long newtime = reservedCheckIn(destination, identity, backupFlag, backupFlag);
+        long newtime = reservedCheckIn(node, identity, backupFlag, backupFlag);
 
         return newtime;
     }
@@ -389,90 +255,33 @@
     /**
      * Delete the check in and roll back the file to the backup at time
      * @param time The time point of the back version we want to retrieve
-     * @param destination The File for which we want undo the check in
+     * @param node The node for which we want undo the check in
      * @exception Exception FileNotFoundException if the back version or the current version
      *                couldn't be found
      */
-    public void undoCheckIn(long time, String destination) throws Exception {
-        FileInputStream in = null;
-        FileOutputStream out = null;
-
-        try {
-            File backup = new File(this.backupDir + "/" + destination + ".bak." + time);
-            File current = new File(this.rootDir + destination);
-            RCML rcml = new RCML(this.rcmlDir, destination, this.rootDir);
-
-            if (!backup.isFile()) {
-                throw new FileNotFoundException(backup.getAbsolutePath());
-            }
-
-            if (!current.isFile()) {
-                throw new FileNotFoundException(current.getAbsolutePath());
-            }
-
-            in = new FileInputStream(backup.getAbsolutePath());
-            out = new FileOutputStream(current.getAbsolutePath());
-            byte[] buffer = new byte[512];
-            int length;
-
-            while ((length = in.read(buffer)) != -1) {
-                out.write(buffer, 0, length);
-            }
-
-            log.debug("Undo: copy " + backup.getAbsolutePath() + " " + current.getAbsolutePath());
-
-            rcml.deleteFirstCheckIn();
-        } catch (FileNotFoundException e) {
-            log.error("File not found " + e.toString());
-        } catch (IOException e) {
-            log.error("IO error " + e.toString());
-        } catch (Exception e) {
-            log.error("Exception " + e.toString());
-        } finally {
-            if (in != null)
-                in.close();
-            if (out != null)
-                out.close();
-        }
+    public void undoCheckIn(long time, Node node) throws Exception {
+        RCML rcml = node.getRcml();
+        rcml.restoreBackup(time);
+        rcml.deleteFirstCheckIn();
     }
 
     /**
      * delete the revisions
-     * @param filename of the document
+     * @param node of the document
      * @throws RevisionControlException when somthing went wrong
      */
-    public void deleteRevisions(String filename) throws RevisionControlException {
-        try {
-            RCML rcml = this.getRCML(filename);
-            String[] times = rcml.getBackupsTime();
-            for (int i = 0; i < times.length; i++) {
-                long time = new Long(times[i]).longValue();
-                File backup = this.getBackupFile(time, filename);
-                File parentDirectory = null;
-                parentDirectory = backup.getParentFile();
-                boolean deleted = backup.delete();
-                if (!deleted) {
-                    throw new RevisionControlException("The backup file, "
-                            + backup.getCanonicalPath() + " could not be deleted!");
-                }
-                if (parentDirectory != null && parentDirectory.exists()
-                        && parentDirectory.isDirectory() && parentDirectory.listFiles().length == 0) {
-                    parentDirectory.delete();
-                }
-            }
-        } catch (Exception e) {
-            throw new RevisionControlException(e);
-        }
+    public void deleteRevisions(Node node) throws RevisionControlException {
+        node.getRcml().deleteRevisions();
     }
 
     /**
      * delete the rcml file
-     * @param filename of the document
+     * @param node of the document
      * @throws RevisionControlException if something went wrong
      */
-    public void deleteRCML(String filename) throws RevisionControlException {
+    public void deleteRCML(Node node) throws RevisionControlException {
         try {
-            RCML rcml = this.getRCML(filename);
+            RCML rcml = node.getRcml();
             boolean deleted = rcml.delete();
             if (!deleted) {
                 throw new RevisionControlException("The rcml file could not be deleted!");

Added: lenya/trunk/src/java/org/apache/lenya/cms/repository/ContentHolder.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/repository/ContentHolder.java?view=auto&rev=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/repository/ContentHolder.java (added)
+++ lenya/trunk/src/java/org/apache/lenya/cms/repository/ContentHolder.java Mon Nov 13 09:44:15 2006
@@ -0,0 +1,48 @@
+package org.apache.lenya.cms.repository;
+
+import java.io.InputStream;
+
+import org.apache.lenya.cms.metadata.MetaDataOwner;
+
+/**
+ * Super interface for nodes and revisions.
+ */
+public interface ContentHolder extends MetaDataOwner {
+
+    /**
+     * @return The last modification date.
+     * @throws RepositoryException if the node does not exist.
+     */
+    long getLastModified() throws RepositoryException;
+    
+    /**
+     * @return The content length.
+     * @throws RepositoryException if the node does not exist.
+     */
+    long getContentLength() throws RepositoryException;
+
+    /**
+     * Accessor for the source URI of this node
+     * @return the source URI
+     */
+    String getSourceURI();
+    
+    /**
+     * @return if the item exists.
+     * @throws RepositoryException if an error occurs.
+     */
+    boolean exists() throws RepositoryException;
+
+    /**
+     * @return The input stream.
+     * @throws RepositoryException if the node does not exist.
+     */
+    InputStream getInputStream() throws RepositoryException;
+
+    /**
+     * @return The MIME type.
+     * @throws RepositoryException if the node does not exist.
+     */
+    String getMimeType() throws RepositoryException;
+
+}

Added: lenya/trunk/src/java/org/apache/lenya/cms/repository/History.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/repository/History.java?view=auto&rev=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/repository/History.java (added)
+++ lenya/trunk/src/java/org/apache/lenya/cms/repository/History.java Mon Nov 13 09:44:15 2006
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.
+ *
+ */
+package org.apache.lenya.cms.repository;
+
+/**
+ * The revision history of a node.
+ */
+public interface History {
+    
+    /**
+     * @return The latest revision.
+     */
+    Revision getLatestRevision();
+    
+    /**
+     * @param number A revision number.
+     * @return A revision.
+     * @throws RepositoryException if no revision with this number exists.
+     */
+    Revision getRevision(int number) throws RepositoryException;
+
+}

Modified: lenya/trunk/src/java/org/apache/lenya/cms/repository/Node.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/repository/Node.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/repository/Node.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/repository/Node.java Mon Nov 13 09:44:15 2006
@@ -17,18 +17,17 @@
  */
 package org.apache.lenya.cms.repository;
 
-import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Collection;
 
-import org.apache.lenya.cms.metadata.MetaDataOwner;
+import org.apache.lenya.cms.rc.RCML;
 
 /**
  * Repository node.
  * 
  * @version $Id$
  */
-public interface Node extends MetaDataOwner, RepositoryItem {
+public interface Node extends RepositoryItem, ContentHolder {
     
     /**
      * @return The session this node belongs to.
@@ -64,42 +63,12 @@
     public Collection getChildren() throws RepositoryException;
 
     /**
-     * @return The input stream.
-     * @throws RepositoryException if the node does not exist.
-     */
-    InputStream getInputStream() throws RepositoryException;
-
-    /**
      * @return The output stream.
      * @throws RepositoryException if the node does not exist.
      */
     OutputStream getOutputStream() throws RepositoryException;
     
     /**
-     * @return The last modification date.
-     * @throws RepositoryException if the node does not exist.
-     */
-    long getLastModified() throws RepositoryException;
-    
-    /**
-     * @return The content length.
-     * @throws RepositoryException if the node does not exist.
-     */
-    long getContentLength() throws RepositoryException;
-    
-    /**
-     * @return The MIME type.
-     * @throws RepositoryException if the node does not exist.
-     */
-    String getMimeType() throws RepositoryException;
-
-    /**
-     * Accessor for the source URI of this node
-     * @return the source URI
-     */
-    String getSourceURI();
-
-    /**
      * Locks the node.
      * @throws RepositoryException if an error occurs.
      */
@@ -165,4 +134,14 @@
      * @return A boolean value.
      */
     boolean isListenerRegistered(NodeListener listener);
+    
+    /**
+     * @return The RCML to use for this node.
+     */
+    RCML getRcml();
+    
+    /**
+     * @return The revision history.
+     */
+    History getHistory();
 }

Modified: lenya/trunk/src/java/org/apache/lenya/cms/repository/RepositoryItem.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/repository/RepositoryItem.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/repository/RepositoryItem.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/repository/RepositoryItem.java Mon Nov 13 09:44:15 2006
@@ -18,5 +18,5 @@
 package org.apache.lenya.cms.repository;
 
 public interface RepositoryItem {
-
+    
 }

Added: lenya/trunk/src/java/org/apache/lenya/cms/repository/Revision.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/repository/Revision.java?view=auto&rev=474413
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/repository/Revision.java (added)
+++ lenya/trunk/src/java/org/apache/lenya/cms/repository/Revision.java Mon Nov 13 09:44:15 2006
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.
+ *
+ */
+package org.apache.lenya.cms.repository;
+
+/**
+ * A revision.
+ */
+public interface Revision extends ContentHolder {
+    
+    /**
+     * @return The revision number.
+     */
+    int getNumber();
+    
+}

Modified: lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/source/DocumentSourceFactory.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/source/DocumentSourceFactory.java?view=diff&rev=474413&r1=474412&r2=474413
==============================================================================
--- lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/source/DocumentSourceFactory.java (original)
+++ lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/source/DocumentSourceFactory.java Mon Nov 13 09:44:15 2006
@@ -40,6 +40,7 @@
 import org.apache.excalibur.source.SourceFactory;
 import org.apache.excalibur.source.SourceResolver;
 import org.apache.lenya.cms.linking.LinkResolver;
+import org.apache.lenya.cms.linking.LinkTarget;
 import org.apache.lenya.cms.publication.Document;
 import org.apache.lenya.cms.publication.DocumentException;
 import org.apache.lenya.cms.publication.DocumentFactory;
@@ -64,6 +65,9 @@
 public class DocumentSourceFactory extends AbstractLogEnabled implements SourceFactory, ThreadSafe,
         Contextualizable, Serviceable, Configurable {
 
+    /**
+     * The URI scheme.
+     */
     public static final String SCHEME = "lenya-document";
 
     private Context context;
@@ -116,7 +120,8 @@
             String webappUrl = ServletHelper.getWebappURI(request);
             Document currentDoc = factory.getFromURL(webappUrl);
 
-            Document doc = resolver.resolve(currentDoc, linkUri);
+            LinkTarget target = resolver.resolve(currentDoc, linkUri);
+            Document doc = target.getDocument();
 
             String format = null;
             if (queryString != null) {
@@ -127,6 +132,9 @@
                 return getFormatSource(doc, format);
             } else {
                 String lenyaURL = doc.getSourceURI();
+                if (target.isRevisionSpecified()) {
+                    lenyaURL += "?rev=" + target.getRevisionNumber();
+                }
                 Session session = RepositoryUtil.getSession(this.manager, request);
                 return new RepositorySource(manager, lenyaURL, session, getLogger());
             }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org