[xwiki-notifications] r6580 - in xwiki-platform/core/trunk: . xwiki-patchservice xwiki-patchservice/src xwiki-patchservice/src/main xwiki-patchservice/src/main/java xwiki-patchservice/src/main/java/org xwiki-patchservice/src/main/java/org/xwiki xwiki-patchservice/src/main/java/org/xwiki/platform xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/web xwiki-patchservice/src/main/resources xwiki-patchservice/src/main/resources/META-INF xwiki-patchservice/src/main/resources/META-INF/services xwiki-patchservice/src/test xwiki-patchservice/src/test/java xwiki-patchservice/src/test/java/org xwiki-patchservice/src/test/java/org/xwiki xwiki-patchservice/src/test/java/org/xwiki/platform

sdumitriu (SVN) notifications at xwiki.org
Wed Jan 2 12:37:01 CET 2008


Author: sdumitriu
Date: 2008-01-02 12:37:01 +0100 (Wed, 02 Jan 2008)
New Revision: 6580

Added:
   xwiki-platform/core/trunk/xwiki-patchservice/
   xwiki-platform/core/trunk/xwiki-patchservice/pom.xml
   xwiki-platform/core/trunk/xwiki-patchservice/src/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/LogicalTime.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Operation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/OperationFactory.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Originator.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Patch.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchCreator.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchId.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchSet.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Position.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOriginator.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatch.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchId.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchSet.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/AbstractOperationImpl.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertySetOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentDeleteOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentInsertOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/LogicalTimeImpl.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OperationFactoryImpl.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OriginatorImpl.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PatchIdImpl.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PropertySetOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/web/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/web/PatchServiceAction.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/resources/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/resources/META-INF/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/resources/META-INF/services/
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/resources/META-INF/services/org.xwiki.platform.patchservice.api.RWOperation
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ClassPropertyOperationsTest.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ContentOperationsTest.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PropertyOperationsTest.java
Log:
XWIKI-1978: Create a new module for the patchservice
Done.
XWIKI-1977: Create a patchservice data model
Almost done.


