1 22 23 package org.xquark.xml.xqueryevaluator.eval; 24 25 import java.util.ArrayList ; 26 27 public class XPathExpr implements Cloneable { 28 29 private static final String RCSRevision = "$Revision: 1.1 $"; 30 private static final String RCSName = "$Name: $"; 31 private java.util.ArrayList fields = new java.util.ArrayList (4); 32 33 public Object clone() { 34 XPathExpr newExpr = new XPathExpr(); 35 newExpr.fields = (ArrayList )fields.clone(); 36 return newExpr; 37 } 38 39 public void addElementStep(String namespaceURI, String localName, boolean isAnyLevel, boolean isSelf) { 40 XPathExpr.Step last = removeSelfNodeStep(); 41 if (last != null) isAnyLevel = isAnyLevel || last.isAnyLevel(); 42 fields.add(new XPathExpr.Step(namespaceURI, localName, isAnyLevel, isSelf, false)); 43 } 44 45 public void addAttributeStep(String namespaceURI, String localName, boolean isAnyLevel) { 46 XPathExpr.Step last = removeSelfNodeStep(); 47 if (last != null) isAnyLevel = isAnyLevel || last.isAnyLevel(); 48 fields.add(new XPathExpr.Step(namespaceURI, localName, isAnyLevel, false, true)); 49 } 50 51 public void addTextStep(boolean isAnyLevel, boolean isSelf) { 52 XPathExpr.Step last = removeSelfNodeStep(); 53 if (last != null) isAnyLevel = isAnyLevel || last.isAnyLevel(); 54 fields.add(new XPathExpr.Step(isAnyLevel, isSelf, true)); 55 } 56 57 public void addNodeStep(boolean isAnyLevel, boolean isSelf) { 58 XPathExpr.Step last = removeSelfNodeStep(); 59 if (last != null) isAnyLevel = isAnyLevel || last.isAnyLevel(); 60 fields.add(new XPathExpr.Step(isAnyLevel, isSelf, false)); 61 } 62 63 public int getStepCount() { 64 return fields.size(); 65 } 66 67 public boolean matchElement(String uri, String localName, int index) { 68 if (index >= fields.size()) 69 return false; 70 XPathExpr.Step step = (XPathExpr.Step) fields.get(index); 71 return step.isElement() && step.matches(uri, localName); 72 } 73 74 public boolean matchAttribute(String uri, String localName, int index) { 75 if (index != fields.size() - 1) 76 return false; 77 XPathExpr.Step step = (XPathExpr.Step) fields.get(index); 78 return step.isAttribute() && step.matches(uri, localName); 79 } 80 81 public boolean matchText(int index) { 82 if (index != fields.size() - 1) 83 return false; 84 XPathExpr.Step step = (XPathExpr.Step) fields.get(index); 85 return step.isText(); 86 } 87 88 public boolean isAnyLevel(int index) { 89 if (index >= fields.size()) 90 return false; 91 XPathExpr.Step step = (XPathExpr.Step) fields.get(index); 92 return step.isAnyLevel(); 93 } 94 95 public boolean isSelf(int index) { 96 if (index >= fields.size()) 97 return false; 98 XPathExpr.Step step = (XPathExpr.Step) fields.get(index); 99 return step.isSelf(); 100 } 101 102 public boolean isSelfElement(int index) { 103 if (index >= fields.size()) 104 return false; 105 XPathExpr.Step step = (XPathExpr.Step) fields.get(index); 106 return step.isSelfElement(); 107 } 108 109 public boolean isSelfNode(int index) { 110 if (index >= fields.size()) 111 return false; 112 XPathExpr.Step step = (XPathExpr.Step) fields.get(index); 113 return step.isSelfNode(); 114 } 115 116 public void removeLastSelfNodeStep() { 117 int lastIndex = fields.size()-1; 118 if (lastIndex >= 0) { 119 XPathExpr.Step last = (XPathExpr.Step) fields.get(lastIndex); 120 if (last.isSelfNode() && !last.isAnyLevel()) 121 fields.remove(lastIndex); 122 } 123 } 124 125 private XPathExpr.Step removeSelfNodeStep() { 126 int lastIndex = fields.size()-1; 127 if (lastIndex < 0) return null; 128 XPathExpr.Step last = (XPathExpr.Step) fields.get(lastIndex); 129 if (last.isSelfNode()) { 130 fields.remove(lastIndex); 131 return last; 132 } else { 133 return null; 134 } 135 } 136 137 static class Step { 138 private static final String RCSRevision = "$Revision: 1.1 $"; 139 private static final String RCSName = "$Name: $"; 140 private static final int ELEMENT = 0; 141 private static final int ATTR = 1; 142 private static final int TEXT = 2; 143 private static final int NODE = 3; 144 145 int nodeKind; 146 String namespaceURI; 147 String localName; 148 boolean isAny = false; 149 boolean anyNamespace = false; 150 boolean anyLevel = false; 151 boolean isSelf = false; 152 153 Step(String namespaceURI, String localName, boolean isAnyLevel, boolean isSelf, boolean isAttribute) { 154 this.namespaceURI = namespaceURI; 155 this.localName = localName; 156 this.anyLevel = isAnyLevel; 157 this.isSelf = isSelf; 158 this.nodeKind = isAttribute ? ATTR : ELEMENT; 159 if ("*".equals(namespaceURI)) { 160 anyNamespace = true; 161 } 162 if ("*".equals(localName)) { 163 this.localName = null; 164 if (namespaceURI == null || anyNamespace) 165 isAny = true; 166 } 167 } 168 169 Step(boolean isAnyLevel, boolean isSelf, boolean isText) { 170 this.anyLevel = isAnyLevel; 171 this.isSelf = isSelf; 172 this.nodeKind = isText ? TEXT : NODE; 173 this.isAny = !isText; 174 } 175 176 boolean isAttribute() { 177 return nodeKind == ATTR; 178 } 179 180 boolean isElement() { 181 return nodeKind == ELEMENT || nodeKind == NODE; 182 } 183 184 boolean isText() { 185 return nodeKind == TEXT || nodeKind == NODE; 186 } 187 188 boolean matches(String ns, String name) { 189 if (isAny) { 190 return true; 191 } else if (localName == null) { 192 return namespaceURI.equals(ns); 193 } else { 194 return localName.equals(name) 195 && (anyNamespace 196 || (namespaceURI == null && ns == null) 197 || (namespaceURI != null && namespaceURI.equals(ns))); 198 } 199 } 200 201 boolean isAnyLevel() { 202 return anyLevel; 203 } 204 205 boolean isSelf() { 206 return isSelf; 207 } 208 209 boolean isSelfNode() { 210 return isSelf && nodeKind == NODE; 211 } 212 213 boolean isSelfElement() { 214 return isSelf && nodeKind == ELEMENT; 215 } 216 } 217 } 218 | Popular Tags |