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

Added:
   
xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PositionImpl.java
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/impl/AbstractOperationImpl.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/test/java/org/xwiki/platform/ContentOperationsTest.java
Log:
XWIKI-1977: Create a patchservice data model
Change from integer position to the Position interface.



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-02 14:45:48 UTC (rev 6587)
+++ 
xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/api/RWOperation.java
     2008-01-02 15:02:12 UTC (rev 6588)
@@ -17,9 +17,9 @@
      * @param position The position where the text is inserted.
      * @return True if the action was successfully stored in the object, false 
otherwise.
      */
-    boolean insert(String text, int position);
+    boolean insert(String text, Position position);
 
-    boolean delete(String text, int position);
+    boolean delete(String text, Position position);
 
     /* Operations affeting the document metadata (name, author, language etc. 
*/
     boolean setProperty(String property, String value);
@@ -38,9 +38,9 @@
 
     boolean setObjectProperty(String objectClass, String index, String 
propertyName, String value);
 
-    boolean insertInProperty(String property, String text, int position);
+    boolean insertInProperty(String property, String text, Position position);
 
-    boolean deleteFromProperty(String property, String text, int position);
+    boolean deleteFromProperty(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-02 14:45:48 UTC (rev 6587)
+++ 
xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/AbstractOperationImpl.java
  2008-01-02 15:02:12 UTC (rev 6588)
@@ -6,6 +6,7 @@
 
 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;
@@ -34,7 +35,7 @@
         return false;
     }
 
-    public boolean delete(String text, int position)
+    public boolean delete(String text, Position position)
     {
         return false;
     }
@@ -44,7 +45,7 @@
         return false;
     }
 
-    public boolean deleteFromProperty(String property, String text, int 
position)
+    public boolean deleteFromProperty(String property, String text, Position 
position)
     {
         return false;
     }
@@ -59,12 +60,12 @@
         return false;
     }
 
-    public boolean insert(String text, int position)
+    public boolean insert(String text, Position position)
     {
         return false;
     }
 
-    public boolean insertInProperty(String property, String text, int position)
+    public boolean insertInProperty(String property, String text, Position 
position)
     {
         return false;
     }

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-02 14:45:48 UTC (rev 6587)
+++ 
xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentDeleteOperation.java
 2008-01-02 15:02:12 UTC (rev 6588)
@@ -6,6 +6,7 @@
 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.XWikiException;
@@ -13,10 +14,8 @@
 
 public class ContentDeleteOperation extends AbstractOperationImpl implements 
RWOperation
 {
-    public static final String POSITION_ATTRIBUTE_NAME = "position";
+    private Position position = null;
 
-    private int position = -1;
-
     private String removedContent;
 
     static {
@@ -36,18 +35,19 @@
     {
         try {
             String content = doc.getContent();
-            if (content.indexOf(this.removedContent, this.position) != 
this.position) {
+            if (!position.checkPosition(content)
+                || 
!position.getTextAfterPosition(content).startsWith(this.removedContent)) {
                 throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
                     XWikiException.ERROR_XWIKI_UNKNOWN,
                     "Patch does not fit. Expected ["
-                        + StringUtils.abbreviate(this.removedContent, 20)
-                        + "], but found ["
-                        + StringUtils.abbreviate(StringUtils.mid(content, 
this.position,
-                            this.removedContent.length()), 20) + "]");
+                        + StringUtils.abbreviate(this.removedContent, 20) + 
"], but found ["
+                        + 
StringUtils.abbreviate(position.getTextAfterPosition(content), 20)
+                        + "]");
             }
             content =
-                content.substring(0, position)
-                    + content.substring(position + 
this.removedContent.length());
+                position.getTextBeforePosition(content)
+                    + position.getTextAfterPosition(content).substring(
+                        this.removedContent.length());
             doc.setContent(content);
         } catch (StringIndexOutOfBoundsException ex) {
             throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
@@ -57,7 +57,7 @@
         }
     }
 
-    public boolean delete(String text, int position)
+    public boolean delete(String text, Position position)
     {
         this.removedContent = text;
         this.position = position;
@@ -66,9 +66,10 @@
 
     public void fromXml(Element e) throws XWikiException
     {
-        Element textNode = (Element) e.getFirstChild();
-        this.position = 
Integer.parseInt(textNode.getAttribute(POSITION_ATTRIBUTE_NAME));
+        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));
     }
 
     public Element toXml(Document doc) throws XWikiException
