Index: xwiki-platform-core/src/test/java/com/xpn/xwiki/doc/XWikiDocumentTest.java
===================================================================
--- xwiki-platform-core/src/test/java/com/xpn/xwiki/doc/XWikiDocumentTest.java (revision 4076)
+++ xwiki-platform-core/src/test/java/com/xpn/xwiki/doc/XWikiDocumentTest.java (working copy)
@@ -94,6 +94,26 @@
assertEquals("Title", this.document.getDisplayTitle(this.context));
}
+ public void testMinorMajorVersions() {
+ // there is no version in doc yet, so 1.1
+ assertEquals("1", this.document.getVersion());
+
+ this.document.setMinorEdit(false);
+ this.document.incrementVersion();
+ // no version => incrementVersion sets 1.1
+ assertEquals("1.1", this.document.getVersion());
+
+ this.document.setMinorEdit(false);
+ this.document.incrementVersion();
+ // increment major version
+ assertEquals("2.1", this.document.getVersion());
+
+ this.document.setMinorEdit(true);
+ this.document.incrementVersion();
+ // increment minor version
+ assertEquals("2.2", this.document.getVersion());
+ }
+
public void testAuthorAfterDocumentCopy() throws XWikiException
{
String author = "Albatross";
Index: xwiki-platform-core/src/test/java/com/xpn/xwiki/doc/XWikiDocumentArchiveTest.java
===================================================================
--- xwiki-platform-core/src/test/java/com/xpn/xwiki/doc/XWikiDocumentArchiveTest.java (revision 4076)
+++ xwiki-platform-core/src/test/java/com/xpn/xwiki/doc/XWikiDocumentArchiveTest.java (working copy)
@@ -19,15 +19,30 @@
*/
package com.xpn.xwiki.doc;
-import junit.framework.TestCase;
+import java.util.Arrays;
+import java.util.Date;
+import org.apache.tools.ant.filters.StringInputStream;
+import org.jmock.cglib.MockObjectTestCase;
+import org.suigeneris.jrcs.rcs.Archive;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+
/**
- * Unit tests for {@link com.xpn.xwiki.doc.XWikiDocumentArchive}.
+ * Unit tests for {@link XWikiDocumentArchive}.
*
* @version $Id: $
*/
-public class XWikiDocumentArchiveTest extends TestCase
+public class XWikiDocumentArchiveTest extends MockObjectTestCase
{
+ private XWikiContext context;
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ this.context = new XWikiContext();
+ }
+
/**
* JRCS uses the user.name system property to set the author of a change. Verify that it
* works if the user name has a space in its name. This used to fail and this test is here to
@@ -37,31 +52,6 @@
*/
public void testUpdateArchiveWhenSpaceInUsername() throws Exception
{
- String originalText = "\"\\n\\n"
- + "\\nKnowledgeBase\\nWebHome\\n"
- + "\\nen\\n0\\n"
- + "Main.Notes\\nXWiki.Admin\\nXWiki.Admin"
- + "\\n\\nXWiki.Admin\\n"
- + "1165874272000\\n1172011434000\\n"
- + "1172011434000\\n1.8\\n"
- + "\\n\\n\\n"
- + "\\n\\n1 Wiki Knowledge Base\\r\\n\\r\\nThis is the "
- + "Wiki Knowledge Base, where you can start writing about your favorite subjects.\\r\\n"
- + "\\r\\nTo create new pages, click edit button and write links using brackets around "
- + "words.\\r\\n\\r\\n* [Example Link 1]\\r\\n* [Example Link 2]\\n"
- + "\\n\"";
-
String originalArchive = "head\t1.1;\n" +
"access;\n" +
"symbols;\n" +
@@ -147,18 +137,95 @@
"* [Example Link 2]\n" +
"\n" +
"@";
-
+
XWikiDocumentArchive archive = new XWikiDocumentArchive(123456789L);
archive.setArchive(originalArchive);
-
+
// Set a username with a space
System.setProperty("user.name", "Vincent Massol");
+
+ XWikiDocument doc = new XWikiDocument("KnowledgeBase", "WebHome");
+ doc.setContent(doc.getContent() + "\nsomething added");
+ archive.updateArchive("XWiki.XWikiGuest", new Date(), "some comment", false, doc, context);
- archive.updateArchive("Main.WebHome", originalText);
-
// Try to construct again the archive from the last modification. This will happen when
// XWiki loads a document from the database for example. We verify here that a username
// with a space works.
- new XWikiDocumentArchive(123456789L).setArchive(archive.getArchive());
+ new XWikiDocumentArchive(123456789L).setArchive(archive.getArchive(context));
}
+
+ public void testUpdateLoad() throws XWikiException {
+ XWikiDocument doc = new XWikiDocument("Test", "Test");
+ doc.setContent("content 1.1");
+
+ XWikiContext context = new XWikiContext();
+
+ XWikiDocumentArchive archive = new XWikiDocumentArchive(doc.getId());
+ assertEquals(0, archive.getNodes().size());
+
+ String author = "XWiki.some author";
+ archive.updateArchive(author, new Date(), "initial, 1.1", false, doc, context);
+ String archive11 = archive.getArchive(context);
+ assertEquals(1, archive.getNodes().size());
+ assertEquals(1, archive.getUpdeteNodeInfos().size());
+ assertEquals(1, archive.getUpdeteNodeContents().size());
+
+ XWikiDocumentArchive archive2 = new XWikiDocumentArchive(doc.getId());
+ archive2.setArchive(archive11);
+ assertEquals(archive11, archive2.getArchive(context));
+ assertEquals(1, archive2.getNodes().size());
+ assertEquals(1, archive2.getUpdeteNodeInfos().size());
+ assertEquals(1, archive2.getUpdeteNodeContents().size());
+
+ doc.setContent("content\n1.2");
+ archive.updateArchive(author, new Date(), "1.2", true, doc, context);
+ String archive12 = archive.getArchive(context);
+ assertEquals(2, archive.getNodes().size());
+ assertEquals(2, archive.getUpdeteNodeInfos().size());
+ assertEquals(2, archive.getUpdeteNodeContents().size());
+
+ XWikiDocumentArchive archive3 = new XWikiDocumentArchive(doc.getId());
+ archive3.setArchive(archive12);
+ assertEquals(2, archive3.getNodes().size());
+ assertEquals(2, archive3.getUpdeteNodeInfos().size());
+ assertEquals(2, archive3.getUpdeteNodeContents().size());
+
+ doc.setContent("major change\ncontent\n2.1");
+ archive.updateArchive(author, new Date(), "2.1", false, doc, context);
+ assertEquals(3, archive.getNodes().size());
+ assertEquals(3, archive.getUpdeteNodeInfos().size());
+ assertEquals(3, archive.getUpdeteNodeContents().size());
+ }
+
+ public void testRemoveVersions() throws XWikiException {
+ XWikiContext context = new XWikiContext();
+
+ XWikiDocument doc = new XWikiDocument("Test", "Test");
+ XWikiDocumentArchive archive = new XWikiDocumentArchive(doc.getId());
+ doc.setDocumentArchive(archive);
+ String author = "XWiki.some author";
+
+ doc.setContent("content 1.1");
+ archive.updateArchive(author, new Date(), "initial, 1.1", false, doc, context);
+ XWikiDocument doc11 = (XWikiDocument) doc.clone();
+
+ doc.setContent("content 2.1\nqwe");
+ archive.updateArchive(author, new Date(), "2.1", false, doc, context);
+
+ doc.setContent("content 2.2\nqweq");
+ archive.updateArchive(author, new Date(), "2.2", true, doc, context);
+
+ doc.setContent("content 2.3\nqweqe");
+ archive.updateArchive(author, new Date(), "2.3", true, doc, context);
+
+ /* TODO: need many mocking
+ archive.removeVersions(new Version(2,1), new Version(2,2), doc, context);
+
+ assertEquals(2, archive.getNodes().size());
+ assertEquals(2, archive.getDeleteNodeInfo().size());
+ assertNull(archive.getNode(new Version(2,1)));
+ assertNull(archive.getNode(new Version(2,2)));
+
+ assertEquals(doc11, archive.loadDocument(doc, new Version(1,1), context));*/
+ }
}
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java (working copy)
@@ -32,7 +32,6 @@
import java.util.Map;
import java.util.Iterator;
import java.lang.reflect.Proxy;
-import java.lang.reflect.InvocationHandler;
public class XWikiHibernateBaseStore {
private static final Log log = LogFactory.getLog(XWikiHibernateBaseStore.class);
@@ -789,4 +788,51 @@
"";
return custommapping;
}
+
+ /** spring-jcr like Callback interface for working in hibernate */
+ public interface HibernateCallBack {
+ Object doInHibernate(Session session) throws Exception;
+ }
+
+ /** spring-jcr like execute method for operations in hibernate
+ * @throws XWikiException */
+ public Object execute(XWikiContext context, boolean bTransaction, boolean doCommit, HibernateCallBack cb) throws XWikiException {
+ MonitorPlugin monitor = Util.getMonitorPlugin(context);
+ try {
+ // Start monitoring timer
+ if (monitor!=null)
+ monitor.startTimer("hibernate");
+
+ if (bTransaction) {
+ checkHibernate(context);
+ bTransaction = beginTransaction(context);
+ }
+
+ return cb.doInHibernate(getSession(context));
+ } catch (Exception e) {
+ if (e instanceof XWikiException)
+ throw (XWikiException)e;
+ throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_UNKNOWN,
+ "Exception while hibernate execute", e);
+ } finally {
+ try {
+ if (bTransaction)
+ endTransaction(context, doCommit);
+ if (monitor!=null)
+ monitor.endTimer("hibernate");
+ } catch (Exception e) {}
+ }
+ }
+
+ /** spring-jcr like execute method for read-only operations in hibernate
+ * @throws XWikiException */
+ public Object executeRead(XWikiContext context, boolean bTransaction, HibernateCallBack cb) throws XWikiException {
+ return execute(context, bTransaction, false, cb);
+ }
+
+ /** spring-jcr like execute method for write operations in hibernate
+ * @throws XWikiException */
+ public Object executeWrite(XWikiContext context, boolean bTransaction, HibernateCallBack cb) throws XWikiException {
+ return execute(context, bTransaction, true, cb);
+ }
}
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java (working copy)
@@ -26,6 +26,7 @@
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiLink;
import com.xpn.xwiki.doc.XWikiLock;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;
import com.xpn.xwiki.monitor.api.MonitorPlugin;
import com.xpn.xwiki.objects.*;
import com.xpn.xwiki.objects.classes.BaseClass;
@@ -235,7 +236,7 @@
}
doc.incrementVersion();
if (context.getWiki().hasVersioning(doc.getFullName(), context))
- context.getWiki().getVersioningStore().updateXWikiDocArchive(doc, doc.toXML(context), false, context);
+ context.getWiki().getVersioningStore().updateXWikiDocArchive(doc, false, context);
doc.setContentDirty(false);
doc.setMetaDataDirty(false);
@@ -531,7 +532,11 @@
deleteXWikiObject(obj, context, false);
}
}
-
+ // Delete history
+ session.createQuery("delete from "+XWikiRCSNodeInfo.class.getName()+" where id.docId=?")
+ .setLong(0, doc.getId())
+ .executeUpdate();
+
session.delete(doc);
// We need to ensure that the deleted document becomes the original document
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/store/XWikiVersioningStoreInterface.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/store/XWikiVersioningStoreInterface.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/store/XWikiVersioningStoreInterface.java (working copy)
@@ -1,18 +1,25 @@
package com.xpn.xwiki.store;
+import org.suigeneris.jrcs.rcs.Version;
+
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiDocumentArchive;
-import org.suigeneris.jrcs.rcs.Version;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeContent;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeId;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;
public interface XWikiVersioningStoreInterface {
public void loadXWikiDocArchive(XWikiDocumentArchive archivedoc, boolean bTransaction, XWikiContext context) throws XWikiException;
public void saveXWikiDocArchive(XWikiDocumentArchive archivedoc, boolean bTransaction, XWikiContext context) throws XWikiException;
- public void updateXWikiDocArchive(XWikiDocument doc, String text, boolean bTransaction, XWikiContext context) throws XWikiException;
+ public void updateXWikiDocArchive(XWikiDocument doc, boolean bTransaction, XWikiContext context) throws XWikiException;
public Version[] getXWikiDocVersions(XWikiDocument doc, XWikiContext context) throws XWikiException;
- // public Archive getXWikiDocRCSArchive(XWikiDocument doc, XWikiContext context) throws XWikiException;
public XWikiDocument loadXWikiDoc(XWikiDocument doc, String version, XWikiContext context) throws XWikiException;
public void resetRCSArchive(XWikiDocument doc, boolean bTransaction, XWikiContext context) throws XWikiException;
public XWikiDocumentArchive getXWikiDocumentArchive(XWikiDocument doc, XWikiContext context) throws XWikiException;
+ /**
+ * Load {@link XWikiRCSNodeContent} by demand. Used in {@link XWikiRCSNodeInfo#getContent(XWikiContext)}
+ */
+ public XWikiRCSNodeContent loadRCSNodeContent(XWikiContext context, XWikiRCSNodeId id, boolean bTransaction) throws XWikiException;
}
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/store/jcr/XWikiJcrPropertyVersioningStore.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/store/jcr/XWikiJcrPropertyVersioningStore.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/store/jcr/XWikiJcrPropertyVersioningStore.java (working copy)
@@ -1,34 +1,38 @@
package com.xpn.xwiki.store.jcr;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+
+import org.suigeneris.jrcs.rcs.Version;
+
import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiDocumentArchive;
-import com.xpn.xwiki.monitor.api.MonitorPlugin;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeContent;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeId;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;
import com.xpn.xwiki.store.XWikiVersioningStoreInterface;
-import com.xpn.xwiki.util.Util;
-import org.suigeneris.jrcs.rcs.Archive;
-import org.suigeneris.jrcs.rcs.Version;
-import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.Property;
-import java.lang.reflect.InvocationTargetException;
-
/** Versions store in jcr property '@archive' of xwiki:document */
public class XWikiJcrPropertyVersioningStore extends XWikiJcrBaseStore implements XWikiVersioningStoreInterface {
public XWikiJcrPropertyVersioningStore(XWiki xwiki, XWikiContext context) throws SecurityException, NoSuchMethodException, ClassNotFoundException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
super(xwiki, context);
}
- public void saveXWikiDocArchive(final XWikiDocumentArchive archivedoc, boolean bTransaction, XWikiContext context) throws XWikiException {
+ public void saveXWikiDocArchive(final XWikiDocumentArchive archivedoc, boolean bTransaction, final XWikiContext context) throws XWikiException {
try {
executeWrite(context, new JcrCallBack() {
public Object doInJcr(XWikiJcrSession session) throws Exception {
Node docNode = getDocNodeById(session, archivedoc.getId());
if (docNode==null) return null;
- String s = archivedoc.getArchive();
+ String s = archivedoc.getArchive(context);
docNode.setProperty("archive", s);
session.save();
return null;
@@ -62,12 +66,14 @@
}
// From XWikiHibernateVersioningStore:
-
public void resetRCSArchive(XWikiDocument doc, boolean bTransaction, XWikiContext context) throws XWikiException {
try {
XWikiDocumentArchive archivedoc = new XWikiDocumentArchive(doc.getId());
loadXWikiDocArchive(archivedoc, bTransaction, context);
- archivedoc.resetArchive(doc.getFullName(), doc.getContent(), doc.getVersion());
+ archivedoc.resetArchive();
+ archivedoc.getDeleteNodeInfo().clear();
+ doc.setMinorEdit(false);
+ updateXWikiDocArchive(doc, false, context);
saveXWikiDocArchive(archivedoc, bTransaction, context);
} catch (Exception e) {
Object[] args = { doc.getFullName() };
@@ -78,10 +84,10 @@
- public void updateXWikiDocArchive(XWikiDocument doc, String text, boolean bTransaction, XWikiContext context) throws XWikiException {
+ public void updateXWikiDocArchive(XWikiDocument doc, boolean bTransaction, XWikiContext context) throws XWikiException {
try {
XWikiDocumentArchive archivedoc = getXWikiDocumentArchive(doc, context);
- archivedoc.updateArchive(doc.getFullName(), text);
+ archivedoc.updateArchive(doc.getContentAuthor(), doc.getDate(), doc.getComment(), doc.isMinorEdit(), doc, context);
saveXWikiDocArchive(archivedoc, bTransaction, context);
} catch (Exception e) {
Object[] args = { doc.getFullName() };
@@ -91,6 +97,8 @@
}
public XWikiDocument loadXWikiDoc(XWikiDocument basedoc, String version, XWikiContext context) throws XWikiException {
+ return null;
+ /* TODO: it will be rewrited
XWikiDocument doc = new XWikiDocument(basedoc.getSpace(), basedoc.getName());
doc.setDatabase(basedoc.getDatabase());
MonitorPlugin monitor = Util.getMonitorPlugin(context);
@@ -139,20 +147,21 @@
if (monitor!=null)
monitor.endTimer("jcr");
}
- return doc;
+ return doc;*/
}
public Version[] getXWikiDocVersions(XWikiDocument doc, XWikiContext context) throws XWikiException {
try {
- Archive archive = getXWikiDocumentArchive(doc, context).getRCSArchive();
+ XWikiDocumentArchive archive = getXWikiDocumentArchive(doc, context);
if (archive==null)
return new Version[0];
-
- org.suigeneris.jrcs.rcs.Node[] nodes = archive.changeLog();
- Version[] versions = new Version[nodes.length];
- for (int i=0;i 0) {
+ for (Iterator it = nodeInfos.iterator(); it.hasNext();) {
+ XWikiRCSNodeInfo nodeinfo = (XWikiRCSNodeInfo) it.next();
+ XWikiJRCSNode node = new XWikiJRCSNode(nodeinfo.getId().getVersion(), null);
+ node.setAuthor(nodeinfo.getAuthor());
+ node.setDate(nodeinfo.getDate());
+ node.setLog(nodeinfo.getComment());
+ node.setDiff(nodeinfo.isDiff());
+ XWikiRCSNodeContent content = nodeinfo.getContent(context);
+ node.setText(content.getPatch().getContent());
+ nodes.put(node.getVersion(), node);
+ }
+ XWikiJRCSNode last = null;
+ for (Iterator it = nodes.keySet().iterator(); it.hasNext();) {
+ Version ver = (Version) it.next();
+ XWikiJRCSNode node = (XWikiJRCSNode) nodes.get(ver);
+ if (last != null) {
+ last.setRCSNext(node);
+ }
+ last = node;
+ if (head == null) {
+ head = node;
+ }
+ }
+ }
+ }
+ /**
+ * Used to deserialize {@link XWikiDocumentArchive}.
+ * @param archivetext - archive text in JRCS format
+ * @throws ParseException if syntax errors
+ */
+ public XWikiRCSArchive(String archivetext) throws ParseException
+ {
+ super("", new StringInputStream(archivetext));
+ }
+ /**
+ * Helper class for convert from {@link XWikiRCSNodeInfo} to JRCS {@link Node}.
+ */
+ private static class XWikiJRCSNode extends TrunkNode
+ {
+ /** bug if author=="". */
+ public static String sauthorIfEmpty = "_";
+ /** mark that node contains not patch. */
+ public static String sfullVersion = "full";
+ /**
+ * @param vernum - version of node
+ * @param next - next node (with smaller version) in history
+ * @throws InvalidTrunkVersionNumberException if version is invalid
+ */
+ public XWikiJRCSNode(Version vernum, TrunkNode next)
+ throws InvalidTrunkVersionNumberException
+ {
+ super(vernum, next);
+ }
+ /** @param other - create class from copying this node */
+ public XWikiJRCSNode(Node other)
+ {
+ this(other.version, null);
+ this.date = other.getDate();
+ this.author = other.getAuthor();
+ this.state = other.getState();
+ this.log = other.getLog();
+ this.locker = other.getLocker();
+ this.setText(other.getText());
+ }
+ /** @param date - date of modification */
+ public void setDate(Date date) {
+ this.date = date;
+ }
+ /** {@inheritDoc} */
+ public void setAuthor(String user)
+ {
+ //
+ if (user == null || "".equals(user)) {
+ super.setAuthor(sauthorIfEmpty);
+ } else {
+ super.setAuthor(user);
+ }
+ }
+ /** @return is this node store diff or full version */
+ public boolean isDiff() {
+ // we need something filed in Node. locker is free
+ return !sfullVersion.equals(getState());
+ }
+ /** @param isdiff - true if node stores a diff, false - if full version */
+ public void setDiff(boolean isdiff) {
+ setState(isdiff ? "diff" : sfullVersion);
+ }
+ }
+
+ /**
+ * @return Collection of pairs [{@link XWikiRCSNodeInfo}, {@link XWikiRCSNodeContent}]
+ * @param docId - docId which will be wrote in {@link XWikiRCSNodeId#setDocId(long)}
+ */
+ public Collection getNodes(long docId) {
+ Collection result = new ArrayList(nodes.values().size());
+ for (Iterator it = nodes.values().iterator(); it.hasNext();) {
+ XWikiJRCSNode node = new XWikiJRCSNode((Node) it.next());
+ XWikiRCSNodeInfo nodeinfo = new XWikiRCSNodeInfo();
+ nodeinfo.setId(new XWikiRCSNodeId(docId, node.getVersion()));
+ nodeinfo.setAuthor(XWikiJRCSNode.sauthorIfEmpty.equals(node.getAuthor())
+ ? "" : node.getAuthor());
+ nodeinfo.setComment(node.getLog());
+ nodeinfo.setDate(node.getDate());
+ nodeinfo.setDiff(node.isDiff());
+ XWikiRCSNodeContent content = new XWikiRCSNodeContent(nodeinfo.getId());
+ content.setPatch(new XWikiPatch(ToString.arrayToString(node.getText()), node.isDiff()));
+ nodeinfo.setContent(content);
+ result.add(nodeinfo);
+ result.add(content);
+ }
+ // ensure latest version is full
+ ((XWikiRCSNodeInfo) result.iterator().next()).setDiff(false);
+ return result;
+ }
+}
Property changes on: xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSArchive.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSNodeId.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSNodeId.java (revision 0)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSNodeId.java (revision 0)
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+package com.xpn.xwiki.doc.rcs;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.suigeneris.jrcs.rcs.Version;
+
+/**
+ * Composite ID component used in {@link XWikiRCSNodeInfo} & {@link XWikiRCSNodeContent}.
+ * Mutable.
+ * @version $Id: $
+ */
+public class XWikiRCSNodeId implements Serializable, Cloneable
+{
+ // composite-key
+ /**
+ * = {@link XWikiDocument#getId()}.
+ * part of composite key
+ */
+ private long docId;
+ /**
+ * version of document.
+ * part of composite key
+ */
+ private Version version = new Version(1, 1);
+
+ /**
+ * default constructor used in Hibernate to load this class.
+ */
+ public XWikiRCSNodeId() { }
+
+ /**
+ * @param docId = {@link XWikiDocument#getId()}
+ * @param version - version of document
+ */
+ public XWikiRCSNodeId(long docId, Version version)
+ {
+ super();
+ this.docId = docId;
+ this.version = version;
+ }
+
+ /*/**
+ * Clone-constructor.
+ * @param node - clone from what node
+ *
+ public XWikiRCSNodeId(XWikiRCSNodeId node)
+ {
+ this(node.getDocId(), node.getVersion());
+ }*/
+
+ /**
+ * @return {@link XWikiDocument#getId()}
+ */
+ public long getDocId()
+ {
+ return docId;
+ }
+
+ /**
+ * @param docId = {@link XWikiDocument#getId()}
+ */
+ public void setDocId(long docId)
+ {
+ this.docId = docId;
+ }
+
+ /**
+ * @return version of document
+ */
+ public Version getVersion()
+ {
+ return version;
+ }
+ /**
+ * @return 1st number in version
+ * used in Hibernate to store this class
+ */
+ protected int getVersion1()
+ {
+ return version.at(0);
+ }
+ /**
+ * @return 2nd number in version
+ * used in Hibernate to store this class
+ */
+ protected int getVersion2()
+ {
+ return version.at(1);
+ }
+ /**
+ * @param ver - version of document
+ */
+ public void setVersion(Version ver)
+ {
+ this.version = ver;
+ }
+ /**
+ * @param v1 = 1st number in version
+ * used in Hibernate to load this class
+ */
+ protected void setVersion1(int v1)
+ {
+ this.version = new Version(v1, version.at(1));
+ }
+ /**
+ * @param v2 = 2nd number in version
+ * used in Hibernate to load this class
+ */
+ protected void setVersion2(int v2)
+ {
+ this.version = new Version(version.at(0), v2);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int hashCode()
+ {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean equals(Object obj)
+ {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws CloneNotSupportedException
+ */
+ public Object clone()
+ {
+ try {
+ // there are no mutable fields, so simple do super.clone()
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ // clone is supported. exception is nonsense.
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString()
+ {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
Property changes on: xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSNodeId.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatch.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatch.java (revision 0)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatch.java (revision 0)
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+package com.xpn.xwiki.doc.rcs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.suigeneris.jrcs.util.ToString;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+/**
+ * Contains differences between revisions.
+ * One field (diff for xml or full xml) for now.
+ * Created for easy migrate to future XWikiPatch system
+ * @version $Id: $
+ */
+public class XWikiPatch
+{
+ /** string serialization for patch. */
+ private String content;
+ /** is content a difference, or full version. */
+ private boolean isDiff;
+ /** Default constructor, need for hibernate. */
+ public XWikiPatch() { }
+ /**
+ * @param content - patch content
+ * @param isDiff - is patch a difference or full version
+ */
+ public XWikiPatch(String content, boolean isDiff)
+ {
+ setContent(content);
+ setDiff(isDiff);
+ }
+ /**
+ * @return string serialization for patch
+ */
+ public String getContent()
+ {
+ return content;
+ }
+ /**
+ * @param content - string serialization for patch
+ */
+ public void setContent(String content)
+ {
+ this.content = content;
+ }
+ /**
+ * @return is content a difference, or full version
+ */
+ public boolean isDiff()
+ {
+ return isDiff;
+ }
+ /**
+ * @param isDiff - is content a difference, or full version
+ */
+ public void setDiff(boolean isDiff)
+ {
+ this.isDiff = isDiff;
+ }
+ /**
+ * Create full patch for document.
+ * @param doc - document to patch
+ * @param context - used for serialization document to xml
+ * @return self
+ * @throws XWikiException if any error
+ */
+ public XWikiPatch setFullVersion(XWikiDocument doc, XWikiContext context) throws XWikiException
+ {
+ setDiff(false);
+ setContent(doc.toXML(context));
+ return this;
+ }
+ /**
+ * Create difference patch for document curdoc, using origdoc as previous version.
+ * @param curdoc - current document
+ * @param origdoc - original document
+ * @param context - used for serialization documents to xml
+ * @return self
+ * @throws XWikiException if any error
+ */
+ public XWikiPatch setDiffVersion(XWikiDocument curdoc, XWikiDocument origdoc,
+ XWikiContext context) throws XWikiException
+ {
+ return setDiffVersion(curdoc, origdoc.toXML(context), context);
+ }
+ /**
+ * Create difference patch for document curdoc, using origdoc as previous version.
+ * @param curdoc - current document
+ * @param origdocxml - xml of original document
+ * @param context - used for serialization document to xml
+ * @return self
+ * @throws XWikiException if any error
+ */
+ public XWikiPatch setDiffVersion(XWikiDocument curdoc, String origdocxml,
+ XWikiContext context) throws XWikiException
+ {
+ setDiff(true);
+ try {
+ setContent(XWikiPatchUtils.getDiff(curdoc.toXML(context), origdocxml));
+ } catch (Exception e) {
+ Object[] args = {curdoc.getFullName()};
+ throw new XWikiException(XWikiException.MODULE_XWIKI_DIFF,
+ XWikiException.ERROR_XWIKI_DIFF_XML_ERROR,
+ "Failed to create diff for doc {}", e, args);
+ }
+ return this;
+ }
+ /**
+ * patch text.
+ * @param origtext - text to patch
+ * @throws XWikiException if exception while patching
+ */
+ public void patch(List origtext) throws XWikiException
+ {
+ if (!isDiff()) {
+ origtext.clear();
+ origtext.addAll(new ArrayList(Arrays.asList(ToString.stringToArray(getContent()))));
+ } else {
+ try {
+ XWikiPatchUtils.patch(origtext, getContent());
+ } catch (Exception e) {
+ throw new XWikiException(XWikiException.MODULE_XWIKI_DIFF,
+ XWikiException.ERROR_XWIKI_DIFF_XML_ERROR, "Exception while patching", e);
+ }
+ }
+ }
+}
Property changes on: xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatch.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatchUtils.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatchUtils.java (revision 0)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatchUtils.java (revision 0)
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+package com.xpn.xwiki.doc.rcs;
+
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.suigeneris.jrcs.diff.Diff;
+import org.suigeneris.jrcs.diff.DifferentiationFailedException;
+import org.suigeneris.jrcs.diff.PatchFailedException;
+import org.suigeneris.jrcs.diff.Revision;
+import org.suigeneris.jrcs.diff.delta.AddDelta;
+import org.suigeneris.jrcs.diff.delta.Chunk;
+import org.suigeneris.jrcs.diff.delta.DeleteDelta;
+import org.suigeneris.jrcs.rcs.InvalidFileFormatException;
+import org.suigeneris.jrcs.rcs.impl.Node;
+import org.suigeneris.jrcs.util.ToString;
+
+/**
+ * diff & patch utility.
+ * @version $Id: $
+ */
+public class XWikiPatchUtils
+{
+ /** prevent to create utility class. */
+ private XWikiPatchUtils() { }
+ /**
+ * @param orig - original text
+ * @param rev - new text
+ * @return diff in JRCS format
+ * @throws DifferentiationFailedException if error when creating diff
+ */
+ public static String getDiff(Object[] orig, Object[] rev) throws DifferentiationFailedException
+ {
+ return Diff.diff(orig, rev).toRCSString();
+ }
+ /**
+ * @param orig - original text
+ * @param rev - new text
+ * @return diff in JRCS format
+ * @throws DifferentiationFailedException if error when creating diff
+ */
+ public static String getDiff(String orig, String rev) throws DifferentiationFailedException {
+ return getDiff(ToString.stringToArray(orig), ToString.stringToArray(rev));
+ }
+
+ /**
+ * From {@link Node#patch(List, boolean)}.
+ * @param orig - text to patch, List<String> of lines.
+ * @param diff - diff to patch, {@link Diff} format
+ * @throws InvalidFileFormatException if diff is incorrect
+ * @throws PatchFailedException if error in patching
+ */
+ public static void patch(List orig, String diff)
+ throws InvalidFileFormatException, PatchFailedException
+ {
+ Revision revision = new Revision();
+ Object[] lines = ToString.stringToArray(diff);
+ for (int it = 0; it < lines.length; it++) {
+ String cmd = lines[it].toString();
+ if (cmd.length()==0)
+ break;
+
+ java.util.StringTokenizer t = new StringTokenizer(cmd, "ad ", true);
+ char action;
+ int n;
+ int count;
+
+ try {
+ action = t.nextToken().charAt(0);
+ n = Integer.parseInt(t.nextToken());
+ // skip the space
+ t.nextToken();
+ count = Integer.parseInt(t.nextToken());
+ } catch (Exception e) {
+ throw new InvalidFileFormatException("line:" + ":" + e.getClass().getName(),
+ e);
+ }
+
+ if (action == 'd') {
+ revision.addDelta(new DeleteDelta(new Chunk(n - 1, count)));
+ } else if (action == 'a') {
+ revision.addDelta(new AddDelta(n, new Chunk(getTextLines(lines,
+ it + 1, it + 1 + count), 0, count, n - 1)));
+ it += count;
+ } else {
+ throw new InvalidFileFormatException();
+ }
+ }
+ revision.applyTo(orig);
+ }
+ /**
+ * @param lines - some text
+ * @param from - from that line
+ * @param to - to that line
+ * @return selected lines of text
+ */
+ private static Object[] getTextLines(Object[] lines, int from, int to)
+ {
+ Object[] ret = new Object[to-from+1];
+ for (int i=from; i0) {
+ setRCSVersion(xda.getLatestVersion());
+ XWikiRCSNodeInfo nodeinfo = xda.getLatestNode();
+ setComment(nodeinfo.getComment());
+ setMinorEdit(nodeinfo.isMinorEdit());
+ setAuthor(nodeinfo.getAuthor());
+ setDate(nodeinfo.getDate());
+ }
setDocumentArchive(xda);
}
@@ -898,6 +918,11 @@
}
}
+ public XWikiRCSNodeInfo getRevisionInfo(String version, XWikiContext context) throws XWikiException
+ {
+ return getDocumentArchive(context).getNode(new Version(version));
+ }
+
public boolean isMostRecent()
{
return mostRecent;
@@ -1563,7 +1588,10 @@
if (comment != null) {
setComment(comment);
}
-
+
+ // Read the minor edit checkbox from the form
+ setMinorEdit(eform.isMinorEdit());
+
String tags = eform.getTags();
if (tags != null) {
setTags(tags, context);
@@ -1779,6 +1807,7 @@
setxWikiClass((BaseClass) document.getxWikiClass().clone());
setxWikiClassXML(document.getxWikiClassXML());
setComment(document.getComment());
+ setMinorEdit(document.isMinorEdit());
clonexWikiObjects(document);
copyAttachments(document);
@@ -1828,6 +1857,7 @@
doc.setxWikiClass((BaseClass) getxWikiClass().clone());
doc.setxWikiClassXML(getxWikiClassXML());
doc.setComment(getComment());
+ doc.setMinorEdit(isMinorEdit());
doc.clonexWikiObjects(this);
doc.copyAttachments(this);
doc.elements = elements;
@@ -1953,6 +1983,10 @@
if (!getComment().equals(doc.getComment())) {
return false;
}
+
+ if (isMinorEdit() == doc.isMinorEdit()) {
+ return false;
+ }
if (!getxWikiClass().equals(doc.getxWikiClass())) {
return false;
@@ -2071,7 +2105,7 @@
Document doc = new DOMDocument();
Element docel = new DOMElement("xwikidoc");
doc.setRootElement(docel);
-
+
Element el = new DOMElement("web");
el.addText(getSpace());
docel.add(el);
@@ -2150,13 +2184,17 @@
el = new DOMElement("comment");
el.addText(getComment());
docel.add(el);
-
+
+ el = new DOMElement("minorEdit");
+ el.addText(String.valueOf(isMinorEdit()));
+ docel.add(el);
+
List alist = getAttachmentList();
for (int ai = 0; ai < alist.size(); ai++) {
XWikiAttachment attach = (XWikiAttachment) alist.get(ai);
docel.add(attach.toXML(bWithAttachmentContent, bWithVersions, context));
}
-
+
if (bWithObjects) {
// Add Class
BaseClass bclass = getxWikiClass();
@@ -2217,7 +2255,7 @@
if (bWithVersions) {
el = new DOMElement("versions");
try {
- el.addText(getDocumentArchive(context).getArchive());
+ el.addText(getDocumentArchive(context).getArchive( context ));
} catch (XWikiException e) {
return null;
}
@@ -2226,7 +2264,7 @@
return doc;
}
-
+
protected String encodedXMLStringAsUTF8(String xmlString)
{
if (xmlString == null) {
@@ -2345,6 +2383,9 @@
setValidationScript(getElement(docel, "validationScript"));
setComment(getElement(docel, "comment"));
+ String minorEdit = getElement(docel, "minorEdit");
+ setMinorEdit(Boolean.valueOf(minorEdit).booleanValue());
+
String strans = getElement(docel, "translation");
if ((strans == null) || strans.equals("")) {
setTranslation(0);
@@ -4056,6 +4097,26 @@
this.comment = comment;
setMetaDataDirty(true);
}
+
+ public boolean isMinorEdit()
+ {
+ return isMinorEdit;
+ }
+ public void setMinorEdit(boolean isMinor)
+ {
+ this.isMinorEdit = isMinor;
+ setMetaDataDirty(true);
+ }
+
+ // methods for easy table update. because default value == null
+ protected Boolean getMinorEdit1()
+ {
+ return Boolean.valueOf(isMinorEdit);
+ }
+ protected void setMinorEdit1(Boolean isMinor)
+ {
+ isMinorEdit = (isMinor!=null && isMinor.booleanValue());
+ }
public BaseObject newObject(String classname, XWikiContext context) throws XWikiException
{
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/XWikiDocumentArchive.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/XWikiDocumentArchive.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/doc/XWikiDocumentArchive.java (working copy)
@@ -1,149 +1,367 @@
+/*
+ * Copyright 2005-2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
package com.xpn.xwiki.doc;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.suigeneris.jrcs.rcs.Version;
+import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.tools.ant.filters.StringInputStream;
-import org.suigeneris.jrcs.rcs.Archive;
-import org.suigeneris.jrcs.util.ToString;
+import com.xpn.xwiki.doc.rcs.XWikiPatch;
+import com.xpn.xwiki.doc.rcs.XWikiRCSArchive;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeContent;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeId;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;
-public class XWikiDocumentArchive {
- private static final Log log = LogFactory.getLog(XWikiDocumentArchive.class);
-
+/**
+ * Contains document history.
+ * Allows to load any version of document.
+ * @version $Id: $
+ */
+public class XWikiDocumentArchive
+{
+ /** =docId. */
private long id;
- private Archive archive;
-
- public XWikiDocumentArchive() {
- }
-
+ /** SortedMap from Version to XWikiRCSNodeInfo. */
+ private SortedMap versionToNode = new TreeMap();
+ /** SortedSet of Version - versions which has full document, not patch.
+ * Latest version is always full. */
+ private SortedSet fullVersions = new TreeSet();
+
+ // store-specific information
+ /** Set of {@link XWikiRCSNodeInfo} which need to delete. */
+ private Set deleteNodes = new TreeSet();
+ /** Set of {@link XWikiRCSNodeInfo} which need to saveOrUpdate. */
+ private Set updateNodeInfos = new TreeSet();
+ /** Set of {@link XWikiRCSNodeContent} which need to update. */
+ private Set updateNodeContents = new TreeSet();
+
+ /** @param id = {@link XWikiDocument#getId()} */
public XWikiDocumentArchive(long id) {
+ this();
setId(id);
}
-
+ /** default constructor. */
+ public XWikiDocumentArchive() { }
+
+ // helper methods
+ /**
+ * @param cur - current version
+ * @param isMinor - is modification is minor
+ * @return next version
+ */
+ protected Version createNextVersion(Version cur, boolean isMinor) {
+ Version result;
+ if (cur == null) {
+ result = new Version(1, 1);
+ } else if (!isMinor) {
+ result = cur.getBase(1).next().newBranch(1);
+ } else {
+ result = cur.next();
+ }
+ return result;
+ }
+ /** @param node - node added to versionToNode and fullNodes */
+ protected void updateNode(XWikiRCSNodeInfo node) {
+ Version ver = node.getId().getVersion();
+ versionToNode.put(ver, node);
+ if (!node.isDiff()) {
+ fullVersions.add(ver);
+ } else {
+ fullVersions.remove(ver);
+ }
+ }
+ /**
+ * @param ver - version of new node
+ * @return new {@link XWikiRCSNodeId} constructing from getId() and ver
+ */
+ protected XWikiRCSNodeId newNodeId(Version ver) {
+ return new XWikiRCSNodeId(getId(), ver);
+ }
+ /**
+ * Make a patch. It is store only modified nodes(latest). New nodes need be saved after.
+ * @param newnode - new node information
+ * @param doc - document for that patch created
+ * @param context - used for loading node contents and generating xml
+ * @return node content for newnode
+ * @throws XWikiException if exception while loading content
+ */
+ protected XWikiRCSNodeContent makePatch(XWikiRCSNodeInfo newnode, XWikiDocument doc,
+ XWikiContext context) throws XWikiException
+ {
+ XWikiRCSNodeContent result = new XWikiRCSNodeContent();
+ result.setPatch(new XWikiPatch().setFullVersion(doc, context));
+ newnode.setContent(result);
+ XWikiRCSNodeInfo latestnode = getLatestNode();
+ if (latestnode != null) {
+ int nodescount = getNodes().size();
+ int nodesperfull = context.getWiki() == null ? 5 : Integer.parseInt(
+ context.getWiki().getConfig().getProperty("xwiki.store.rcs.nodesPerFull", "5"));
+ if (nodesperfull <= 0 || (nodescount % nodesperfull) != 0) {
+ XWikiRCSNodeContent latestcontent = latestnode.getContent(context);
+ latestcontent.getPatch().setDiffVersion(doc,
+ latestcontent.getPatch().getContent(), context);
+ latestnode.setContent(latestcontent);
+ updateNode(latestnode);
+ getUpdeteNodeContents().add(latestcontent);
+ }
+ }
+ return result;
+ }
+ /** @return {@link XWikiDocument#getId()} - primary key */
public long getId() {
return id;
}
-
+ /** @param id = {@link XWikiDocument#getId()} */
public void setId(long id) {
this.id = id;
}
-
- public Archive getRCSArchive() {
- return archive;
+ /** @return collection of XWikiRCSNodeInfo order by version desc */
+ public Collection getNodes() {
+ return versionToNode.values();
}
-
- public void setRCSArchive(Archive archive) {
- this.archive = archive;
+ /**
+ * @return collection of XWikiRCSNodeInfo where vfrom>=version>=vto order by version desc
+ * @param vfrom - start version
+ * @param vto - end version
+ */
+ public Collection getNodes(Version vfrom, Version vto) {
+ int[] ito = vto.getNumbers();
+ ito[1]--;
+ return versionToNode.subMap(vfrom, new Version(ito)).values();
}
-
- public String getArchive() throws XWikiException {
- if (archive == null)
- return "";
- else {
- StringBuffer buffer = new StringBuffer();
- archive.toString(buffer);
- return buffer.toString();
+ /** @param versions - collection of XWikiRCSNodeInfo */
+ public void setNodes(Collection versions) {
+ resetArchive();
+ for (Iterator it = versions.iterator(); it.hasNext();) {
+ updateNode((XWikiRCSNodeInfo) it.next());
}
+ if (getNodes().size() > 0) {
+ // ensure latest version is full
+ getLatestNode().setDiff(false);
+ updateNode(getLatestNode());
+ }
}
-
+ /**
+ * @param context - used for load nodes content
+ * @return serialization of class
+ * used in {@link PackagePlugin}.
+ * @throws XWikiException if any error
+ */
+ public String getArchive(XWikiContext context) throws XWikiException {
+ XWikiRCSArchive archive = new XWikiRCSArchive(getNodes(), context);
+ return archive.toString();
+ }
+ /**
+ * Deserialize class.
+ * Used in {@link PackagePlugin}.
+ * @param text - archive in JRCS format
+ * @throws XWikiException if parse error
+ */
public void setArchive(String text) throws XWikiException {
+ XWikiRCSArchive archive;
try {
- if ((text!=null)&&(!text.trim().equals(""))) {
- StringInputStream is = new StringInputStream(text);
- archive = new Archive("", is);
- } else
- if (text == null){
- Object[] lines = new Object[1];
- lines[0] = "";
- archive = new Archive(lines, "", "1.0");
- }
- else
- {
- Object[] lines = ToString.stringToArray(text);
- archive = new Archive(lines, "", "1.0");
- }
+ archive = new XWikiRCSArchive(text);
+ } catch (Exception e) {
+ throw new XWikiException(XWikiException.MODULE_XWIKI_DIFF,
+ XWikiException.ERROR_XWIKI_DIFF_CONTENT_ERROR,
+ "Exception while constructing document archive", e);
}
- catch (Exception e) {
- Object[] args = { "" };
- throw new XWikiException(XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_ARCHIVEFORMAT,
- "Exception while manipulating the archive for doc {0}", e, args);
+ resetArchive();
+ Collection nodes = archive.getNodes(getId());
+ for (Iterator it = nodes.iterator(); it.hasNext();) {
+ XWikiRCSNodeInfo nodeinfo = (XWikiRCSNodeInfo) it.next();
+ XWikiRCSNodeContent nodecontent = (XWikiRCSNodeContent) it.next();
+ updateNode(nodeinfo);
+ updateNodeInfos.add(nodeinfo);
+ updateNodeContents.add(nodecontent);
}
}
-
- public void updateArchive(String docname, String text) throws XWikiException {
-
- // JRCS used the user.name System property to set the author of a change. However JRCS
- // has a bug when the user name has a space in the name
- // (see http://www.suigeneris.org/issues/browse/JRCS-22). The workaround is to set the
- // user.name System property to some user without a space in its name. In addition
- // we're not using that information anywhere so it won't matter. When JRCS bug is fixed
- // remove this hack.
-
- // Saving the property in case some other part of the code or some dependent framework
- // needs it.
- String originalUsername = System.getProperty("user.name");
-
- System.setProperty("user.name", "xwiki");
-
- try {
- Object[] lines = ToString.stringToArray(text);
- if (archive != null)
- archive.addRevision(lines, "");
- else
- archive = new Archive(lines, docname, "1.0");
+ /**
+ * Update history with new document version.
+ * @param author - author of version
+ * @param date - date of version
+ * @param comment - version comment
+ * @param isMinor - is minor version
+ * @param doc - document for this version
+ * @param context - used for loading nodes content
+ * @throws XWikiException in any error
+ */
+ public void updateArchive(String author, Date date, String comment, boolean isMinor,
+ XWikiDocument doc, XWikiContext context) throws XWikiException
+ {
+ XWikiRCSNodeInfo newnode = new XWikiRCSNodeInfo(newNodeId(
+ createNextVersion(getLatestVersion(), isMinor)));
+ newnode.setAuthor(author);
+ newnode.setComment(comment);
+ newnode.setDate(date);
+ XWikiRCSNodeContent newcontent = makePatch(newnode, doc, context);
+
+ updateNode(newnode);
+ updateNodeInfos.add(newnode);
+ updateNodeContents.add(newcontent);
+ }
+ /**
+ * Remove document versions from vfrom to vto, inclusive.
+ * @param context - used for loading nodes content
+ * @param vfrom - start version
+ * @param vto - end version
+ * @param doc - document for this archive
+ * @throws XWikiException if any error
+ */
+ public void removeVersions(Version vfrom, Version vto, XWikiDocument doc, XWikiContext context)
+ throws XWikiException
+ {
+ Version vfrom0 = vfrom;
+ Version vto0 = vto;
+ if (vfrom0.compareVersions(vto0) < 0) {
+ Version tmp = vfrom0;
+ vfrom0 = vto0;
+ vto0 = tmp;
}
- catch (Exception e) {
- Object[] args = { docname };
- throw new XWikiException(XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_ARCHIVEFORMAT,
- "Exception while manipulating the archive for doc {0}", e, args);
- } finally {
- // Restore the user name to its original value
- System.setProperty("user.name", originalUsername);
+ Version vfrom1 = getNextVersion(vfrom0);
+ Version vto1 = getPrevVersion(vto0);
+ if (vfrom1 == null && vto1 == null) {
+ resetArchive();
+ return;
}
-
- }
-
- public Object clone() {
- XWikiDocumentArchive docarchive = null;
- try {
- docarchive = (XWikiDocumentArchive) getClass().newInstance();
- } catch (Exception e) {
- // This should not happen
+ if (vfrom1 == null) {
+ // store full version in vto1
+ XWikiDocument docto1 = loadDocument(doc, vto1, context);
+ XWikiRCSNodeInfo nito1 = getNode(vto1);
+ XWikiRCSNodeContent ncto1 = nito1.getContent(context);
+ ncto1.getPatch().setFullVersion(docto1, context);
+ nito1.setContent(ncto1);
+ updateNode(nito1);
+ getUpdeteNodeContents().add(ncto1);
+ } else if (vto1 != null) {
+ XWikiDocument docfrom1 = loadDocument(doc, vfrom1, context);
+ XWikiDocument docto1 = loadDocument(doc, vto1, context);
+ XWikiRCSNodeInfo nito1 = getNode(vto1);
+ XWikiRCSNodeContent ncto1 = nito1.getContent(context);
+ ncto1.getPatch().setDiffVersion(docfrom1, docto1, context);
+ nito1.setContent(ncto1);
+ updateNode(nito1);
+ getUpdeteNodeContents().add(ncto1);
+ } // if (vto1==null) => nothing to do, except delete
+ for (Iterator it = getNodes(vfrom0, vto0).iterator(); it.hasNext();) {
+ XWikiRCSNodeInfo ni = (XWikiRCSNodeInfo) it.next();
+ fullVersions.remove(ni.getId().getVersion());
+ deleteNodes.add(ni);
+ it.remove();
}
-
- docarchive.setId(getId());
- docarchive.setRCSArchive(getRCSArchive());
- return docarchive;
}
-
-
- public boolean equals(Object object) {
- XWikiDocumentArchive doc = (XWikiDocumentArchive) object;
- if (getId()!=doc.getId())
- return false;
-
- try {
- if (!getArchive().equals(doc.getArchive()))
- return false;
- } catch (XWikiException e) {
- return false;
- }
-
- return true;
+ /**
+ * @return selected version of document
+ * @param origdoc - load old version for this document
+ * @param version - which version to load
+ * @param context - used for loading
+ * @throws XWikiException if any error
+ */
+ public XWikiDocument loadDocument(XWikiDocument origdoc, Version version, XWikiContext context)
+ throws XWikiException
+ {
+ return context.getWiki().getVersioningStore().loadXWikiDoc(origdoc,
+ version.toString(), context);
}
-
- public void resetArchive(String docname, String text, String version) throws XWikiException {
- Object[] lines = ToString.stringToArray(text);
- archive = new Archive(lines, docname, version);
+ /**
+ * @return {@link XWikiRCSNodeInfo} by version. null if none.
+ * @param version which version to get
+ */
+ public XWikiRCSNodeInfo getNode(Version version)
+ {
+ return version == null ? null : (XWikiRCSNodeInfo) versionToNode.get(version);
}
-
+ /** @return latest version in history for document. null if none. */
+ public Version getLatestVersion()
+ {
+ return versionToNode.size() == 0 ? null : (Version) versionToNode.firstKey();
+ }
+ /** @return latest node in history for document. null if none. */
+ public XWikiRCSNodeInfo getLatestNode() {
+ return getNode(getLatestVersion());
+ }
+ /**
+ * @return next version in history. null if none
+ * @param ver - current version
+ */
+ public Version getNextVersion(Version ver) {
+ // headMap is exclusive
+ SortedMap headmap = versionToNode.headMap(ver);
+ return (headmap.size() == 0) ? null : (Version) headmap.lastKey();
+ }
/**
- * {@inheritDoc}
- * @see Object#toString()
+ * @return previous version in history. null if none
+ * @param ver - current version
*/
- public String toString()
+ public Version getPrevVersion(Version ver) {
+ // tailMap is inclusive
+ SortedMap tailmap = versionToNode.tailMap(ver);
+ if (tailmap.size() <= 1) {
+ return null;
+ }
+ Iterator it = tailmap.keySet().iterator();
+ it.next();
+ return (Version) it.next();
+ }
+ /**
+ * @param ver - for what version find nearest
+ * @return nearest version which contain full information (not patch)
+ */
+ public Version getNearestFullVersion(Version ver)
{
- return "id = [" + getId() + "], archive = ["
- + (getRCSArchive() == null ? "null" : getRCSArchive().toString()) + "]";
+ if (fullVersions.contains(ver)) {
+ return ver;
+ }
+ SortedSet headSet = fullVersions.headSet(ver);
+ return (Version) ((headSet.size() == 0) ? null : headSet.last());
}
+ /** reset history. history becomes empty. */
+ public void resetArchive()
+ {
+ versionToNode.clear();
+ fullVersions.clear();
+ deleteNodes.addAll(updateNodeInfos);
+ updateNodeInfos.clear();
+ updateNodeContents.clear();
+ }
+ /** @return mutable Set of {@link XWikiRCSNodeInfo} which are need for delete */
+ public Set getDeleteNodeInfo()
+ {
+ return deleteNodes;
+ }
+ /** @return mutable Set of {@link XWikiRCSNodeInfo} which are need for saveOrUpdate */
+ public Set getUpdeteNodeInfos()
+ {
+ return updateNodeInfos;
+ }
+ /** @return mutable Set of {@link XWikiRCSNodeContent} which are need for update */
+ public Set getUpdeteNodeContents()
+ {
+ return updateNodeContents;
+ }
}
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/api/RevisionInfo.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/api/RevisionInfo.java (revision 0)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/api/RevisionInfo.java (revision 0)
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ */
+package com.xpn.xwiki.api;
+
+import java.util.Date;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;
+
+/**
+ * API object for get info about some version of Document.
+ * @version $Id: $
+ */
+public class RevisionInfo extends Api
+{
+ /** used for get all information. */
+ private XWikiRCSNodeInfo nodeInfo;
+ /**
+ * @param nodeInfo - from that nodeinfo all information is getting
+ * @param context - needed for {@link Api}
+ */
+ public RevisionInfo(XWikiRCSNodeInfo nodeInfo, XWikiContext context)
+ {
+ super(context);
+ this.nodeInfo = nodeInfo;
+ }
+ /** @return version of this revision */
+ public String getVersion()
+ {
+ return nodeInfo.getId().getVersion().toString();
+ }
+ /** @return date of this revision */
+ public Date getDate()
+ {
+ return nodeInfo.getDate();
+ }
+ /** @return author of this revision */
+ public String getAuthor()
+ {
+ return nodeInfo.getAuthor();
+ }
+ /** @return revision comment */
+ public String getComment()
+ {
+ return nodeInfo.getComment();
+ }
+ /** @return is revision is minor */
+ public boolean isMinorEdit() {
+ return nodeInfo.isMinorEdit();
+ }
+}
Property changes on: xwiki-platform-core/src/main/java/com/xpn/xwiki/api/RevisionInfo.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/api/XWiki.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/api/XWiki.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/api/XWiki.java (working copy)
@@ -34,7 +34,7 @@
import com.xpn.xwiki.stats.impl.DocumentStats;
import com.xpn.xwiki.web.Utils;
import com.xpn.xwiki.web.XWikiEngineContext;
-import org.suigeneris.jrcs.diff.Chunk;
+import org.suigeneris.jrcs.diff.delta.Chunk;
import java.awt.image.BufferedImage;
import java.io.IOException;
@@ -2319,6 +2319,14 @@
{
return xwiki.isEditCommentMandatory(context);
}
+
+ /**
+ * API to check if the minor edit feature is active
+ * minor edit are activated in xwiki.cfg or in the XWiki Preferences
+ */
+ public boolean hasMinorEdit() {
+ return xwiki.hasMinorEdit(context);
+ }
/**
* API to rename a page (experimental) Rights are necessary to edit the source and target page
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/api/Document.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/api/Document.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/api/Document.java (working copy)
@@ -288,6 +288,11 @@
{
return doc.getComment();
}
+
+ public boolean isMinorEdit()
+ {
+ return doc.isMinorEdit();
+ }
/**
* return the list of possible traduction for this document
@@ -362,7 +367,7 @@
*/
public String getArchive() throws XWikiException
{
- return doc.getDocumentArchive(getXWikiContext()).getArchive();
+ return doc.getDocumentArchive(getXWikiContext()).getArchive(getXWikiContext());
}
/**
@@ -688,6 +693,10 @@
{
return doc.getRecentRevisions(nb, getXWikiContext());
}
+
+ public RevisionInfo getRevisionInfo(String version) throws XWikiException {
+ return new RevisionInfo( doc.getRevisionInfo(version, getXWikiContext()), getXWikiContext() );
+ }
public List getAttachmentList()
{
@@ -1406,6 +1415,10 @@
{
getDoc().setComment(comment);
}
+
+ public void setMinorEdit(boolean isMinor) {
+ getDoc().setMinorEdit(isMinor);
+ }
public void save() throws XWikiException
{
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/XWiki.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/XWiki.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/XWiki.java (working copy)
@@ -895,8 +895,14 @@
// If no comment is provided we should use an empty comment
saveDocument(doc, "", context);
}
+
+ public void saveDocument(XWikiDocument doc, String comment, XWikiContext context)
+ throws XWikiException
+ {
+ saveDocument(doc, comment, false, context);
+ }
- public void saveDocument(XWikiDocument doc, String comment, XWikiContext context)
+ public void saveDocument(XWikiDocument doc, String comment, boolean isMinorEdit, XWikiContext context)
throws XWikiException
{
String server = null, database = null;
@@ -910,6 +916,7 @@
// Setting comment before saving
doc.setComment((comment == null) ? "" : comment);
+ doc.setMinorEdit(isMinorEdit);
getStore().saveXWikiDoc(doc, context);
@@ -4953,6 +4960,16 @@
return false;
return "1".equals(Param("xwiki.editcomment.mandatory", "0"));
}
+
+ public boolean hasMinorEdit(XWikiContext context)
+ {
+ String bl = getXWikiPreference("minoredit", "", context);
+ if ("1".equals(bl))
+ return true;
+ if ("0".equals(bl))
+ return false;
+ return "1".equals(Param("xwiki.minoredit", "1"));
+ }
/**
* @deprecated use {@link XWikiDocument#rename(String, XWikiContext)} instead
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/Utils.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/Utils.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/Utils.java (working copy)
@@ -136,14 +136,18 @@
return redirect;
}
- public static String getRedirect(String action, XWikiContext context) {
+ public static String getRedirect(String action, String params, XWikiContext context) {
String redirect;
redirect = context.getRequest().getParameter("xredirect");
if ((redirect == null) || (redirect.equals("")))
- redirect = context.getDoc().getURL(action, true, context);
+ redirect = context.getDoc().getURL(action, params, true, context);
return redirect;
}
+ public static String getRedirect(String action, XWikiContext context) {
+ return getRedirect(action, null, context);
+ }
+
public static String getPage(XWikiRequest request, String defaultpage) {
String page;
page = request.getParameter("xpage");
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/EditForm.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/EditForm.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/EditForm.java (working copy)
@@ -50,11 +50,13 @@
private String title;
private String comment;
+
+ private boolean isMinorEdit = false;
private String tags;
private boolean lockForce;
-
+
public void readRequest()
{
XWikiRequest request = getRequest();
@@ -71,6 +73,7 @@
setDefaultLanguage(request.getParameter("default_language"));
setTags(request.getParameterValues("tags"));
setLockForce("1".equals(request.getParameter("force")));
+ setMinorEdit(request.getParameter("minor_edit")!=null);
}
public void setTags(String[] parameter)
@@ -231,6 +234,16 @@
{
this.comment = comment;
}
+
+ public boolean isMinorEdit()
+ {
+ return isMinorEdit;
+ }
+
+ public void setMinorEdit(boolean isMinorEdit)
+ {
+ this.isMinorEdit = isMinorEdit;
+ }
public boolean isLockForce()
{
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/CommentAddAction.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/CommentAddAction.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/CommentAddAction.java (working copy)
@@ -55,7 +55,7 @@
newobject.setNumber(oldobject.getNumber());
newobject.setName(doc.getFullName());
doc.setObject(className, nb, newobject);
- xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.addComment"), context);
+ xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.addComment"), true, context);
}
// forward to edit
String redirect = Utils.getRedirect("edit", context);
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/ObjectRemoveAction.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/ObjectRemoveAction.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/ObjectRemoveAction.java (working copy)
@@ -43,7 +43,7 @@
objects.set(classId, null);
doc.addObjectsToRemove(object);
doc.setAuthor(context.getUser());
- xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.deleteObject"), context);
+ xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.deleteObject"), true, context);
// forward to edit
String redirect = Utils.getRedirect("edit", context);
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/SaveAction.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/SaveAction.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/SaveAction.java (working copy)
@@ -95,6 +95,7 @@
tdoc.setContent(content);
tdoc.setTitle(title);
tdoc.setComment(sectionDoc.getComment());
+ tdoc.setMinorEdit(sectionDoc.isMinorEdit());
}else{
tdoc.readFromForm((EditForm) form, context);
}
@@ -110,7 +111,7 @@
// We get the comment to be used from the document
// It was read using readFromForm
- xwiki.saveDocument(tdoc, tdoc.getComment(), context);
+ xwiki.saveDocument(tdoc, tdoc.getComment(), tdoc.isMinorEdit(), context);
XWikiLock lock = tdoc.getLock(context);
if (lock != null)
tdoc.removeLock(context);
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/PropAddAction.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/PropAddAction.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/PropAddAction.java (working copy)
@@ -62,7 +62,7 @@
if (doc.isNew()) {
doc.setCreator(username);
}
- xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.addClassProperty"), context);
+ xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.addClassProperty"), true, context);
}
}
// forward to edit
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/XWikiPortlet.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/XWikiPortlet.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/XWikiPortlet.java (working copy)
@@ -179,6 +179,8 @@
form = new ObjectRemoveForm();
else if (action.equals("propadd"))
form = new PropAddForm();
+ else if (action.equals("deleteversions"))
+ form = new DeleteVersionsForm();
if (form != null) {
form.reset(null, request);
@@ -217,6 +219,8 @@
(new RegisterAction()).action(context);
} else if (action.equals("inline")) {
(new InlineAction()).action(context);
+ } else if (action.equals("deleteversions")) {
+ (new DeleteVersionsAction()).action(context);
}
} catch (Throwable e) {
handleException(request, response, e, context);
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/ObjectAddAction.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/ObjectAddAction.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/ObjectAddAction.java (working copy)
@@ -63,7 +63,7 @@
if (doc.isNew()) {
doc.setCreator(username);
}
- xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.addObject"), context);
+ xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.addObject"), true, context);
// forward to edit
String redirect = Utils.getRedirect("edit", context);
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/DeleteVersionsForm.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/DeleteVersionsForm.java (revision 0)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/DeleteVersionsForm.java (revision 0)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package com.xpn.xwiki.web;
+
+/**
+ * Struts form for {@link DeleteVersionsAction}.
+ * @version $Id: $
+ */
+public class DeleteVersionsForm extends XWikiForm
+{
+ /** from revision. */
+ private String rev1;
+ /** to revision. */
+ private String rev2;
+ /** document language. */
+ private String language;
+ /** is action confirmed. */
+ private boolean confirm;
+ /** {@inheritDoc} */
+ public void readRequest()
+ {
+ XWikiRequest request = getRequest();
+ rev1 = request.getParameter("rev1");
+ rev2 = request.getParameter("rev2");
+ language = request.getParameter("language");
+ confirm = request.getParameter("confirm") != null;
+ }
+ /**
+ * @return from revision
+ */
+ public String getRev1()
+ {
+ return rev1;
+ }
+ /**
+ * @return to revision
+ */
+ public String getRev2()
+ {
+ return rev2;
+ }
+ /**
+ * @return document language
+ */
+ public String getLanguage()
+ {
+ return language;
+ }
+ /**
+ * @return is action confirmed
+ */
+ public boolean isConfirmed()
+ {
+ return confirm;
+ }
+}
Property changes on: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/DeleteVersionsForm.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/PropUpdateAction.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/PropUpdateAction.java (revision 4076)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/PropUpdateAction.java (working copy)
@@ -75,7 +75,7 @@
doc.setxWikiClass(bclass2);
doc.renameProperties(bclass.getName(), fieldsToRename);
- xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.updateClassProperty"), context);
+ xwiki.saveDocument(doc, context.getMessageTool().get("core.comment.updateClassProperty"), true, context);
// We need to load all documents that use this property and rename it
if (fieldsToRename.size() > 0) {
@@ -88,7 +88,7 @@
for (int i = 0; i < list.size(); i++) {
XWikiDocument doc2 = xwiki.getDocument((String) list.get(i), context);
doc2.renameProperties(bclass.getName(), fieldsToRename);
- xwiki.saveDocument(doc2, context.getMessageTool().get("core.comment.updateClassPropertyName"), context);
+ xwiki.saveDocument(doc2, context.getMessageTool().get("core.comment.updateClassPropertyName"), true, context);
}
}
xwiki.flushCache();
Index: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/DeleteVersionsAction.java
===================================================================
--- xwiki-platform-core/src/main/java/com/xpn/xwiki/web/DeleteVersionsAction.java (revision 0)
+++ xwiki-platform-core/src/main/java/com/xpn/xwiki/web/DeleteVersionsAction.java (revision 0)
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package com.xpn.xwiki.web;
+
+import org.suigeneris.jrcs.rcs.Version;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.doc.XWikiDocumentArchive;
+
+/**
+ * Struts action for delete document versions.
+ * @version $Id: $
+ */
+public class DeleteVersionsAction extends XWikiAction
+{
+ /**
+ * {@inheritDoc}
+ */
+ public boolean action(XWikiContext context) throws XWikiException
+ {
+ XWikiResponse response = context.getResponse();
+ XWikiDocument doc = context.getDoc();
+ DeleteVersionsForm form = (DeleteVersionsForm) context.getForm();
+
+ boolean confirm = form.isConfirmed();
+ String rev1 = form.getRev1();
+ String rev2 = form.getRev2();
+ String language = form.getLanguage();
+ XWikiDocument tdoc;
+
+ if (confirm) {
+ if (language == null || language.equals("") || language.equals("default")
+ || language.equals(doc.getDefaultLanguage())) {
+ // Need to save parent and defaultLanguage if they have changed
+ tdoc = doc;
+ } else {
+ tdoc = doc.getTranslatedDocument(language, context);
+ if (tdoc == doc) {
+ tdoc = new XWikiDocument(doc.getSpace(), doc.getName());
+ tdoc.setLanguage(language);
+ }
+ tdoc.setTranslation(1);
+ }
+
+ XWikiDocumentArchive archive = tdoc.getDocumentArchive(context);
+ Version v1;
+ Version v2;
+ try {
+ v1 = new Version(rev1);
+ v2 = new Version(rev2);
+ } catch (NullPointerException e) {
+ // incorrect or unselected versions
+ sendRedirect(context);
+ return false;
+ }
+ archive.removeVersions(v1, v2, tdoc, context);
+ context.getWiki().getVersioningStore().saveXWikiDocArchive(archive, true, context);
+ tdoc.setDocumentArchive(archive);
+ }
+ sendRedirect(context);
+ return false;
+ }
+ /**
+ * redirect back to view history.
+ * @param context used in redirecting
+ * @throws XWikiException if any error
+ */
+ private void sendRedirect(XWikiContext context) throws XWikiException {
+ // forward to view
+ String redirect = Utils.getRedirect("view", "viewer=history", context);
+ sendRedirect(context.getResponse(), redirect);
+ }
+}
Property changes on: xwiki-platform-core/src/main/java/com/xpn/xwiki/web/DeleteVersionsAction.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: xwiki-platform-core/src/main/resources/ApplicationResources.properties
===================================================================
--- xwiki-platform-core/src/main/resources/ApplicationResources.properties (revision 4076)
+++ xwiki-platform-core/src/main/resources/ApplicationResources.properties (working copy)
@@ -702,6 +702,10 @@
core.comment.rollback=Rollback to version {0}
core.comment.updateContent=Update Content
+core.minoredit=Is minor edit
+core.minoredit.show=Show minor edits
+core.minoredit.hide=Hide minor edits
+
# top menu
core.menu.documentation=Documentation
core.menu.create=Create
@@ -738,6 +742,9 @@
core.delete.confirm=The deletion of a document is not reversible. Are you sure you wish to continue?
core.delete.confirmWithBacklinks=In addition, the deletion of a document is not reversible. Are you sure you wish to continue?
+core.versions.delete=Delete versions
+core.versions.delete.confirm=Do you want to delete selected versions?
+
core.tagedit.title=Tags:
panels.documentInformation.title=Document information
Index: xwiki-platform-core/src/main/resources/xwiki.oracle.hbm.xml
===================================================================
--- xwiki-platform-core/src/main/resources/xwiki.oracle.hbm.xml (revision 4076)
+++ xwiki-platform-core/src/main/resources/xwiki.oracle.hbm.xml (working copy)
@@ -101,17 +101,37 @@
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: xwiki-platform-core/src/main/resources/xwiki.derby.hbm.xml
===================================================================
--- xwiki-platform-core/src/main/resources/xwiki.derby.hbm.xml (revision 4076)
+++ xwiki-platform-core/src/main/resources/xwiki.derby.hbm.xml (working copy)
@@ -107,17 +107,37 @@
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: xwiki-platform-core/src/main/resources/xwiki.hbm.xml
===================================================================
--- xwiki-platform-core/src/main/resources/xwiki.hbm.xml (revision 4076)
+++ xwiki-platform-core/src/main/resources/xwiki.hbm.xml (working copy)
@@ -99,17 +99,33 @@
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: xwiki-platform-core/pom.xml
===================================================================
--- xwiki-platform-core/pom.xml (revision 4076)
+++ xwiki-platform-core/pom.xml (working copy)
@@ -83,14 +83,12 @@
org.suigeneris
jrcs.diff
- 0.3.0
- xwiki
+ 0.4.2
org.suigeneris
jrcs.rcs
- 0.3.0
- xwiki
+ 0.4.2
@@ -560,4 +563,4 @@
-
\ No newline at end of file
+