Package org.apache.xindice.core.xupdate

Source Code of org.apache.xindice.core.xupdate.XUpdateImpl

/*
* Copyright 1999-2004 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.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* CVS $Id: XUpdateImpl.java,v 1.12 2004/02/08 02:50:54 vgritsenko Exp $
*/

package org.apache.xindice.core.xupdate;

import org.apache.xindice.core.Collection;
import org.apache.xindice.core.data.NodeSet;
import org.apache.xindice.xml.NamespaceMap;
import org.apache.xindice.xml.NodeSource;
import org.apache.xindice.xml.dom.CompressedNode;
import org.apache.xindice.xml.dom.DBNode;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xmldb.xupdate.lexus.XUpdateQueryImpl;
import org.xmldb.xupdate.lexus.commands.CommandConstants;
import org.xmldb.xupdate.lexus.commands.CommandObject;
import org.xmldb.xupdate.lexus.commands.DefaultCommand;

import java.util.Enumeration;
import java.util.Hashtable;

/**
* 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>.
*
* @version CVS $Revision: 1.12 $, $Date: 2004/02/08 02:50:54 $
*/
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;

    /**
     * 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);
        }
    }


    /**
     * 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);
                }
            }
        }

        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;
        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);
                    }
                }
            }
        }
    }

    public int getModifiedCount() {
        return nodesModified;
    }
}
TOP

Related Classes of org.apache.xindice.core.xupdate.XUpdateImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.