@@ -77,10 +78,10 @@
         xmlNode.setAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME,
             Operation.TYPE_CONTENT_DELETE);
         Element textNode = doc.createElement(TEXT_NODE_NAME);
-        textNode.setAttribute(POSITION_ATTRIBUTE_NAME, this.position + "");
         textNode
             
.appendChild(doc.createTextNode(StringEscapeUtils.escapeXml(this.removedContent)));
         xmlNode.appendChild(textNode);
+        xmlNode.appendChild(position.toXml(doc));
         return xmlNode;
     }
 
@@ -88,7 +89,7 @@
     {
         try {
             ContentDeleteOperation otherOperation = (ContentDeleteOperation) 
other;
-            return (otherOperation.position == this.position)
+            return otherOperation.position.equals(this.position)
                 && otherOperation.removedContent.equals(this.removedContent);
         } catch (Exception e) {
             return false;
@@ -103,7 +104,6 @@
 
     public String toString()
     {
-        return this.getType() + ": [" + this.removedContent + "] at "
-            + this.position;
+        return this.getType() + ": [" + this.removedContent + "] at " + 
this.position;
     }
 }

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-02 14:45:48 UTC (rev 6587)
+++ 
xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/ContentInsertOperation.java
 2008-01-02 15:02:12 UTC (rev 6588)
@@ -5,6 +5,7 @@
 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.XWikiException;
@@ -12,10 +13,8 @@
 
 public class ContentInsertOperation extends AbstractOperationImpl implements 
RWOperation
 {
-    public static final String POSITION_ATTRIBUTE_NAME = "position";
+    private Position position = null;
 
-    private int position = -1;
-
     private String addedContent;
 
     static {
@@ -30,20 +29,19 @@
 
     public void apply(XWikiDocument doc) throws XWikiException
     {
-        try {
-            String content = doc.getContent();
-            content =
-                content.substring(0, position) + this.addedContent + 
content.substring(position);
-            doc.setContent(content);
-        } catch (StringIndexOutOfBoundsException ex) {
+        String content = doc.getContent();
+        if (!position.checkPosition(content)) {
             throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
                 XWikiException.ERROR_XWIKI_UNKNOWN,
-                "Patch cannot be applied",
-                ex);
+                "Patch cannot be applied: invalid position " + position);
         }
+        content =
+            position.getTextBeforePosition(content) + this.addedContent
+                + position.getTextAfterPosition(content);
+        doc.setContent(content);
     }
 
-    public boolean insert(String text, int position)
+    public boolean insert(String text, Position position)
     {
         this.addedContent = text;
         this.position = position;
@@ -52,20 +50,20 @@
 
     public void fromXml(Element e) throws XWikiException
     {
-        Element textNode = (Element) e.getFirstChild();
-        this.position = 
Integer.parseInt(textNode.getAttribute(POSITION_ATTRIBUTE_NAME));
+        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));
     }
 
     public Element toXml(Document doc) throws XWikiException
     {
         Element xmlNode = doc.createElement(AbstractOperationImpl.NODE_NAME);
-        xmlNode.setAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME,
-            Operation.TYPE_CONTENT_INSERT);
+        xmlNode.setAttribute(AbstractOperationImpl.TYPE_ATTRIBUTE_NAME, 
this.getType());
         Element textNode = doc.createElement(TEXT_NODE_NAME);
-        textNode.setAttribute(POSITION_ATTRIBUTE_NAME, this.position + "");
         
textNode.appendChild(doc.createTextNode(StringEscapeUtils.escapeXml(this.addedContent)));
         xmlNode.appendChild(textNode);
+        xmlNode.appendChild(position.toXml(doc));
         return xmlNode;
     }
 
