ASF Bugzilla – Attachment 12540 Details for
Bug 30878
[PATCH] org.apache.xindice.core.xupdate.XUpdateImpl
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Possible patch
XUpdateImpl.java.patch (text/plain), 12.65 KB, created by
Todd Byrne
on 2004-08-26 22:22:04 UTC
(
hide
)
Description:
Possible patch
Filename:
MIME Type:
Creator:
Todd Byrne
Created:
2004-08-26 22:22:04 UTC
Size:
12.65 KB
patch
obsolete
>--- xml-xindice/java/src/org/apache/xindice/core/xupdate/XUpdateImpl.java 2004-02-07 19:50:54.000000000 -0700 >+++ /home/byrne/jbproject/xindice-cvs-src/xml-xindice/java/src/org/apache/xindice/core/xupdate/XUpdateImpl.java 2004-08-26 13:50:53.000000000 -0600 >@@ -27,6 +27,7 @@ > > import org.w3c.dom.Document; > import org.w3c.dom.Node; >+import org.w3c.dom.NodeList; > import org.xml.sax.SAXException; > import org.xmldb.xupdate.lexus.XUpdateQueryImpl; > import org.xmldb.xupdate.lexus.commands.CommandConstants; >@@ -35,6 +36,7 @@ > > import java.util.Enumeration; > import java.util.Hashtable; >+import org.apache.xindice.core.data.Key; > > /** > * Provides Collection and document based XUpdate capabilities. >@@ -44,148 +46,194 @@ > * > * @version CVS $Revision: 1.12 $, $Date: 2004/02/08 02:50:54 $ > */ >-public class XUpdateImpl extends XUpdateQueryImpl { >+public class XUpdateImpl >+ extends XUpdateQueryImpl { > >- protected int nodesModified = 0; >- protected NamespaceMap nsMap; >+ 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; >- >- /** >- * Set the namespace map to be used when resolving queries >- */ >- public void setNamespaceMap(NamespaceMap nsMap) { >- if (nsMap == null) { >- return; >- } >- >- if (this.nsMap == null) { >- this.nsMap = nsMap; >- } else { >- this.nsMap.includeNamespaces(nsMap, API_NS_PRECEDENCE); >- } >+ /** >+ * 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; >+ >+ /** >+ * Set the namespace map to be used when resolving queries >+ */ >+ public void setNamespaceMap(NamespaceMap nsMap) { >+ if (nsMap == null) { >+ return; > } > >- >- /** >- * Sets the query string to be used when executing update >- */ >- public void setQString(String query) throws SAXException { >- super.setQString(query); >- if (nsMap == null) { >- nsMap = new NamespaceMap(); >- } >- nsMap.includeNamespaces(super.namespaces, !API_NS_PRECEDENCE); >+ if (this.nsMap == null) { >+ this.nsMap = nsMap; > } >+ else { >+ this.nsMap.includeNamespaces(nsMap, API_NS_PRECEDENCE); >+ } >+ } > >+ /** >+ * Sets the query string to be used when executing update >+ */ >+ public void setQString(String query) throws SAXException { >+ super.setQString(query); >+ if (nsMap == null) { >+ nsMap = new NamespaceMap(); >+ } >+ nsMap.includeNamespaces(super.namespaces, !API_NS_PRECEDENCE); >+ } > >- /** >- * Execute the XUpdate commands against a document. >- */ >- public void execute(Node contextNode) throws Exception { >- CommandObject currentCommand = new DefaultCommand(contextNode); >- Enumeration commands = super.query[0].elements(); >- Enumeration attributes = super.query[1].elements(); >- Enumeration characters = super.query[2].elements(); >- Node origNode = contextNode; >- CommandObject.getXPath().setNamespace(nsMap.getContextNode()); >- >- while (commands.hasMoreElements()) { >- int id = ((Integer) commands.nextElement()).intValue(); >- >- if (id == CommandConstants.ATTRIBUTES) { >- currentCommand.submitAttributes((Hashtable) attributes.nextElement()); >- } else if (id == CommandConstants.CHARACTERS) { >- currentCommand.submitCharacters((String) characters.nextElement()); >- } else if (id > 0) { >- if (!currentCommand.submitInstruction(id)) { >- super.commandConstants.setContextNode(contextNode); >- currentCommand = super.commandConstants.commandForID(id); >- if (currentCommand == null) { >- throw new Exception("Operation can not have any XUpdate-instruction!"); >- } >- currentCommand.reset(); >- } >- } else { >- if (!currentCommand.executeInstruction()) { >- try { >- contextNode = currentCommand.execute(); >- } catch (Exception e) { >- // While not ideal, CommandObject.execute throws >- // Exception("no nodes selected !") if nothing is >- // selected for modification we trap that case >- // and ignore allowing continued processing >- // of remaining xupdate instructions that may be present >- if (!"no nodes selected !".equals(e.getMessage())) { >- throw e; >- } >- } >- // Default do-nothing command will soak up anything >- // (characters, attributes, etc.) encountered until we >- // come across the next xupdate instruction >- // (e.g. remove, append, insert, etc.) >- currentCommand = new DefaultCommand(contextNode); >- } >+ /** >+ * Execute the XUpdate commands against a document. >+ */ >+ public void execute(Node contextNode) throws Exception { >+ CommandObject currentCommand = new DefaultCommand(contextNode); >+ Enumeration commands = super.query[0].elements(); >+ Enumeration attributes = super.query[1].elements(); >+ Enumeration characters = super.query[2].elements(); >+ Node origNode = contextNode; >+ CommandObject.getXPath().setNamespace(nsMap.getContextNode()); >+ boolean contextNodeNeedsCleaning = false; >+ >+ while (commands.hasMoreElements()) { >+ int id = ( (Integer) commands.nextElement()).intValue(); >+ >+ if (id == CommandConstants.ATTRIBUTES) { >+ currentCommand.submitAttributes( (Hashtable) attributes.nextElement()); >+ } >+ else if (id == CommandConstants.CHARACTERS) { >+ currentCommand.submitCharacters( (String) characters.nextElement()); >+ } >+ else if (id > 0) { >+ if (!currentCommand.submitInstruction(id)) { >+ super.commandConstants.setContextNode(contextNode); >+ currentCommand = super.commandConstants.commandForID(id); >+ if (currentCommand == null) { >+ throw new Exception( >+ "Operation can not have any XUpdate-instruction!"); >+ } >+ currentCommand.reset(); >+ } >+ } >+ else { >+ if (!currentCommand.executeInstruction()) { >+ try { >+ contextNode = currentCommand.execute(); >+ } >+ catch (Exception e) { >+ // While not ideal, CommandObject.execute throws >+ // Exception("no nodes selected !") if nothing is >+ // selected for modification we trap that case >+ // and ignore allowing continued processing >+ // of remaining xupdate instructions that may be present >+ if (!"no nodes selected !".equals(e.getMessage())) { >+ throw e; > } >- } >- >- if (origNode instanceof CompressedNode) { >- CompressedNode cn = (CompressedNode) origNode; >- if (cn.isDirty()) { >- nodesModified++; >+ // from my tests I figure out it adds one temporary node per >+ // command, but when the exception gets thrown it never cleans it self up >+ // this one node is always at the end >+ String lastNodeName = origNode.getLastChild().getNodeName(); >+ if (lastNodeName.equals("temporaryXUpdateTree")) { >+ // assuming that one command one temporary node. >+ origNode.removeChild(origNode.getLastChild()); >+ } >+ else { // search for it? >+ contextNodeNeedsCleaning = true; > } >+ } >+ // Default do-nothing command will soak up anything >+ // (characters, attributes, etc.) encountered until we >+ // come across the next xupdate instruction >+ // (e.g. remove, append, insert, etc.) >+ currentCommand = new DefaultCommand(contextNode); > } >+ } > } >+ if (contextNodeNeedsCleaning) { >+ // search entire tree and to verify no extra nodes where left around. >+ cleanUpNode(origNode); >+ } >+ if (origNode instanceof CompressedNode) { >+ CompressedNode cn = (CompressedNode) origNode; >+ if (cn.isDirty()) { >+ nodesModified++; >+ } >+ } >+ } >+ >+ /** >+ * Execute the set of XUpdate commands against a collection. >+ * >+ * @param col The collection against which the command will be executed >+ * @exception Exception Description of Exception >+ */ >+ public void execute(Collection col) throws Exception { >+ >+ int attribIndex = 0; >+ int temp = 0; >+ Hashtable docsUpdated = new Hashtable(); >+ >+ 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"); >+ >+ // If we found an XPath selector we need to execute the commands. >+ // save to skip variable because at this point we have already run the commands on the >+ // files. >+ if (selector != null && !selector.startsWith("$")) { >+ NodeSet ns = col.queryCollection("XPath", selector, nsMap); >+ >+ while (ns != null && ns.hasMoreNodes()) { >+ DBNode node = (DBNode) ns.getNextNode(); >+ Document doc = node.getOwnerDocument(); >+ NodeSource source = node.getSource(); >+ Node contextNode = doc.getDocumentElement(); > >- /** >- * Execute the set of XUpdate commands against a collection. >- * >- * @param col The collection against which the command will be executed >- * @exception Exception Description of Exception >- */ >- public void execute(Collection col) throws Exception { >- >- int attribIndex = 0; >- 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"); >- >- // If we found an XPath selector we need to execute the commands. >- if (selector != null) { >- NodeSet ns = col.queryCollection("XPath", selector, nsMap); >- Document lastDoc = null; >- while (ns != null && ns.hasMoreNodes()) { >- DBNode node = (DBNode) ns.getNextNode(); >- Document doc = node.getOwnerDocument(); >- >- if (doc == lastDoc) { >- continue; // We only have to process it once >- } else { >- lastDoc = doc; >- } >- >- NodeSource source = node.getSource(); >- >- Node contextNode = doc.getDocumentElement(); >- execute(contextNode); >- >- col.setDocument(source.getKey(), doc); >- } >- } >+ if (docsUpdated.containsKey(source.getKey())) { >+ continue; // We only have to process it once > } >+ else { >+ docsUpdated.put(source.getKey(), doc); >+ } >+ execute(contextNode); >+ } > } >+ } >+ } >+ Enumeration keys = docsUpdated.keys(); >+ while (keys.hasMoreElements()) { >+ Key docID = (Key) keys.nextElement(); >+ col.setDocument(docID, (Document) docsUpdated.get(docID)); > } >+ } >+ >+ public int getModifiedCount() { >+ return nodesModified; >+ } >+/** >+ * Search the document tree for nodes left around from the xupdate commands. >+ * >+ */ > >- public int getModifiedCount() { >- return nodesModified; >+ private void cleanUpNode(Node n) { >+ NodeList list = n.getChildNodes(); >+ int listLength = list.getLength(); >+ >+ for (int i = listLength - 1; i >= 0; i--) { >+ Node currentNode = list.item(i); >+ if (currentNode.getNodeName().equals("temporaryXUpdateTree")) { >+ n.removeChild(currentNode); >+ } >+ else { >+ cleanUpNode(currentNode); >+ } > } >-} > >+ } >+} >\ No newline at end of file
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 30878
: 12540 |
12568
|
12569