1 package net.sf.saxon.xom; 2 3 import net.sf.saxon.Configuration; 4 import net.sf.saxon.event.PipelineConfiguration; 5 import net.sf.saxon.event.Receiver; 6 import net.sf.saxon.expr.XPathContext; 7 import net.sf.saxon.om.*; 8 import net.sf.saxon.trans.DynamicError; 9 import net.sf.saxon.trans.XPathException; 10 import net.sf.saxon.value.Value; 11 import net.sf.saxon.value.SingletonNode; 12 import net.sf.saxon.value.SequenceExtent; 13 import nu.xom.Document; 14 import nu.xom.Node; 15 16 import javax.xml.transform.Result ; 17 import javax.xml.transform.Source ; 18 import java.util.ArrayList ; 19 import java.util.HashSet ; 20 import java.util.List ; 21 import java.util.WeakHashMap ; 22 import java.lang.reflect.Array ; 23 import java.io.Serializable ; 24 25 26 27 32 33 public class XOMObjectModel implements ExternalObjectModel, Serializable { 34 35 private transient WeakHashMap documentMap = new WeakHashMap (20); 36 37 public XOMObjectModel() {} 38 39 42 43 public boolean isRecognizedNode(Object object) { 44 return (object instanceof nu.xom.Node); 45 } 46 47 54 55 public boolean isRecognizedNodeClass(Class nodeClass) { 56 return nu.xom.Node.class.isAssignableFrom(nodeClass); 57 } 58 59 66 67 public boolean isRecognizedNodeListClass(Class nodeClass) { 68 return false; 69 } 70 71 76 77 public Receiver getDocumentBuilder(Result result) { 78 return null; } 80 81 86 87 public boolean sendSource(Source source, Receiver receiver, PipelineConfiguration pipe) throws XPathException { 88 return false; } 90 91 95 96 public NodeInfo unravel(Source source, Configuration config) { 97 return null; } 99 100 106 107 public Value convertObjectToXPathValue(Object object, Configuration config) throws XPathException { 108 if (object instanceof Node) { 109 return new SingletonNode(wrapNode((Node)object, config)); 110 } else if (object instanceof Node[]) { 111 NodeInfo[] nodes = new NodeInfo[((Node[])object).length]; 112 for (int i=0; i<nodes.length; i++) { 113 nodes[i] = wrapNode(((Node[])object)[i], config); 114 } 115 return new SequenceExtent(nodes); 116 } else { 117 return null; 118 } 119 } 120 121 private synchronized NodeInfo wrapNode(Node node, Configuration config) { 122 if (documentMap == null) { 123 documentMap = new WeakHashMap (20); 125 } 126 Document root = node.getDocument(); 127 VirtualNode wrapper = (VirtualNode)documentMap.get(root); 128 if (wrapper == null) { 129 wrapper = new DocumentWrapper(root, "", config); 130 addToDocumentMap(root, (DocumentWrapper)wrapper); 131 } 132 return (((DocumentWrapper)wrapper).wrap(node)); 133 } 134 135 138 139 public synchronized void addToDocumentMap(Document doc, DocumentWrapper wrapper) { 140 if (documentMap == null) { 141 documentMap = new WeakHashMap (20); 143 } 144 documentMap.put(doc, wrapper); 145 } 146 147 154 155 public Object convertXPathValueToObject(Value value, Class targetClass, XPathContext context) 156 throws XPathException { 157 boolean requireXOM = 161 (Node.class.isAssignableFrom(targetClass) || 162 (targetClass.isArray() && Node.class.isAssignableFrom(targetClass.getComponentType()))); 163 164 167 boolean allowXOM = 168 (targetClass == Object .class || targetClass.isAssignableFrom(ArrayList .class) || 169 targetClass.isAssignableFrom(HashSet .class) || 170 (targetClass.isArray() && targetClass.getComponentType() == Object .class)); 171 if (!(requireXOM || allowXOM)) { 172 return null; 173 } 174 List nodes = new ArrayList (20); 175 176 SequenceIterator iter = value.iterate(context); 177 while (true) { 178 Item item = iter.next(); 179 if (item == null) { 180 break; 181 } 182 if (item instanceof VirtualNode) { 183 Object o = ((VirtualNode)item).getUnderlyingNode(); 184 if (o instanceof Node) { 185 nodes.add(o); 186 } else { 187 if (requireXOM) { 188 DynamicError err = new DynamicError("Extension function required class " + targetClass.getName() + 189 "; supplied value of class " + item.getClass().getName() + 190 " could not be converted"); 191 throw err; 192 }; 193 } 194 } else if (requireXOM) { 195 DynamicError err = new DynamicError("Extension function required class " + targetClass.getName() + 196 "; supplied value of class " + item.getClass().getName() + 197 " could not be converted"); 198 throw err; 199 } else { 200 return null; } 202 } 203 204 if (nodes.size() == 0 && !requireXOM) { 205 return null; } 207 if (Node.class.isAssignableFrom(targetClass)) { 208 if (nodes.size() != 1) { 209 DynamicError err = new DynamicError("Extension function requires a single XOM Node" + 210 "; supplied value contains " + nodes.size() + " nodes"); 211 throw err; 212 } 213 return nodes.get(0); 214 } else if (targetClass.isArray() && Node.class.isAssignableFrom(targetClass.getComponentType())) { 215 Node[] array = (Node[])Array.newInstance(targetClass.getComponentType(), nodes.size()); 216 nodes.toArray(array); 217 return array; 218 } else if (targetClass.isAssignableFrom(ArrayList .class)) { 219 return nodes; 220 } else if (targetClass.isAssignableFrom(HashSet .class)) { 221 return new HashSet (nodes); 222 } else { 223 return null; 225 } 226 } 227 228 236 237 public DocumentInfo wrapDocument(Object node, String baseURI, Configuration config) { 238 Document documentNode = ((Node)node).getDocument(); 239 return new DocumentWrapper(documentNode, baseURI, config); 240 } 241 242 250 251 public NodeInfo wrapNode(DocumentInfo document, Object node) { 252 if (!(node instanceof Node)) { 253 throw new IllegalArgumentException ("Object to be wrapped is not a XOM Node: " + node.getClass()); 254 } 255 return ((DocumentWrapper)document).wrap((Node)node); 256 } 257 258 265 266 public Object convertToNodeList(SequenceExtent extent) { 267 return null; 268 } 269 270 } 271 272 273 | Popular Tags |