Author: andreas
Date: Thu Aug 9 09:28:15 2007
New Revision: 564264
URL: http://svn.apache.org/viewvc?view=rev&rev=564264
Log:
Refactored revision control: clean up XML reading+writing. RCML objects are now singletons per source URI. This allows to synchronize access per RCML object, avoiding synchronization issues which occured when running load tests. UnitOfWork.commit() and rollback() are now synchronized via the class object to avoid inter-usecase commit synchronization issues (also occured during load tests).
Modified:
lenya/trunk/src/impl/java/org/apache/lenya/cms/repository/SharedItemStoreImpl.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/impl/test/org/apache/lenya/transaction/MockTransactionable.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/flow/FlowHelperImpl.java
lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckInEntry.java
lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckOutEntry.java
lenya/trunk/src/java/org/apache/lenya/cms/rc/RCML.java
lenya/trunk/src/java/org/apache/lenya/cms/rc/RCMLEntry.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/Session.java
lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java
lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java
lenya/trunk/src/java/org/apache/lenya/transaction/Versionable.java
lenya/trunk/src/modules-core/sitemanagement/java/src/org/apache/lenya/cms/site/usecases/Rollback.java
lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java
lenya/trunk/src/modules/development/test/jmeter/lenyaJMeterTest.jmx
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/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/SourceWrapper.java
Modified: lenya/trunk/src/impl/java/org/apache/lenya/cms/repository/SharedItemStoreImpl.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/impl/java/org/apache/lenya/cms/repository/SharedItemStoreImpl.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/impl/java/org/apache/lenya/cms/repository/SharedItemStoreImpl.java (original)
+++ lenya/trunk/src/impl/java/org/apache/lenya/cms/repository/SharedItemStoreImpl.java Thu Aug 9 09:28:15 2007
@@ -108,5 +108,9 @@
public synchronized void clear() {
this.map = null;
}
+
+ public String getId() {
+ return getClass().getName();
+ }
}
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=564264&r1=564263&r2=564264
==============================================================================
--- 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 Thu Aug 9 09:28:15 2007
@@ -21,7 +21,6 @@
package org.apache.lenya.cms.rc;
import java.io.PrintWriter;
-import java.util.Date;
import org.w3c.dom.Document;
import org.apache.lenya.ac.impl.AbstractAccessControlTest;
@@ -67,7 +66,7 @@
try {
org.apache.lenya.cms.publication.Document doc = null;
RCML rcml = doc.getRepositoryNode().getRcml();
- rcml.checkOutIn(RCML.co, "michi", new Date().getTime(), false);
+ rcml.checkOut(doc.getRepositoryNode());
(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=564264&r1=564263&r2=564264
==============================================================================
--- 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 Thu Aug 9 09:28:15 2007
@@ -26,6 +26,7 @@
import org.apache.lenya.ac.impl.AbstractAccessControlTest;
import org.apache.lenya.cms.publication.Document;
import org.apache.lenya.cms.publication.DocumentManager;
+import org.apache.lenya.cms.repository.RepositoryException;
/**
* Revision Controller test
@@ -33,29 +34,31 @@
public class RevisionControllerTest extends AbstractAccessControlTest {
/**
- * @see <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=41005">Bug 41005</a>
+ * @see <a
+ * href="http://issues.apache.org/bugzilla/show_bug.cgi?id=41005">Bug
+ * 41005</a>
* @throws Exception
*/
public void testCheckIn() throws Exception {
login("lenya");
-
+
DocumentManager docMgr = null;
try {
docMgr = (DocumentManager) getManager().lookup(DocumentManager.ROLE);
- Document source = getPublication("test").getArea("authoring").getSite().getNode("/links").getLink("en").getDocument();
+ Document source = getPublication("test").getArea("authoring").getSite().getNode(
+ "/links").getLink("en").getDocument();
Document target = docMgr.addVersion(source, "authoring", "es");
target.delete();
- }
- finally {
+ } finally {
if (docMgr != null) {
getManager().release(docMgr);
}
}
-
+
getFactory().getSession().commit();
}
- public void testRevisionController() {
+ public void testRevisionController() throws RepositoryException, RevisionControlException {
String[] args = { "", "", "", "" };
@@ -78,35 +81,8 @@
String identityD = args[2];
String destination = args[3];
RevisionController rc = new RevisionController(getLogger());
- try {
- rc.reservedCheckOut(doc1.getRepositoryNode(), identityS);
- } catch (FileNotFoundException e) // No such source file
- {
- System.out.println(e.toString());
- } catch (FileReservedCheckOutException e) // Source has been checked
- // out already
- {
- System.out.println(e.toString());
- // System.out.println(error(e.source + "is already check out by " +
- // e.checkOutUsername + " since " + e.checkOutDate));
- return;
-
- } catch (IOException e) { // Cannot create rcml file
- System.out.println(e.toString());
- return;
-
- } catch (Exception e) {
- System.out.println(e.toString());
- return;
- }
-
- try {
- rc.reservedCheckIn(doc2.getRepositoryNode(), identityD, true, true);
- } catch (FileReservedCheckInException e) {
- System.out.println(e.toString());
- } catch (Exception e) {
- System.out.println(e.toString());
- }
+ doc1.getRepositoryNode().checkout();
+ doc2.getRepositoryNode().getRcml().checkIn(doc2.getRepositoryNode(), true, true);
}
}
Modified: lenya/trunk/src/impl/test/org/apache/lenya/transaction/MockTransactionable.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/impl/test/org/apache/lenya/transaction/MockTransactionable.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/impl/test/org/apache/lenya/transaction/MockTransactionable.java (original)
+++ lenya/trunk/src/impl/test/org/apache/lenya/transaction/MockTransactionable.java Thu Aug 9 09:28:15 2007
@@ -74,7 +74,7 @@
return MockRevisionController.getHistory(this).isCheckedOut();
}
- public boolean isCheckedOutByUser() throws TransactionException {
+ public boolean isCheckedOutBySession() throws TransactionException {
String user = MockRevisionController.getHistory(this).getCheckOutUser();
return user != null && user.equals(getUserId());
}
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=564264&r1=564263&r2=564264
==============================================================================
--- 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 Thu Aug 9 09:28:15 2007
@@ -26,8 +26,8 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.SourceResolver;
-import org.apache.lenya.cms.rc.FileReservedCheckInException;
import org.apache.lenya.cms.repository.Node;
+import org.apache.lenya.cms.repository.RepositoryException;
/**
* Checkin document
@@ -53,19 +53,10 @@
try {
Node node = getNode();
- if (node.isCheckedOutByUser()) {
- getRc().reservedCheckIn(node, getUsername(), backup, true);
+ if (node.isCheckedOutBySession()) {
+ node.getRcml().checkIn(node, backup, true);
}
- } catch (FileReservedCheckInException e) {
- actionMap.put("exception", "fileReservedCheckInException");
- actionMap.put("filename", getNode().getSourceURI());
- actionMap.put("checkType", e.getTypeString());
- actionMap.put("user", e.getUsername());
- actionMap.put("date", e.getDate());
- getLogger().warn(e.getMessage());
-
- return actionMap;
- } catch (Exception e) {
+ } catch (RepositoryException e) {
actionMap.put("exception", "genericException");
actionMap.put("filename", getNode().getSourceURI());
actionMap.put("message", e.getMessage());
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=564264&r1=564263&r2=564264
==============================================================================
--- 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 Thu Aug 9 09:28:15 2007
@@ -26,8 +26,9 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.SourceResolver;
-import org.apache.lenya.cms.rc.FileReservedCheckOutException;
import org.apache.lenya.cms.repository.Node;
+import org.apache.lenya.cms.repository.RepositoryException;
+import org.apache.lenya.util.Assert;
/**
* Action doing reserved checkout
@@ -49,31 +50,13 @@
Node node = getNode();
String username = getUsername();
- getLogger().debug(".act(): Node: " + node.getSourceURI());
- getLogger().debug(".act(): Username: " + username);
+ Assert.notNull("node", node);
+ Assert.notNull("username", username);
- if (getNode() == null) {
- throw new Exception("Filename is null");
+ if (!node.isCheckedOutBySession()) {
+ node.checkout();
}
-
- if (getUsername() == null) {
- throw new Exception("Username is null");
- }
-
- if (!node.isCheckedOutByUser()) {
- getRc().reservedCheckOut(node, username);
- }
- } catch (FileReservedCheckOutException e) {
- actionMap.put("exception", "fileReservedCheckOutException");
- actionMap.put("filename", getNode().getSourceURI());
- actionMap.put("user", e.getCheckOutUsername());
- actionMap.put("date", e.getCheckOutDate());
- getLogger().warn(
- "Node " + getNode().getSourceURI() + " already checked-out by "
- + e.getCheckOutUsername() + " since " + e.getCheckOutDate());
-
- return actionMap;
- } catch (Exception e) {
+ } catch (RepositoryException e) {
actionMap.put("exception", "genericException");
actionMap.put("filename", getNode().getSourceURI());
actionMap.put("message", "" + e.getMessage());
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=564264&r1=564263&r2=564264
==============================================================================
--- 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 Thu Aug 9 09:28:15 2007
@@ -26,9 +26,9 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.SourceResolver;
-import org.apache.lenya.cms.rc.FileReservedCheckOutException;
import org.apache.lenya.cms.rc.RCML;
import org.apache.lenya.cms.rc.RCMLEntry;
+import org.apache.lenya.cms.repository.RepositoryException;
/**
@@ -52,14 +52,11 @@
if ((entry == null) || (entry.getType() != RCML.co) || !entry.getIdentity().equals(getUsername())) {
//check out
- getRc().reservedCheckOut(getNode(), getUsername());
+ getNode().checkout();
}
- } catch (FileReservedCheckOutException e) {
- actionMap.put("exception", "fileReservedCheckOutException");
+ } catch (RepositoryException e) {
+ actionMap.put("exception", "RepositoryException");
actionMap.put("filename", getNode().getSourceURI());
- actionMap.put("user", e.getCheckOutUsername());
- actionMap.put("date", e.getCheckOutDate());
- getLogger().warn("Node " + getNode().getSourceURI() + " already checked-out by " + e.getCheckOutUsername() + " since " + e.getCheckOutDate());
return actionMap;
} catch (Exception e) {
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=564264&r1=564263&r2=564264
==============================================================================
--- 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 Thu Aug 9 09:28:15 2007
@@ -29,10 +29,8 @@
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.cocoon.components.flow.javascript.fom.FOM_Cocoon;
-import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.lenya.ac.AccessControlException;
-import org.apache.lenya.ac.Identity;
import org.apache.lenya.cms.publication.Document;
import org.apache.lenya.cms.publication.DocumentFactory;
import org.apache.lenya.cms.publication.DocumentUtil;
@@ -170,15 +168,9 @@
*/
public void reservedCheckIn(FOM_Cocoon cocoon, boolean backup)
throws FileReservedCheckInException, Exception {
- final Identity identity = (Identity) ObjectModelHelper.getRequest(cocoon.getObjectModel())
- .getSession()
- .getAttribute(Identity.class.getName());
final PageEnvelope pageEnvelope = getPageEnvelope(cocoon);
Node node = pageEnvelope.getDocument().getRepositoryNode();
- getRevisionController(cocoon).reservedCheckIn(node,
- identity.getUser().getId(),
- backup,
- true);
+ node.getRcml().checkIn(node, backup, true);
}
private ServiceManager manager;
Modified: lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckInEntry.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckInEntry.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckInEntry.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckInEntry.java Thu Aug 9 09:28:15 2007
@@ -27,14 +27,17 @@
public class CheckInEntry extends RCMLEntry {
/**
* Creates a new CheckInEntry object.
+ * @param sessionId The session ID.
* @param identity The identity to use
* @param time The time
* @param version The version number.
+ * @param backup If this entry has a backup.
*/
- public CheckInEntry(String identity, long time, int version) {
- super(identity, time);
+ public CheckInEntry(String sessionId, String identity, long time, int version, boolean backup) {
+ super(sessionId, identity, time);
setType(RCML.ci);
this.version = version;
+ this.backup = backup;
}
/**
@@ -45,5 +48,10 @@
}
private int version = 0;
+ private boolean backup;
+
+ public boolean hasBackup() {
+ return this.backup;
+ }
}
Modified: lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckOutEntry.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckOutEntry.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckOutEntry.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/rc/CheckOutEntry.java Thu Aug 9 09:28:15 2007
@@ -26,11 +26,12 @@
public class CheckOutEntry extends RCMLEntry {
/**
* Creates a new CheckOutEntry object.
+ * @param sessionId The session ID.
* @param identity The identity
* @param time The time
*/
- public CheckOutEntry(String identity, long time) {
- super(identity, time);
+ public CheckOutEntry(String sessionId, String identity, long time) {
+ super(sessionId, identity, time);
setType(RCML.co);
}
}
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=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/rc/RCML.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/rc/RCML.java Thu Aug 9 09:28:15 2007
@@ -20,11 +20,15 @@
package org.apache.lenya.cms.rc;
-import java.io.IOException;
import java.util.Vector;
+import org.apache.lenya.cms.repository.Node;
+import org.apache.lenya.cms.repository.Session;
+
/**
- * Handle with the RCML file
+ * An object of this class handles the revisions of a node. The node is passed
+ * as a parameter so an RCML object can be shared between sessions for synchronization
+ * purposes.
*/
public interface RCML {
@@ -38,118 +42,108 @@
short ci = 1;
/**
- * Write the xml RCML-document in the RCML-file.
- * @throws IOException if an error occurs
- * @throws Exception if an error occurs
+ * Check the RCML in.
+ * @param node The node.
+ * @param backup If a backup shall be created.
+ * @param newVersion If a new version shall be created.
+ * @throws RevisionControlException if an error occurs.
*/
- public void write() throws Exception;
-
+ void checkIn(Node node, boolean backup, boolean newVersion) throws RevisionControlException;
+
/**
- * Write a new entry for a check out or a check in the RCML-File made by the user with identity
- * at time
- * @param type co for a check out, ci for a check in
- * @param identity The identity of the user
- * @param time Time at which the check in/out is made
- * @param backup Create backup element
- * @throws IOException if an error occurs
- * @throws Exception if an error occurs
+ * Check the RCML out.
+ * @param node The node.
+ * @throws RevisionControlException if an error occurs.
*/
- public void checkOutIn(short type, String identity, long time, boolean backup)
- throws Exception;
+ void checkOut(Node node) throws RevisionControlException;
/**
* get the latest check out
* @return CheckOutEntry The entry of the check out
- * @throws Exception if an error occurs
+ * @throws RevisionControlException if an error occurs
*/
- public CheckOutEntry getLatestCheckOutEntry() throws Exception;
+ CheckOutEntry getLatestCheckOutEntry() throws RevisionControlException;
/**
* get the latest check in
* @return CheckInEntry The entry of the check in
- * @throws Exception if an error occurs
+ * @throws RevisionControlException if an error occurs
*/
- public CheckInEntry getLatestCheckInEntry() throws Exception;
+ CheckInEntry getLatestCheckInEntry() throws RevisionControlException;
/**
* 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
+ * @throws RevisionControlException if an error occurs
*/
- public RCMLEntry getLatestEntry() throws Exception;
+ RCMLEntry getLatestEntry() throws RevisionControlException;
/**
* 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
+ * @throws RevisionControlException if an error occurs
*/
- public Vector getEntries() throws Exception;
+ Vector getEntries() throws RevisionControlException;
/**
* 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;
+ Vector getBackupEntries() throws Exception;
/**
* Creates a backup.
* @param time The time.
* @throws RevisionControlException
*/
- public void makeBackup(long time) throws RevisionControlException;
+ void makeBackup(long time) throws RevisionControlException;
/**
* Restores a backup.
+ * @param node The node to restore the backup to.
* @param time The time.
* @throws RevisionControlException
*/
- public void restoreBackup(long time) throws RevisionControlException;
+ void restoreBackup(Node node, long time) throws RevisionControlException;
/**
* Prune the list of entries and delete the corresponding backups. Limit the number of entries
* to the value maximalNumberOfEntries (2maxNumberOfRollbacks(configured)+1)
* @throws Exception if an error occurs
*/
- 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;
+ void pruneEntries() throws Exception;
/**
* Check if the document is dirty
* @return boolean dirty
*/
- public boolean isDirty();
+ boolean isDirty();
/**
* Delete the latest check in
* @throws Exception if an error occurs
*/
- public void deleteFirstCheckIn() throws Exception;
+ void deleteFirstCheckIn() throws Exception;
/**
* Delete the latest check in
* @throws Exception if an error occurs
*/
- public void deleteFirstCheckOut() throws Exception;
+ 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;
+ String[] getBackupsTime() throws Exception;
/**
- * delete the rcml file and the directory if this one is empty
+ * delete the RCML file and the directory if this one is empty
* @return boolean true, if the file was deleted
*/
- public boolean delete();
+ boolean delete();
/**
* Delete all revisions.
@@ -158,8 +152,22 @@
void deleteRevisions() throws RevisionControlException;
/**
- * @param other The RCML to copy the entries from.
+ * @param node The target node.
+ * @param otherNode The source node.
+ * @throws RevisionControlException if an error occurs.
+ */
+ void copyFrom(Node node, Node otherNode) throws RevisionControlException;
+
+ /**
+ * @return if the RCML is checked out.
+ * @throws RevisionControlException if an error occurs.
+ */
+ boolean isCheckedOut() throws RevisionControlException;
+
+ /**
+ * @param session The session.
+ * @return if the RCML is checked out by this session.
* @throws RevisionControlException if an error occurs.
*/
- void copyFrom(RCML other) throws RevisionControlException;
+ boolean isCheckedOutBySession(Session session) throws RevisionControlException;
}
Modified: lenya/trunk/src/java/org/apache/lenya/cms/rc/RCMLEntry.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/rc/RCMLEntry.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/rc/RCMLEntry.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/rc/RCMLEntry.java Thu Aug 9 09:28:15 2007
@@ -28,15 +28,18 @@
private String identity = null;
private long time = 0;
private short type = 0;
+ private String sessionId;
/**
* Creates a new RCMLEntry object.
+ * @param sessionId The session ID.
* @param _identity The identity of the person for this RCML
* @param _time The time of the checkin / checkout
*/
- public RCMLEntry(String _identity, long _time) {
+ public RCMLEntry(String sessionId, String _identity, long _time) {
this.identity = _identity;
this.time = _time;
+ this.sessionId = sessionId;
}
/**
@@ -74,6 +77,10 @@
*/
protected void setType(short s) {
this.type = s;
+ }
+
+ public String getSessionId() {
+ return this.sessionId;
}
}
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=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/rc/RevisionController.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/rc/RevisionController.java Thu Aug 9 09:28:15 2007
@@ -20,8 +20,6 @@
package org.apache.lenya.cms.rc;
-import java.util.Date;
-
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.lenya.cms.repository.Node;
@@ -66,35 +64,6 @@
}
/**
- * Try to make a reserved check out of the file source for a user with
- * identity
- *
- * @param node The node to check out
- * @param identity The identity of the user
- * @throws Exception if an error occurs
- */
- public void reservedCheckOut(Node node, String identity) throws Exception {
-
- RCML rcml = node.getRcml();
-
- RCMLEntry entry = rcml.getLatestEntry();
- if (entry != null && entry.getType() == RCML.co) {
-
- // don't check out twice
- if (entry.getIdentity().equals(identity)) {
- return;
- }
-
- // checked out by somebody else
- else {
- throw new FileReservedCheckOutException(node.getSourceURI(), rcml);
- }
- }
-
- rcml.checkOutIn(RCML.co, identity, new Date().getTime(), false);
- }
-
- /**
* Checks if a source can be checked out.
* @param node The node.
* @param identity The identity who requests checking out.
@@ -111,118 +80,9 @@
}
/**
- * @param node A node.
- * @return If the node is checked out.
- * @throws Exception if an error occurs.
- */
- public boolean isCheckedOut(Node node) throws Exception {
- RCML rcml = node.getRcml();
- RCMLEntry entry = rcml.getLatestEntry();
- return entry != null && entry.getType() == RCML.co;
- }
-
- /**
- * Try to make a reserved check in of the file destination for a user with
- * identity. A backup copy can be made.
- *
- * @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.
- *
- * @return long The time.
- *
- * @exception FileReservedCheckInException if the document couldn't be
- * checked in (for instance because it is already checked out by
- * someone other ...)
- * @exception Exception if other problems occur
- */
- public long reservedCheckIn(Node node, String identity, boolean backup, boolean newVersion)
- throws FileReservedCheckInException, Exception {
-
- RCML rcml;
- long time = new Date().getTime();
-
- rcml = node.getRcml();
-
- CheckOutEntry coe = rcml.getLatestCheckOutEntry();
- CheckInEntry cie = rcml.getLatestCheckInEntry();
-
- // 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);
- }
- } else {
- // Case 2
- if (!coe.getIdentity().equals(identity)) {
- // Case 2.2., abort...
- //
- throw new FileReservedCheckInException(node.getSourceURI(), rcml);
- }
- }
- }
-
- if (backup) {
- rcml.makeBackup(time);
- }
-
- if (newVersion) {
- rcml.checkOutIn(RCML.ci, identity, time, backup);
- } else {
- rcml.deleteFirstCheckOut();
- }
- rcml.pruneEntries();
- rcml.write();
-
- return time;
- }
-
- /**
- * Rolls back to the given point in time.
- * @param node The node which will be rolled back
- * before the rollback
- * @param time The time point of the desired version
- * @exception Exception if a problem occurs
- */
- public void rollback(Node node, long time)
- throws Exception {
- node.getRcml().restoreBackup(time);
- }
-
- /**
* delete the revisions
* @param node of the document
- * @throws RevisionControlException when somthing went wrong
+ * @throws RevisionControlException when something went wrong
*/
public void deleteRevisions(Node node) throws RevisionControlException {
node.getRcml().deleteRevisions();
@@ -252,7 +112,7 @@
* @throws RevisionControlException if an error occurs.
*/
public void copyRCML(Node source, Node destination) throws RevisionControlException {
- destination.getRcml().copyFrom(source.getRcml());
+ destination.getRcml().copyFrom(destination, source);
}
}
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=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/repository/Node.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/repository/Node.java Thu Aug 9 09:28:15 2007
@@ -105,10 +105,10 @@
boolean isCheckedOut() throws RepositoryException;
/**
- * @return if the node is checked out by the current user.
+ * @return if the node is checked out by the current session.
* @throws RepositoryException if an error occurs.
*/
- boolean isCheckedOutByUser() throws RepositoryException;
+ boolean isCheckedOutBySession() throws RepositoryException;
/**
* @return if the node is locked.
Modified: lenya/trunk/src/java/org/apache/lenya/cms/repository/Session.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/repository/Session.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/repository/Session.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/repository/Session.java Thu Aug 9 09:28:15 2007
@@ -84,4 +84,8 @@
*/
boolean isModifiable();
+ /**
+ * @return The ID of this session.
+ */
+ String getId();
}
Modified: lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java Thu Aug 9 09:28:15 2007
@@ -66,19 +66,25 @@
this.manager = manager;
this.identityMap = new IdentityMapImpl(logger);
-
this.identity = identity;
-
+
ObservationRegistry registry = null;
+ UUIDGenerator generator = null;
try {
registry = (ObservationRegistry) this.manager.lookup(ObservationRegistry.ROLE);
addListener(registry);
+
+ generator = (UUIDGenerator) this.manager.lookup(UUIDGenerator.ROLE);
+ this.id = generator.nextUUID();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (registry != null) {
this.manager.release(registry);
}
+ if (generator == null) {
+ this.manager.release(generator);
+ }
}
if (modifiable) {
@@ -232,6 +238,12 @@
public boolean isModifiable() {
return this.unitOfWork != null;
+ }
+
+ private String id;
+
+ public String getId() {
+ return this.id;
}
}
Modified: lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java Thu Aug 9 09:28:15 2007
@@ -44,11 +44,11 @@
*/
public UnitOfWorkImpl(IdentityMap map, Identity identity, Logger logger) {
ContainerUtil.enableLogging(this, logger);
-
+
Assert.notNull(map);
this.identityMap = map;
this.identityMap.setUnitOfWork(this);
-
+
this.identity = identity;
}
@@ -88,66 +88,73 @@
this.removedObjects.add(object);
}
+ private static Object classLock = UnitOfWorkImpl.class;
+
/**
+ * Commit the transaction. We lock this method for the whole class to avoid
+ * synchronization problems.
* @see org.apache.lenya.transaction.UnitOfWork#commit()
*/
- public synchronized void commit() throws TransactionException {
+ public void commit() throws TransactionException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("UnitOfWorkImpl::commit() called");
}
- Set lockedObjects = this.locks.keySet();
+ synchronized (classLock) {
- for (Iterator i = lockedObjects.iterator(); i.hasNext();) {
- Transactionable t = (Transactionable) i.next();
- if (t.hasChanged()) {
- throw new ConcurrentModificationException(t);
+ Set lockedObjects = this.locks.keySet();
+
+ for (Iterator i = lockedObjects.iterator(); i.hasNext();) {
+ Transactionable t = (Transactionable) i.next();
+ if (t.hasChanged()) {
+ throw new ConcurrentModificationException(t);
+ }
}
- }
- Set involvedObjects = new HashSet();
- involvedObjects.addAll(this.newObjects);
- involvedObjects.addAll(this.modifiedObjects);
- involvedObjects.addAll(this.removedObjects);
-
- for (Iterator i = involvedObjects.iterator(); i.hasNext();) {
- Transactionable t = (Transactionable) i.next();
- t.checkout();
- }
+ Set involvedObjects = new HashSet();
+ involvedObjects.addAll(this.newObjects);
+ involvedObjects.addAll(this.modifiedObjects);
+ involvedObjects.addAll(this.removedObjects);
+
+ for (Iterator i = involvedObjects.iterator(); i.hasNext();) {
+ Transactionable t = (Transactionable) i.next();
+ t.checkout();
+ }
- for (Iterator i = this.newObjects.iterator(); i.hasNext();) {
- Transactionable t = (Transactionable) i.next();
- t.createTransactionable();
- t.saveTransactionable();
- }
- for (Iterator i = this.modifiedObjects.iterator(); i.hasNext();) {
- Transactionable t = (Transactionable) i.next();
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("UnitOfWorkImpl::commit() calling save on [" + t + "]");
+ for (Iterator i = this.newObjects.iterator(); i.hasNext();) {
+ Transactionable t = (Transactionable) i.next();
+ t.createTransactionable();
+ t.saveTransactionable();
+ }
+ for (Iterator i = this.modifiedObjects.iterator(); i.hasNext();) {
+ Transactionable t = (Transactionable) i.next();
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("UnitOfWorkImpl::commit() calling save on [" + t + "]");
+ }
+ t.saveTransactionable();
+ }
+ for (Iterator i = this.removedObjects.iterator(); i.hasNext();) {
+ Transactionable t = (Transactionable) i.next();
+ t.deleteTransactionable();
}
- t.saveTransactionable();
- }
- for (Iterator i = this.removedObjects.iterator(); i.hasNext();) {
- Transactionable t = (Transactionable) i.next();
- t.deleteTransactionable();
- }
- if (getIdentityMap() != null) {
- Object[] objects = getIdentityMap().getObjects();
- for (int i = 0; i < objects.length; i++) {
- if (objects[i] instanceof Transactionable) {
- Transactionable t = (Transactionable) objects[i];
- if (t.isCheckedOutByUser() && !this.removedObjects.contains(t)) {
- t.checkin();
- }
- if (t.isLocked()) {
- t.unlock();
+ if (getIdentityMap() != null) {
+ Object[] objects = getIdentityMap().getObjects();
+ for (int i = 0; i < objects.length; i++) {
+ if (objects[i] instanceof Transactionable) {
+ Transactionable t = (Transactionable) objects[i];
+ if (t.isCheckedOutBySession() && !this.removedObjects.contains(t)) {
+ t.checkin();
+ }
+ if (t.isLocked()) {
+ t.unlock();
+ }
}
}
}
+
+ resetTransaction();
}
-
- resetTransaction();
}
@@ -171,27 +178,31 @@
}
/**
+ * Rollback the transaction. We lock this method for the whole class to
+ * avoid synchronization problems.
* @see org.apache.lenya.transaction.UnitOfWork#rollback()
*/
public synchronized void rollback() throws TransactionException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("UnitOfWorkImpl::rollback() called");
}
- if (getIdentityMap() != null) {
- Object[] objects = getIdentityMap().getObjects();
- for (int i = 0; i < objects.length; i++) {
- if (objects[i] instanceof Transactionable) {
- Transactionable t = (Transactionable) objects[i];
- if (t.isCheckedOutByUser()) {
- t.checkin();
- }
- if (t.isLocked()) {
- t.unlock();
+ synchronized (classLock) {
+ if (getIdentityMap() != null) {
+ Object[] objects = getIdentityMap().getObjects();
+ for (int i = 0; i < objects.length; i++) {
+ if (objects[i] instanceof Transactionable) {
+ Transactionable t = (Transactionable) objects[i];
+ if (t.isCheckedOutBySession()) {
+ t.checkin();
+ }
+ if (t.isLocked()) {
+ t.unlock();
+ }
}
}
}
+ resetTransaction();
}
- resetTransaction();
}
private Map locks = new HashMap();
Modified: lenya/trunk/src/java/org/apache/lenya/transaction/Versionable.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/transaction/Versionable.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/transaction/Versionable.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/transaction/Versionable.java Thu Aug 9 09:28:15 2007
@@ -43,10 +43,10 @@
boolean isCheckedOut() throws TransactionException;
/**
- * @return if the object is checked out by the current user.
+ * @return if the object is checked out by the current session.
* @throws TransactionException if an error occurs.
*/
- boolean isCheckedOutByUser() throws TransactionException;
+ boolean isCheckedOutBySession() throws TransactionException;
/**
* Checks if the object has been changed since it has been locked.
Modified: lenya/trunk/src/modules-core/sitemanagement/java/src/org/apache/lenya/cms/site/usecases/Rollback.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/sitemanagement/java/src/org/apache/lenya/cms/site/usecases/Rollback.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/modules-core/sitemanagement/java/src/org/apache/lenya/cms/site/usecases/Rollback.java (original)
+++ lenya/trunk/src/modules-core/sitemanagement/java/src/org/apache/lenya/cms/site/usecases/Rollback.java Thu Aug 9 09:28:15 2007
@@ -18,6 +18,7 @@
package org.apache.lenya.cms.site.usecases;
import org.apache.lenya.cms.publication.Document;
+import org.apache.lenya.cms.repository.Node;
import org.apache.lenya.cms.usecase.DocumentUsecase;
import org.apache.lenya.cms.usecase.UsecaseException;
import org.apache.lenya.cms.workflow.WorkflowUtil;
@@ -55,7 +56,8 @@
Document document = getSourceDocument();
long time = new Long(rollbackTime).longValue();
- document.getRepositoryNode().getRcml().restoreBackup(time);
+ Node node = document.getRepositoryNode();
+ node.getRcml().restoreBackup(node, time);
WorkflowUtil.invoke(this.manager, getSession(), getLogger(), getSourceDocument(),
getEvent());
Modified: lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java?view=diff&rev=564264&r1=564263&r2=564264
==============================================================================
--- lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java (original)
+++ lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java Thu Aug 9 09:28:15 2007
@@ -306,7 +306,7 @@
}
} catch (ConcurrentModificationException e) {
getLogger().error(
- "Could not commit/rollback usecase [" + getName() + "]: " + e.getMessage());
+ "Could not commit usecase [" + getName() + "]: " + e.getMessage());
addErrorMessage(e.getMessage());
} catch (Exception e1) {
getLogger().error("Could not commit/rollback usecase [" + getName() + "]: ", e1);
@@ -761,7 +761,7 @@
"AbstractUsecase::lockInvolvedObjects() locking " + objects[i]);
objects[i].lock();
}
- if (!isOptimistic() && !objects[i].isCheckedOutByUser()) {
+ if (!isOptimistic() && !objects[i].isCheckedOutBySession()) {
objects[i].checkout();
}
}
@@ -774,7 +774,7 @@
boolean canExecute = true;
for (int i = 0; i < objects.length; i++) {
- if (objects[i].isCheckedOut() && !objects[i].isCheckedOutByUser()) {
+ if (objects[i].isCheckedOut() && !objects[i].isCheckedOutBySession()) {
if (getLogger().isDebugEnabled())
getLogger().debug(
"AbstractUsecase::lockInvolvedObjects() can not execute, object ["
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.