OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [xml/] [xpath/] [Selector.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* Selector.java --
2
   Copyright (C) 2004 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.xml.xpath;
39
 
40
import java.util.ArrayList;
41
import java.util.Collection;
42
import java.util.Iterator;
43
import java.util.LinkedHashSet;
44
import java.util.List;
45
import java.util.Set;
46
import javax.xml.XMLConstants;
47
import javax.xml.namespace.QName;
48
import org.w3c.dom.Attr;
49
import org.w3c.dom.NamedNodeMap;
50
import org.w3c.dom.Node;
51
 
52
/**
53
 * A single component of a location path.
54
 *
55
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
56
 */
57
public final class Selector
58
  extends Path
59
{
60
 
61
  public static final int ANCESTOR = 0;
62
  public static final int ANCESTOR_OR_SELF = 1;
63
  public static final int ATTRIBUTE = 2;
64
  public static final int CHILD = 3;
65
  public static final int DESCENDANT = 4;
66
  public static final int DESCENDANT_OR_SELF = 5;
67
  public static final int FOLLOWING = 6;
68
  public static final int FOLLOWING_SIBLING = 7;
69
  public static final int NAMESPACE = 8;
70
  public static final int PARENT = 9;
71
  public static final int PRECEDING = 10;
72
  public static final int PRECEDING_SIBLING = 11;
73
  public static final int SELF = 12;
74
 
75
  /**
76
   * Axis to select nodes in.
77
   */
78
  final int axis;
79
 
80
  /**
81
   * List of tests to perform on candidates.
82
   */
83
  final Test[] tests;
84
 
85
  public Selector(int axis, List tests)
86
  {
87
    this.axis = axis;
88
    this.tests = new Test[tests.size()];
89
    tests.toArray(this.tests);
90
    if (axis == NAMESPACE &&
91
        this.tests.length > 0 &&
92
        this.tests[0] instanceof NameTest)
93
      {
94
        NameTest nt = (NameTest) this.tests[0];
95
        this.tests[0] = new NamespaceTest(nt.qName, nt.anyLocalName, nt.any);
96
      }
97
  }
98
 
99
  /**
100
   * Returns the list of tests to perform on candidates.
101
   */
102
  public Test[] getTests()
103
  {
104
    return tests;
105
  }
106
 
107
  public boolean matches(Node context)
108
  {
109
    short nodeType = context.getNodeType();
110
    switch (axis)
111
      {
112
      case CHILD:
113
        if (nodeType == Node.ATTRIBUTE_NODE)
114
          {
115
            return false;
116
          }
117
        break;
118
      case ATTRIBUTE:
119
      case NAMESPACE:
120
        if (nodeType != Node.ATTRIBUTE_NODE)
121
          {
122
            return false;
123
          }
124
        break;
125
      case DESCENDANT_OR_SELF:
126
        return true;
127
      default:
128
        return false;
129
      }
130
    int tlen = tests.length;
131
    if (tlen > 0)
132
      {
133
        int pos = getContextPosition(context);
134
        int len = getContextSize(context);
135
        for (int j = 0; j < tlen && len > 0; j++)
136
          {
137
            Test test = tests[j];
138
            if (!test.matches(context, pos, len))
139
              {
140
                return false;
141
              }
142
          }
143
      }
144
    return true;
145
  }
146
 
147
  private int getContextPosition(Node ctx)
148
  {
149
    int pos = 1;
150
    for (ctx = ctx.getPreviousSibling(); ctx != null;
151
         ctx = ctx.getPreviousSibling())
152
      {
153
        pos++;
154
      }
155
    return pos;
156
  }
157
 
158
  private int getContextSize(Node ctx)
159
  {
160
    if (ctx.getNodeType() == Node.ATTRIBUTE_NODE)
161
      {
162
        Node parent = ((Attr) ctx).getOwnerElement();
163
        return parent.getAttributes().getLength();
164
      }
165
    Node parent = ctx.getParentNode();
166
    if (parent != null)
167
      {
168
        return parent.getChildNodes().getLength();
169
      }
170
    return 1;
171
  }
172
 
173
  public Object evaluate(Node context, int pos, int len)
174
  {
175
    Set acc = new LinkedHashSet();
176
    addCandidates(context, acc);
177
    List candidates = new ArrayList(acc);
178
    //Collections.sort(candidates, documentOrderComparator);
179
    List ret = filterCandidates(candidates, false);
180
    return ret;
181
  }
182
 
183
  Collection evaluate(Node context, Collection ns)
184
  {
185
    Set acc = new LinkedHashSet();
186
    for (Iterator i = ns.iterator(); i.hasNext(); )
187
      {
188
        addCandidates((Node) i.next(), acc);
189
      }
190
    List candidates = new ArrayList(acc);
191
    //Collections.sort(candidates, documentOrderComparator);
192
    List ret = filterCandidates(candidates, true);
193
    return ret;
194
  }
195
 
196
  /**
197
   * Filter the given list of candidates according to the node tests.
198
   */
199
  List filterCandidates(List candidates, boolean cascade)
200
  {
201
    int len = candidates.size();
202
    int tlen = tests.length;
203
    if (tlen > 0 && len > 0)
204
      {
205
        // Present the result of each successful generation to the next test
206
        for (int j = 0; j < tlen && len > 0; j++)
207
          {
208
            Test test = tests[j];
209
            List successful = new ArrayList(len);
210
            for (int i = 0; i < len; i++)
211
              {
212
                Node node = (Node) candidates.get(i);
213
                if (cascade)
214
                  {
215
                    // Documents and DocumentFragments should be considered
216
                    // if part of a location path where the axis involves
217
                    // the SELF concept
218
                    short nodeType = node.getNodeType();
219
                    if ((nodeType == Node.DOCUMENT_NODE ||
220
                         nodeType == Node.DOCUMENT_FRAGMENT_NODE) &&
221
                        (axis == DESCENDANT_OR_SELF ||
222
                         axis == ANCESTOR_OR_SELF ||
223
                         axis == SELF) &&
224
                        (tests.length == 1 &&
225
                         tests[0] instanceof NodeTypeTest &&
226
                         ((NodeTypeTest) tests[0]).type == (short) 0))
227
                      {
228
                        successful.add(node);
229
                        continue;
230
                      }
231
                  }
232
                if (test.matches(node, i + 1, len))
233
                  {
234
                    successful.add(node);
235
                  }
236
                /*
237
                   System.err.println("Testing "+node);
238
                   int p = getContextPosition(node);
239
                   int l = getContextSize(node);
240
                   if (test.matches(node, p, l))
241
                   {
242
                   successful.add(node);
243
                   }*/
244
              }
245
            candidates = successful;
246
            len = candidates.size();
247
          }
248
      }
249
    return candidates;
250
  }
251
 
252
  void addCandidates(Node context, Collection candidates)
253
  {
254
    // Build list of candidates
255
    switch (axis)
256
      {
257
      case CHILD:
258
        addChildNodes(context, candidates, false);
259
        break;
260
      case DESCENDANT:
261
        addChildNodes(context, candidates, true);
262
        break;
263
      case DESCENDANT_OR_SELF:
264
        candidates.add (context);
265
        addChildNodes(context, candidates, true);
266
        break;
267
      case PARENT:
268
        addParentNode(context, candidates, false);
269
        break;
270
      case ANCESTOR:
271
        addParentNode(context, candidates, true);
272
        break;
273
      case ANCESTOR_OR_SELF:
274
        candidates.add(context);
275
        addParentNode(context, candidates, true);
276
        break;
277
      case FOLLOWING_SIBLING:
278
        addFollowingNodes(context, candidates, false);
279
        break;
280
      case PRECEDING_SIBLING:
281
        addPrecedingNodes(context, candidates, false);
282
        break;
283
      case FOLLOWING:
284
        addFollowingNodes(context, candidates, true);
285
        break;
286
      case PRECEDING:
287
        addPrecedingNodes(context, candidates, true);
288
        break;
289
      case ATTRIBUTE:
290
        addAttributes(context, candidates);
291
        break;
292
      case NAMESPACE:
293
        addNamespaceAttributes(context, candidates);
294
        break;
295
      case SELF:
296
        candidates.add(context);
297
        break;
298
      }
299
  }
300
 
301
  void addChildNodes(Node context, Collection acc, boolean recurse)
302
  {
303
    Node child = context.getFirstChild();
304
    while (child != null)
305
      {
306
        acc.add(child);
307
        if (recurse)
308
          {
309
            addChildNodes(child, acc, recurse);
310
          }
311
        child = child.getNextSibling();
312
      }
313
  }
314
 
315
  void addParentNode(Node context, Collection acc, boolean recurse)
316
  {
317
    Node parent = (context.getNodeType() == Node.ATTRIBUTE_NODE) ?
318
      ((Attr) context).getOwnerElement() : context.getParentNode();
319
    if (parent != null)
320
      {
321
        acc.add(parent);
322
        if (recurse)
323
          {
324
            addParentNode(parent, acc, recurse);
325
          }
326
      }
327
  }
328
 
329
  void addFollowingNodes(Node context, Collection acc, boolean recurse)
330
  {
331
    Node cur = context.getNextSibling();
332
    while (cur != null)
333
      {
334
        acc.add(cur);
335
        if (recurse)
336
          {
337
            addChildNodes(cur, acc, true);
338
          }
339
        cur = cur.getNextSibling();
340
      }
341
    if (recurse)
342
      {
343
        context = (context.getNodeType() == Node.ATTRIBUTE_NODE) ?
344
          ((Attr) context).getOwnerElement() : context.getParentNode();
345
        if (context != null)
346
          {
347
            addFollowingNodes(context, acc, recurse);
348
          }
349
      }
350
  }
351
 
352
  void addPrecedingNodes(Node context, Collection acc, boolean recurse)
353
  {
354
    Node cur = context.getPreviousSibling();
355
    while (cur != null)
356
      {
357
        acc.add(cur);
358
        if (recurse)
359
          {
360
            addChildNodes(cur, acc, true);
361
          }
362
        cur = cur.getPreviousSibling();
363
      }
364
    if (recurse)
365
      {
366
        context = (context.getNodeType() == Node.ATTRIBUTE_NODE) ?
367
          ((Attr) context).getOwnerElement() : context.getParentNode();
368
        if (context != null)
369
          {
370
            addPrecedingNodes(context, acc, recurse);
371
          }
372
      }
373
  }
374
 
375
  void addAttributes(Node context, Collection acc)
376
  {
377
    NamedNodeMap attrs = context.getAttributes();
378
    if (attrs != null)
379
      {
380
        int attrLen = attrs.getLength();
381
        for (int i = 0; i < attrLen; i++)
382
          {
383
            Node attr = attrs.item(i);
384
            if (!isNamespaceAttribute(attr))
385
              {
386
                acc.add(attr);
387
              }
388
          }
389
      }
390
  }
391
 
392
  void addNamespaceAttributes(Node context, Collection acc)
393
  {
394
    NamedNodeMap attrs = context.getAttributes();
395
    if (attrs != null)
396
      {
397
        int attrLen = attrs.getLength();
398
        for (int i = 0; i < attrLen; i++)
399
          {
400
            Node attr = attrs.item(i);
401
            if (isNamespaceAttribute(attr))
402
              {
403
                acc.add(attr);
404
              }
405
          }
406
      }
407
  }
408
 
409
  final boolean isNamespaceAttribute(Node node)
410
  {
411
    String uri = node.getNamespaceURI();
412
    return (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri) ||
413
            XMLConstants.XMLNS_ATTRIBUTE.equals(node.getPrefix()) ||
414
            XMLConstants.XMLNS_ATTRIBUTE.equals(node.getNodeName()));
415
  }
416
 
417
  public Expr clone(Object context)
418
  {
419
    int len = tests.length;
420
    List tests2 = new ArrayList(len);
421
    for (int i = 0; i < len; i++)
422
      {
423
        tests2.add(tests[i].clone(context));
424
      }
425
    return new Selector(axis, tests2);
426
  }
427
 
428
  public boolean references(QName var)
429
  {
430
    for (int i = 0; i < tests.length; i++)
431
      {
432
        if (tests[i].references(var))
433
          {
434
            return true;
435
          }
436
      }
437
    return false;
438
  }
439
 
440
  public String toString()
441
  {
442
    StringBuffer buf = new StringBuffer();
443
    switch (axis)
444
      {
445
      case ANCESTOR:
446
        buf.append("ancestor::");
447
        break;
448
      case ANCESTOR_OR_SELF:
449
        buf.append("ancestor-or-self::");
450
        break;
451
      case ATTRIBUTE:
452
        if (tests.length == 0 ||
453
            (tests[0] instanceof NameTest))
454
          {
455
            buf.append('@');
456
          }
457
        else
458
          {
459
            buf.append("attribute::");
460
          }
461
        break;
462
      case CHILD:
463
        //buf.append("child::");
464
        break;
465
      case DESCENDANT:
466
        buf.append("descendant::");
467
        break;
468
      case DESCENDANT_OR_SELF:
469
        buf.append("descendant-or-self::");
470
        break;
471
      case FOLLOWING:
472
        buf.append("following::");
473
        break;
474
      case FOLLOWING_SIBLING:
475
        buf.append("following-sibling::");
476
        break;
477
      case NAMESPACE:
478
        buf.append("namespace::");
479
        break;
480
      case PARENT:
481
        if (tests.length == 0 ||
482
            (tests[0] instanceof NodeTypeTest &&
483
             ((NodeTypeTest) tests[0]).type == 0))
484
          {
485
            return "..";
486
          }
487
        buf.append("parent::");
488
        break;
489
      case PRECEDING:
490
        buf.append("preceding::");
491
        break;
492
      case PRECEDING_SIBLING:
493
        buf.append("preceding-sibling::");
494
        break;
495
      case SELF:
496
        if (tests.length == 0 ||
497
            (tests[0] instanceof NodeTypeTest &&
498
             ((NodeTypeTest) tests[0]).type == 0))
499
          {
500
            return ".";
501
          }
502
        buf.append("self::");
503
        break;
504
      }
505
    if (tests.length == 0)
506
      {
507
        buf.append('*');
508
      }
509
    else
510
      {
511
        for (int i = 0; i < tests.length; i++)
512
          {
513
            buf.append(tests[i]);
514
          }
515
      }
516
    return buf.toString();
517
  }
518
 
519
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.