list = new ArrayList(100);
} else {
try {
list = (Collection)target.newInstance();
} catch (Exception e) {
DynamicError de = new DynamicError("Cannot instantiate collection class " + target);
de.setXPathContext(context);
throw de;
}
}
SequenceIterator iter = iterate(null);
while (true) {
Item it = iter.next();
if (it == null) {
return list;
}
list.add(it);
}
} else if (target.isArray()) {
Class component = target.getComponentType();
if (component.isAssignableFrom(Item.class) ||
component.isAssignableFrom(NodeInfo.class) ||
component.isAssignableFrom(DocumentInfo.class) ||
component.isAssignableFrom(Node.class)) {
SequenceExtent extent = materialize();
int length = extent.getLength();
Object array = Array.newInstance(component, length);
for (int i=0; i<length; i++) {
try {
Array.set(array, i, extent.itemAt(i));
} catch (Exception err) {
DynamicError d = new DynamicError(
"Cannot convert item in sequence to the component type of the Java array", err);
d.setXPathContext(context);
throw d;
}
}
return array;
} else {
// try atomizing the sequence
SequenceIterator it = new Atomizer(this).iterate(context);
int length;
if (it instanceof LastPositionFinder) {
length = ((LastPositionFinder)it).getLastPosition();
} else {
SequenceExtent extent = new SequenceExtent(it);
length = extent.getLength();
it = extent.iterate(context);
}
Object array = Array.newInstance(component, length);
for (int i=0; i<length; i++) {
try {
AtomicValue val = (AtomicValue)it.next();
Object jval = val.convertToJava(component, config, context);
Array.set(array, i, jval);
} catch (Exception err) {
DynamicError d = new DynamicError(
"Cannot convert item in atomized sequence to the component type of the Java array", err);
d.setXPathContext(context);
throw d;
}
}
return array;
}
} else if (target.isAssignableFrom(NodeList.class)) {
return DOMNodeList.checkAndMake(materialize());
} else if (target.isAssignableFrom(Item.class) ||
target.isAssignableFrom(NodeInfo.class) ||
target.isAssignableFrom(DocumentInfo.class) ||
target.isAssignableFrom(Node.class)) {
// try passing the first item in the sequence
SequenceIterator iter = iterate(null);
Item first = null;
while (true) {
Item next = iter.next();
if (next == null) {
break;
}
if (first != null) {
DynamicError err = new DynamicError("Sequence contains more than one value; Java method expects only one");
err.setXPathContext(context);
throw err;
}
first = next;
}
if (first == null) {
// sequence is empty; pass a Java null
return null;
}
if (target.isAssignableFrom(first.getClass())) {
// covers Item, NodeInfo and DOM Node
return first;
}
Object n = first;
while (n instanceof VirtualNode) {
// If we've got a wrapper around a DOM or JDOM node, and the user wants a DOM
// or JDOM node, we unwrap it
Object vn = ((VirtualNode) n).getUnderlyingNode();
if (target.isAssignableFrom(vn.getClass())) {
return vn;
} else {
n = vn;
}
}
throw new DynamicError("Cannot convert supplied XPath value to the required type for the extension function");
} else {
// try atomizing the value
SequenceIterator it = new Atomizer(this).iterate(context);
Item first = null;
while (true) {
Item next = it.next();
if (next == null) {
break;
}
if (first != null) {
DynamicError err = new DynamicError("Sequence contains more than one value; Java method expects only one");
err.setXPathContext(context);
throw err;
}
first = next;
}
if (first == null) {