You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xindice-dev@xml.apache.org by vg...@apache.org on 2005/05/26 03:17:11 UTC
cvs commit: xml-xindice/java/tests/src/org/apache/xindice/integration/client/services XUpdateQueryTest.java
vgritsenko 2005/05/25 18:17:11
Modified: . status.xml
java/src/org/apache/xindice/core/xupdate XUpdateImpl.java
java/tests/src/org/apache/xindice/integration/client/services
XUpdateQueryTest.java
Log:
apply patch from Todd Byrne, fix xupdate bug #30878
Revision Changes Path
1.52 +8 -1 xml-xindice/status.xml
Index: status.xml
===================================================================
RCS file: /home/cvs/xml-xindice/status.xml,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -r1.51 -r1.52
--- status.xml 4 Mar 2005 03:38:14 -0000 1.51
+++ status.xml 26 May 2005 01:17:11 -0000 1.52
@@ -73,7 +73,14 @@
</todo>
<changes>
- <release version="1.1b5-dev" date="March 3 2005">
+ <release version="1.1b5-dev" date="May 25 2005">
+ <action dev="VG" type="fix" fixes-bug="30878" due-to="Todd Byrne">
+ Make sure that XUpdate commands are run only once per document.
+ In case XUpdate command does not complete successfully, revert
+ all affected documents to the original state. This requires
+ buffering of modified documents - so XUpdate on large collection
+ might require lots of memory.
+ </action>
<action dev="VG" type="update" fixes-bug="33657" due-to="Dave Brosius">
Added support for current Xalan CVS (post 2.6.0 release).
</action>
1.13 +34 -21 xml-xindice/java/src/org/apache/xindice/core/xupdate/XUpdateImpl.java
Index: XUpdateImpl.java
===================================================================
RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/xupdate/XUpdateImpl.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- XUpdateImpl.java 8 Feb 2004 02:50:54 -0000 1.12
+++ XUpdateImpl.java 26 May 2005 01:17:11 -0000 1.13
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,27 +34,30 @@
import org.xmldb.xupdate.lexus.commands.DefaultCommand;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
/**
* Provides Collection and document based XUpdate capabilities.
*
* For more detail about XUpdate look at the
- * <a href="http://www.xmldb.org/xupdate/xupdate-wd.html">XUpdate Working Draft</a>.
+ * <a href="http://xmldb-org.sourceforge.net/xupdate/xupdate-wd.html">XUpdate Working Draft</a>.
*
* @version CVS $Revision$, $Date$
*/
public class XUpdateImpl extends XUpdateQueryImpl {
- protected int nodesModified = 0;
- protected NamespaceMap nsMap;
-
/**
* If set to true, then namespaces set explicitly via an API call will take precendence.
* If set to false, then namespaces set implicitly within query string will take precedence.
*/
private static final boolean API_NS_PRECEDENCE = true;
+ protected int nodesModified;
+ protected NamespaceMap nsMap;
+
/**
* Set the namespace map to be used when resolving queries
*/
@@ -148,44 +151,54 @@
* @exception Exception Description of Exception
*/
public void execute(Collection col) throws Exception {
-
int attribIndex = 0;
+
+ // TODO: Don't cache all the documents in memory.
+ // Need to keep updated documents in memory so that can
+ // 'rollback' all the changes in case of failure.
+ // Won't need this in case underlying collection supports
+ // transaction.
+ HashMap docsUpdated = new HashMap();
for (int i = 0; i < super.query[0].size(); i++) {
int cmdID = ((Integer) super.query[0].elementAt(i)).intValue();
if (cmdID == CommandConstants.ATTRIBUTES) {
Hashtable attribs = (Hashtable) super.query[1].elementAt(attribIndex);
- attribIndex++;
String selector = (String) attribs.get("select");
+ attribIndex++;
- // If we found an XPath selector we need to execute the commands.
- if (selector != null) {
+ // If we found an XPath selector we need to execute the commands,
+ // but we can not execute xupdate variables again.
+ // all variables start with a '$'
+ if (selector != null && !selector.startsWith("$")) {
NodeSet ns = col.queryCollection("XPath", selector, nsMap);
- Document lastDoc = null;
while (ns != null && ns.hasMoreNodes()) {
DBNode node = (DBNode) ns.getNextNode();
Document doc = node.getOwnerDocument();
+ NodeSource source = node.getSource();
- if (doc == lastDoc) {
+ if (docsUpdated.containsKey(source.getKey())) {
continue; // We only have to process it once
} else {
- lastDoc = doc;
+ docsUpdated.put(source.getKey(), doc);
}
- NodeSource source = node.getSource();
-
- Node contextNode = doc.getDocumentElement();
- execute(contextNode);
-
- col.setDocument(source.getKey(), doc);
+ execute(doc.getDocumentElement());
}
}
}
}
+
+ // Update all documents at once
+ // this way we don't get any half run xupdate commands.
+ Iterator i = docsUpdated.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry set = (Map.Entry) i.next();
+ col.setDocument(set.getKey(), (Document) set.getValue());
+ }
}
public int getModifiedCount() {
return nodesModified;
}
}
-
1.8 +44 -7 xml-xindice/java/tests/src/org/apache/xindice/integration/client/services/XUpdateQueryTest.java
Index: XUpdateQueryTest.java
===================================================================
RCS file: /home/cvs/xml-xindice/java/tests/src/org/apache/xindice/integration/client/services/XUpdateQueryTest.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- XUpdateQueryTest.java 1 Apr 2005 02:46:43 -0000 1.7
+++ XUpdateQueryTest.java 26 May 2005 01:17:11 -0000 1.8
@@ -22,6 +22,9 @@
import org.xmldb.api.modules.XUpdateQueryService;
import org.xmldb.api.base.Collection;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.custommonkey.xmlunit.XMLAssert;
/**
* @version CVS $Revision$, $Date$
@@ -29,7 +32,7 @@
*/
public class XUpdateQueryTest
extends AbstractXmlDbClientTest {
-
+ private static final Log log = LogFactory.getLog(XUpdateQueryTest.class);
public void setUp() throws Exception {
super.setUp();
@@ -96,6 +99,7 @@
"<last>Smith</last>" +
"<phone type=\"work\">480-300-3003</phone>" +
"</person>";
+
String updatedDocument2 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<person status=\"divorced\">" +
"<first>Ben</first>" +
@@ -103,18 +107,51 @@
"<phone type=\"work\">480-300-3003</phone>" +
"</person>";
+ String query2 =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<xupdate:modifications version=\"1.0\" xmlns:xupdate=\"http://www.xmldb.org/xupdate\">" +
+ "<xupdate:append select=\"/person/first\">" +
+ "<xupdate:element name=\"test2\"/>" +
+ "</xupdate:append>" +
+ "<xupdate:append select=\"/person/last\">" +
+ "<xupdate:element name=\"test1\"/>" +
+ "</xupdate:append>" +
+ "</xupdate:modifications>";
+
+ String updatedDocument3 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<person status=\"divorced\">" +
+ "<first>Ben" +
+ "<test2 />" +
+ "</first>" +
+ "<last>Benton"+
+ "<test1 />" +
+ "</last>" +
+ "<phone type=\"work\">480-300-3003</phone>" +
+ "</person>";
+
Collection col = this.client.getCollection(TEST_COLLECTION_PATH);
XUpdateQueryService service = (XUpdateQueryService) col.getService("XUpdateQueryService", "1.0");
-
long count = service.update(query);
- assertEquals(6, count);
+ // Fixed: was 6 should be 2. The old code would cause multiple updates.
+ assertEquals(2, count);
String doc = this.client.getDocument(TEST_COLLECTION_PATH, "doc1");
assertNotNull(doc);
- assertEquals(updatedDocument1, doc);
+ XMLAssert.assertXMLEqual(updatedDocument1, doc);
doc = this.client.getDocument(TEST_COLLECTION_PATH, "doc2");
assertNotNull(doc);
- assertEquals(updatedDocument2, doc);
+ XMLAssert.assertXMLEqual(updatedDocument2, doc);
+
+ // test the second query should update 2 docs
+ count = service.update(query2);
+ assertEquals(2,count);
+
+ // check the second doc to make sure its correct
+ doc = this.client.getDocument(TEST_COLLECTION_PATH, "doc2");
+
+ log.debug("Doc2:=\n " + doc);
+ log.debug("UpdatedDoc3:\n " + updatedDocument3);
+ XMLAssert.assertXMLEqual(updatedDocument3,doc);
}
}