1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
package com.jclark.xsl.expr;
import com.jclark.xsl.om.*;
import java.net.URL;
class DocumentFunction implements Function {
public ConvertibleExpr makeCallExpr(ConvertibleExpr args[], final Node exprNode)
throws ParseException {
if (args.length != 1 && args.length != 2)
throw new ParseException("expected one or two arguments");
ConvertibleExpr e = args[0];
final NodeSetExpr base = (args.length == 1
? null
: args[1].makeNodeSetExpr());
if (e instanceof NodeSetExpr) {
final NodeSetExpr nse = (NodeSetExpr)e;
return new ConvertibleNodeSetExpr() {
public NodeIterator eval(Node node, ExprContext context) throws XSLException {
return document(context,
nse.eval(node, context),
base == null
? null
: base.eval(node, context).next());
}
};
}
else if (e instanceof VariantExpr) {
final VariantExpr ve = (VariantExpr)e;
return new ConvertibleNodeSetExpr() {
public NodeIterator eval(Node node, ExprContext context) throws XSLException {
Variant v = ve.eval(node, context);
if (v.isNodeSet())
return document(context,
v.convertToNodeSet(),
base == null
? null
: base.eval(node, context).next());
else {
Node baseNode = v.getBaseNode();
if (baseNode == null)
baseNode = exprNode;
return document(context,
v.convertToString(),
base == null
? baseNode
: base.eval(node, context).next());
}
}
};
}
else {
final StringExpr se = e.makeStringExpr();
return new ConvertibleNodeSetExpr() {
public NodeIterator eval(Node node, ExprContext context)
throws XSLException {
return document(context,
se.eval(node, context),
base == null
? exprNode
: base.eval(node, context).next());
}
};
}
}
private static final NodeIterator document(ExprContext context, NodeIterator iter, Node baseNode) throws XSLException {
NodeIterator[] iters = new NodeIterator[1];
int len = 0;
for (;;) {
Node node = iter.next();
if (node == null)
break;
if (len == iters.length) {
NodeIterator[] oldIters = iters;
iters = new NodeIterator[iters.length*2];
System.arraycopy(oldIters, 0, iters, 0, oldIters.length);
}
iters[len++] = document(context,
Converter.toString(node),
baseNode == null ? node : baseNode);
}
if (len > 1)
return new MergeNodeIterator(iters, len);
if (len == 1)
return iters[0];
return new SingleNodeIterator(null);
}
private static final NodeIterator document(ExprContext context, String urlRef, Node baseNode) throws XSLException {
return context.getDocument(baseNode == null ? null : baseNode.getURL(),
urlRef);
}
}
|