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

sdumitriu (SVN) notifications at xwiki.org
Thu Jan 3 15:11:30 CET 2008


Author: sdumitriu
Date: 2008-01-03 15:11:30 +0100 (Thu, 03 Jan 2008)
New Revision: 6613

Added:
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertyAddOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectAddOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectDeleteOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertyDeleteAtOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertyInsertAtOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertySetOperation.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/CheckAllOperationsImplementedTest.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ObjectOperationsTest.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PositionImplTest.java
Modified:
   xwiki-platform/core/trunk/xwiki-patchservice/pom.xml
   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/RWOperation.java
   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/ClassPropertyDeleteOperation.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/OperationFactoryImpl.java
   xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PositionImpl.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/resources/META-INF/services/org.xwiki.platform.patchservice.api.RWOperation
   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-1977: Create a patchservice data model
Reorganize the XML document structure.
Cleanup the XML import/export code.
Added some tests for PositionImpl.
Added Object operation implementation + tests.
Fix some bugs discovered by the tests.



Modified: xwiki-platform/core/trunk/xwiki-patchservice/pom.xml
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/pom.xml	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/pom.xml	2008-01-03 14:11:30 UTC (rev 6613)
@@ -46,6 +46,24 @@
       <version>2.4</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>jmock</groupId>
+      <artifactId>jmock</artifactId>
+      <version>1.1.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>jmock</groupId>
+      <artifactId>jmock-cglib</artifactId>
+      <version>1.1.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>xerces</groupId>
+      <artifactId>xercesImpl</artifactId>
+      <version>2.8.1</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <plugins>

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/Operation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -1,5 +1,6 @@
 package org.xwiki.platform.patchservice.api;
 
+import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.XWikiDocument;
 
@@ -50,17 +51,17 @@
     /**
      * Operation affecting the contained Class: Add a new property definition.
      */
-    String TYPE_CLASS_PROPERTY_ADD = "class-prop-add";
+    String TYPE_CLASS_PROPERTY_ADD = "class-property-add";
 
     /**
      * Operation affecting the contained Class: Change a property definition.
      */
-    String TYPE_CLASS_PROPERTY_CHANGE = "class-prop-change";
+    String TYPE_CLASS_PROPERTY_CHANGE = "class-property-change";
 
     /**
      * Operation affecting the contained Class: Delete a property definition.
      */
-    String TYPE_CLASS_PROPERTY_DELETE = "class-prop-delete";
+    String TYPE_CLASS_PROPERTY_DELETE = "class-property-delete";
 
     /**
      * Operation affecting an attached object: Add a new object.
@@ -70,24 +71,24 @@
     /**
      * Operation affecting an attached object: Delete an existing object.
      */
-    String TYPE_DBJECT_DELETE = "object-delete";
+    String TYPE_OBJECT_DELETE = "object-delete";
 
     /**
      * Operation affecting an attached object: Change the value for an object property.
      */
-    String TYPE_OBJECT_PROPERTY_SET = "object-prop-set";
+    String TYPE_OBJECT_PROPERTY_SET = "object-property-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";
+    String TYPE_OBJECT_PROPERTY_INSERT_AT = "object-property-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";
+    String TYPE_OBJECT_PROPERTY_DELETE_AT = "object-property-textdelete";
 
     /**
      * Operation affecting the document attachments: Add a new attachment.
@@ -123,5 +124,5 @@
      *             well defined, or is not compatible with the document version (a conflict was
      *             detected).
      */
-    void apply(XWikiDocument doc) throws XWikiException;
+    void apply(XWikiDocument doc, XWikiContext context) throws XWikiException;
 }

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -4,8 +4,8 @@
 import java.util.Map;
 
 /**
- * A read-write operation, or one that can be defined using method calls. The 
- *  
+ * A read-write operation, or one that can be defined using method calls. The
+ * 
  * @see Operation
  * @version $Id: $
  */
@@ -14,6 +14,7 @@
     /* 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.
@@ -26,22 +27,24 @@
     boolean setProperty(String property, String value);
 
     /* Operations affeting the XObjectDefinition stored in a document */
-    boolean createType(String propertyType, Map properties);
+    boolean createType(String className, String propertyName, String propertyType, Map properties);
 
-    boolean modifyType(String propertyName, Map properties);
+    boolean modifyType(String className, String propertyName, Map properties);
 