@@ -73,7 +71,7 @@
     {
         try {
             ContentInsertOperation otherOperation = (ContentInsertOperation) 
other;
-            return (otherOperation.position == this.position)
+            return otherOperation.position.equals(this.position)
                 && otherOperation.addedContent.equals(this.addedContent);
         } catch (Exception e) {
             return false;

Added: 
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
                           (rev 0)
+++ 
xwiki-platform/core/trunk/xwiki-patchservice/src/main/java/org/xwiki/platform/patchservice/impl/PositionImpl.java
   2008-01-02 15:02:12 UTC (rev 6588)
@@ -0,0 +1,146 @@
+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;
+import org.w3c.dom.Element;
+import org.xwiki.platform.patchservice.api.Position;
+
+import com.xpn.xwiki.XWikiException;
+
+public class PositionImpl implements Position
+{
+    public static final String NODE_NAME = "position";
+
+    public static final String ROW_ATTRIBUTE_NAME = "row";
+
+    public static final String COLUMN_ATTRIBUTE_NAME = "column";
+
+    public static final String SPAN_ATTRIBUTE_NAME = "span";
+
+    public static final String BEFORE_ATTRIBUTE_NAME = "before";
+
+    public static final String AFTER_ATTRIBUTE_NAME = "after";
+
+    private String before = null;
+
+    private String after = null;
+
+    private int row = -1;
+
+    private int column = -1;
+
+    private int span = -1;
+
+    public PositionImpl()
+    {
+    }
+
+    public PositionImpl(int row, int column)
+    {
+        this(row, column, -1);
+    }
+
+    public PositionImpl(int row, int column, int span)
+    {
+        this(row, column, span, null, null);
+    }
+
+    public PositionImpl(int row, int column, String before, String after)
+    {
+        this(row, column, -1, before, after);
+    }
+
+    public PositionImpl(int row, int column, int span, String before, String 
after)
+    {
+        this.row = row;
+        this.column = column;
+        this.span = span;
+        this.before = before;
+        this.after = after;
+    }
+
+    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;
+            }
+        }
+        return false;
+    }
+
+    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);
+    }
+
+    public String getTextAfterPosition(String text)
+    {
+        String[] rows = StringUtils.splitPreserveAllTokens(text, '\n');
+        String textAfter =
+            StringUtils.substring(rows[row], column)
+                + StringUtils.join(ArrayUtils.subarray(rows, row + 1, 
rows.length), '\n');
+        return (span <= 0) ? textAfter : textAfter.substring(span);
+    }
+
+    public void fromXml(Element e) throws XWikiException
+    {
+        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));
+        }
+        if (e.hasAttribute(AFTER_ATTRIBUTE_NAME)) {
+            this.after = 
StringEscapeUtils.unescapeXml(e.getAttribute(AFTER_ATTRIBUTE_NAME));
+        }
+    }
+
+    public Element toXml(Document doc) throws XWikiException
+    {
+        Element xmlNode = doc.createElement(NODE_NAME);
+        xmlNode.setAttribute(ROW_ATTRIBUTE_NAME, row + "");
+        xmlNode.setAttribute(COLUMN_ATTRIBUTE_NAME, column + "");
+        if (!StringUtils.isEmpty(before)) {
+            xmlNode.setAttribute(BEFORE_ATTRIBUTE_NAME, 
StringEscapeUtils.escapeXml(before));
+        }
+        if (!StringUtils.isEmpty(after)) {
+            xmlNode.setAttribute(AFTER_ATTRIBUTE_NAME, 
StringEscapeUtils.escapeXml(after));
+        }
+        return xmlNode;
+    }
+
+    public boolean equals(Object other)
+    {
+        try {
+            PositionImpl otherPosition = (PositionImpl) other;
+            return (otherPosition.row == this.row)
+                && otherPosition.column == this.column
+                && StringUtils.defaultString(otherPosition.before).equals(
+                    StringUtils.defaultString(before))
+                && StringUtils.defaultString(otherPosition.after).equals(
+                    StringUtils.defaultString(after));
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    public int hashCode()
+    {
+        return new HashCodeBuilder(5, 
47).append(this.row).append(this.column).append(
+            
StringUtils.defaultString(before)).append(StringUtils.defaultString(after))
+            .toHashCode();
+    }
+
+    public String toString()
+    {
+        return "@" + this.row + "," + this.column + ": << [" + this.before + 
"] >> ["
+            + this.after + "]";
+    }
+}


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

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-02 14:45:48 UTC (rev 6587)
+++ 
xwiki-platform/core/trunk/xwiki-patchservice/src/test/java/org/xwiki/platform/ContentOperationsTest.java
    2008-01-02 15:02:12 UTC (rev 6588)
@@ -10,6 +10,7 @@
 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.XWikiException;
 import com.xpn.xwiki.doc.XWikiDocument;
@@ -35,7 +36,7 @@
         doc.setContent("this is the content");
         RWOperation operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
-        operation.insert("new ", 12);
+        operation.insert("new ", new PositionImpl(0, 12));
         operation.apply(doc);
         assertEquals("this is the new content", doc.getContent());
     }
