View Javadoc

1   package org.softnetwork.xml.dom.xpath;
2   
3   import java.util.List;
4   import java.util.StringTokenizer;
5   import org.w3c.dom.Attr;
6   import org.w3c.dom.Element;
7   import org.w3c.dom.Node;
8   
9   /**
10   * @author stephane.manciot@ebiznext.com
11   *
12   */
13  class XPathToken implements XPath {
14      
15      private String  name;
16      
17      private String  value;
18      
19      private boolean equality;
20      
21      private boolean positionedElement;
22      
23      private boolean lastElement;
24      
25      private int     position = -1;
26      
27      private boolean inequality;
28      
29      private boolean attribute;
30      
31      private String  token;
32      
33      private boolean test;
34      
35      XPathToken(String token) throws XPathFormatException {
36          this.token = token;
37          int equalityPos = -1;
38          test = (equalityPos = token.indexOf(XPATH_EQUALITY)) > 0;
39          if (test) {
40              inequality = (token.charAt(equalityPos - 1) == '!');
41              equality = !inequality;
42              String left = null;
43              String right = token.substring(equalityPos + 1);
44              if (inequality)
45                  left = token.substring(0, equalityPos - 1);
46              else
47                  left = token.substring(0, equalityPos);
48              name = left;
49              value = new StringTokenizer(right, "'").nextToken();
50              positionedElement = name.equals(XPATH_POS_FUNCTION);
51          } else {
52              name = token;
53              try {
54                  position = Integer.parseInt(name);
55                  positionedElement = true;
56              } catch (NumberFormatException e) {
57              }
58          }
59          lastElement = name.equals(XPATH_LAST_POS_FUNCTION);
60          attribute = name.startsWith(XPATH_ATTRIBUTE);
61          if (attribute)
62              name = name.substring(1);
63      }
64      
65      public String toString() {
66          String str = ((test) ? ((isAttribute()) ? "Attribute " : "")
67          + getName() + " must be "
68                  + ((isInequality()) ? "different" : "equal") + " to "
69                  + getValue() : getToken());
70          return str;
71      }
72      
73      /**
74       * @return Renvoie token.
75       */
76      public String getToken() {
77          return token;
78      }
79      
80      /**
81       * @return Returns the attribute.
82       */
83      public boolean isAttribute() {
84          return attribute;
85      }
86      
87      /**
88       * @return Returns the inequality.
89       */
90      public boolean isInequality() {
91          return inequality;
92      }
93      
94      /**
95       * @return Returns the name.
96       */
97      public String getName() {
98          return name;
99      }
100     
101     /**
102      * @return Returns the value.
103      */
104     public String getValue() {
105         return value;
106     }
107     
108     /**
109      * @return Returns the positionedElement.
110      */
111     public boolean isPositionedElement() {
112         return positionedElement;
113     }
114     
115     /**
116      * @return Returns the position.
117      */
118     public int getPosition() {
119         return position;
120     }
121     
122     /**
123      * @return Returns the lastElement.
124      */
125     public boolean isLastElement() {
126         return lastElement;
127     }
128     
129     /**
130      * @return Returns the equality.
131      */
132     public boolean isEquality() {
133         return equality;
134     }
135     
136     public Element[] selectElements(Element current)
137     throws XPathFormatException {
138         if (isEquality() || isInequality()) {
139             if (isPositionedElement()) {
140                 try {
141                     int value = Integer.parseInt(getValue());
142                     if (XPathTools.getElementPosition(current) == value)
143                         return (isEquality()) ? new Element[] { current }
144                         : EMPTY;
145                     else
146                         return (isInequality()) ? new Element[] { current }
147                         : EMPTY;
148                 } catch (NumberFormatException n) {
149                     throw new XPathFormatException(getToken(), n.getMessage());
150                 }
151             } else if (isAttribute()) {
152                 if (getValue().equals(current.getAttribute(name)))
153                     return (isEquality()) ? new Element[] { current } : EMPTY;
154                 else
155                     return (isInequality()) ? new Element[] { current } : EMPTY;
156             } else if (name.equals(XPATH_TEXT_FUNCTION))
157                 if (current.getNodeValue().equals(getValue()))
158                     return (isEquality()) ? new Element[] { current } : EMPTY;
159                 else
160                     return (isInequality()) ? new Element[] { current } : EMPTY;
161         } else if (isLastElement()) {
162             ;
163         } else if (isAttribute()) {
164             return (current.getAttribute(getName()) != null) ? new Element[] { current }
165             : EMPTY;
166         } else if (isPositionedElement()) {
167             try {
168                 if (XPathTools.getElementPosition(current) == getPosition())
169                     return new Element[] { current };
170                 else
171                     return EMPTY;
172             } catch (NumberFormatException n) {
173                 throw new XPathFormatException(getToken(), n.getMessage());
174             }
175         } else {
176             List list = XPathTools.getNamedElements(current, name);
177             if (list != null)
178                 return (Element[])list.toArray(new Element[0]);
179         }
180         return EMPTY;
181     }
182     
183     public Node[] selectNodes(Node current) throws XPathFormatException {
184         if (isEquality() || isInequality()) {
185             if (isPositionedElement()) {
186                 if (current instanceof Element)
187                     try {
188                         int value = Integer.parseInt(getValue());
189                         if (XPathTools.getElementPosition((Element) current) == value)
190                             return (isEquality()) ? new Node[] { current }
191                             : EMPTY_NODES;
192                         else
193                             return (isInequality()) ? new Node[] { current }
194                             : EMPTY_NODES;
195                     } catch (NumberFormatException n) {
196                         throw new XPathFormatException(getToken(), n
197                                 .getMessage());
198                     }
199                 return EMPTY_NODES;
200             } else if (isAttribute()) {
201                 if (current instanceof Element)// && isFilter()
202                     if (getValue().equals(
203                         ((Element) current).getAttribute(name)))
204                         return (isEquality()) ? new Node[] { current }
205                         : EMPTY_NODES;
206                     else
207                         return (isInequality()) ? new Node[] { current }
208                         : EMPTY_NODES;
209                 // else
210                 // throw new XPathFormatException(getToken(), "");
211             } else if (name.equals(XPATH_TEXT_FUNCTION))
212                 if (current.getNodeValue().equals(getValue()))
213                     return (isEquality()) ? new Node[] { current }
214                     : EMPTY_NODES;
215                 else
216                     return (isInequality()) ? new Node[] { current }
217                     : EMPTY_NODES;
218         } else if (isLastElement()) {
219             ;
220         } else if (isAttribute()) {
221             if (isFilter())
222                 if (current instanceof Element)
223                     return (((Element) current).getAttribute(getName()) != null) ? new Node[] { current }
224                     : EMPTY_NODES;
225                 else
226                     return EMPTY_NODES;
227             else if (current instanceof Element) {
228                 Attr a = ((Element) current).getAttributeNode(getName());
229                 return (a != null) ? new Node[] { a } : EMPTY_NODES;
230             } else if (current instanceof Attr)
231                 return (current.getNodeName().equals(getName())) ? new Node[] { current }
232                 : EMPTY_NODES;
233             return EMPTY_NODES;
234         } else if (isPositionedElement()) {
235             try {
236                 if (current instanceof Element
237                         && XPathTools.getElementPosition((Element) current) == getPosition())
238                     return new Node[] { current };
239                 else
240                     return EMPTY_NODES;
241             } catch (NumberFormatException n) {
242                 throw new XPathFormatException(getToken(), n.getMessage());
243             }
244         } else if (current instanceof Element) {
245             List list = XPathTools.getNamedElements((Element)current, name);
246             if (list != null)
247                 return (Element[])list.toArray(new Element[0]);
248         }
249         return EMPTY_NODES;
250     }
251     
252     protected boolean isFilter() {
253         return false;
254     }
255     
256 }