-    boolean deleteType(String propertyName);
+    boolean deleteType(String className, 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 setObjectProperty(String objectClass, int index, String propertyName, String value);
 
-    boolean insertInProperty(String property, String text, Position position);
+    boolean insertInProperty(String objectClass, int index, String property, String text,
+        Position position);
 
-    boolean deleteFromProperty(String property, String text, Position position);
+    boolean deleteFromProperty(String objectClass, int index, String property, String text,
+        Position position);
 
     /* Operations affeting the attachments */
     boolean setAttachment(InputStream is);

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/AbstractOperationImpl.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -3,23 +3,41 @@
 import java.io.InputStream;
 import java.util.Map;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 import org.xwiki.platform.patchservice.api.Position;
 import org.xwiki.platform.patchservice.api.RWOperation;
 
+import com.xpn.xwiki.XWikiException;
+
 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 OPERATION_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 OBJECT_TYPE_ATTRIBUTE_NAME = OPERATION_TYPE_ATTRIBUTE_NAME;
 
+    public static final String OBJECT_NUMBER_ATTRIBUTE_NAME = "number";
+
+    public static final String CLASS_NODE_NAME = "class";
+
+    public static final String CLASS_NAME_ATTRIBUTE_NAME = "name";
+
     public static final String PROPERTY_NODE_NAME = "property";
 
+    public static final String PROPERTY_NAME_ATTRIBUTE_NAME = CLASS_NAME_ATTRIBUTE_NAME;
+
+    public static final String PROPERTY_TYPE_ATTRIBUTE_NAME = OPERATION_TYPE_ATTRIBUTE_NAME;
+
+    public static final String PROPERTY_VALUE_ATTRIBUTE_NAME = "value";
+
+    public static final String ATTACHMENT_NODE_NAME = "attachment";
+
     private String type;
 
     /**
@@ -33,7 +51,8 @@
     /**
      * {@inheritDoc}
      */
-    public boolean createType(String propertyType, Map properties)
+    public boolean createType(String className, String propertyName, String propertyType,
+        Map properties)
     {
         return false;
     }
@@ -57,7 +76,8 @@
     /**
      * {@inheritDoc}
      */
-    public boolean deleteFromProperty(String property, String text, Position position)
+    public boolean deleteFromProperty(String objectClass, int index, String property,
+        String text, Position position)
     {
         return false;
     }
@@ -73,7 +93,7 @@
     /**
      * {@inheritDoc}
      */
-    public boolean deleteType(String propertyName)
+    public boolean deleteType(String className, String propertyName)
     {
         return false;
     }
@@ -89,7 +109,8 @@
     /**
      * {@inheritDoc}
      */
-    public boolean insertInProperty(String property, String text, Position position)
+    public boolean insertInProperty(String objectClass, int index, String property, String text,
+        Position position)
     {
         return false;
     }
@@ -97,7 +118,7 @@
     /**
      * {@inheritDoc}
      */
-    public boolean modifyType(String propertyName, Map properties)
+    public boolean modifyType(String className, String propertyName, Map properties)
     {
         return false;
     }
@@ -113,7 +134,7 @@
     /**
      * {@inheritDoc}
      */
-    public boolean setObjectProperty(String objectClass, String index, String propertyName,
+    public boolean setObjectProperty(String objectClass, int index, String propertyName,
         String value)
     {
         return false;
@@ -142,4 +163,136 @@
     {
         return this.type;
     }
+
+    public Element createOperationNode(Document doc)
+    {
+        Element xmlNode = doc.createElement(NODE_NAME);
+        xmlNode.setAttribute(OPERATION_TYPE_ATTRIBUTE_NAME, getType());
+        return xmlNode;
+    }
+
+    public String getOperationType(Element e)
+    {
+        return e.getAttribute(OPERATION_TYPE_ATTRIBUTE_NAME);
+    }
+
+    public Element createTextNode(String content, Document doc)
+    {
+        Element xmlNode = doc.createElement(TEXT_NODE_NAME);
+        xmlNode.setTextContent(content);
+        return xmlNode;
+    }
+
+    public Element getTextNode(Element e)
+    {
+        return (Element) e.getElementsByTagName(TEXT_NODE_NAME).item(0);
+    }
+
+    public String getTextValue(Element e)
+    {
+        return getTextNode(e).getTextContent();
+    }
+
+    public Element createObjectNode(String className, Document doc)
+    {
+        return createObjectNode(className, -1, doc);
+    }
+
+    public Element createObjectNode(String className, int number, Document doc)
+    {
+        Element xmlNode = doc.createElement(OBJECT_NODE_NAME);
+        xmlNode.setAttribute(OBJECT_TYPE_ATTRIBUTE_NAME, className);
+        if (number >= 0) {
+            xmlNode.setAttribute(OBJECT_NUMBER_ATTRIBUTE_NAME, number + "");
+        }
+        return xmlNode;
+    }
+
+    public Element getObjectNode(Element e)
+    {
+        return (Element) e.getElementsByTagName(OBJECT_NODE_NAME).item(0);
+    }
+
+    public String getObjectClassname(Element e)
+    {
+        return getObjectNode(e).getAttribute(OBJECT_TYPE_ATTRIBUTE_NAME);
+    }
+
+    public int getObjectNumber(Element e)
+    {
+        try {
+            return Integer.parseInt(getObjectNode(e).getAttribute(OBJECT_NUMBER_ATTRIBUTE_NAME));
+        } catch (Exception ex) {
+            return -1;
+        }
+    }
+
+    public Element createPropertyNode(String propertyName, Document doc)
+    {
+        return createPropertyNode(propertyName, null, doc);
+    }
+
+    public Element createPropertyNode(String propertyName, String value, Document doc)
+    {
+        Element xmlNode = doc.createElement(PROPERTY_NODE_NAME);
+        xmlNode.setAttribute(PROPERTY_NAME_ATTRIBUTE_NAME, propertyName);
+        if (value != null) {
+            xmlNode.setAttribute(PROPERTY_VALUE_ATTRIBUTE_NAME, value);
+        }
+        return xmlNode;
+    }
+
+    public Element createClassPropertyNode(String propertyName, String propertyType, Document doc)
+    {
+        Element xmlNode = doc.createElement(PROPERTY_NODE_NAME);
+        xmlNode.setAttribute(PROPERTY_NAME_ATTRIBUTE_NAME, propertyName);
+        xmlNode.setAttribute(PROPERTY_TYPE_ATTRIBUTE_NAME, propertyType);
+        return xmlNode;
+    }
+
+    public Element getPropertyNode(Element e)
+    {
+        return (Element) e.getElementsByTagName(PROPERTY_NODE_NAME).item(0);
+    }
+
+    public String getPropertyName(Element e)
+    {
+        return getPropertyNode(e).getAttribute(PROPERTY_NAME_ATTRIBUTE_NAME);
+    }
+
+    public String getPropertyType(Element e)
+    {
+        return getPropertyNode(e).getAttribute(PROPERTY_TYPE_ATTRIBUTE_NAME);
+    }
+
+    public String getPropertyValue(Element e)
+    {
+        Element propertyNode = getPropertyNode(e);
+        return (propertyNode != null) ? propertyNode.getAttribute(PROPERTY_VALUE_ATTRIBUTE_NAME)
+            : null;
+    }
+
+    public Element createClassNode(String className, Document doc)
+    {
+        Element xmlNode = doc.createElement(CLASS_NODE_NAME);
+        xmlNode.setAttribute(CLASS_NAME_ATTRIBUTE_NAME, className);
+        return xmlNode;
+    }
+
+    public Element getClassNode(Element e)
+    {
+        return (Element) e.getElementsByTagName(CLASS_NODE_NAME).item(0);
+    }
+
+    public String getClassName(Element e)
+    {
+        return getClassNode(e).getAttribute(CLASS_NAME_ATTRIBUTE_NAME);
+    }
+
+    public Position loadPositionNode(Element e) throws XWikiException
+    {
+        Position position = new PositionImpl();
+        position.fromXml((Element) e.getElementsByTagName(PositionImpl.NODE_NAME).item(0));
+        return position;
+    }
 }

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertyAddOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertyAddOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertyAddOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -0,0 +1,157 @@
+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.XWikiContext;
+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 ClassPropertyAddOperation extends AbstractOperationImpl implements RWOperation
+{
+    private String propertyName;
+
+    private String propertyType;
+
+    private Map propertyConfig;
+
+    private String className;
+
+    static {
+        OperationFactoryImpl.registerTypeProvider(Operation.TYPE_CLASS_PROPERTY_ADD,
+            ClassPropertyAddOperation.class);
+    }
+
+    public ClassPropertyAddOperation()
+    {
+        this.setType(Operation.TYPE_CLASS_PROPERTY_ADD);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
+    {
+        BaseClass bclass = doc.getxWikiClass();
+        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);
+            pclass.setName(propertyName);
+            bclass.put(pclass.getName(), pclass);
+        } else {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                "Invalid property type : " + this.propertyType);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean createType(String className, String propertyName, String propertyType,
+        Map properties)
+    {
+        this.className = className;
+        this.propertyName = propertyName;
+        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());
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void fromXml(Element e) throws XWikiException
+    {
+        this.className = getClassName(e);
+        this.propertyName = getPropertyName(e);
+        this.propertyType = getPropertyType(e);
+        Element propertyNode = getPropertyNode(getClassNode(e));
+        this.propertyConfig = new HashMap();
+        NodeList properties = propertyNode.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);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = createOperationNode(doc);
+        Element classNode = createClassNode(className, doc);
+        Element typeNode = createClassPropertyNode(propertyName, propertyType, doc);
+        for (Iterator it = propertyConfig.keySet().iterator(); it.hasNext();) {
+            String propName = (String) it.next();
+            typeNode.appendChild(createPropertyNode(propName, propertyConfig.get(propName)
+                .toString(), doc));
+        }
+        classNode.appendChild(typeNode);
+        xmlNode.appendChild(classNode);
+        return xmlNode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(Object other)
+    {
+        try {
+            ClassPropertyAddOperation that = (ClassPropertyAddOperation) other;
+            return (this.getType().equals(that.getType()))
+                && this.propertyType.equals(that.propertyType)
+                && this.propertyName.equals(that.propertyName)
+                && (this.propertyConfig.values().containsAll(that.propertyConfig.values()))
+                && (that.propertyConfig.values().containsAll(this.propertyConfig.values()))
+                && (this.propertyConfig.keySet().containsAll(that.propertyConfig.keySet()))
+                && (that.propertyConfig.keySet().containsAll(this.propertyConfig.keySet()));
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode()
+    {
+        // return new HashCodeBuilder(11, 13).append(this.propertyType).append(this.propertyConfig)
+        // .toHashCode();
+        int i =
+            new HashCodeBuilder(11, 13).append(this.propertyName).append(this.propertyType)
+                .append(this.propertyConfig).toHashCode();
+        return i;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+        return this.getType() + ": [" + this.propertyName + ":" + this.propertyType + "] = "
+            + this.propertyConfig;
+    }
+}


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

Modified: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertyDeleteOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertyDeleteOperation.java	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertyDeleteOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -6,6 +6,7 @@
 import org.xwiki.platform.patchservice.api.Operation;
 import org.xwiki.platform.patchservice.api.RWOperation;
 
+import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.classes.BaseClass;
@@ -13,10 +14,10 @@
 
 public class ClassPropertyDeleteOperation extends AbstractOperationImpl implements RWOperation
 {
-    public static final String PROPERTY_NAME_ATTRIBUTE_NAME = "name";
-
     private String propertyName;
 
+    private String className;
+
     static {
         OperationFactoryImpl.registerTypeProvider(Operation.TYPE_CLASS_PROPERTY_DELETE,
             ClassPropertyDeleteOperation.class);
@@ -30,10 +31,7 @@
     /**
      * {@inheritDoc}
      */
-    /**
-     * {@inheritDoc}
-     */
-    public void apply(XWikiDocument doc) throws XWikiException
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
     {
         BaseClass bclass = doc.getxWikiClass();
         PropertyClass prop = (PropertyClass) bclass.get(propertyName);
@@ -49,8 +47,9 @@
     /**
      * {@inheritDoc}
      */
-    public boolean deleteType(String propertyName)
+    public boolean deleteType(String className, String propertyName)
     {
+        this.className = className;
         this.propertyName = propertyName;
         return true;
     }
@@ -60,7 +59,8 @@
      */
     public void fromXml(Element e) throws XWikiException
     {
-        this.propertyName = e.getAttribute(PROPERTY_NAME_ATTRIBUTE_NAME);
+        this.className = getClassName(e);
+        this.propertyName = getPropertyName(getClassNode(e));
     }
 
     /**
@@ -68,9 +68,10 @@
      */
     public Element toXml(Document doc) throws XWikiException
     {
-        Element xmlNode = doc.createElement(AbstractOperationImpl.NODE_NAME);
-        xmlNode.setAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME, this.getType());
-        xmlNode.setAttribute(PROPERTY_NAME_ATTRIBUTE_NAME, propertyName);
+        Element xmlNode = createOperationNode(doc);
+        Element classNode = createClassNode(className, doc);
+        classNode.appendChild(createPropertyNode(propertyName, doc));
+        xmlNode.appendChild(classNode);
         return xmlNode;
     }
 
@@ -80,8 +81,9 @@
     public boolean equals(Object other)
     {
         try {
-            ClassPropertyDeleteOperation otherOperation = (ClassPropertyDeleteOperation) other;
-            return otherOperation.propertyName.equals(this.propertyName);
+            ClassPropertyDeleteOperation that = (ClassPropertyDeleteOperation) other;
+            return this.className.equals(that.className)
+                && this.propertyName.equals(that.propertyName);
         } catch (Exception e) {
             return false;
         }

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ClassPropertySetOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -11,93 +11,73 @@
 import org.xwiki.platform.patchservice.api.Operation;
 import org.xwiki.platform.patchservice.api.RWOperation;
 
+import com.xpn.xwiki.XWikiContext;
 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";
+    private String propertyName;
 
-    public static final String PROPERTY_NAME_ATTRIBUTE_NAME = "name";
-
-    public static final String PROPERTY_VALUE_ATTRIBUTE_NAME = "value";
-
-    private String propertyType;
-
     private Map propertyConfig;
 
+    private String className;
+
     static {
-        OperationFactoryImpl.registerTypeProvider(Operation.TYPE_CLASS_PROPERTY_ADD,
-            ClassPropertySetOperation.class);
         OperationFactoryImpl.registerTypeProvider(Operation.TYPE_CLASS_PROPERTY_CHANGE,
             ClassPropertySetOperation.class);
     }
 
     public ClassPropertySetOperation()
     {
-        this.setType(Operation.TYPE_CLASS_PROPERTY_ADD);
+        this.setType(Operation.TYPE_CLASS_PROPERTY_CHANGE);
     }
 
     /**
      * {@inheritDoc}
      */
-    public void apply(XWikiDocument doc) throws XWikiException
+    public void apply(XWikiDocument doc, XWikiContext context) 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);
+        PropertyClass pclass = (PropertyClass) bclass.get(propertyName);
+        if (pclass != null) {
             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);
+                "Invalid propert name : " + this.propertyName);
         }
     }
 
     /**
      * {@inheritDoc}
      */
-    public boolean createType(String propertyType, Map properties)
+    public boolean modifyType(String className, String propertyName, Map properties)
     {
-        this.propertyType = propertyType;
+        this.className = className;
+        this.propertyName = propertyName;
         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;
     }
 
     /**
      * {@inheritDoc}
      */
-    public boolean modifyType(String propertyType, Map properties)
-    {
-        this.propertyType = propertyType;
-        this.propertyConfig = properties;
-        this.setType(Operation.TYPE_CLASS_PROPERTY_CHANGE);
-        return true;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
     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.setType(getOperationType(e));
+        this.className = getClassName(e);
+        Element propertyNode = getPropertyNode(getClassNode(e));
+        this.propertyName = propertyNode.getAttribute(PROPERTY_NAME_ATTRIBUTE_NAME);
         this.propertyConfig = new HashMap();
-        NodeList properties = e.getElementsByTagName(PROPERTY_NODE_NAME);
+        NodeList properties = propertyNode.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);
@@ -111,19 +91,16 @@
      */
     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);
+        Element xmlNode = createOperationNode(doc);
+        Element classNode = createClassNode(className, doc);
+        Element typeNode = createPropertyNode(propertyName, doc);
         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);
+            typeNode.appendChild(createPropertyNode(propName, propertyConfig.get(propName)
+                .toString(), doc));
         }