@@ -44,7 +45,7 @@
     {
         RWOperation operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
-        operation.insert("added <con\"ten>t", 10);
+        operation.insert("added <con\"ten>t", new PositionImpl(0, 10));
         Element e = operation.toXml(domDoc);
         Operation loadedOperation = 
OperationFactoryImpl.getInstance().loadOperation(e);
         assertEquals(loadedOperation, operation);
@@ -55,7 +56,7 @@
         doc.setContent("this is the short content");
         RWOperation operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
-        operation.insert("something", 42);
+        operation.insert("something", new PositionImpl(0, 42));
         try {
             operation.apply(doc);
             assertFalse(true);
@@ -69,7 +70,7 @@
         doc.setContent("this is the old content");
         RWOperation operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
-        operation.delete("old ", 12);
+        operation.delete("old ", new PositionImpl(0, 12));
         operation.apply(doc);
         assertEquals("this is the content", doc.getContent());
     }
@@ -78,7 +79,7 @@
     {
         RWOperation operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
-        operation.delete("something", 10);
+        operation.delete("something", new PositionImpl(0, 10));
         Element e = operation.toXml(domDoc);
         Operation loadedOperation = 
OperationFactoryImpl.getInstance().loadOperation(e);
         assertEquals(operation, loadedOperation);
@@ -89,14 +90,14 @@
         doc.setContent("this is the short content");
         RWOperation operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
-        operation.delete("something", 42);
+        operation.delete("something", new PositionImpl(0, 42));
         try {
             operation.apply(doc);
             assertFalse(true);
         } catch (XWikiException ex) {
             // This is expected
         }
-        operation.delete("this", 2);
+        operation.delete("this", new PositionImpl(0, 2));
         try {
             operation.apply(doc);
             assertFalse(true);
@@ -110,20 +111,20 @@
         doc.setContent("this is the old content");
         RWOperation operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
-        operation.delete("old", 12);
+        operation.delete("old", new PositionImpl(0, 12));
         operation.apply(doc);
         operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
-        operation.insert("new", 12);
+        operation.insert("new", new PositionImpl(0, 12));
         operation.apply(doc);
         assertEquals("this is the new content", doc.getContent());
         operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_INSERT);
-        operation.insert("restored", 15);
+        operation.insert("restored", new PositionImpl(0, 15));
         operation.apply(doc);
         operation =
             
OperationFactoryImpl.getInstance().newOperation(RWOperation.TYPE_CONTENT_DELETE);
-        operation.delete("new", 12);
+        operation.delete("new", new PositionImpl(0, 12));
         operation.apply(doc);
         assertEquals("this is the restored content", doc.getContent());
     }

_______________________________________________
notifications mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/notifications

Reply via email to