1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package no.sintef.clix.functions;
22
23 import java.math.BigDecimal;
24 import java.util.Collection;
25 import java.util.Iterator;
26
27 import no.sintef.xml.XmlHelper;
28
29 import org.apache.log4j.Logger;
30 import org.jaxen.JaxenException;
31 import org.jaxen.NamespaceContext;
32 import org.jaxen.VariableContext;
33 import org.jaxen.XPath;
34 import org.w3c.dom.Attr;
35 import org.w3c.dom.Element;
36 import org.w3c.dom.Node;
37 import org.w3c.dom.NodeList;
38 import org.w3c.dom.Text;
39
40 public class Selector {
41
42 private static final Logger LOGGER = Logger.getLogger(Selector.class);
43
44 public static final Collection selectNodes(Object context, XPath xpath, VariableContext variableContext, NamespaceContext namespaceContext) throws JaxenException {
45 if (variableContext != null) {
46 xpath.setVariableContext(variableContext);
47 }
48 if (namespaceContext != null) {
49 xpath.setNamespaceContext(namespaceContext);
50 }
51 return xpath.selectNodes(context);
52 }
53
54 public static final String stringValueOf(Object context, XPath xpath, VariableContext variableContext, NamespaceContext namespaceContext) throws JaxenException {
55 if (variableContext != null) {
56 xpath.setVariableContext(variableContext);
57 }
58 if (namespaceContext != null) {
59 xpath.setNamespaceContext(namespaceContext);
60 }
61 return xpath.stringValueOf(context);
62 }
63
64 protected static boolean equals(Collection c1, Collection c2) {
65
66 Object o1 = getCompareObject(c1);
67 Object o2 = getCompareObject(c2);
68 if (LOGGER.isDebugEnabled()) {
69 LOGGER.debug("equals(" + o1 + ", " + o2 + ")");
70 }
71 if (o1 == o2) {
72 return true;
73 } else if (o1 == null || o2 == null) {
74 return false;
75 }
76 if (o1 instanceof Boolean && o2 instanceof Number) {
77 o2 = getBooleanValue((Number)o2);
78 } else if (o1 instanceof Number && o2 instanceof Boolean) {
79 o1 = getBooleanValue((Number)o1);
80 } else if (o1 instanceof Boolean && o2 instanceof String) {
81 o1 = o1.toString();
82 } else if (o1 instanceof String && o2 instanceof Boolean) {
83 o2 = o2.toString();
84 } else if (o1 instanceof String && o2 instanceof Number) {
85 o2 = getStringValue((Number)o2);
86 } else if (o1 instanceof Number && o2 instanceof String) {
87 o1 = getStringValue((Number)o1);
88 } else if (o1 instanceof String && o2 instanceof String) {
89
90 } else {
91 assert false :
92 "Unexpected compare objects: "
93 + o1 + '(' + o1.getClass() + "), "
94 + o2 + '(' + o2.getClass() + ')';
95 }
96 return o1.equals(o2);
97 }
98
99 private static String getStringValue(Node node) {
100 if (node instanceof Attr || node instanceof Text){
101 return node.getNodeValue();
102 } else if (node instanceof Element) {
103 Element e = (Element) node;
104
105 return XmlHelper.getText(e);
106 } else {
107 System.err.println("Unexpected node type: " + node + (node != null ? " [" + node.getClass() + "]" : ""));
108 return null;
109 }
110 }
111
112 private static Object getStringValue(Number n) {
113 if (n instanceof Float || n instanceof Double) {
114 double d = n.doubleValue();
115 if (Double.isNaN(d)) {
116 return "NaN";
117 }
118 String s = "" + d;
119 if (s.indexOf('.') != -1)
120 s = s.replaceFirst(".0*$", "");
121 return s;
122 } else {
123 long l = n.longValue();
124 return "" + l;
125 }
126 }
127
128 private static Boolean getBooleanValue(Number n) {
129 if (n instanceof Float || n instanceof Double || n instanceof BigDecimal) {
130 double d = n.doubleValue();
131 return Boolean.valueOf(d != 0.0 && !Double.isNaN(d));
132 }
133 long l = n.longValue();
134 return Boolean.valueOf(l != 0);
135 }
136
137 protected static Object getCompareObject(Collection c) {
138 if (c == null || c.size() == 0) {
139 return "";
140 } else if (c.size() == 1) {
141 Object o = c.iterator().next();
142 if (o instanceof Node) {
143 return getStringValue((Node)o);
144 } else {
145 return o;
146 }
147 }
148
149 String result = "";
150 for (Iterator i = c.iterator(); i.hasNext();) {
151 Object o = (Object) i.next();
152 if (o instanceof Node) {
153 result += getStringValue((Node)o);
154 } else {
155 result += o.toString();
156 }
157 }
158 return result;
159 }
160
161 }