+        classNode.appendChild(typeNode);
+        xmlNode.appendChild(classNode);
         return xmlNode;
     }
 
@@ -134,7 +111,7 @@
     {
         try {
             ClassPropertySetOperation otherOperation = (ClassPropertySetOperation) other;
-            return otherOperation.propertyType.equals(this.propertyType)
+            return otherOperation.propertyName.equals(this.propertyName)
                 && (this.getType().equals(otherOperation.getType()))
                 && (this.propertyConfig.values().containsAll(otherOperation.propertyConfig
                     .values()))
@@ -157,7 +134,7 @@
         // return new HashCodeBuilder(11, 13).append(this.propertyType).append(this.propertyConfig)
         // .toHashCode();
         int i =
-            new HashCodeBuilder(11, 13).append(this.propertyType).append(this.propertyConfig)
+            new HashCodeBuilder(11, 13).append(this.propertyName).append(this.propertyConfig)
                 .toHashCode();
         return i;
     }
@@ -167,6 +144,6 @@
      */
     public String toString()
     {
-        return this.getType() + ": [" + this.propertyType + "] = " + this.propertyConfig;
+        return this.getType() + ": [" + this.propertyName + "] = " + this.propertyConfig;
     }
 }

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentDeleteOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -1,6 +1,5 @@
 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;
@@ -9,6 +8,7 @@
 import org.xwiki.platform.patchservice.api.Position;
 import org.xwiki.platform.patchservice.api.RWOperation;
 
+import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.XWikiDocument;
 
@@ -31,7 +31,7 @@
     /**
      * {@inheritDoc}
      */
