Index: src/test/java/com/xpn/xwiki/doc/XWikiDocumentTest.java
===================================================================
--- src/test/java/com/xpn/xwiki/doc/XWikiDocumentTest.java (revision 4044)
+++ src/test/java/com/xpn/xwiki/doc/XWikiDocumentTest.java (working copy)
@@ -79,4 +79,24 @@
assertEquals("Title", this.document.getDisplayTitle(this.context));
}
+
+ public void testMinorMajorVersions() {
+ // there is no version in doc yet, so 1.1
+ assertEquals("1.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());
+ }
}
Index: src/test/java/com/xpn/xwiki/doc/XWikiDocumentArchiveTest.java
===================================================================
--- src/test/java/com/xpn/xwiki/doc/XWikiDocumentArchiveTest.java (revision 4044)
+++ src/test/java/com/xpn/xwiki/doc/XWikiDocumentArchiveTest.java (working copy)
@@ -19,10 +19,19 @@
*/
package com.xpn.xwiki.doc;
+import java.util.Arrays;
+import java.util.Date;
+
import junit.framework.TestCase;
+import org.apache.tools.ant.filters.StringInputStream;
+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: $
*/
@@ -37,31 +46,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" +
@@ -153,12 +137,70 @@
// Set a username with a space
System.setProperty("user.name", "Vincent Massol");
+
+ XWikiContext context = new XWikiContext();
+ XWikiDocument doc = new XWikiDocument("Main", "WebHome");
+ 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 = "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 testJrcsQuote() throws Exception {
+ // test for http://www.suigeneris.org/issues/browse/JRCS-23
+ Object[] text = {"qwe @ qwe", "qwe @@ qwe"};
+ String log = "some bad @ log";
+ Archive arch = new Archive(text, log);
+ String sarch = arch.toString();
+
+ Archive arch2 = new Archive("", new StringInputStream(sarch));
+ assertEquals( sarch, arch2.toString() );
+ assertTrue( Arrays.equals( text, arch2.getRevision() ) );
+ assertEquals( log, arch2.getLog("1.1") );
+ }
}
Index: src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java
===================================================================
--- src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java (revision 4044)
+++ 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);
@@ -787,4 +786,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: src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java
===================================================================
--- src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java (revision 4044)
+++ 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: src/main/java/com/xpn/xwiki/store/XWikiVersioningStoreInterface.java
===================================================================
--- src/main/java/com/xpn/xwiki/store/XWikiVersioningStoreInterface.java (revision 4044)
+++ 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: src/main/java/com/xpn/xwiki/store/XWikiHibernateVersioningStore.java
===================================================================
--- src/main/java/com/xpn/xwiki/store/XWikiHibernateVersioningStore.java (revision 4044)
+++ src/main/java/com/xpn/xwiki/store/XWikiHibernateVersioningStore.java (working copy)
@@ -1,39 +1,41 @@
package com.xpn.xwiki.store;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Session;
+import org.hibernate.criterion.Restrictions;
+import org.suigeneris.jrcs.rcs.Version;
+import org.suigeneris.jrcs.util.ToString;
+
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.util.Util;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.ObjectNotFoundException;
-import org.hibernate.Session;
-import org.suigeneris.jrcs.rcs.Archive;
-import org.suigeneris.jrcs.rcs.Node;
-import org.suigeneris.jrcs.rcs.Version;
+import com.xpn.xwiki.doc.rcs.XWikiDiff;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeContent;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeId;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;
public class XWikiHibernateVersioningStore extends XWikiHibernateBaseStore implements XWikiVersioningStoreInterface {
private static final Log log = LogFactory.getLog(XWikiHibernateVersioningStore.class);
/**
- * THis allows to initialize our storage engine.
- * The hibernate config file path is taken from xwiki.cfg
- * or directly in the WEB-INF directory.
- * @param xwiki
- * @param context
+ * {@inheritDoc}
*/
public XWikiHibernateVersioningStore(XWiki xwiki, XWikiContext context) {
super(xwiki, context);
}
/**
- * Initialize the storage engine with a specific path
- * This is used for tests.
- * @param hibpath
+ * {@inheritDoc}
*/
public XWikiHibernateVersioningStore(String hibpath) {
super(hibpath);
@@ -41,14 +43,15 @@
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];
-
- 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.setPatch(nodeinfo.isPatch());
+ XWikiRCSNodeContent content = nodeinfo.getContent(context);
+ node.setText(content.getDelta());
+ 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 node - 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 patch or full version */
+ public boolean isPatch() {
+ // we need something filed in Node. locker is free
+ return !sfullVersion.equals(getState());
+ }
+ /** @param ispatch - true if node stores a patch, false - if full version */
+ public void setPatch(boolean ispatch) {
+ setState(ispatch ? "patch" : 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.setPatch(node.isPatch());
+ XWikiRCSNodeContent content = new XWikiRCSNodeContent(nodeinfo.getId());
+ content.setDelta(ToString.arrayToString(node.getText()));
+ nodeinfo.setContent(content);
+ result.add(nodeinfo);
+ result.add(content);
+ }
+ // ensure latest version is full
+ ((XWikiRCSNodeInfo) result.iterator().next()).setPatch(false);
+ return result;
+ }
+}
Property changes on: src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSArchive.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSNodeId.java
===================================================================
--- src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSNodeId.java (revision 0)
+++ src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSNodeId.java (revision 0)
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2007, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * 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: src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSNodeId.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/main/java/com/xpn/xwiki/doc/XWikiDocument.java
===================================================================
--- src/main/java/com/xpn/xwiki/doc/XWikiDocument.java (revision 4044)
+++ src/main/java/com/xpn/xwiki/doc/XWikiDocument.java (working copy)
@@ -28,6 +28,7 @@
import com.xpn.xwiki.content.parsers.ReplacementResultCollection;
import com.xpn.xwiki.content.parsers.RenamePageReplaceLinkHandler;
import com.xpn.xwiki.content.Link;
+import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;
import com.xpn.xwiki.api.DocumentSection;
import com.xpn.xwiki.notify.XWikiNotificationRule;
import com.xpn.xwiki.objects.BaseCollection;
@@ -156,6 +157,9 @@
// Comment on the latest modification
private String comment;
+
+ // Is latest modification is minor edit
+ private boolean isMinorEdit = false;
// Used to make sure the MetaData String is regenerated
private boolean isContentDirty = true;
@@ -285,13 +289,17 @@
public void setVersion(String version)
{
- this.version = new Version(version);
+ if (version!=null && !"".equals(version)) {
+ this.version = new Version(version);
+ }
}
public Version getRCSVersion()
{
if (version == null) {
- version = new Version("1.1");
+ // if we assign this.version = new Version("1.1") before save (ex: $doc.getVersion() in a page), then version will be > 1.1 after the first save
+ // version 1.0 do not work for some reason inside JRCS
+ return new Version("1.1");
}
return version;
}
@@ -669,7 +677,11 @@
if (version == null) {
version = new Version("1.1");
} else {
- version = version.next();
+ if (isMinorEdit()) {
+ version = version.next();
+ } else {
+ version = version.getBranchPoint().next().newBranch(1);
+ }
}
}
@@ -851,6 +863,14 @@
{
XWikiDocumentArchive xda = new XWikiDocumentArchive(getId());
xda.setArchive(sarch);
+ if (xda.getNodes().size()>0) {
+ setRCSVersion(xda.getLatestVersion());
+ XWikiRCSNodeInfo nodeinfo = xda.getLatestNode();
+ setComment(nodeinfo.getComment());
+ setMinorEdit(nodeinfo.isMinorEdit());
+ setAuthor(nodeinfo.getAuthor());
+ setDate(nodeinfo.getDate());
+ }
setDocumentArchive(xda);
}
@@ -885,6 +905,11 @@
}
}
+ public XWikiRCSNodeInfo getRevisionInfo(String version, XWikiContext context) throws XWikiException
+ {
+ return getDocumentArchive(context).getNode(new Version(version));
+ }
+
public boolean isMostRecent()
{
return mostRecent;
@@ -1548,7 +1573,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);
@@ -1786,6 +1814,7 @@
setxWikiClass((BaseClass) document.getxWikiClass().clone());
setxWikiClassXML(document.getxWikiClassXML());
setComment(document.getComment());
+ setMinorEdit(document.isMinorEdit());
clonexWikiObjects(document);
copyAttachments(document);
@@ -1835,6 +1864,7 @@
doc.setxWikiClass((BaseClass) getxWikiClass().clone());
doc.setxWikiClassXML(getxWikiClassXML());
doc.setComment(getComment());
+ doc.setMinorEdit(isMinorEdit());
doc.clonexWikiObjects(this);
doc.copyAttachments(this);
doc.elements = elements;
@@ -1960,6 +1990,10 @@
if (!getComment().equals(doc.getComment())) {
return false;
}
+
+ if (isMinorEdit() == doc.isMinorEdit()) {
+ return false;
+ }
if (!getxWikiClass().equals(doc.getxWikiClass())) {
return false;
@@ -2078,7 +2112,7 @@
Document doc = new DOMDocument();
Element docel = new DOMElement("xwikidoc");
doc.setRootElement(docel);
-
+
Element el = new DOMElement("web");
el.addText(getSpace());
docel.add(el);
@@ -2157,13 +2191,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();
@@ -2213,7 +2251,7 @@
if (bWithVersions) {
el = new DOMElement("versions");
try {
- el.addText(getDocumentArchive(context).getArchive());
+ el.addText(getDocumentArchive(context).getArchive( context ));
} catch (XWikiException e) {
return null;
}
@@ -2222,7 +2260,7 @@
return doc;
}
-
+
protected String encodedXMLStringAsUTF8(String xmlString)
{
if (xmlString == null) {
@@ -2341,6 +2379,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);
@@ -4052,6 +4093,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: src/main/java/com/xpn/xwiki/doc/XWikiDocumentArchive.java
===================================================================
--- src/main/java/com/xpn/xwiki/doc/XWikiDocumentArchive.java (revision 4044)
+++ src/main/java/com/xpn/xwiki/doc/XWikiDocumentArchive.java (working copy)
@@ -1,149 +1,311 @@
+/*
+ * Copyright 2006-2007, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * 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.Comparator;
+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.diff.DifferentiationFailedException;
+import org.suigeneris.jrcs.rcs.Version;
+import org.suigeneris.jrcs.rcs.parse.ParseException;
+
+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.XWikiDiff;
+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;
+import com.xpn.xwiki.plugin.packaging.PackagePlugin;
-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. */
+ private SortedSet fullNodes = 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(new Comparator() {
+ public int compare(Object arg0, Object arg1)
+ {
+ XWikiRCSNodeInfo o1 = (XWikiRCSNodeInfo) arg0;
+ XWikiRCSNodeInfo o2 = (XWikiRCSNodeInfo) arg1;
+ return o1.getId().getVersion().compareTo(o2.getId().getVersion());
+ }
+ });
+ /** Set of {@link XWikiRCSNodeContent} which need to update. */
+ private Set updateNodeContents = new TreeSet(new Comparator() {
+ public int compare(Object arg0, Object arg1)
+ {
+ XWikiRCSNodeContent o1 = (XWikiRCSNodeContent) arg0;
+ XWikiRCSNodeContent o2 = (XWikiRCSNodeContent) arg1;
+ return o1.getId().getVersion().compareTo(o2.getId().getVersion());
+ }
+ });
+
+ // helper methods
+ /**
+ * @param cur - current version
+ * @param isMinor - is modification is minor
+ * @return next version
+ */
+ protected Version getNextVersion(Version cur, boolean isMinor) {
+ if (!isMinor) {
+ return cur.getBase(1).next().newBranch(1);
+ } else {
+ return cur.next();
+ }
}
+ /** @param node - node added to versionToNode and fullNodes */
+ protected void addNode(XWikiRCSNodeInfo node) {
+ versionToNode.put(node.getId().getVersion(), node);
+ if (!node.isPatch()) {
+ fullNodes.add(node.getId().getVersion());
+ }
+ }
+ /**
+ * @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);
+ }
+ /**
+ * @param latestnode - latest node in history (always full)
+ * @param curdoc - document from that diff created
+ * @param context - used for loading latestnode content
+ * @return new latestnode's content
+ * @throws DifferentiationFailedException if error then creating diff
+ * @throws XWikiException if error loading content
+ */
+ protected XWikiRCSNodeContent makeDiffs(XWikiRCSNodeInfo latestnode, XWikiDocument curdoc,
+ XWikiContext context) throws DifferentiationFailedException, XWikiException
+ {
+ XWikiRCSNodeContent result = new XWikiRCSNodeContent();
+ String text = curdoc.toXML(context);
+ result.setDelta( text );
+ 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.setDelta( XWikiDiff.diff(text, latestcontent.getDelta()) );
+ latestnode.setPatch(true);
+ fullNodes.remove(latestnode.getId().getVersion());
+ }
+ }
+ return result;
+ }
+ /** @param id = {@link XWikiDocument#getId()} */
public XWikiDocumentArchive(long id) {
setId(id);
}
-
+ /** @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 */
+ 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(); )
+ addNode((XWikiRCSNodeInfo) it.next());
+ if (getNodes().size()>0) {
+ // ensure latest version is full
+ getLatestNode().setPatch(false);
+ fullNodes.add(getLatestNode().getId().getVersion());
}
}
-
+ /**
+ * @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 (ParseException 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();
+ addNode(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");
-
+ /**
+ * 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 curdoc - 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 curdoc, XWikiContext context) throws XWikiException
+ {
try {
- Object[] lines = ToString.stringToArray(text);
- if (archive != null)
- archive.addRevision(lines, "");
- else
- archive = new Archive(lines, docname, "1.0");
+ if (versionToNode.size()>0) {
+ XWikiRCSNodeInfo orignode = getLatestNode();
+
+ XWikiRCSNodeInfo newnode = new XWikiRCSNodeInfo();
+ newnode.setId(newNodeId(getNextVersion(orignode.getId().getVersion(), isMinor)));
+ newnode.setComment(comment);
+ newnode.setAuthor(author);
+ newnode.setDate(date);
+
+ XWikiRCSNodeContent origcontent = orignode.getContent(context);
+ XWikiRCSNodeContent newcontent = makeDiffs(orignode, curdoc, context);
+ newnode.setContent(newcontent);
+ newnode.setPatch(false);
+
+ addNode(newnode);
+ updateNodeInfos.add(newnode);
+ updateNodeContents.add(newcontent);
+ if (orignode.isPatch()) {
+ updateNodeInfos.add(orignode);
+ updateNodeContents.add(origcontent);
+ }
+ } else {
+ XWikiRCSNodeInfo newnode = new XWikiRCSNodeInfo(
+ new XWikiRCSNodeId(id, new Version(1,1)));
+ newnode.setAuthor(author);
+ newnode.setDate(date);
+ newnode.setComment(comment);
+ XWikiRCSNodeContent newcontent = makeDiffs(null, curdoc, context);
+ newnode.setContent(newcontent);
+ newnode.setPatch(false);
+ addNode(newnode);
+ updateNodeInfos.add(newnode);
+ updateNodeContents.add(newcontent);
+ }
+ } catch (DifferentiationFailedException e) {
+ Object[] args = new Object[]{Long.valueOf(getId())};
+ throw new XWikiException(XWikiException.MODULE_XWIKI_DIFF,
+ XWikiException.ERROR_XWIKI_DIFF_CONTENT_ERROR,
+ "Exception while updateArchive for docId={}", e, args);
}
- 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);
- }
-
}
-
- public Object clone() {
- XWikiDocumentArchive docarchive = null;
- try {
- docarchive = (XWikiDocumentArchive) getClass().newInstance();
- } catch (Exception e) {
- // This should not happen
- }
-
- docarchive.setId(getId());
- docarchive.setRCSArchive(getRCSArchive());
- return docarchive;
+ /**
+ * @return {@link XWikiRCSNodeInfo} by version
+ * @param version which version to get
+ */
+ public XWikiRCSNodeInfo getNode(Version version)
+ {
+ return (XWikiRCSNodeInfo) versionToNode.get(version);
}
-
-
- 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 latest version in history for document */
+ public Version getLatestVersion()
+ {
+ return (Version) versionToNode.firstKey();
}
-
- public void resetArchive(String docname, String text, String version) throws XWikiException {
- Object[] lines = ToString.stringToArray(text);
- archive = new Archive(lines, docname, version);
+ /** @return latest node in history for document */
+ public XWikiRCSNodeInfo getLatestNode() {
+ return getNode( getLatestVersion() );
}
-
- /**
- * {@inheritDoc}
- * @see Object#toString()
+ /**
+ * @param ver - version for what nearest
+ * @return nearest version which contain full information (not patch)
*/
- public String toString()
+ public Version getNearestFullVersion(Version ver) {
+ if (fullNodes.contains(ver))
+ return ver;
+ return (Version) fullNodes.headSet(ver).last();
+ // latest node is always full
+ }
+ /** reset history. history becomes empty. */
+ public void resetArchive()
{
- return "id = [" + getId() + "], archive = ["
- + (getRCSArchive() == null ? "null" : getRCSArchive().toString()) + "]";
+ versionToNode.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: src/main/java/com/xpn/xwiki/api/RevisionInfo.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/RevisionInfo.java (revision 0)
+++ src/main/java/com/xpn/xwiki/api/RevisionInfo.java (revision 0)
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2007, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * 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: src/main/java/com/xpn/xwiki/api/RevisionInfo.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/main/java/com/xpn/xwiki/api/XWiki.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/XWiki.java (revision 4044)
+++ 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;
@@ -2320,6 +2320,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: src/main/java/com/xpn/xwiki/api/Document.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/Document.java (revision 4044)
+++ src/main/java/com/xpn/xwiki/api/Document.java (working copy)
@@ -280,6 +280,11 @@
{
return doc.getComment();
}
+
+ public boolean isMinorEdit()
+ {
+ return doc.isMinorEdit();
+ }
/**
* return the list of possible traduction for this document
@@ -354,7 +359,7 @@
*/
public String getArchive() throws XWikiException
{
- return doc.getDocumentArchive(getXWikiContext()).getArchive();
+ return doc.getDocumentArchive(getXWikiContext()).getArchive(getXWikiContext());
}
/**
@@ -680,6 +685,10 @@
{
return doc.getRecentRevisions(nb, getXWikiContext());
}
+
+ public RevisionInfo getRevisionInfo(String version) throws XWikiException {
+ return new RevisionInfo( doc.getRevisionInfo(version, getXWikiContext()), getXWikiContext() );
+ }
public List getAttachmentList()
{
@@ -1398,6 +1407,10 @@
{
getDoc().setComment(comment);
}
+
+ public void setMinorEdit(boolean isMinor) {
+ getDoc().setMinorEdit(isMinor);
+ }
public void save() throws XWikiException
{
Index: src/main/java/com/xpn/xwiki/XWiki.java
===================================================================
--- src/main/java/com/xpn/xwiki/XWiki.java (revision 4044)
+++ src/main/java/com/xpn/xwiki/XWiki.java (working copy)
@@ -939,8 +939,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;
@@ -954,6 +960,7 @@
// Setting comment before saving
doc.setComment((comment == null) ? "" : comment);
+ doc.setMinorEdit(isMinorEdit);
getStore().saveXWikiDoc(doc, context);
@@ -4937,6 +4944,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: src/main/java/com/xpn/xwiki/web/EditForm.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/EditForm.java (revision 4044)
+++ 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: src/main/java/com/xpn/xwiki/web/CommentAddAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/CommentAddAction.java (revision 4044)
+++ 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: src/main/java/com/xpn/xwiki/web/ObjectRemoveAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/ObjectRemoveAction.java (revision 4044)
+++ 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: src/main/java/com/xpn/xwiki/web/SaveAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/SaveAction.java (revision 4044)
+++ 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: src/main/java/com/xpn/xwiki/web/PropAddAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/PropAddAction.java (revision 4044)
+++ 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: src/main/java/com/xpn/xwiki/web/ObjectAddAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/ObjectAddAction.java (revision 4044)
+++ 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: src/main/java/com/xpn/xwiki/web/PropUpdateAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/PropUpdateAction.java (revision 4044)
+++ 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: src/main/resources/ApplicationResources.properties
===================================================================
--- src/main/resources/ApplicationResources.properties (revision 4044)
+++ 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
Index: src/main/resources/xwiki.derby.hbm.xml
===================================================================
--- src/main/resources/xwiki.derby.hbm.xml (revision 4044)
+++ src/main/resources/xwiki.derby.hbm.xml (working copy)
@@ -107,17 +107,33 @@
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: src/main/resources/xwiki.oracle.hbm.xml
===================================================================
--- src/main/resources/xwiki.oracle.hbm.xml (revision 4044)
+++ src/main/resources/xwiki.oracle.hbm.xml (working copy)
@@ -101,17 +101,33 @@
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: src/main/resources/xwiki.hbm.xml
===================================================================
--- src/main/resources/xwiki.hbm.xml (revision 4044)
+++ src/main/resources/xwiki.hbm.xml (working copy)
@@ -99,17 +99,30 @@
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: pom.xml
===================================================================
--- pom.xml (revision 4044)
+++ pom.xml (working copy)
@@ -83,13 +83,13 @@
org.suigeneris
jrcs.diff
- 0.3.0
+ 0.4.1
xwiki
org.suigeneris
jrcs.rcs
- 0.3.0
+ 0.4.1
xwiki
@@ -519,7 +519,11 @@
**/content/**/*.java,
**/XWikiMessageTool.java,
**/XWikiListFilter.java,
- **/MyPersistentLoginManager.java
+ **/MyPersistentLoginManager.java,
+ **/XWikiRCS*.java,
+ **/RevisionInfo.java
+
**/RenamePageReplaceLinkHandler.java
@@ -560,4 +564,4 @@
-
\ No newline at end of file
+