Java tutorial
/* * Copyright 2002,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. */ package org.apache.commons.jelly.xpath; import java.util.Comparator; import java.util.List; import org.apache.commons.jelly.util.NestedRuntimeException; import org.dom4j.Node; import org.jaxen.JaxenException; import org.jaxen.XPath; /** * Compares xml nodes by extracting the value at xpath and * comparing it. * * @author <a href="mailto:jason@jhorman.org">Jason Horman</a> * @version $Id: XPathComparator.java,v 1.4 2004/09/09 12:29:36 dion Exp $ */ public class XPathComparator implements Comparator { /** The xpath to use to extract value from nodes to compare */ private XPath xpath = null; /** Sort descending or ascending */ private boolean descending = false; public XPathComparator() { } public XPathComparator(XPath xpath, boolean descending) { this.xpath = xpath; this.descending = descending; } public void setXpath(XPath xpath) { this.xpath = xpath; } public XPath getXpath() { return xpath; } public void setDescending(boolean descending) { this.descending = descending; } public int compare(Object o1, Object o2) { return compare((Node) o1, (Node) o2); } public int compare(Node n1, Node n2) { try { // apply the xpaths. not using stringValueOf since I don't // want all of the child nodes appended to the strings Object val1 = xpath.evaluate(n1); Object val2 = xpath.evaluate(n2); // return if null if (val1 == null || val2 == null) { return val1 == null ? (val2 == null ? 1 : -1) : 1; } Comparable c1 = getComparableValue(val1); Comparable c2 = getComparableValue(val2); // compare descending or ascending if (!descending) { return c1.compareTo(c2); } else { return c2.compareTo(c1); } } catch (JaxenException e) { throw new XPathSortException("error sorting nodes", e); } } /** * Turns the XPath result value into a Comparable object. */ protected Comparable getComparableValue(Object value) { if (value instanceof List) { List list = (List) value; if (list.isEmpty()) { value = ""; } value = list.get(0); if (value == null) { value = ""; } } if (value instanceof Comparable) { return (Comparable) value; } else if (value instanceof Node) { Node node = (Node) value; return node.getStringValue(); } return value.toString(); } /** * My own runtime exception in case something goes wrong with sort. */ public static class XPathSortException extends NestedRuntimeException { public XPathSortException(String message, Throwable cause) { super(message, cause); } } }