-    public void apply(XWikiDocument doc) throws XWikiException
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
     {
         try {
             String content = doc.getContent();
@@ -72,10 +72,8 @@
      */
     public void fromXml(Element e) throws XWikiException
     {
-        Element textNode = (Element) e.getElementsByTagName(TEXT_NODE_NAME).item(0);
-        this.removedContent = StringEscapeUtils.unescapeXml(textNode.getTextContent());
-        this.position = new PositionImpl();
-        position.fromXml((Element) e.getElementsByTagName(PositionImpl.NODE_NAME).item(0));
+        this.removedContent = getTextValue(e);
+        this.position = loadPositionNode(e);
     }
 
     /**
@@ -83,13 +81,8 @@
      */
     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
-            .appendChild(doc.createTextNode(StringEscapeUtils.escapeXml(this.removedContent)));
-        xmlNode.appendChild(textNode);
+        Element xmlNode = createOperationNode(doc);
+        xmlNode.appendChild(createTextNode(removedContent, doc));
         xmlNode.appendChild(position.toXml(doc));
         return xmlNode;
     }

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentInsertOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -1,6 +1,5 @@
 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;
@@ -8,6 +7,7 @@
 import org.xwiki.platform.patchservice.api.Position;
 import org.xwiki.platform.patchservice.api.RWOperation;
 
+import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.XWikiDocument;
 
@@ -30,7 +30,7 @@
     /**
      * {@inheritDoc}
      */
-    public void apply(XWikiDocument doc) throws XWikiException
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
     {
         String content = doc.getContent();
         if (!position.checkPosition(content)) {
@@ -59,10 +59,8 @@
      */
     public void fromXml(Element e) throws XWikiException
     {
-        Element textNode = (Element) e.getElementsByTagName(TEXT_NODE_NAME).item(0);
-        this.addedContent = StringEscapeUtils.unescapeXml(textNode.getTextContent());
-        this.position = new PositionImpl();
-        position.fromXml((Element) e.getElementsByTagName(PositionImpl.NODE_NAME).item(0));
+        this.addedContent = getTextValue(e);
+        this.position = loadPositionNode(e);
     }
 
     /**
@@ -70,11 +68,8 @@
      */
     public Element toXml(Document doc) throws XWikiException
     {
-        Element xmlNode = doc.createElement(AbstractOperationImpl.NODE_NAME);
-        xmlNode.setAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME, this.getType());
-        Element textNode = doc.createElement(TEXT_NODE_NAME);
-        textNode.appendChild(doc.createTextNode(StringEscapeUtils.escapeXml(this.addedContent)));
-        xmlNode.appendChild(textNode);
+        Element xmlNode = createOperationNode(doc);
+        xmlNode.appendChild(createTextNode(addedContent, doc));
         xmlNode.appendChild(position.toXml(doc));
         return xmlNode;
     }

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectAddOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectAddOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectAddOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -0,0 +1,97 @@
+package org.xwiki.platform.patchservice.impl;
+
+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.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseObject;
+
+public class ObjectAddOperation extends AbstractOperationImpl implements RWOperation
+{
+    private String className;
+
+    static {
+        OperationFactoryImpl.registerTypeProvider(Operation.TYPE_OBJECT_ADD,
+            ObjectAddOperation.class);
+    }
+
+    public ObjectAddOperation()
+    {
+        this.setType(Operation.TYPE_OBJECT_ADD);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
+    {
+        BaseObject obj = doc.newObject(this.className, context);
+        if (obj == null) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                "Invalid class name: " + this.className);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean addObject(String objectClass)
+    {
+        this.className = objectClass;
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void fromXml(Element e) throws XWikiException
+    {
+        this.className = getObjectClassname(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = createOperationNode(doc);
+        xmlNode.appendChild(createObjectNode(className, doc));
+        return xmlNode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(Object other)
+    {
+        try {
+            ObjectAddOperation otherOperation = (ObjectAddOperation) other;
+            return otherOperation.getType().equals(this.getType())
+                && otherOperation.className.equals(this.className);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode()
+    {
+        return new HashCodeBuilder(17, 19).append(this.className).toHashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+        return this.getType() + ": [" + this.className + "]";
+    }
+}


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

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectDeleteOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectDeleteOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectDeleteOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -0,0 +1,106 @@
+package org.xwiki.platform.patchservice.impl;
+
+import java.util.Formatter;
+
+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.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseObject;
+
+public class ObjectDeleteOperation extends AbstractOperationImpl implements RWOperation
+{
+    private String className;
+
+    private int number = -1;
+
+    static {
+        OperationFactoryImpl.registerTypeProvider(Operation.TYPE_OBJECT_DELETE,
+            ObjectDeleteOperation.class);
+    }
+
+    public ObjectDeleteOperation()
+    {
+        this.setType(Operation.TYPE_OBJECT_DELETE);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
+    {
+        BaseObject obj = doc.getObject(className, number);
+        if (obj == null) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                new Formatter().format("Invalid object type/number: %s[%d]",
+                    new Object[] {this.className, new Integer(number)}).toString());
+        }
+        doc.removeObject(obj);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean deleteObject(String objectClass, int index)
+    {
+        this.className = objectClass;
+        this.number = index;
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void fromXml(Element e) throws XWikiException
+    {
+        this.className = getObjectClassname(e);
+        this.number = getObjectNumber(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = createOperationNode(doc);
+        xmlNode.appendChild(createObjectNode(className, number, doc));
+        return xmlNode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(Object other)
+    {
+        try {
+            ObjectDeleteOperation otherOperation = (ObjectDeleteOperation) other;
+            return otherOperation.getType().equals(this.getType())
+                && otherOperation.className.equals(this.className)
+                && (otherOperation.number == this.number);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode()
+    {
+        return new HashCodeBuilder(19, 23).append(this.className).append(this.number).toHashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+        return this.getType() + ": [" + this.className + "[" + number + "]]";
+    }
+}


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

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertyDeleteAtOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertyDeleteAtOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertyDeleteAtOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -0,0 +1,144 @@
+package org.xwiki.platform.patchservice.impl;
+
+import java.util.Formatter;
+
+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.Position;
+import org.xwiki.platform.patchservice.api.RWOperation;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseObject;
+
+public class ObjectPropertyDeleteAtOperation extends AbstractOperationImpl implements RWOperation
+{
+    private String className;
+
+    private int number = -1;
+
+    private String propertyName;
+
+    private Position position;
+
+    private String deletedContent;
+
+    static {
+        OperationFactoryImpl.registerTypeProvider(Operation.TYPE_OBJECT_PROPERTY_DELETE_AT,
+            ObjectPropertyDeleteAtOperation.class);
+    }
+
+    public ObjectPropertyDeleteAtOperation()
+    {
+        this.setType(Operation.TYPE_OBJECT_PROPERTY_DELETE_AT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
+    {
+        BaseObject obj = doc.getObject(className, number);
+        if (obj == null) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                new Formatter().format("Invalid object type/number: %s[%d]",
+                    new Object[] {this.className, new Integer(number)}).toString());
+        }
+        try {
+            String value = obj.getLargeStringValue(propertyName);
+            if (!position.checkPosition(value)
+                || !position.getTextAfterPosition(value).startsWith(this.deletedContent)) {
+                throw new Exception();
+            }
+            value =
+                position.getTextBeforePosition(value)
+                    + StringUtils.substring(position.getTextAfterPosition(value), deletedContent
+                        .length());
+            obj.set(propertyName, value, context);
+        } catch (Exception e) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                new Formatter().format("Invalid deleted text: [%s] for object property [%s]",
+                    new Object[] {deletedContent, propertyName}).toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean deleteFromProperty(String objectClass, int index, String propertyName,
+        String value, Position position)
+    {
+        this.className = objectClass;
+        this.number = index;
+        this.propertyName = propertyName;
+        this.deletedContent = value;
+        this.position = position;
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void fromXml(Element e) throws XWikiException
+    {
+        this.className = getObjectClassname(e);
+        this.number = getObjectNumber(e);
+        this.propertyName = getPropertyName(getObjectNode(e));
+        this.deletedContent = getTextValue(e);
+        this.position = loadPositionNode(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = createOperationNode(doc);
+        Element objectNode = createObjectNode(className, number, doc);
+        objectNode.appendChild(createPropertyNode(propertyName, doc));
+        xmlNode.appendChild(objectNode);
+        xmlNode.appendChild(createTextNode(deletedContent, doc));
+        xmlNode.appendChild(position.toXml(doc));
+        return xmlNode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(Object other)
+    {
+        try {
+            ObjectPropertyDeleteAtOperation that = (ObjectPropertyDeleteAtOperation) other;
+            return that.getType().equals(this.getType()) && that.className.equals(this.className)
+                && (that.number == this.number) && that.propertyName.equals(this.propertyName)
+                && that.deletedContent.equals(this.deletedContent)
+                && that.position.equals(this.position);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode()
+    {
+        return new HashCodeBuilder(31, 37).append(className).append(number).append(propertyName)
+            .append(deletedContent).append(position).toHashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+        return getType() + ": [" + className + "[" + number + "]#" + propertyName + "]@"
+            + position + " = [" + deletedContent + "]";
+    }
+}


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

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertyInsertAtOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertyInsertAtOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertyInsertAtOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -0,0 +1,141 @@
+package org.xwiki.platform.patchservice.impl;
+
+import java.util.Formatter;
+
+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.Position;
+import org.xwiki.platform.patchservice.api.RWOperation;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseObject;
+
+public class ObjectPropertyInsertAtOperation extends AbstractOperationImpl implements RWOperation
+{
+    private String className;
+
+    private int number = -1;
+
+    private String propertyName;
+
+    private Position position;
+
+    private String addedContent;
+
+    static {
+        OperationFactoryImpl.registerTypeProvider(Operation.TYPE_OBJECT_PROPERTY_INSERT_AT,
+            ObjectPropertyInsertAtOperation.class);
+    }
+
+    public ObjectPropertyInsertAtOperation()
+    {
+        this.setType(Operation.TYPE_OBJECT_PROPERTY_INSERT_AT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
+    {
+        BaseObject obj = doc.getObject(className, number);
+        if (obj == null) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                new Formatter().format("Invalid object type/number: %s[%d]",
+                    new Object[] {this.className, new Integer(number)}).toString());
+        }
+        try {
+            String value = obj.getLargeStringValue(propertyName);
+            if (!position.checkPosition(value)) {
+                throw new Exception();
+            }
+            value =
+                position.getTextBeforePosition(value) + addedContent
+                    + position.getTextAfterPosition(value);
+            obj.set(propertyName, value, context);
+        } catch (Exception e) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                new Formatter().format("Invalid inserted text: [%s] for object property [%s]",
+                    new Object[] {addedContent, propertyName}).toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean insertInProperty(String objectClass, int index, String propertyName,
+        String value, Position position)
+    {
+        this.className = objectClass;
+        this.number = index;
+        this.propertyName = propertyName;
+        this.addedContent = value;
+        this.position = position;
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void fromXml(Element e) throws XWikiException
+    {
+        this.className = getObjectClassname(e);
+        this.number = getObjectNumber(e);
+        this.propertyName = getPropertyName(getObjectNode(e));
+        this.addedContent = getTextValue(e);
+        this.position = loadPositionNode(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = createOperationNode(doc);
+        Element objectNode = createObjectNode(className, number, doc);
+        objectNode.appendChild(createPropertyNode(propertyName, doc));
+        xmlNode.appendChild(objectNode);
+        xmlNode.appendChild(createTextNode(addedContent, doc));
+        xmlNode.appendChild(position.toXml(doc));
+        return xmlNode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(Object other)
+    {
+        try {
+            ObjectPropertyInsertAtOperation that = (ObjectPropertyInsertAtOperation) other;
+            return that.getType().equals(this.getType()) && that.className.equals(this.className)
+                && (that.number == this.number) && that.propertyName.equals(this.propertyName)
+                && that.addedContent.equals(this.addedContent)
+                && that.position.equals(this.position);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode()
+    {
+        return new HashCodeBuilder(29, 31).append(className).append(number).append(propertyName)
+            .append(addedContent).append(position).toHashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+        return getType() + ": [" + className + "[" + number + "]#" + propertyName + "]@"
+            + position + " = [" + addedContent + "]";
+    }
+}


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

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertySetOperation.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertySetOperation.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ObjectPropertySetOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -0,0 +1,129 @@
+package org.xwiki.platform.patchservice.impl;
+
+import java.util.Formatter;
+
+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.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.BaseObject;
+
+public class ObjectPropertySetOperation extends AbstractOperationImpl implements RWOperation
+{
+    private String className;
+
+    private int number = -1;
+
+    private String propertyName;
+
+    private String value;
+
+    static {
+        OperationFactoryImpl.registerTypeProvider(Operation.TYPE_OBJECT_PROPERTY_SET,
+            ObjectPropertySetOperation.class);
+    }
+
+    public ObjectPropertySetOperation()
+    {
+        this.setType(Operation.TYPE_OBJECT_PROPERTY_SET);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
+    {
+        BaseObject obj = doc.getObject(className, number);
+        if (obj == null) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                new Formatter().format("Invalid object type/number: %s[%d]",
+                    new Object[] {this.className, new Integer(number)}).toString());
+        }
+        try {
+            obj.set(propertyName, value, context);
+        } catch (RuntimeException e) {
+            throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
+                XWikiException.ERROR_XWIKI_UNKNOWN,
+                new Formatter().format("Invalid value: [%s] for object property [%s]",
+                    new Object[] {value, propertyName}).toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean setObjectProperty(String objectClass, int number, String propertyName,
+        String value)
+    {
+        this.className = objectClass;
+        this.number = number;
+        this.propertyName = propertyName;
+        this.value = value;
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void fromXml(Element e) throws XWikiException
+    {
+        this.className = getObjectClassname(e);
+        this.number = getObjectNumber(e);
+        this.propertyName = getPropertyName(e);
+        this.value = getTextValue(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = createOperationNode(doc);
+        Element objectNode = createObjectNode(className, number, doc);
+        objectNode.appendChild(createPropertyNode(propertyName, doc));
+        xmlNode.appendChild(objectNode);
+        xmlNode.appendChild(createTextNode(value, doc));
+        return xmlNode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(Object other)
+    {
+        try {
+            ObjectPropertySetOperation otherOperation = (ObjectPropertySetOperation) other;
+            return otherOperation.getType().equals(this.getType())
+                && otherOperation.className.equals(this.className)
+                && (otherOperation.number == this.number)
+                && otherOperation.propertyName.equals(this.propertyName)
+                && otherOperation.value.equals(this.value);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode()
+    {
+        return new HashCodeBuilder(23, 29).append(className).append(number).append(propertyName)
+            .append(value).toHashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+        return getType() + ": [" + className + "[" + number + "]#" + propertyName + "] = ["
+            + value + "]";
+    }
+}


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

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/OperationFactoryImpl.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -64,7 +64,7 @@
 
     public Operation loadOperation(Element e) throws XWikiException
     {
-        String type = e.getAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME);
+        String type = e.getAttribute(AbstractOperationImpl.OPERATION_TYPE_ATTRIBUTE_NAME);
         Operation op = newOperation(type);
         op.fromXml(e);
         return op;

Modified: xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PositionImpl.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PositionImpl.java	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PositionImpl.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -1,7 +1,6 @@
 package org.xwiki.platform.patchservice.impl;
 
 import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.builder.HashCodeBuilder;
 import org.w3c.dom.Document;
@@ -23,6 +22,8 @@
     public static final String BEFORE_ATTRIBUTE_NAME = "before";
 
     public static final String AFTER_ATTRIBUTE_NAME = "after";
+    
+    private static final String SEPARATOR = "\n";
 
     private String before;
 
@@ -36,6 +37,7 @@
 
     public PositionImpl()
     {
+        this(0, 0, -1, null, null);
     }
 
     public PositionImpl(int row, int column)
@@ -67,14 +69,13 @@
      */
     public boolean checkPosition(String text)
     {
-        String[] rows = StringUtils.splitPreserveAllTokens(text, '\n');
-        if (rows.length > row && rows[row].length() > column) {
-            if ((StringUtils.isEmpty(before) || getTextBeforePosition(text).endsWith(before))
-                && (StringUtils.isEmpty(after) || getTextAfterPosition(text).startsWith(after))) {
-                return true;
-            }
+        String[] rows = StringUtils.splitPreserveAllTokens(text, SEPARATOR);
+        if (rows != null && rows.length > row && rows[row].length() >= column) {
+            return (StringUtils.isEmpty(before) || getTextBeforePosition(text).endsWith(before))
+                && (StringUtils.isEmpty(after) || getTextAfterPosition(text).startsWith(after));
         }
-        return false;
+        return row == 0 && column == 0 && StringUtils.isEmpty(before)
+            && StringUtils.isEmpty(after);
     }
 
     /**
@@ -82,9 +83,12 @@
      */
     public String getTextBeforePosition(String text)
     {
-        String[] rows = StringUtils.splitPreserveAllTokens(text, '\n');
-        return StringUtils.join(ArrayUtils.subarray(rows, 0, row), '\n')
-            + StringUtils.substring(rows[row], 0, column);
+        String[] rows = StringUtils.splitPreserveAllTokens(text, SEPARATOR);
+        if (ArrayUtils.getLength(rows) <= row) {
+            return StringUtils.defaultString(StringUtils.join(rows, SEPARATOR));
+        }
+        return StringUtils.join(ArrayUtils.subarray(rows, 0, row), SEPARATOR)
+            + ((row > 0) ? SEPARATOR : "") + StringUtils.substring(rows[row], 0, column);
     }
 
     /**
@@ -92,11 +96,14 @@
      */
     public String getTextAfterPosition(String text)
     {
-        String[] rows = StringUtils.splitPreserveAllTokens(text, '\n');
+        String[] rows = StringUtils.splitPreserveAllTokens(text, SEPARATOR);
+        if (ArrayUtils.getLength(rows) <= row) {
+            return "";
+        }
         String textAfter =
-            StringUtils.substring(rows[row], column)
-                + StringUtils.join(ArrayUtils.subarray(rows, row + 1, rows.length), '\n');
-        return (span <= 0) ? textAfter : textAfter.substring(span);
+            StringUtils.substring(rows[row], column) + ((row + 1 < rows.length) ? SEPARATOR : "")
+                + StringUtils.join(ArrayUtils.subarray(rows, row + 1, rows.length), SEPARATOR);
+        return (span <= 0) ? textAfter : StringUtils.substring(textAfter, span);
     }
 
     /**
@@ -107,11 +114,14 @@
         this.row = Integer.parseInt(e.getAttribute(ROW_ATTRIBUTE_NAME));
         this.column = Integer.parseInt(e.getAttribute(COLUMN_ATTRIBUTE_NAME));
         if (e.hasAttribute(BEFORE_ATTRIBUTE_NAME)) {
-            this.before = StringEscapeUtils.unescapeXml(e.getAttribute(BEFORE_ATTRIBUTE_NAME));
+            this.before = e.getAttribute(BEFORE_ATTRIBUTE_NAME);
         }
         if (e.hasAttribute(AFTER_ATTRIBUTE_NAME)) {
-            this.after = StringEscapeUtils.unescapeXml(e.getAttribute(AFTER_ATTRIBUTE_NAME));
+            this.after = e.getAttribute(AFTER_ATTRIBUTE_NAME);
         }
+        if (e.hasAttribute(SPAN_ATTRIBUTE_NAME)) {
+            this.span = Integer.parseInt(e.getAttribute(SPAN_ATTRIBUTE_NAME));
+        }
     }
 
     /**
@@ -123,11 +133,14 @@
         xmlNode.setAttribute(ROW_ATTRIBUTE_NAME, row + "");
         xmlNode.setAttribute(COLUMN_ATTRIBUTE_NAME, column + "");
         if (!StringUtils.isEmpty(before)) {
-            xmlNode.setAttribute(BEFORE_ATTRIBUTE_NAME, StringEscapeUtils.escapeXml(before));
+            xmlNode.setAttribute(BEFORE_ATTRIBUTE_NAME, before);
         }
         if (!StringUtils.isEmpty(after)) {
-            xmlNode.setAttribute(AFTER_ATTRIBUTE_NAME, StringEscapeUtils.escapeXml(after));
+            xmlNode.setAttribute(AFTER_ATTRIBUTE_NAME, after);
         }
+        if (span >= 0) {
+            xmlNode.setAttribute(SPAN_ATTRIBUTE_NAME, span + "");
+        }
         return xmlNode;
     }
 
@@ -137,13 +150,13 @@
     public boolean equals(Object other)
     {
         try {
-            PositionImpl otherPosition = (PositionImpl) other;
-            return (otherPosition.row == this.row)
-                && otherPosition.column == this.column
-                && StringUtils.defaultString(otherPosition.before).equals(
+            PositionImpl that = (PositionImpl) other;
+            return (that.row == this.row)
+                && that.column == this.column
+                && StringUtils.defaultString(that.before).equals(
                     StringUtils.defaultString(before))
-                && StringUtils.defaultString(otherPosition.after).equals(
-                    StringUtils.defaultString(after));
+                && StringUtils.defaultString(that.after).equals(StringUtils.defaultString(after))
+                && (that.span == this.span);
         } catch (Exception e) {
             return false;
         }

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PropertySetOperation.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -1,6 +1,5 @@
 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;
@@ -8,15 +7,12 @@
 import org.xwiki.platform.patchservice.api.Operation;
 import org.xwiki.platform.patchservice.api.RWOperation;
 
+import com.xpn.xwiki.XWikiContext;
 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;
@@ -34,7 +30,7 @@
     /**
      * {@inheritDoc}
      */
-    public void apply(XWikiDocument doc) throws XWikiException
+    public void apply(XWikiDocument doc, XWikiContext context) throws XWikiException
     {
         try {
             doc.getClass().getMethod("set" + StringUtils.capitalize(propertyName),
@@ -62,11 +58,8 @@
      */
     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));
+        this.propertyName = getPropertyName(e);
+        this.propertyValue = getTextValue(e);
     }
 
     /**
@@ -74,15 +67,9 @@
      */
     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);
+        Element xmlNode = createOperationNode(doc);
+        xmlNode.appendChild(createPropertyNode(propertyName, doc));
+        xmlNode.appendChild(createTextNode(propertyValue, doc));
         return xmlNode;
     }
 

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/main/resources/META-INF/services/org.xwiki.platform.patchservice.api.RWOperation	2008-01-03 14:11:30 UTC (rev 6613)
@@ -1,5 +1,11 @@
 org.xwiki.platform.patchservice.impl.ContentInsertOperation
 org.xwiki.platform.patchservice.impl.ContentDeleteOperation
 org.xwiki.platform.patchservice.impl.PropertySetOperation
+org.xwiki.platform.patchservice.impl.ClassPropertyAddOperation
 org.xwiki.platform.patchservice.impl.ClassPropertySetOperation
 org.xwiki.platform.patchservice.impl.ClassPropertyDeleteOperation
+org.xwiki.platform.patchservice.impl.ObjectAddOperation
+org.xwiki.platform.patchservice.impl.ObjectDeleteOperation
+org.xwiki.platform.patchservice.impl.ObjectPropertySetOperation
+org.xwiki.platform.patchservice.impl.ObjectPropertyInsertAtOperation
+org.xwiki.platform.patchservice.impl.ObjectPropertyDeleteAtOperation

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/CheckAllOperationsImplementedTest.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/CheckAllOperationsImplementedTest.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/CheckAllOperationsImplementedTest.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -0,0 +1,148 @@
+package org.xwiki.platform;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.xwiki.platform.patchservice.api.RWOperation;
+import org.xwiki.platform.patchservice.impl.OperationFactoryImpl;
+import org.xwiki.platform.patchservice.impl.PositionImpl;
+
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.objects.BaseProperty;
+import com.xpn.xwiki.objects.classes.BaseClass;
+import com.xpn.xwiki.objects.classes.PropertyClass;
+
+public class CheckAllOperationsImplementedTest extends TestCase
+{
+    public void testAllOperationsImplemented() throws XWikiException
+    {
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_CONTENT_INSERT));
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_CONTENT_DELETE));
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_PROPERTY_SET));
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_CLASS_PROPERTY_ADD));
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_CLASS_PROPERTY_CHANGE));
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_CLASS_PROPERTY_DELETE));
+        assertNotNull(OperationFactoryImpl.getInstance()
+            .newOperation(RWOperation.TYPE_OBJECT_ADD));
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_OBJECT_DELETE));
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_OBJECT_PROPERTY_SET));
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_OBJECT_PROPERTY_INSERT_AT));
+        assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+            RWOperation.TYPE_OBJECT_PROPERTY_DELETE_AT));
+        // assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+        // RWOperation.TYPE_ATTACHMENT_ADD));
+        // assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+        // RWOperation.TYPE_ATTACHMENT_SET));
+        // assertNotNull(OperationFactoryImpl.getInstance().newOperation(
+        // RWOperation.TYPE_ATTACHMENT_DELETE));
+    }
+
+    public void testXmlOutput() throws Exception
+    {
+        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+        Element root = doc.createElement("patch");
+        doc.appendChild(root);
+        root.appendChild(doc.createTextNode("\n"));
+
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
+        operation.insert(" as/<>\"'&d ", new PositionImpl(2, 3, " \"'<>befo&amp;re", "after "));
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
+        operation.delete("Here ", new PositionImpl(0, 0));
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_PROPERTY_SET);
+        operation.setProperty("prop", "val");
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        BaseClass b = new BaseClass();
+        b.addBooleanField("field", "The field", "yesno");
+        operation = getOperation((PropertyClass) b.get("field"), true);
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        operation = getOperation((PropertyClass) b.get("field"), false);
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        operation =
+            OperationFactoryImpl.getInstance().newOperation(
+                RWOperation.TYPE_CLASS_PROPERTY_DELETE);
+        operation.deleteType("XWiki.Class", "prop1");
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        operation = OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_ADD);
+        operation.addObject("XWiki.Class");
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_DELETE);
+        operation.deleteObject("XWiki.Class", 2);
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_PROPERTY_SET);
+        operation.setObjectProperty("XWiki.Class", 2, "propertyName", "value");
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        operation =
+            OperationFactoryImpl.getInstance().newOperation(
+                RWOperation.TYPE_OBJECT_PROPERTY_INSERT_AT);
+        operation.insertInProperty("XWiki.Class", 0, "property", "inserted text",
+            new PositionImpl(2, 0));
+        root.appendChild(operation.toXml(doc));
+        root.appendChild(doc.createTextNode("\n"));
+
+        DOMImplementationLS ls = (DOMImplementationLS) doc.getImplementation();
+        System.out.println(ls.createLSSerializer().writeToString(doc));
+    }
+
+    private RWOperation getOperation(PropertyClass property, boolean create)
+        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(
+                create ? RWOperation.TYPE_CLASS_PROPERTY_ADD
+                    : RWOperation.TYPE_CLASS_PROPERTY_CHANGE);
+        if (create) {
+            operation.createType("XWiki.Class", property.getName(), type, config);
+        } else {
+            operation.modifyType("XWiki.Class", property.getName(), config);
+        }
+        return operation;
+    }
+}


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

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ClassPropertyOperationsTest.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -15,6 +15,7 @@
 import org.xwiki.platform.patchservice.api.RWOperation;
 import org.xwiki.platform.patchservice.impl.OperationFactoryImpl;
 
+import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseProperty;
@@ -29,6 +30,8 @@
 
     BaseClass bclass;
 
+    XWikiContext context;
+
     protected void setUp()
     {
         try {
@@ -37,6 +40,7 @@
             doc.setFullName("XWiki.XWikiTestClass");
             bclass = new BaseClass();
             bclass.setName("XWiki.XWikiTestClass");
+            context = new XWikiContext();
         } catch (ParserConfigurationException e) {
             e.printStackTrace();
         }
@@ -48,7 +52,7 @@
         bclass.addBooleanField("prop2", "Property 2", "yesno");
         for (Iterator it = bclass.getFieldList().iterator(); it.hasNext();) {
             RWOperation operation = getOperation((PropertyClass) it.next(), true);
-            operation.apply(doc);
+            operation.apply(doc, context);
         }
         assertEquals(2, doc.getxWikiClass().getProperties().length);
         assertNotNull(doc.getxWikiClass().getField("prop1"));
@@ -61,8 +65,8 @@
     {
         bclass.addTextField("prop1", "Property 1", 30);
         RWOperation operation = getOperation((PropertyClass) bclass.getProperties()[0], true);
-        operation.apply(doc);
-        operation.apply(doc);
+        operation.apply(doc, context);
+        operation.apply(doc, context);
         assertEquals(1, doc.getxWikiClass().getProperties().length);
         assertEquals("prop1", doc.getxWikiClass().get("prop1").getName());
     }
@@ -71,9 +75,9 @@
     {
         RWOperation operation =
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CLASS_PROPERTY_ADD);
-        operation.createType("invalid", new HashMap());
+        operation.createType(doc.getFullName(), "invalid", "invalid", new HashMap());
         try {
-            operation.apply(doc);
+            operation.apply(doc, context);
             assertTrue(false);
         } catch (XWikiException ex) {
             assertTrue(true);
@@ -95,7 +99,7 @@
         testApplyPropertyAddOperation();
         ((PropertyClass) bclass.get("prop1")).setPrettyName("new Property 1");
         RWOperation operation = getOperation((PropertyClass) bclass.get("prop1"), false);
-        operation.apply(doc);
+        operation.apply(doc, context);
         assertEquals("new Property 1", ((PropertyClass) doc.getxWikiClass().get("prop1"))
             .getPrettyName());
     }
@@ -115,8 +119,8 @@
         RWOperation operation =
             OperationFactoryImpl.getInstance().newOperation(
                 RWOperation.TYPE_CLASS_PROPERTY_DELETE);
-        operation.deleteType("prop1");
-        operation.apply(doc);
+        operation.deleteType(doc.getFullName(), "prop1");
+        operation.apply(doc, context);
         assertEquals(1, doc.getxWikiClass().getProperties().length);
         assertNull(doc.getxWikiClass().get("prop1"));
         assertNotNull(doc.getxWikiClass().get("prop2"));
@@ -127,9 +131,9 @@
         RWOperation operation =
             OperationFactoryImpl.getInstance().newOperation(
                 RWOperation.TYPE_CLASS_PROPERTY_DELETE);
-        operation.deleteType("prop3");
+        operation.deleteType(doc.getFullName(), "prop3");
         try {
-            operation.apply(doc);
+            operation.apply(doc, context);
             assertTrue(false);
         } catch (XWikiException ex) {
             assertTrue(true);
@@ -142,7 +146,7 @@
         RWOperation operation =
             OperationFactoryImpl.getInstance().newOperation(
                 RWOperation.TYPE_CLASS_PROPERTY_DELETE);
-        operation.deleteType("prop1");
+        operation.deleteType(doc.getFullName(), "prop1");
         Element e = operation.toXml(domDoc);
         Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
         assertEquals(loadedOperation, operation);
@@ -152,29 +156,29 @@
     {
         bclass.addTextField("prop1", "Property 1", 30);
         RWOperation operation = getOperation((PropertyClass) bclass.get("prop1"), true);
-        operation.apply(doc);
+        operation.apply(doc, context);
         assertEquals(1, doc.getxWikiClass().getProperties().length);
         assertNotNull(doc.getxWikiClass().getField("prop1"));
         assertEquals("prop1", doc.getxWikiClass().get("prop1").getName());
 
         ((PropertyClass) bclass.get("prop1")).setPrettyName("new Property 1");
         operation = getOperation((PropertyClass) bclass.get("prop1"), false);
-        operation.apply(doc);
+        operation.apply(doc, context);
         assertEquals("new Property 1", ((PropertyClass) doc.getxWikiClass().get("prop1"))
             .getPrettyName());
         assertEquals(1, doc.getxWikiClass().getProperties().length);
 
         bclass.addBooleanField("prop2", "Property 2", "yesno");
         operation = getOperation((PropertyClass) bclass.get("prop2"), true);
-        operation.apply(doc);
+        operation.apply(doc, context);
         assertEquals(2, doc.getxWikiClass().getProperties().length);
 
         operation =
             OperationFactoryImpl.getInstance().newOperation(
                 RWOperation.TYPE_CLASS_PROPERTY_DELETE);
-        operation.deleteType("prop1");
+        operation.deleteType(doc.getFullName(), "prop1");
         assertEquals(2, doc.getxWikiClass().getProperties().length);
-        operation.apply(doc);
+        operation.apply(doc, context);
         assertEquals(1, doc.getxWikiClass().getProperties().length);
         assertNotNull(doc.getxWikiClass().getField("prop2"));
         assertNull(doc.getxWikiClass().getField("prop1"));
@@ -194,9 +198,9 @@
                 create ? RWOperation.TYPE_CLASS_PROPERTY_ADD
                     : RWOperation.TYPE_CLASS_PROPERTY_CHANGE);
         if (create) {
-            operation.createType(type, config);
+            operation.createType(doc.getFullName(), property.getName(), type, config);
         } else {
-            operation.modifyType(type, config);
+            operation.modifyType(doc.getFullName(), property.getName(), config);
         }
         return operation;
     }

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ContentOperationsTest.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -12,6 +12,7 @@
 import org.xwiki.platform.patchservice.impl.OperationFactoryImpl;
 import org.xwiki.platform.patchservice.impl.PositionImpl;
 
+import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.XWikiDocument;
 
@@ -21,11 +22,14 @@
 
     XWikiDocument doc;
 
+    XWikiContext context;
+
     protected void setUp()
     {
         try {
             domDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
             doc = new XWikiDocument();
+            context = new XWikiContext();
         } catch (ParserConfigurationException e) {
             e.printStackTrace();
         }
@@ -37,7 +41,7 @@
         RWOperation operation =
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
         operation.insert("new ", new PositionImpl(0, 12));
-        operation.apply(doc);
+        operation.apply(doc, context);
         assertEquals("this is the new content", doc.getContent());
     }
 
@@ -58,10 +62,10 @@
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
         operation.insert("something", new PositionImpl(0, 42));
         try {
-            operation.apply(doc);
+            operation.apply(doc, context);
             assertFalse(true);
         } catch (XWikiException ex) {
-            // This is expected
+            assertTrue(true);
         }
     }
 
@@ -71,7 +75,7 @@
         RWOperation operation =
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
         operation.delete("old ", new PositionImpl(0, 12));
-        operation.apply(doc);
+        operation.apply(doc, context);
         assertEquals("this is the content", doc.getContent());
     }
 
@@ -92,14 +96,14 @@
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
         operation.delete("something", new PositionImpl(0, 42));
         try {
-            operation.apply(doc);
+            operation.apply(doc, context);
             assertFalse(true);
         } catch (XWikiException ex) {
             // This is expected
         }
         operation.delete("this", new PositionImpl(0, 2));
         try {
-            operation.apply(doc);
+            operation.apply(doc, context);
             assertFalse(true);
         } catch (XWikiException ex) {
             // This is expected
@@ -112,20 +116,20 @@
         RWOperation operation =
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
         operation.delete("old", new PositionImpl(0, 12));
-        operation.apply(doc);
+        operation.apply(doc, context);
         operation =
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
         operation.insert("new", new PositionImpl(0, 12));
-        operation.apply(doc);
+        operation.apply(doc, context);
         assertEquals("this is the new content", doc.getContent());
         operation =
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
         operation.insert("restored", new PositionImpl(0, 15));
-        operation.apply(doc);
+        operation.apply(doc, context);
         operation =
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
         operation.delete("new", new PositionImpl(0, 12));
-        operation.apply(doc);
+        operation.apply(doc, context);
         assertEquals("this is the restored content", doc.getContent());
     }
 }

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ObjectOperationsTest.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ObjectOperationsTest.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ObjectOperationsTest.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -0,0 +1,333 @@
+package org.xwiki.platform;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jmock.Mock;
+import org.jmock.cglib.MockObjectTestCase;
+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 org.xwiki.platform.patchservice.impl.PositionImpl;
+
+import com.xpn.xwiki.XWiki;
+import com.xpn.xwiki.XWikiConfig;
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.objects.classes.BaseClass;
+
+public class ObjectOperationsTest extends MockObjectTestCase
+{
+    Document domDoc;
+
+    XWikiDocument doc;
+
+    XWikiContext context;
+
+    private Mock mockXWiki;
+
+    protected void setUp()
+    {
+        try {
+            domDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+            doc = new XWikiDocument();
+            doc.setFullName("XWiki.XWikiTestDocument");
+            context = new XWikiContext();
+            this.mockXWiki =
+                mock(XWiki.class, new Class[] {XWikiConfig.class, XWikiContext.class},
+                    new Object[] {new XWikiConfig(), this.context});
+            BaseClass bclass = new BaseClass();
+            bclass.addTextField("property", "The Property", 20);
+            bclass.addTextAreaField("textarea", "Textarea property", 60, 10);
+            bclass.addNumberField("number", "Number Property", 10, "integer");
+            this.mockXWiki.stubs().method("getClass").with(eq("XWiki.SomeClass"), eq(context))
+                .will(returnValue(bclass));
+            this.context.setWiki((XWiki) this.mockXWiki.proxy());
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void testApplyObjectAddOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_ADD);
+        operation.addObject("XWiki.SomeClass");
+        operation.apply(doc, context);
+        assertEquals(1, doc.getObjectNumbers("XWiki.SomeClass"));
+        assertNotNull(doc.getObject("XWiki.SomeClass"));
+        assertNull(doc.getObject("Invalid.Class"));
+    }
+
+    public void testApplyTwiceObjectAddOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_ADD);
+        operation.addObject("XWiki.SomeClass");
+        operation.apply(doc, context);
+        operation.apply(doc, context);
+        assertEquals(2, doc.getObjectNumbers("XWiki.SomeClass"));
+    }
+
+    public void testXmlRoundtripObjectAddOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_ADD);
+        operation.addObject("XWiki.SomeClass");
+        Element e = operation.toXml(domDoc);
+        Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
+        assertEquals(operation, loadedOperation);
+    }
+
+    public void testApplyObjectDeleteOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_DELETE);
+        operation.deleteObject("XWiki.SomeClass", 0);
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        doc.newObject("XWiki.SomeClass", context);
+        assertNotNull(doc.getObject("XWiki.SomeClass", 0));
+        operation.apply(doc, context);
+        assertNull(doc.getObject("XWiki.SomeClass", 0));
+    }
+
+    public void testApplyTwiceObjectDeleteOperation() throws XWikiException
+    {
+        doc.newObject("XWiki.SomeClass", context);
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_DELETE);
+        operation.deleteObject("XWiki.SomeClass", 0);
+        operation.apply(doc, context);
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        assertNull(doc.getObject("XWiki.SomeClass", 0));
+    }
+
+    public void testApplyInvalidObjectDeleteOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_DELETE);
+        operation.deleteObject("XWiki.InvalidClass", 0);
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+    }
+
+    public void testXmlRoundtripObjectDeleteOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_DELETE);
+        operation.deleteObject("XWiki.SomeClass", 0);
+        Element e = operation.toXml(domDoc);
+        Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
+        assertEquals(operation, loadedOperation);
+    }
+
+    public void testApplyObjectPropertySetOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_PROPERTY_SET);
+        operation.setObjectProperty("XWiki.SomeClass", 0, "property", "value");
+        doc.newObject("XWiki.SomeClass", context);
+        assertEquals("", doc.getObject("XWiki.SomeClass", 0).displayView("property", context));
+        operation.apply(doc, context);
+        assertEquals("value", doc.getObject("XWiki.SomeClass", 0)
+            .displayView("property", context));
+        operation.setObjectProperty("XWiki.SomeClass", 0, "number", "30");
+        operation.apply(doc, context);
+        assertEquals("30", doc.getObject("XWiki.SomeClass", 0).displayView("number", context));
+    }
+
+    public void testApplyInvalidObjectPropertySetOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_PROPERTY_SET);
+        operation.setObjectProperty("XWiki.SomeClass", 0, "property", "value");
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        doc.newObject("XWiki.SomeClass", context);
+        operation.apply(doc, context);
+        operation.setObjectProperty("XWiki.SomeClass", 0, "number", "value");
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        assertEquals("value", doc.getObject("XWiki.SomeClass", 0)
+            .displayView("property", context));
+    }
+
+    public void testXmlRoundtripObjectPropertySetOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_OBJECT_PROPERTY_SET);
+        operation.setObjectProperty("XWiki.SomeClass", 0, "property", "  val<\">'ue   ");
+        Element e = operation.toXml(domDoc);
+        Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
+        assertEquals(operation, loadedOperation);
+    }
+
+    public void testApplyObjectPropertyInsertAtOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(
+                RWOperation.TYPE_OBJECT_PROPERTY_INSERT_AT);
+        doc.newObject("XWiki.SomeClass", context);
+        doc.setLargeStringValue("XWiki.SomeClass", "textarea", "first row\nthird row");
+        operation.insertInProperty("XWiki.SomeClass", 0, "textarea", "second row\n",
+            new PositionImpl(1, 0, "first row\n", "third"));
+        assertEquals("first row\nthird row", doc.getObject("XWiki.SomeClass", 0).displayView(
+            "textarea", context));
+        operation.apply(doc, context);
+        assertEquals("first row\nsecond row\nthird row", doc.getObject("XWiki.SomeClass", 0)
+            .displayView("textarea", context));
+    }
+
+    public void testApplyInvalidObjectPropertyInsertAtOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(
+                RWOperation.TYPE_OBJECT_PROPERTY_INSERT_AT);
+        operation.insertInProperty("XWiki.SomeClass", 0, "textarea", "second row\n",
+            new PositionImpl(1, 0, "first row\n", "third row"));
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        doc.newObject("XWiki.SomeClass", context);
+        doc.setIntValue("XWiki.SomeClass", "number", 42);
+        doc.setLargeStringValue("XWiki.SomeClass", "textarea", "first row and \n the third row");
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        doc.setLargeStringValue("XWiki.SomeClass", "textarea", "first row\nthird row");
+        operation.apply(doc, context);
+        operation.insertInProperty("XWiki.SomeClass", 0, "number", "value", new PositionImpl());
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        assertEquals("42", doc.getObject("XWiki.SomeClass", 0).displayView("number", context));
+        operation.insertInProperty("XWiki.SomeClass", 0, "textarea", "value", new PositionImpl(0,
+            0,
+            "invalid",
+            "invalid"));
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+    }
+
+    public void testXmlRoundtripObjectPropertyInsertAtOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(
+                RWOperation.TYPE_OBJECT_PROPERTY_INSERT_AT);
+        operation.insertInProperty("XWiki.SomeClass", 0, "textarea", "value", new PositionImpl());
+        Element e = operation.toXml(domDoc);
+        Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
+        assertEquals(operation, loadedOperation);
+    }
+
+    public void testApplyObjectPropertyDeleteAtOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(
+                RWOperation.TYPE_OBJECT_PROPERTY_DELETE_AT);
+        doc.newObject("XWiki.SomeClass", context);
+        doc
+            .setLargeStringValue("XWiki.SomeClass", "textarea",
+                "first row\nsecond row\nthird row");
+        operation.deleteFromProperty("XWiki.SomeClass", 0, "textarea", "second row\n",
+            new PositionImpl(1, 0, "first row\n", "second"));
+        assertEquals("first row\nsecond row\nthird row", doc.getObject("XWiki.SomeClass", 0)
+            .displayView("textarea", context));
+        operation.apply(doc, context);
+        assertEquals("first row\nthird row", doc.getObject("XWiki.SomeClass", 0).displayView(
+            "textarea", context));
+    }
+
+    public void testApplyInvalidObjectPropertyDeleteAtOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(
+                RWOperation.TYPE_OBJECT_PROPERTY_DELETE_AT);
+        operation.deleteFromProperty("XWiki.SomeClass", 0, "textarea", "second row\n",
+            new PositionImpl(1, 0, "first row\n", "second row\nthird row"));
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        doc.newObject("XWiki.SomeClass", context);
+        doc.setIntValue("XWiki.SomeClass", "number", 42);
+        doc.setLargeStringValue("XWiki.SomeClass", "textarea", "first row and \n the third row");
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        doc
+            .setLargeStringValue("XWiki.SomeClass", "textarea",
+                "first row\nsecond row\nthird row");
+        operation.apply(doc, context);
+        operation.deleteFromProperty("XWiki.SomeClass", 0, "number", "value", new PositionImpl());
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+        operation.deleteFromProperty("XWiki.SomeClass", 0, "textarea", "value",
+            new PositionImpl(0, 0, "invalid", "invalid"));
+        try {
+            operation.apply(doc, context);
+            assertTrue(false);
+        } catch (XWikiException ex) {
+            assertTrue(true);
+        }
+    }
+
+    public void testXmlRoundtripObjectPropertyDeleteAtOperation() throws XWikiException
+    {
+        RWOperation operation =
+            OperationFactoryImpl.getInstance().newOperation(
+                RWOperation.TYPE_OBJECT_PROPERTY_DELETE_AT);
+        operation.deleteFromProperty("XWiki.SomeClass", 0, "textarea", "value",
+            new PositionImpl());
+        Element e = operation.toXml(domDoc);
+        Operation loadedOperation = OperationFactoryImpl.getInstance().loadOperation(e);
+        assertEquals(operation, loadedOperation);
+    }
+}


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