Added: xwiki-platform/core/trunk/xwiki-patchservice/pom.xml
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/pom.xml	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/pom.xml	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,65 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.xpn.xwiki.platform</groupId>
+    <artifactId>xwiki-core-parent</artifactId>
+    <version>1.3-SNAPSHOT</version>
+  </parent>
+  <groupId>org.xwiki.platform</groupId>
+  <artifactId>xwiki-core-patchservice</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>xwiki-core-patchservice</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.xpn.xwiki.platform</groupId>
+      <artifactId>xwiki-core</artifactId>
+      <version>1.3-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.santuario</groupId>
+      <artifactId>xmlsec</artifactId>
+      <version>1.4.0</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+      <version>1.3</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <!-- Needed for the tests to run, otherwise a NoClassDefFoundError occurs -->
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.4</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <dependencies>
+          <dependency>
+            <groupId>com.xpn.xwiki.platform</groupId>
+            <artifactId>xwiki-build-verifications</artifactId>
+            <version>${platform.tools.version}</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+    </plugins>
+  </build>
+</project>


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/pom.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/LogicalTime.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/LogicalTime.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/LogicalTime.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,13 @@
+package org.xwiki.platform.patchservice.api;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.xpn.xwiki.XWikiException;
+
+public interface LogicalTime extends Comparable
+{
+    Element toXml(Document doc) throws XWikiException;
+
+    void fromXml(Element e) throws XWikiException;
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/LogicalTime.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Operation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Operation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Operation.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,150 @@
+package org.xwiki.platform.patchservice.api;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+/**
+ * An <tt>Operation</tt> is the basic unit of change affecting a document. Currently there are 5
+ * types of possible changes:
+ * <ul>
+ * <li>changes affecting the document content;</li>
+ * <li>changes affecting the document properties (author, date, language...);</li>
+ * <li>changes affecting the Class properties (or property definitions);</li>
+ * <li>changes affecting the object properties;</li>
+ * <li>changes affecting the attachments.</li>
+ * </ul>
+ * <p>
+ * Editing and saving a new version of a document is equivalent to applying several operations. For
+ * example, between two consecutive document versions there can be several content operations
+ * (delete a continuous portion of text, insert new text at a certain position, insert new text at
+ * another position) and several document properties operations (change the author, change the
+ * modification date).
+ * </p>
+ * <p>
+ * This interface describes a read-only operation, one that can only be applied on a document.
+ * {@link RWOperation} describes a read-write operation, one that can be programatically
+ * created/defined.
+ * </p>
+ * 
+ * @see RWOperation
+ * @version $Id: $
+ */
+public interface Operation
+{
+    /* Operation type flags */
+    /**
+     * Operation affecting the document content: Insert some text at a certain position.
+     */
+    String TYPE_CONTENT_INSERT = "content-insert";
+
+    /**
+     * Operation affecting the document content: Delete some text from a certain position.
+     */
+    String TYPE_CONTENT_DELETE = "content-delete";
+
+    /**
+     * Operation affecting the document properties: Set a new value for a document property.
+     */
+    String TYPE_PROPERTY_SET = "property-set";
+
+    /**
+     * Operation affecting the contained Class: Add a new property definition.
+     */
+    String TYPE_CLASS_PROPERTY_ADD = "class-prop-add";
+
+    /**
+     * Operation affecting the contained Class: Change a property definition.
+     */
+    String TYPE_CLASS_PROPERTY_CHANGE = "class-prop-change";
+
+    /**
+     * Operation affecting the contained Class: Delete a property definition.
+     */
+    String TYPE_CLASS_PROPERTY_DELETE = "class-prop-delete";
+
+    /**
+     * Operation affecting an attached object: Add a new object.
+     */
+    String TYPE_OBJECT_ADD = "object-add";
+
+    /**
+     * Operation affecting an attached object: Delete an existing object.
+     */
+    String TYPE_DBJECT_DELETE = "object-delete";
+
+    /**
+     * Operation affecting an attached object: Change the value for an object property.
+     */
+    String TYPE_OBJECT_PROPERTY_SET = "object-prop-set";
+
+    /**
+     * Operation affecting an attached object: Insert some text at a certain position inside a
+     * multiline object property.
+     */
+    String TYPE_OBJECT_PROPERTY_INSERT_AT = "object-prop-textinsert";
+
+    /**
+     * Operation affecting an attached object: Delete some text from a certain position from inside
+     * a multiline object property.
+     */
+    String TYPE_OBJECT_PROPERTY_DELETE_AT = "object-prop-textdelete";
+
+    /**
+     * Operation affecting the document attachments: Add a new attachment.
+     */
+    String TYPE_ATTACHMENT_ADD = "attachment-add";
+
+    /**
+     * Operation affecting the document attachments: Set a new content (version) for an existing
+     * attachment.
+     */
+    String TYPE_ATTACHMENT_SET = "attachment-set";
+
+    /**
+     * Operation affecting the document attachments: Delete an existing attachment.
+     */
+    String TYPE_ATTACHMENT_DELETE = "attachment-delete";
+
+    /* Operation metadata */
+    /**
+     * Get the type of this operation.
+     * 
+     * @return A string identifying the operation type, one of the constant values defined in this
+     *         class, or <tt>null</tt> if this operation was not properly initialized.
+     */
+    String getType();
+
+    /* Actions */
+    /**
+     * Serialize this operation as a DOM Element that can be inserted in the given DOM Document.
+     * 
+     * @param doc A DOM Document used for generating a compatible Element. The document is not
+     *            changed, as the constructed Element is just returned, not inserted in the
+     *            document.
+     * @return The operation exported as a DOM Element.
+     * @throws XWikiException If the Operation is not well defined.
+     */
+    Element toXml(Document doc) throws XWikiException;
+
+    /**
+     * Load the operation from an XML.
+     * 
+     * @param e A DOM Element defining the Operation.
+     * @throws XWikiException If the provided element is not a valid (or compatible) exported
+     *             Operation.
+     */
+    void fromXml(Element e) throws XWikiException;
+
+    /**
+     * Apply this operation on a document.
+     * 
+     * @param doc The document being patched.
+     * @throws XWikiException If the patch cannot be applied, either because the operation is not
+     *             well defined, or is not compatible with the document version (a conflict was
+     *             detected).
+     */
+    void apply(XWikiDocument doc) throws XWikiException;
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Operation.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/OperationFactory.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/OperationFactory.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/OperationFactory.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,12 @@
+package org.xwiki.platform.patchservice.api;
+
+import org.w3c.dom.Element;
+
+import com.xpn.xwiki.XWikiException;
+
+public interface OperationFactory
+{
+    RWOperation newOperation(String type) throws XWikiException;
+
+    Operation loadOperation(Element e) throws XWikiException;
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/OperationFactory.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Originator.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Originator.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Originator.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,19 @@
+package org.xwiki.platform.patchservice.api;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.xpn.xwiki.XWikiException;
+
+public interface Originator
+{
+    String getAuthor();
+
+    String getHostId();
+
+    String getWikiId();
+
+    Element toXml(Document doc) throws XWikiException;
+
+    void fromXml(Element e) throws XWikiException;
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Originator.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Patch.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Patch.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Patch.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,47 @@
+package org.xwiki.platform.patchservice.api;
+
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+public interface Patch
+{
+    String getSpecVersion();
+
+    PatchId getId();
+
+    Originator getOriginator();
+
+    String getDescription();
+
+    List getOperations();
+
+    /*
+     * We shouldn't make our own hash/sign methods, but instead use Standard W3C XML signatures. See
+     * http://santuario.apache.org/
+     */
+    // String getHash();
+    //
+    // boolean checkHash();
+    //
+    // String getSignature();
+    //
+    // boolean checkSignature();
+    Element toXml() throws XWikiException;
+
+    Element toXml(Document doc) throws XWikiException;
+
+    void fromXml(Element e) throws XWikiException;
+
+    /**
+     * Apply this patch on a document.
+     * 
+     * @param doc The document being patched.
+     * @throws XWikiException if the patch cannot be applied on the document.
+     */
+    void apply(XWikiDocument doc) throws XWikiException;
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Patch.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchCreator.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchCreator.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchCreator.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,8 @@
+package org.xwiki.platform.patchservice.api;
+
+import com.xpn.xwiki.doc.XWikiDocument;
+
+public interface PatchCreator
+{
+    Patch getPatch(XWikiDocument oldDoc, XWikiDocument newDoc);
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchCreator.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchId.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchId.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchId.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,23 @@
+package org.xwiki.platform.patchservice.api;
+
+import java.util.Date;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.xpn.xwiki.XWikiException;
+
+public interface PatchId
+{
+    String getHostId();
+
+    LogicalTime getLogicalTime();
+
+    Date getTime();
+
+    String getDocumentId();
+
+    Element toXml(Document doc) throws XWikiException;
+
+    void fromXml(Element e) throws XWikiException;
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchId.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchSet.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchSet.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchSet.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,27 @@
+package org.xwiki.platform.patchservice.api;
+
+import java.util.List;
+
+import org.w3c.dom.Element;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+public interface PatchSet
+{
+    List getVersionRange();
+
+    List getPatches();
+
+    Element toXml() throws XWikiException;
+
+    void fromXml(Element e) throws XWikiException;
+
+    /**
+     * Apply this patch set on a document.
+     * 
+     * @param doc The document being patched.
+     * @return The document with all the patches in this patch set applied.
+     */
+    void apply(XWikiDocument doc) throws XWikiException;
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/PatchSet.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Position.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Position.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Position.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,57 @@
+package org.xwiki.platform.patchservice.api;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.xpn.xwiki.XWikiException;
+
+public interface Position
+{
+    /**
+     * Checks if the position is still valid for the given text.
+     * 
+     * @param text The text where this position is supposed to be defined.
+     * @return True if the position is valid for the given text, false otherwise. Some
+     *         implementations can return true even if the position does not match exactly, but can
+     *         be identified in the text.
+     */
+    boolean checkPosition(String text);
+
+    /**
+     * Returns the text between the start of the text and this Position.
+     * 
+     * @param text The text where this position is supposed to be defined.
+     * @return The portion of text before this position, or <tt>null</tt> if the position is not
+     *         valid.
+     */
+    String getTextBeforePosition(String text);
+
+    /**
+     * Returns the text between this Position and the end of the text.
+     * 
+     * @param text The text where this position is supposed to be defined.
+     * @return The portion of text after this position, or <tt>null</tt> if the position is not
+     *         valid.
+     */
+    String getTextAfterPosition(String text);
+
+    /**
+     * Serialize this position as a DOM Element that can be inserted in the given DOM Document.
+     * 
+     * @param doc A DOM Document used for generating a compatible Element. The document is not
+     *            changed, as the constructed Element is just returned, not inserted in the
+     *            document.
+     * @return The operation exported as a DOM Element.
+     * @throws XWikiException If the Operation is not well defined.
+     */
+    Element toXml(Document doc) throws XWikiException;
+
+    /**
+     * Load the operation from an XML.
+     * 
+     * @param e A DOM Element defining the Operation.
+     * @throws XWikiException If the provided element is not a valid (or compatible) exported
+     *             Operation.
+     */
+    void fromXml(Element e) throws XWikiException;
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Position.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOperation.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,54 @@
+package org.xwiki.platform.patchservice.api;
+
+import java.io.InputStream;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * A read-write operation, or one that can be defined using method calls. The 
+ * @see Operation
+ */
+public interface RWOperation extends Operation
+{
+    /* Operations affeting the content of the document */
+    /**
+     * Record a text insert operation in the document content.
+     * @param text The text being inserted.
+     * @param position The position where the text is inserted.
+     * @return True if the action was successfully stored in the object, false otherwise.
+     */
+    boolean insert(String text, int position);
+
+    boolean delete(String text, int position);
+
+    /* Operations affeting the document metadata (name, author, language etc. */
+    boolean setProperty(String property, String value);
+
+    /* Operations affeting the XObjectDefinition stored in a document */
+    boolean createType(String propertyType, Map properties);
+
+    boolean modifyType(String propertyName, Map properties);
+
+    boolean deleteType(String propertyName);
+
+    /* Operations affeting the document's objects */
+    boolean addObject(String objectClass);
+
+    boolean deleteObject(String objectClass, int index);
+
+    boolean setObjectProperty(String objectClass, String index, String propertyName, String value);
+
+    boolean insertInProperty(String property, String text, int position);
+
+    boolean deleteFromProperty(String property, String text, int position);
+
+    /* Operations affeting the attachments */
+    boolean setAttachment(InputStream is);
+
+    boolean deleteAttachment(String name);
+
+    /* Operation metadata */
+    void setTime(Date time);
+
+    void setType(String type);
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOperation.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOriginator.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOriginator.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOriginator.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,10 @@
+package org.xwiki.platform.patchservice.api;
+
+public interface RWOriginator extends Originator
+{
+    void setAuthor(String author);
+
+    void setHostId(String hostId);
+
+    void setWikiId(String  wikiId);
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOriginator.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatch.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatch.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatch.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,32 @@
+package org.xwiki.platform.patchservice.api;
+
+import java.util.List;
+
+public interface RWPatch extends Patch
+{
+    void setSpecVersion(String specVersion);
+
+    void setId(PatchId id);
+
+    void setOriginator(Originator originator);
+
+    void setDescription(String description);
+
+    void setOperations(List operations);
+
+    void addOperation(Operation op);
+
+    void clearOperations();
+
+    /*
+     * We shouldn't make our own hash/sign methods, but instead use Standard W3C XML signatures. See
+     * http://santuario.apache.org/
+     */
+    // void setHash(String hash);
+    //
+    // void computeHash();
+    //
+    // void setSignature(String sign);
+    //
+    // void sign();
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatch.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchId.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchId.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchId.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,14 @@
+package org.xwiki.platform.patchservice.api;
+
+import java.util.Date;
+
+public interface RWPatchId extends PatchId
+{
+    void setHostId(String hostId);
+
+    void setLogicalTime(LogicalTime logicalTime);
+
+    void setTime(Date time);
+
+    void setDocumentId(String documentId);
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchId.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchSet.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchSet.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchSet.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,16 @@
+package org.xwiki.platform.patchservice.api;
+
+import java.util.List;
+
+public interface RWPatchSet extends PatchSet
+{
+    void setVersionRange(List versions);
+
+    void addVersion(PatchId version);
+
+    void setPatches(List patches);
+
+    void addPatch(Patch patch);
+
+    void clearPatchset();
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWPatchSet.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/AbstractOperationImpl.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/AbstractOperationImpl.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/AbstractOperationImpl.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,118 @@
+package org.xwiki.platform.patchservice.impl;
+
+import java.io.InputStream;
+import java.util.Date;
+import java.util.Map;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.RWOperation;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+public abstract class AbstractOperationImpl implements RWOperation
+{
+    public static final String NODE_NAME = "operation";
+    public static final String TYPE_ATTRIBUTE_NAME = "type";
+    public static final String TEXT_NODE_NAME = "text";
+    public static final String OBJECT_NODE_NAME = "object";
+    public static final String ATTACHMENT_NODE_NAME = "attachment";
+    public static final String PROPERTY_NODE_NAME = "property";
+
+    private Date time;
+
+    private String type;
+
+    public boolean addObject(String objectClass)
+    {
+        return false;
+    }
+
+    public boolean createType(String propertyType, Map properties)
+    {
+        return false;
+    }
+
+    public boolean delete(String text, int position)
+    {
+        return false;
+    }
+
+    public boolean deleteAttachment(String name)
+    {
+        return false;
+    }
+
+    public boolean deleteFromProperty(String property, String text, int position)
+    {
+        return false;
+    }
+
+    public boolean deleteObject(String objectClass, int index)
+    {
+        return false;
+    }
+
+    public boolean deleteType(String propertyName)
+    {
+        return false;
+    }
+
+    public boolean insert(String text, int position)
+    {
+        return false;
+    }
+
+    public boolean insertInProperty(String property, String text, int position)
+    {
+        return false;
+    }
+
+    public boolean modifyType(String propertyName, Map properties)
+    {
+        return false;
+    }
+
+    public boolean setAttachment(InputStream is)
+    {
+        return false;
+    }
+
+    public boolean setObjectProperty(String objectClass, String index, String propertyName,
+        String value)
+    {
+        return false;
+    }
+
+    public boolean setProperty(String property, String value)
+    {
+        return false;
+    }
+
+    public void setTime(Date date)
+    {
+        this.time = date;
+    }
+
+    public void setType(String type)
+    {
+        this.type = type;
+    }
+
+    public Date getTime()
+    {
+        return this.time;
+    }
+
+    public String getType()
+    {
+        return this.type;
+    }
+
+    public abstract void apply(XWikiDocument doc) throws XWikiException;
+
+    public abstract void fromXml(Element e) throws XWikiException;
+
+    public abstract Element toXml(Document doc) throws XWikiException;
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/AbstractOperationImpl.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertySetOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertySetOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertySetOperation.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,152 @@
+package org.xwiki.platform.patchservice.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xwiki.platform.patchservice.api.Operation;
+import org.xwiki.platform.patchservice.api.RWOperation;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.classes.BaseClass;
+import com.xpn.xwiki.objects.classes.PropertyClass;
+import com.xpn.xwiki.objects.meta.MetaClass;
+import com.xpn.xwiki.objects.meta.PropertyMetaClass;
+
+public class ClassPropertySetOperation extends AbstractOperationImpl implements RWOperation
+{
+    public static final String TYPE_NODE_NAME = "type";
+
+    public static final String PROPERTY_NAME_ATTRIBUTE_NAME = "name";
+
+    public static final String PROPERTY_VALUE_ATTRIBUTE_NAME = "value";
+
+    private String propertyType;
+
+    private Map propertyConfig;
+
+    static {
+        OperationFactoryImpl.getInstance().registerTypeProvider(
+            Operation.TYPE_CLASS_PROPERTY_ADD, ClassPropertySetOperation.class);
+        OperationFactoryImpl.getInstance().registerTypeProvider(
+            Operation.TYPE_CLASS_PROPERTY_CHANGE, ClassPropertySetOperation.class);
+    }
+
+    public ClassPropertySetOperation()
+    {
+        this.setType(Operation.TYPE_CLASS_PROPERTY_ADD);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void apply(XWikiDocument doc) throws XWikiException
+    {
+        BaseClass bclass = doc.getxWikiClass();
+        bclass.setName(doc.getFullName());
+        MetaClass mclass = MetaClass.getMetaClass();
+        PropertyMetaClass pmclass = (PropertyMetaClass) mclass.get(this.propertyType);
+        if (pmclass != null) {
+            PropertyClass pclass = (PropertyClass) pmclass.newObject(null);
+            pclass.setObject(bclass);
+            pclass.getxWikiClass(null).fromMap(propertyConfig, pclass);
+            bclass.put(pclass.getName(), pclass);
+        } else {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                "Invalid operation type : " + this.propertyType);
+        }
+    }
+
+    public boolean createType(String propertyType, Map properties)
+    {
+        this.propertyType = propertyType;
+        this.propertyConfig = new HashMap();
+        for (Iterator it = properties.keySet().iterator(); it.hasNext();) {
+            String prop = (String) it.next();
+            this.propertyConfig.put(prop, properties.get(prop).toString());
+        }
+        this.setType(Operation.TYPE_CLASS_PROPERTY_ADD);
+        return true;
+    }
+
+    public boolean modifyType(String propertyType, Map properties)
+    {
+        this.propertyType = propertyType;
+        this.propertyConfig = properties;
+        this.setType(Operation.TYPE_CLASS_PROPERTY_CHANGE);
+        return true;
+    }
+
+    public void fromXml(Element e) throws XWikiException
+    {
+        this.setType(e.getAttribute(TYPE_ATTRIBUTE_NAME));
+        this.propertyType = e.getElementsByTagName(TYPE_NODE_NAME).item(0).getTextContent();
+        this.propertyConfig = new HashMap();
+        NodeList properties = e.getElementsByTagName(PROPERTY_NODE_NAME);
+        for (int i = 0; i < properties.getLength(); ++i) {
+            Element prop = (Element) properties.item(i);
+            String name = prop.getAttribute(PROPERTY_NAME_ATTRIBUTE_NAME);
+            String value = prop.getAttribute(PROPERTY_VALUE_ATTRIBUTE_NAME);
+            propertyConfig.put(name, value);
+        }
+    }
+
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = doc.createElement(AbstractOperationImpl.NODE_NAME);
+        xmlNode.setAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME, this.getType());
+        Element typeNode = doc.createElement(TYPE_NODE_NAME);
+        typeNode.appendChild(doc.createTextNode(this.propertyType));
+        xmlNode.appendChild(typeNode);
+        for (Iterator it = propertyConfig.keySet().iterator(); it.hasNext();) {
+            Element propertyNode = doc.createElement(PROPERTY_NODE_NAME);
+            String propName = (String) it.next();
+            propertyNode.setAttribute(PROPERTY_NAME_ATTRIBUTE_NAME, propName);
+            propertyNode.setAttribute(PROPERTY_VALUE_ATTRIBUTE_NAME, propertyConfig.get(propName)
+                .toString());
+            xmlNode.appendChild(propertyNode);
+        }
+        return xmlNode;
+    }
+
+    public boolean equals(Object other)
+    {
+        try {
+            ClassPropertySetOperation otherOperation = (ClassPropertySetOperation) other;
+            return (otherOperation.propertyType == this.propertyType)
+                && (this.propertyConfig.values().containsAll(otherOperation.propertyConfig
+                    .values()))
+                && (otherOperation.propertyConfig.values().containsAll(this.propertyConfig
+                    .values()))
+                && (this.propertyConfig.keySet().containsAll(otherOperation.propertyConfig
+                    .keySet()))
+                && (otherOperation.propertyConfig.keySet().containsAll(this.propertyConfig
+                    .keySet()));
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    public int hashCode()
+    {
+        // return new HashCodeBuilder(11, 13).append(this.propertyType).append(this.propertyConfig)
+        // .toHashCode();
+        int i =
+            new HashCodeBuilder(11, 13).append(this.propertyType).append(this.propertyConfig)
+                .toHashCode();
+        System.out.print(" asd > " + i);
+        return i;
+    }
+
+    public String toString()
+    {
+        return Operation.TYPE_CLASS_PROPERTY_ADD + ": [" + this.propertyType + "] = "
+            + this.propertyConfig;
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertySetOperation.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentDeleteOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentDeleteOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentDeleteOperation.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,109 @@
+package org.xwiki.platform.patchservice.impl;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.Operation;
+import org.xwiki.platform.patchservice.api.RWOperation;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+public class ContentDeleteOperation extends AbstractOperationImpl implements RWOperation
+{
+    public static final String POSITION_ATTRIBUTE_NAME = "position";
+
+    private int position = -1;
+
+    private String removedContent;
+
+    static {
+        OperationFactoryImpl.getInstance().registerTypeProvider(Operation.TYPE_CONTENT_DELETE,
+            ContentDeleteOperation.class);
+    }
+
+    public ContentDeleteOperation()
+    {
+        this.setType(Operation.TYPE_CONTENT_DELETE);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void apply(XWikiDocument doc) throws XWikiException
+    {
+        try {
+            String content = doc.getContent();
+            if (content.indexOf(this.removedContent, this.position) != this.position) {
+                throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                    XWikiException.ERROR_XWIKI_UNKNOWN,
+                    "Patch does not fit. Expected ["
+                        + StringUtils.abbreviate(this.removedContent, 20)
+                        + "], but found ["
+                        + StringUtils.abbreviate(StringUtils.mid(content, this.position,
+                            this.removedContent.length()), 20) + "]");
+            }
+            content =
+                content.substring(0, position)
+                    + content.substring(position + this.removedContent.length());
+            doc.setContent(content);
+        } catch (StringIndexOutOfBoundsException ex) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                "Patch cannot be applied",
+                ex);
+        }
+    }
+
+    public boolean delete(String text, int position)
+    {
+        this.removedContent = text;
+        this.position = position;
+        return true;
+    }
+
+    public void fromXml(Element e) throws XWikiException
+    {
+        Element textNode = (Element) e.getFirstChild();
+        this.position = Integer.parseInt(textNode.getAttribute(POSITION_ATTRIBUTE_NAME));
+        this.removedContent = StringEscapeUtils.unescapeXml(textNode.getTextContent());
+    }
+
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = doc.createElement(AbstractOperationImpl.NODE_NAME);
+        xmlNode.setAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME,
+            Operation.TYPE_CONTENT_DELETE);
+        Element textNode = doc.createElement(TEXT_NODE_NAME);
+        textNode.setAttribute(POSITION_ATTRIBUTE_NAME, this.position + "");
+        textNode
+            .appendChild(doc.createTextNode(StringEscapeUtils.escapeXml(this.removedContent)));
+        xmlNode.appendChild(textNode);
+        return xmlNode;
+    }
+
+    public boolean equals(Object other)
+    {
+        try {
+            ContentDeleteOperation otherOperation = (ContentDeleteOperation) other;
+            return (otherOperation.position == this.position)
+                && otherOperation.removedContent.equals(this.removedContent);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    public int hashCode()
+    {
+        return new HashCodeBuilder(5, 7).append(this.position).append(this.removedContent)
+            .toHashCode();
+    }
+
+    public String toString()
+    {
+        return Operation.TYPE_CONTENT_DELETE + ": [" + this.removedContent + "] at "
+            + this.position;
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentDeleteOperation.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentInsertOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentInsertOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentInsertOperation.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,93 @@
+package org.xwiki.platform.patchservice.impl;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.Operation;
+import org.xwiki.platform.patchservice.api.RWOperation;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+public class ContentInsertOperation extends AbstractOperationImpl implements RWOperation
+{
+    public static final String POSITION_ATTRIBUTE_NAME = "position";
+
+    private int position = -1;
+
+    private String addedContent;
+
+    static {
+        OperationFactoryImpl.getInstance().registerTypeProvider(Operation.TYPE_CONTENT_INSERT,
+            ContentInsertOperation.class);
+    }
+    
+    public ContentInsertOperation()
+    {
+        this.setType(Operation.TYPE_CONTENT_INSERT);
+    }
+
+    public void apply(XWikiDocument doc) throws XWikiException
+    {
+        try {
+            String content = doc.getContent();
+            content =
+                content.substring(0, position) + this.addedContent + content.substring(position);
+            doc.setContent(content);
+        } catch (StringIndexOutOfBoundsException ex) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                "Patch cannot be applied",
+                ex);
+        }
+    }
+
+    public boolean insert(String text, int position)
+    {
+        this.addedContent = text;
+        this.position = position;
+        return true;
+    }
+
+    public void fromXml(Element e) throws XWikiException
+    {
+        Element textNode = (Element) e.getFirstChild();
+        this.position = Integer.parseInt(textNode.getAttribute(POSITION_ATTRIBUTE_NAME));
+        this.addedContent = StringEscapeUtils.unescapeXml(textNode.getTextContent());
+    }
+
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = doc.createElement(AbstractOperationImpl.NODE_NAME);
+        xmlNode.setAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME,
+            Operation.TYPE_CONTENT_INSERT);
+        Element textNode = doc.createElement(TEXT_NODE_NAME);
+        textNode.setAttribute(POSITION_ATTRIBUTE_NAME, this.position + "");
+        textNode.appendChild(doc.createTextNode(StringEscapeUtils.escapeXml(this.addedContent)));
+        xmlNode.appendChild(textNode);
+        return xmlNode;
+    }
+
+    public boolean equals(Object other)
+    {
+        try {
+            ContentInsertOperation otherOperation = (ContentInsertOperation) other;
+            return (otherOperation.position == this.position)
+                && otherOperation.addedContent.equals(this.addedContent);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    public int hashCode()
+    {
+        return new HashCodeBuilder(3, 5).append(this.position).append(this.addedContent)
+            .toHashCode();
+    }
+
+    public String toString()
+    {
+        return Operation.TYPE_CONTENT_INSERT + ": [" + this.addedContent + "] at " + this.position;
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentInsertOperation.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/LogicalTimeImpl.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/LogicalTimeImpl.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/LogicalTimeImpl.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,42 @@
+package org.xwiki.platform.patchservice.impl;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.LogicalTime;
+
+import com.xpn.xwiki.XWikiException;
+
+public class LogicalTimeImpl implements LogicalTime
+{
+    public static final String NODE_NAME = "logicalTime";
+
+    public LogicalTimeImpl()
+    {
+    }
+
+    public LogicalTimeImpl(Element e) throws XWikiException
+    {
+        fromXml(e);
+    }
+
+    public void fromXml(Element e) throws XWikiException
+    {
+        // TODO Auto-generated method stub
+    }
+
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = doc.createElement(NODE_NAME);
+        return xmlNode;
+    }
+
+    public int compareTo(Object other)
+    {
+        if (!(other instanceof LogicalTimeImpl))
+        {
+            return -1;
+        }
+        return 0;
+    }
+
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/LogicalTimeImpl.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OperationFactoryImpl.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OperationFactoryImpl.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OperationFactoryImpl.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,96 @@
+package org.xwiki.platform.patchservice.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.radeox.util.Service;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.Operation;
+import org.xwiki.platform.patchservice.api.OperationFactory;
+import org.xwiki.platform.patchservice.api.RWOperation;
+
+import com.xpn.xwiki.XWikiException;
+
+public class OperationFactoryImpl implements OperationFactory
+{
+    private static final Log LOG = LogFactory.getLog(OperationFactoryImpl.class);
+
+    private static OperationFactoryImpl theInstance = new OperationFactoryImpl();
+
+    private static boolean initialized;
+
+    public Map typeMap = new HashMap();
+
+    private OperationFactoryImpl()
+    {
+        // Private constructor so that it cannot be instantiated.
+    }
+
+    private static void init()
+    {
+        for (Iterator it = Service.providers(RWOperation.class); it.hasNext();) {
+            Operation op = (Operation) it.next();
+            LOG.info("Registering " + op.getClass().getCanonicalName() + " for type "
+                + op.getType());
+        }
+    }
+
+    public static OperationFactoryImpl getInstance()
+    {
+        if (!initialized) {
+            synchronized (OperationFactoryImpl.class) {
+                if (!initialized) {
+                    initialized = true;
+                    init();
+                }
+            }
+        }
+        return theInstance;
+    }
+
+    public RWOperation newOperation(String type) throws XWikiException
+    {
+        RWOperation op;
+        try {
+            Class opClass = (Class) typeMap.get(type);
+            op = (RWOperation) opClass.newInstance();
+        } catch (NullPointerException ex) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_NOT_IMPLEMENTED,
+                "No implementation registered for the operation type [" + type + "]");
+        } catch (InstantiationException ex) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_NOT_IMPLEMENTED,
+                "Error instantiating the implementation for the operation type [" + type + "]");
+        } catch (IllegalAccessException ex) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_NOT_IMPLEMENTED,
+                "The implementation for the operation type [" + type
+                    + "] does not have a public default constructor");
+        }
+        return op;
+    }
+
+    public Operation loadOperation(Element e) throws XWikiException
+    {
+        String type = e.getAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME);
+        Operation op = newOperation(type);
+        op.fromXml(e);
+        return op;
+    }
+
+    public void registerTypeProvider(String type, Class provider)
+    {
+        this.typeMap.put(type, provider);
+    }
+
+    public void registerTypeProvider(String[] types, Class provider)
+    {
+        for (int i = 0; i < types.length; ++i) {
+            this.registerTypeProvider(types[i], provider);
+        }
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OperationFactoryImpl.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OriginatorImpl.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OriginatorImpl.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OriginatorImpl.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,63 @@
+package org.xwiki.platform.patchservice.impl;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.RWOriginator;
+
+import com.xpn.xwiki.XWikiException;
+
+public class OriginatorImpl implements RWOriginator
+{
+    public static final String NODE_NAME = "originator";
+    public static final String AUTHOR_ATTRIBUTE_NAME = "author";
+    public static final String HOST_ATTRIBUTE_NAME = "host";
+    public static final String WIKI_ATTRIBUTE_NAME = "wiki";
+    private String author;
+    private String hostId;
+    private String wikiId;
+    public void setAuthor(String author)
+    {
+        this.author = author;
+    }
+
+    public void setHostId(String hostId)
+    {
+        this.hostId = hostId;
+    }
+
+    public void setWikiId(String wikiId)
+    {
+        this.wikiId = wikiId;
+    }
+
+    public void fromXml(Element e) throws XWikiException
+    {
+        this.author = e.getAttribute(AUTHOR_ATTRIBUTE_NAME);
+        this.hostId = e.getAttribute(HOST_ATTRIBUTE_NAME);
+        this.wikiId = e.getAttribute(WIKI_ATTRIBUTE_NAME);
+    }
+
+    public String getAuthor()
+    {
+        return this.author;
+    }
+
+    public String getHostId()
+    {
+        return this.hostId;
+    }
+
+    public String getWikiId()
+    {
+        return this.wikiId;
+    }
+
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = doc.createElement(NODE_NAME);
+        xmlNode.setAttribute(AUTHOR_ATTRIBUTE_NAME, this.author);
+        xmlNode.setAttribute(HOST_ATTRIBUTE_NAME, this.hostId);
+        xmlNode.setAttribute(WIKI_ATTRIBUTE_NAME, this.wikiId);
+        return xmlNode;
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OriginatorImpl.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PatchIdImpl.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PatchIdImpl.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PatchIdImpl.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,103 @@
+package org.xwiki.platform.patchservice.impl;
+
+import java.util.Date;
+
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.lang.time.DateUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.LogicalTime;
+import org.xwiki.platform.patchservice.api.RWPatchId;
+
+import com.xpn.xwiki.XWikiException;
+
+public class PatchIdImpl implements RWPatchId
+{
+    public static final String NODE_NAME = "id";
+
+    public static final String DOCID_ATTRIBUTE_NAME = "doc";
+
+    public static final String HOSTID_ATTRIBUTE_NAME = "host";
+
+    public static final String TIME_ATTRIBUTE_NAME = "time";
+
+    public static final String[] FORMATS =
+        new String[] {DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()};
+
+    private String documentId;
+
+    private String hostId;
+
+    private Date time;
+
+    private LogicalTime logicalTime;
+
+    public void setDocumentId(String documentId)
+    {
+        this.documentId = documentId;
+    }
+
+    public void setHostId(String hostId)
+    {
+        this.hostId = hostId;
+    }
+
+    public void setLogicalTime(LogicalTime logicalTime)
+    {
+        this.logicalTime = logicalTime;
+    }
+
+    public void setTime(Date time)
+    {
+        this.time = time;
+    }
+
+    public void fromXml(Element e) throws XWikiException
+    {
+        try {
+            this.documentId = e.getAttribute(DOCID_ATTRIBUTE_NAME);
+            this.hostId = e.getAttribute(HOSTID_ATTRIBUTE_NAME);
+            String timeText = e.getAttribute(TIME_ATTRIBUTE_NAME);
+            this.time = DateUtils.parseDate(timeText, FORMATS);
+            this.logicalTime =
+                new LogicalTimeImpl((Element) e.getElementsByTagName(LogicalTimeImpl.NODE_NAME)
+                    .item(0));
+        } catch (Exception ex) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_DOC_XML_PARSING,
+                "Invalid Patch XML",
+                ex);
+        }
+    }
+
+    public String getDocumentId()
+    {
+        return this.documentId;
+    }
+
+    public String getHostId()
+    {
+        return this.hostId;
+    }
+
+    public LogicalTime getLogicalTime()
+    {
+        return this.logicalTime;
+    }
+
+    public Date getTime()
+    {
+        return this.time;
+    }
+
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = doc.createElement(NODE_NAME);
+        xmlNode.setAttribute(DOCID_ATTRIBUTE_NAME, this.documentId);
+        xmlNode.setAttribute(HOSTID_ATTRIBUTE_NAME, this.hostId);
+        xmlNode.setAttribute(TIME_ATTRIBUTE_NAME, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT
+            .format(this.time));
+        xmlNode.appendChild(this.logicalTime.toXml(doc));
+        return xmlNode;
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PatchIdImpl.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PropertySetOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PropertySetOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PropertySetOperation.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,102 @@
+package org.xwiki.platform.patchservice.impl;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.Operation;
+import org.xwiki.platform.patchservice.api.RWOperation;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+public class PropertySetOperation extends AbstractOperationImpl implements RWOperation
+{
+    public static final String NAME_ATTRIBUTE_NAME = "name";
+
+    public static final String VALUE_ATTRIBUTE_NAME = "value";
+
+    private String propertyName;
+
+    private String propertyValue;
+
+    static {
+        OperationFactoryImpl.getInstance().registerTypeProvider(Operation.TYPE_PROPERTY_SET,
+            PropertySetOperation.class);
+    }
+
+    public PropertySetOperation()
+    {
+        this.setType(Operation.TYPE_PROPERTY_SET);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void apply(XWikiDocument doc) throws XWikiException
+    {
+        try {
+            doc.getClass().getMethod("set" + StringUtils.capitalize(propertyName),
+                new Class[] {String.class}).invoke(doc, new Object[] {this.propertyValue});
+        } catch (Exception ex) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                "Patch cannot be applied",
+                ex);
+        }
+    }
+
+    public boolean setProperty(String property, String value)
+    {
+        this.propertyName = property;
+        this.propertyValue = value;
+        return true;
+    }
+
+    public void fromXml(Element e) throws XWikiException
+    {
+        Element textNode = (Element) e.getFirstChild();
+        this.propertyName =
+            StringEscapeUtils.unescapeXml(textNode.getAttribute(NAME_ATTRIBUTE_NAME));
+        this.propertyValue =
+            StringEscapeUtils.unescapeXml(textNode.getAttribute(VALUE_ATTRIBUTE_NAME));
+    }
+
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = doc.createElement(AbstractOperationImpl.NODE_NAME);
+        xmlNode.setAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME,
+            Operation.TYPE_PROPERTY_SET);
+        Element propertyNode = doc.createElement(PROPERTY_NODE_NAME);
+        propertyNode.setAttribute(NAME_ATTRIBUTE_NAME, StringEscapeUtils
+            .escapeXml(this.propertyName));
+        propertyNode.setAttribute(VALUE_ATTRIBUTE_NAME, StringEscapeUtils
+            .escapeXml(this.propertyValue));
+        xmlNode.appendChild(propertyNode);
+        return xmlNode;
+    }
+
+    public boolean equals(Object other)
+    {
+        try {
+            PropertySetOperation otherOperation = (PropertySetOperation) other;
+            return otherOperation.propertyName.equals(this.propertyName)
+                && otherOperation.propertyValue.equals(this.propertyValue);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    public int hashCode()
+    {
+        return new HashCodeBuilder(7, 11).append(this.propertyName).append(this.propertyValue)
+            .toHashCode();
+    }
+
+    public String toString()
+    {
+        return Operation.TYPE_PROPERTY_SET + ": [" + this.propertyName + "] to ["
+            + this.propertyValue + "]";
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PropertySetOperation.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/web/PatchServiceAction.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/web/PatchServiceAction.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/web/PatchServiceAction.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,16 @@
+package org.xwiki.platform.patchservice.web;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.web.XWikiAction;
+
+public class PatchServiceAction extends XWikiAction
+{
+    /**
+     * @todo Write me!
+     */
+    public boolean action(XWikiContext context) throws XWikiException
+    {
+        return super.action(context);
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/web/PatchServiceAction.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/resources/META-INF/services/org.xwiki.platform.patchservice.api.RWOperation
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/resources/META-INF/services/org.xwiki.platform.patchservice.api.RWOperation	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/resources/META-INF/services/org.xwiki.platform.patchservice.api.RWOperation	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,4 @@
+org.xwiki.platform.patchservice.impl.ContentInsertOperation
+org.xwiki.platform.patchservice.impl.ContentDeleteOperation
+org.xwiki.platform.patchservice.impl.PropertySetOperation
+org.xwiki.platform.patchservice.impl.ClassPropertySetOperation

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ClassPropertyOperationsTest.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ClassPropertyOperationsTest.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ClassPropertyOperationsTest.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,106 @@
+package org.xwiki.platform;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.Operation;
+import org.xwiki.platform.patchservice.api.RWOperation;
+import org.xwiki.platform.patchservice.impl.OperationFactoryImpl;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseProperty;
+import com.xpn.xwiki.objects.classes.BaseClass;
+import com.xpn.xwiki.objects.classes.PropertyClass;
+
+public class ClassPropertyOperationsTest extends TestCase
+{
+    Document domDoc;
+
+    XWikiDocument doc;
+    
+    BaseClass bclass;
+
+    protected void setUp()
+    {
+        try {
+            domDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+            doc = new XWikiDocument();
+            doc.setFullName("XWiki.XWikiTestClass");
+            bclass = new BaseClass();
+            bclass.setName("XWiki.XWikiTestClass");
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void testApplyPropertyAddOperation() throws XWikiException
+    {
+        bclass.addTextField("prop1", "Property 1", 30);
+        bclass.addBooleanField("prop2", "Property 2", "yesno");
+        for (Iterator it = bclass.getFieldList().iterator(); it.hasNext();) {
+            RWOperation operation = getOperation((PropertyClass) it.next());
+            operation.apply(doc);
+        }
+        assertEquals(2, doc.getxWikiClass().getProperties().length);
+        assertNotNull(doc.getxWikiClass().getField("prop1"));
+        assertNotNull(doc.getxWikiClass().getField("prop2"));
+        assertNull(doc.getxWikiClass().getField("prop3"));
+        assertEquals("prop1", doc.getxWikiClass().get("prop1").getName());
+    }
+
+    public void testApplyTwicePropertyAddOperation() throws XWikiException
+    {
+        bclass.addTextField("prop1", "Property 1", 30);
+        RWOperation operation = getOperation((PropertyClass) bclass.getProperties()[0]);
+        operation.apply(doc);
+        operation.apply(doc);
+        assertEquals(1, doc.getxWikiClass().getProperties().length);
+        assertEquals("prop1", doc.getxWikiClass().get("prop1").getName());
+    }
+
+    public void testInvalidPropertyAddOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CLASS_PROPERTY_ADD);
+        operation.createType("invalid", new HashMap());
+        try {
+            operation.apply(doc);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        assertEquals(0, doc.getxWikiClass().getProperties().length);
+    }
+
+    public void testXmlRoundtripPropertyAddOperation() throws XWikiException
+    {
+        bclass.addTextField("prop1", "Property 1", 30);
+        RWOperation operation = getOperation((PropertyClass) bclass.getProperties()[0]);
+        Element e = operation.toXml(domDoc);
+        Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
+        assertEquals(loadedOperation, operation);
+    }
+
+    private RWOperation getOperation(PropertyClass property) throws XWikiException
+    {
+        String type = property.getClass().getCanonicalName();
+        Map config = new HashMap();
+        for (Iterator it2 = property.getFieldList().iterator(); it2.hasNext();) {
+            BaseProperty pr = (BaseProperty) it2.next();
+            config.put(pr.getName(), pr.getValue());
+        }
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CLASS_PROPERTY_ADD);
+        operation.createType(type, config);
+        return operation;
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ClassPropertyOperationsTest.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ContentOperationsTest.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ContentOperationsTest.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ContentOperationsTest.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,130 @@
+package org.xwiki.platform;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.Operation;
+import org.xwiki.platform.patchservice.api.RWOperation;
+import org.xwiki.platform.patchservice.impl.OperationFactoryImpl;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+public class ContentOperationsTest extends TestCase
+{
+    Document domDoc;
+
+    XWikiDocument doc;
+
+    protected void setUp()
+    {
+        try {
+            domDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+            doc = new XWikiDocument();
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void testApplyContentInsertOperation() throws XWikiException
+    {
+        doc.setContent("this is the content");
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
+        operation.insert("new ", 12);
+        operation.apply(doc);
+        assertEquals("this is the new content", doc.getContent());
+    }
+
+    public void testXmlRoundtripContentInsertOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
+        operation.insert("added <con\"ten>t", 10);
+        Element e = operation.toXml(domDoc);
+        Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
+        assertEquals(loadedOperation, operation);
+    }
+
+    public void testInvalidContentInsertOperation() throws XWikiException
+    {
+        doc.setContent("this is the short content");
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
+        operation.insert("something", 42);
+        try {
+            operation.apply(doc);
+            assertFalse(true);
+        } catch (XWikiException ex) {
+            // This is expected
+        }
+    }
+
+    public void testApplyContentDeleteOperation() throws XWikiException
+    {
+        doc.setContent("this is the old content");
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
+        operation.delete("old ", 12);
+        operation.apply(doc);
+        assertEquals("this is the content", doc.getContent());
+    }
+
+    public void testXmlRoundtripContentDeleteOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
+        operation.delete("something", 10);
+        Element e = operation.toXml(domDoc);
+        Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
+        assertEquals(operation, loadedOperation);
+    }
+
+    public void testInvalidContentDeleteOperation() throws XWikiException
+    {
+        doc.setContent("this is the short content");
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
+        operation.delete("something", 42);
+        try {
+            operation.apply(doc);
+            assertFalse(true);
+        } catch (XWikiException ex) {
+            // This is expected
+        }
+        operation.delete("this", 2);
+        try {
+            operation.apply(doc);
+            assertFalse(true);
+        } catch (XWikiException ex) {
+            // This is expected
+        }
+    }
+
+    public void testConsecutiveContentInsertDeleteOperations() throws XWikiException
+    {
+        doc.setContent("this is the old content");
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
+        operation.delete("old", 12);
+        operation.apply(doc);
+        operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
+        operation.insert("new", 12);
+        operation.apply(doc);
+        assertEquals("this is the new content", doc.getContent());
+        operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
+        operation.insert("restored", 15);
+        operation.apply(doc);
+        operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
+        operation.delete("new", 12);
+        operation.apply(doc);
+        assertEquals("this is the restored content", doc.getContent());
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ContentOperationsTest.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PropertyOperationsTest.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PropertyOperationsTest.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PropertyOperationsTest.java	2008-01-02 11:37:01 UTC (rev 6580)
@@ -0,0 +1,71 @@
+package org.xwiki.platform;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.Operation;
+import org.xwiki.platform.patchservice.api.RWOperation;
+import org.xwiki.platform.patchservice.impl.OperationFactoryImpl;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+public class PropertyOperationsTest extends TestCase
+{
+    Document domDoc;
+
+    XWikiDocument doc;
+
+    protected void setUp()
+    {
+        try {
+            domDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+            doc = new XWikiDocument();
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void testApplyPropertySetOperation() throws XWikiException
+    {
+        doc.setAuthor("XWiki.Admin");
+        doc.setCreator("XWiki.Admin");
+        doc.setLanguage("en");
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_PROPERTY_SET);
+        operation.setProperty("author", "XWiki.XWikiGuest");
+        operation.apply(doc);
+        operation.setProperty("language", "fr");
+        operation.apply(doc);
+        assertEquals("XWiki.XWikiGuest", doc.getAuthor());
+        assertEquals("fr", doc.getLanguage());
+        assertEquals("XWiki.Admin", doc.getCreator());
+    }
+
+    public void testXmlRoundtripPropertySetOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_PROPERTY_SET);
+        operation.setProperty("property", "value");
+        Element e = operation.toXml(domDoc);
+        Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
+        assertEquals(loadedOperation, operation);
+    }
+
+    public void testInvalidPropertySetOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_PROPERTY_SET);
+        operation.setProperty("invalidPropertyName", "value");
+        try {
+            operation.apply(doc);
+            assertFalse(true);
+        } catch (XWikiException ex) {
+            // This is expected
+        }
+    }
+}


Property changes on: xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PropertyOperationsTest.java
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the notifications mailing list