01: // Copyright (c) 2003 Per M.A. Bothner.
02: // This is free software; for terms and warranty disclaimer see ./COPYING.
03:
04: package gnu.kawa.xml;
05:
06: import gnu.bytecode.Type;
07: import gnu.lists.*;
08: import gnu.mapping.*;
09: import gnu.expr.*;
10: import java.io.*;
11:
12: /** Abstract class that scans part of a node tree.
13: * Takes a node argument, and writes matching "relative" nodes
14: * out to a PositionConsumer as a sequence of position pairs.
15: * This is uses to implement "path expressions" as in XPath/XSLT/XQuery.
16: * For example, the ChildAxis sub-class writes out all child nodes
17: * of the argument that match the 'type' NodePredicate.
18: */
19:
20: public abstract class TreeScanner extends MethodProc implements
21: Externalizable, CanInline {
22: public NodePredicate type;
23:
24: public NodePredicate getNodePredicate() {
25: return type;
26: }
27:
28: public abstract void scan(AbstractSequence seq, int ipos,
29: PositionConsumer out);
30:
31: public int numArgs() {
32: return 0x1001;
33: }
34:
35: public void apply(CallContext ctx) throws Throwable {
36: PositionConsumer out = (PositionConsumer) ctx.consumer;
37: Object node = ctx.getNextArg();
38: ctx.lastArg();
39: KNode spos;
40: try {
41: spos = (KNode) node;
42: } catch (ClassCastException ex) {
43: throw new WrongType(getDesc(), WrongType.ARG_CAST, node,
44: "node()");
45: }
46: scan(spos.sequence, spos.getPos(), out);
47: }
48:
49: public void writeExternal(ObjectOutput out) throws IOException {
50: out.writeObject(type);
51: }
52:
53: public void readExternal(ObjectInput in) throws IOException,
54: ClassNotFoundException {
55: type = (NodePredicate) in.readObject();
56: }
57:
58: public String getDesc() {
59: String this Name = getClass().getName();
60: int dot = this Name.lastIndexOf('.');
61: if (dot > 0)
62: this Name = this Name.substring(dot + 1);
63: return this Name + "::" + type;
64: }
65:
66: public String toString() {
67: return "#<" + getClass().getName() + ' ' + type + '>';
68: }
69:
70: public Expression inline(ApplyExp exp, ExpWalker walker) {
71: if (exp.getTypeRaw() == null && type instanceof Type)
72: exp.setType(NodeSetType.getInstance((Type) type));
73: return exp;
74: }
75: }
|