Added: xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PositionImplTest.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PositionImplTest.java	                        (rev 0)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PositionImplTest.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -0,0 +1,264 @@
+package org.xwiki.platform;
+
+import junit.framework.TestCase;
+
+import org.xwiki.platform.patchservice.api.Position;
+import org.xwiki.platform.patchservice.impl.PositionImpl;
+
+public class PositionImplTest extends TestCase
+{
+    public void testCheckSimplePosition()
+    {
+        PositionImpl p = new PositionImpl(0, 0);
+        assertTrue(p.checkPosition(null));
+        assertTrue(p.checkPosition(""));
+        assertTrue(p.checkPosition("anyhing"));
+        assertTrue(p.checkPosition("anyhing\nand some more"));
+        assertTrue(p.checkPosition("anyhing\nand some more\n"));
+        assertTrue(p.checkPosition("\nanyhing\nand some more"));
+        assertTrue(p.checkPosition("\n\n\n"));
+
+        p = new PositionImpl(0, 5);
+        assertFalse(p.checkPosition(null));
+        assertFalse(p.checkPosition(""));
+        assertTrue(p.checkPosition("some text"));
+        assertFalse(p.checkPosition("some\ntext\n"));
+        assertTrue(p.checkPosition("some \ntext\n"));
+        assertFalse(p.checkPosition("so\nme\ntext\n"));
+        assertTrue(p.checkPosition("   some text with spaces"));
+        assertFalse(p.checkPosition("\n\n\n"));
+
+        p = new PositionImpl(1, 0);
+        assertFalse(p.checkPosition(null));
+        assertFalse(p.checkPosition(""));
+        assertTrue(p.checkPosition("\n"));
+        assertFalse(p.checkPosition("some text"));
+        assertTrue(p.checkPosition("some text\n"));
+        assertTrue(p.checkPosition(" \n s\nome text with newlines"));
+        assertTrue(p.checkPosition("first line\nsecond line\nthird line"));
+        assertTrue(p.checkPosition("\n\n\n"));
+
+        p = new PositionImpl(1, 5);
+        assertFalse(p.checkPosition(null));
+        assertFalse(p.checkPosition(""));
+        assertFalse(p.checkPosition("\n"));
+        assertFalse(p.checkPosition("some text"));
+        assertFalse(p.checkPosition("some text\n"));
+        assertTrue(p.checkPosition("some text\nsome more text"));
+        assertTrue(p.checkPosition("some text\nsome more text\n"));
+        assertFalse(p.checkPosition("some text\n\nsome mbore text"));
+        assertFalse(p.checkPosition("some text\n\nsome more text\n"));
+        assertFalse(p.checkPosition(" \n s\nome text with newlines"));
+        assertTrue(p.checkPosition("first line\nsecond line\nthird line"));
+        assertFalse(p.checkPosition("\n\n\n"));
+    }
+
+    public void testCheckPositionWithBefore()
+    {
+        PositionImpl p = new PositionImpl(0, 0, null, null);
+        assertTrue(p.checkPosition(null));
+        assertTrue(p.checkPosition(""));
+        assertTrue(p.checkPosition("anyhing"));
+        assertTrue(p.checkPosition("\n\n\n"));
+
+        p = new PositionImpl(0, 0, "", "");
+        assertTrue(p.checkPosition(null));
+        assertTrue(p.checkPosition(""));
+        assertTrue(p.checkPosition("anyhing"));
+        assertTrue(p.checkPosition("\n\n\n"));
+
+        p = new PositionImpl(0, 0, "before", null);
+        assertFalse(p.checkPosition(null));
+        assertFalse(p.checkPosition(""));
+        assertFalse(p.checkPosition("anyhing"));
+        assertFalse(p.checkPosition("\n\n\n"));
+
+        p = new PositionImpl(1, 0, "before", null);
+        assertFalse(p.checkPosition(null));
+        assertFalse(p.checkPosition(""));
+        assertFalse(p.checkPosition("before"));
+        assertFalse(p.checkPosition("before\n"));
+
+        p = new PositionImpl(1, 0, "before\n", null);
+        assertFalse(p.checkPosition("before"));
+        assertFalse(p.checkPosition("efore\n"));
+        assertTrue(p.checkPosition("before\n"));
+        assertTrue(p.checkPosition("before\nafter"));
+        assertTrue(p.checkPosition("more before\n"));
+
+        p = new PositionImpl(1, 6, "before", null);
+        assertFalse(p.checkPosition("before"));
+        assertFalse(p.checkPosition("before\n"));
+        assertTrue(p.checkPosition("\nbefore\n"));
+        assertFalse(p.checkPosition("\nefore this\n"));
+        assertTrue(p.checkPosition("\nbefore\n"));
+        assertFalse(p.checkPosition("\n before\n"));
+        assertTrue(p.checkPosition("before\nbefore\nafter"));
+        assertTrue(p.checkPosition("more\nbefore and after\n"));
+
+        p = new PositionImpl(1, 4, "be\nfore", null);
+        assertFalse(p.checkPosition("before"));
+        assertFalse(p.checkPosition("before\n"));
+        assertTrue(p.checkPosition("be\nfore\n"));
+        assertFalse(p.checkPosition("\nbefore this\n"));
+        assertTrue(p.checkPosition("be\nfore\n"));
+        assertTrue(p.checkPosition("more be\nfore\n"));
+        assertTrue(p.checkPosition("beforebe\nfore\nafter"));
+        assertTrue(p.checkPosition("more be\nfore and after\n"));
+    }
+
+    public void testCheckPositionWithAfter()
+    {
+        PositionImpl p = new PositionImpl(0, 0, null, null);
+        assertTrue(p.checkPosition(null));
+        assertTrue(p.checkPosition(""));
+        assertTrue(p.checkPosition("anyhing"));
+        assertTrue(p.checkPosition("\n\n\n"));
+
+        p = new PositionImpl(0, 0, "", "");
+        assertTrue(p.checkPosition(null));
+        assertTrue(p.checkPosition(""));
+        assertTrue(p.checkPosition("anyhing"));
+        assertTrue(p.checkPosition("\n\n\n"));
+
+        p = new PositionImpl(0, 0, null, "after");
+        assertFalse(p.checkPosition(null));
+        assertFalse(p.checkPosition(""));
+        assertFalse(p.checkPosition("anyhing"));
+        assertFalse(p.checkPosition("\n\n\n"));
+        assertTrue(p.checkPosition("after"));
+        assertTrue(p.checkPosition("after and some more"));
+
+        p = new PositionImpl(1, 0, null, "after");
+        assertFalse(p.checkPosition(null));
+        assertFalse(p.checkPosition(""));
+        assertFalse(p.checkPosition("before"));
+        assertFalse(p.checkPosition("before\n"));
+        assertTrue(p.checkPosition("before\nafter"));
+        assertTrue(p.checkPosition("before\nafter\n"));
+        assertFalse(p.checkPosition("before\n after"));
+        assertFalse(p.checkPosition("before\n\nafter"));
+
+        p = new PositionImpl(1, 0, null, "\nafter");
+        assertFalse(p.checkPosition("after"));
+        assertFalse(p.checkPosition("\nafter"));
+        assertTrue(p.checkPosition("\n\nafter"));
+        assertTrue(p.checkPosition("before\n\nafter"));
+        assertTrue(p.checkPosition("\n\nafter and more"));
+
+        p = new PositionImpl(1, 6, null, "after");
+        assertFalse(p.checkPosition("before\nafter"));
+        assertFalse(p.checkPosition("before\nmiddle\nafter"));
+        assertTrue(p.checkPosition("\nbeforeafter\n"));
+        assertTrue(p.checkPosition("\nbeforeafter\nmore after"));
+        assertTrue(p.checkPosition("\nbeforeafter more after"));
+        assertFalse(p.checkPosition("\nbefore after"));
+        assertTrue(p.checkPosition("more\n      after and more after\n"));
+
+        p = new PositionImpl(1, 2, null, "af\nter");
+        assertFalse(p.checkPosition("before\n  after"));
+        assertFalse(p.checkPosition("before\n"));
+        assertTrue(p.checkPosition("\n  af\nter"));
+        assertTrue(p.checkPosition("befor\ne af\nter and more\n"));
+    }
+    
+    public void testCheckPositionWithBeforeAndAfter()
+    {
+        Position p = new PositionImpl(1, 6, "before", "after");
+        assertFalse(p.checkPosition("before\nafter"));
+        assertTrue(p.checkPosition("\nbeforeafter"));
+        assertTrue(p.checkPosition("\nbeforeafter\n"));
+        assertTrue(p.checkPosition("more \nbeforeafter and more"));
+        assertTrue(p.checkPosition("more \nbeforeafter\n and more"));
+    }
+
+    public void testTextBefore()
+    {
+        PositionImpl p = new PositionImpl(0, 0);
+        assertEquals("", p.getTextBeforePosition(null));
+        assertEquals("", p.getTextBeforePosition(""));
+        assertEquals("", p.getTextBeforePosition("anyhing"));
+
+        p = new PositionImpl(0, 5);
+        assertEquals("", p.getTextBeforePosition(null));
+        assertEquals("", p.getTextBeforePosition(""));
+        assertEquals("some ", p.getTextBeforePosition("some text"));
+        assertEquals("some", p.getTextBeforePosition("some\ntext\n"));
+        assertEquals("so", p.getTextBeforePosition("so\nme\ntext\n"));
+        assertEquals("   so", p.getTextBeforePosition("   some text with spaces"));
+        assertEquals(" ", p.getTextBeforePosition(" \n s\nome text with newlines"));
+
+        p = new PositionImpl(1, 0);
+        assertEquals("", p.getTextBeforePosition(null));
+        assertEquals("", p.getTextBeforePosition(""));
+        assertEquals("\n", p.getTextBeforePosition("\n"));
+        assertEquals("some text", p.getTextBeforePosition("some text"));
+        assertEquals("some text\n", p.getTextBeforePosition("some text\n"));
+        assertEquals(" \n", p.getTextBeforePosition(" \n s\nome text with newlines"));
+        assertEquals("first line\n", p
+            .getTextBeforePosition("first line\nsecond line\nthird line"));
+
+        p = new PositionImpl(1, 5);
+        assertEquals("", p.getTextBeforePosition(null));
+        assertEquals("", p.getTextBeforePosition(""));
+        assertEquals("\n", p.getTextBeforePosition("\n"));
+        assertEquals("some text", p.getTextBeforePosition("some text"));
+        assertEquals("some text\n", p.getTextBeforePosition("some text\n"));
+        assertEquals("some text\n", p.getTextBeforePosition("some text\n\nsome more text"));
+        assertEquals(" \n s", p.getTextBeforePosition(" \n s\nome text with newlines"));
+        assertEquals("first line\nsecon", p
+            .getTextBeforePosition("first line\nsecond line\nthird line"));
+    }
+
+    public void testTextAfter()
+    {
+        PositionImpl p = new PositionImpl(0, 0);
+        assertEquals("", p.getTextAfterPosition(null));
+        assertEquals("", p.getTextAfterPosition(""));
+        assertEquals("anyhing", p.getTextAfterPosition("anyhing"));
+        assertEquals("anyhing\nand some more", p.getTextAfterPosition("anyhing\nand some more"));
+        assertEquals("anyhing\nand some more\n", p
+            .getTextAfterPosition("anyhing\nand some more\n"));
+        assertEquals("\nanyhing\nand some more", p
+            .getTextAfterPosition("\nanyhing\nand some more"));
+        assertEquals("\n\n\n", p.getTextAfterPosition("\n\n\n"));
+
+        p = new PositionImpl(0, 5);
+        assertEquals("", p.getTextAfterPosition(null));
+        assertEquals("", p.getTextAfterPosition(""));
+        assertEquals("text", p.getTextAfterPosition("some text"));
+        assertEquals("\ntext\n", p.getTextAfterPosition("some\ntext\n"));
+        assertEquals("\nme\ntext\n", p.getTextAfterPosition("so\nme\ntext\n"));
+        assertEquals("me text with spaces", p.getTextAfterPosition("   some text with spaces"));
+        assertEquals("\n\n\n", p.getTextAfterPosition("\n\n\n"));
+
+        p = new PositionImpl(1, 0);
+        assertEquals("", p.getTextAfterPosition(null));
+        assertEquals("", p.getTextAfterPosition(""));
+        assertEquals("", p.getTextAfterPosition("\n"));
+        assertEquals("", p.getTextAfterPosition("some text"));
+        assertEquals("", p.getTextAfterPosition("some text\n"));
+        assertEquals(" s\nome text with newlines", p
+            .getTextAfterPosition(" \n s\nome text with newlines"));
+        assertEquals("second line\nthird line", p
+            .getTextAfterPosition("first line\nsecond line\nthird line"));
+        assertEquals("\n\n", p.getTextAfterPosition("\n\n\n"));
+
+        p = new PositionImpl(1, 5);
+        assertEquals("", p.getTextAfterPosition(null));
+        assertEquals("", p.getTextAfterPosition(""));
+        assertEquals("", p.getTextAfterPosition("\n"));
+        assertEquals("", p.getTextAfterPosition("some text"));
+        assertEquals("", p.getTextAfterPosition("some text\n"));
+        assertEquals("more text", p.getTextAfterPosition("some text\nsome more text"));
+        assertEquals("more text\n", p.getTextAfterPosition("some text\nsome more text\n"));
+        assertEquals("\nsome more text", p.getTextAfterPosition("some text\n\nsome more text"));
+        assertEquals("\nsome more text\n", p
+            .getTextAfterPosition("some text\n\nsome more text\n"));
+        assertEquals("\nome text with newlines", p
+            .getTextAfterPosition(" \n s\nome text with newlines"));
+        assertEquals("d line\nthird line", p
+            .getTextAfterPosition("first line\nsecond line\nthird line"));
+        assertEquals("\n\n", p.getTextAfterPosition("\n\n\n"));
+    }
+}


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

Modified: 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	2008-01-03 12:03:27 UTC (rev 6612)
+++ xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/PropertyOperationsTest.java	2008-01-03 14:11:30 UTC (rev 6613)
@@ -11,6 +11,7 @@
 import org.xwiki.platform.patchservice.api.RWOperation;
 import org.xwiki.platform.patchservice.impl.OperationFactoryImpl;
 
+import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.XWikiDocument;
 
@@ -19,12 +20,15 @@
     Document domDoc;
 
     XWikiDocument doc;
+    
+    XWikiContext context;
 
     protected void setUp()
     {
         try {
             domDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
             doc = new XWikiDocument();
+            context = new XWikiContext();
         } catch (ParserConfigurationException e) {
             e.printStackTrace();
         }
@@ -38,34 +42,34 @@
         RWOperation operation =
             OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_PROPERTY_SET);
         operation.setProperty("author", "XWiki.XWikiGuest");
-        operation.apply(doc);
+