org.nuxeo.ecm.platform.annotations.gwt.client.util.XPathUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.nuxeo.ecm.platform.annotations.gwt.client.util.XPathUtil.java

Source

/*
 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others.
 *
 * 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.
 *
 * Contributors:
 *     Alexandre Russel
 *
 * $Id$
 */

package org.nuxeo.ecm.platform.annotations.gwt.client.util;

import java.util.ArrayList;
import java.util.List;

import org.nuxeo.ecm.platform.annotations.gwt.client.AnnotationConstant;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.SpanElement;

/**
 * @author <a href="mailto:arussel@nuxeo.com">Alexandre Russel</a>
 */
public class XPathUtil {
    public String getXPath(Node node) {
        Log.debug("XPathUtil] node: " + node.getNodeName() + " parent node: " + node.getParentNode().getNodeName());
        Document document = node.getOwnerDocument();
        Node current = node;
        StringBuilder xpath = new StringBuilder();
        while (!current.equals(document)) {
            int counter = 1;
            String name = current.getNodeName();
            while (current.getPreviousSibling() != null) {
                if (current.getPreviousSibling().getNodeName().equalsIgnoreCase(name)
                        && !isIgnored(current.getPreviousSibling())) {
                    counter++;
                }
                current = current.getPreviousSibling();
            }
            xpath.insert(0, "/" + name.toLowerCase() + "[" + counter + "]");
            current = current.getParentNode();
        }
        Log.debug("XPathUtil] xpath: " + xpath);
        return xpath.toString();
    }

    public String getSelectionXPointer(Range range) {
        int start = range.getStartOffset();
        Node clickedNode = range.getStartContainer();
        Node parentNode = clickedNode.getParentNode();

        if (clickedNode.getNodeType() == Node.TEXT_NODE) {
            TextGrabberVisitor processor = new TextGrabberVisitor();
            Visitor visitor = new Visitor(processor);
            visitor.process(parentNode, clickedNode);
            start += processor.getText().length();
        }
        Log.debug("getSelectionXPointer; start: " + start);
        return "#xpointer(string-range(" + getXPath(parentNode) + ",\"\"," + start + ","
                + getShortLength(range.getSelectedText()) + "))";
    }

    public int getShortLength(String selectedText) {
        for (String removed : new String[] { "\n", "\r" }) {
            selectedText = selectedText.replace(removed, "");
        }
        return selectedText.length();
    }

    public List<Node> getNode(String xpath, Document document) {
        List<Node> nodes = new ArrayList<Node>();
        if (xpath.startsWith("//")) {
            xpath = xpath.substring(2);
            NodeList<Element> n = document.getElementsByTagName(xpath);
            for (int x = 0; x < n.getLength(); x++) {
                nodes.add(n.getItem(x));
            }
            return nodes;
        }
        Log.debug("XPathUtil#getNode -- xpath: " + xpath);
        String[] paths = xpath.split("/");
        Node result = document;
        for (String path : paths) {
            if ("".equals(path)) {
                continue;
            }
            NodeList<Node> nodeList = result.getChildNodes();
            String name = path.substring(0, path.indexOf("["));
            int index = Integer.parseInt(path.substring(path.indexOf("[") + 1, path.indexOf("]")));
            int counter = 1;
            for (int x = 0; x < nodeList.getLength(); x++) {
                Node node = nodeList.getItem(x);
                if (node.getNodeName().equalsIgnoreCase(name)) {
                    if (isIgnored(node)) {// considered as text node
                        continue;
                    }
                    if (counter == index) {
                        result = node;
                        break;
                    }
                    counter++;
                }
            }

        }
        nodes.add(result);
        Log.debug("XPathUtil#getNode -- end function: ");
        return nodes;
    }

    private boolean isIgnored(Node node) {
        int nodeType = node.getNodeType();
        if (nodeType != Node.ELEMENT_NODE && nodeType != Node.TEXT_NODE) {
            return true; // ignore non element and non text node
        }
        if (node.getNodeName().equalsIgnoreCase("span")) {
            SpanElement spanElement = SpanElement.as(node).cast();
            String name = spanElement.getClassName();
            if (name == null) {
                return false;
            }
            return name.contains(AnnotationConstant.IGNORED_ELEMENT);
        } else if (node.getNodeName().equalsIgnoreCase("div")) {
            DivElement divElement = DivElement.as(node).cast();
            return divElement.getClassName().equals(AnnotationConstant.IGNORED_ELEMENT);
        }
        return false;
    }

    public boolean isChildOfIgnored(Node node) {
        boolean ignored = false;
        while (node != null && !ignored) {
            ignored = isIgnored(node);
            node = node.getParentNode();
        }
        return ignored;
    }

    public static String toIdableName(String xpath) {
        xpath = "X" + xpath;
        xpath = xpath.replace("/", "-");
        xpath = xpath.replace("[", "_");
        return xpath.replace("]", ":");
    }

    public static String fromIdableName(String xpath) {
        xpath = xpath.substring(1);
        xpath = xpath.replace("-", "/");
        xpath = xpath.replace("_", "[");
        return xpath.replace(":", "]");
    }
}