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