1 package com.icl.saxon.expr; 2 import com.icl.saxon.*; 3 import com.icl.saxon.om.*; 4 import com.icl.saxon.tree.TreeBuilder; 5 import com.icl.saxon.tree.AttributeCollection; 6 import com.icl.saxon.output.*; 7 import java.util.Vector; 8 import java.util.Enumeration; 9 import org.xml.sax.Attributes; 10 import javax.xml.transform.TransformerException; 11 12 13 18 19 public final class FragmentValue extends SingletonNodeSet { 20 21 private char[] buffer = new char[4096]; 22 private int used = 0; 23 private Vector events = new Vector(20, 20); 24 private String baseURI = null; 25 private FragmentEmitter emitter = new FragmentEmitter(); 26 private Controller controller; 27 28 private static AttributeCollection emptyAttributeCollection = new AttributeCollection((NamePool)null); 29 30 private static Integer START_ELEMENT = new Integer(1); 31 private static Integer END_ELEMENT = new Integer(2); 32 private static Integer START_NAMESPACE = new Integer(3); 33 private static Integer END_NAMESPACE = new Integer(4); 34 private static Integer CHARACTERS = new Integer(5); 35 private static Integer PROCESSING_INSTRUCTION = new Integer(6); 36 private static Integer COMMENT = new Integer(7); 37 private static Integer ESCAPING_ON = new Integer(8); 38 private static Integer ESCAPING_OFF = new Integer(9); 39 40 public FragmentValue(Controller c) { 41 controller = c; 42 generalUseAllowed = false; 43 } 44 45 49 50 public void setBaseURI(String uri) { 51 baseURI = uri; 52 } 53 54 57 58 62 65 66 public Emitter getEmitter() { 67 return emitter; 68 } 69 70 73 74 public String asString() { 75 return new String(buffer, 0, used); 76 } 77 78 84 85 public void outputStringValue(Outputter out, Context context) throws TransformerException { 86 out.writeContent(buffer, 0, used); 87 } 88 89 92 93 public double asNumber() { 94 return Value.stringToNumber(asString()); 95 } 96 97 100 101 public boolean asBoolean() { 102 return true; 103 } 104 105 108 109 public int getCount() { 110 return 1; 111 } 112 113 116 117 public Expression simplify() { 118 return this; 120 } 121 122 126 127 public NodeInfo getFirst() { 128 return getRootNode(); 129 } 130 131 134 135 public NodeEnumeration enumerate() throws XPathException { 136 if (!generalUseAllowed) { 137 throw new XPathException("Cannot process a result tree fragment as a node-set under XSLT 1.0"); 138 } 139 return new SingletonEnumeration(getRootNode()); 140 } 141 142 145 146 public boolean equals(Value other) throws XPathException { 147 if (other instanceof StringValue) { return asString().equals(other.asString()); 149 } 150 return new StringValue(asString()).equals(other); 151 } 152 153 156 157 public boolean notEquals(Value other) throws XPathException { 158 return new StringValue(asString()).notEquals(other); 159 } 160 161 164 165 public boolean compare(int operator, Value other) throws XPathException { 166 return new StringValue(asString()).compare(operator, other); 167 } 168 169 173 174 public int getType() { 175 return Value.NODESET; 176 } 177 178 182 183 public int getDataType() { 184 return Value.NODESET; 185 } 186 187 190 191 public DocumentInfo getRootNode() { 192 if (node!=null) { return (DocumentInfo)node; 194 } 195 try { 196 Builder builder = new TreeBuilder(); 197 builder.setSystemId(baseURI); 198 builder.setNamePool(controller.getNamePool()); 199 builder.startDocument(); 200 replay(builder); 201 builder.endDocument(); 202 node = builder.getCurrentDocument(); 203 controller.getDocumentPool().add((DocumentInfo)node, null); 204 return (DocumentInfo)node; 205 } catch (TransformerException err) { 206 throw new InternalSaxonError("Error building temporary tree: " + err.getMessage()); 207 } 208 } 209 210 213 214 public void copy(Outputter out) throws TransformerException { 215 Emitter emitter = out.getEmitter(); 216 replay(emitter); 217 } 218 219 222 223 public void replay(Emitter emitter) throws TransformerException { 224 Enumeration enum = events.elements(); 225 226 while (enum.hasMoreElements()) { 227 Object e = enum.nextElement(); 228 Object e1; 229 Object e2; 230 Object e3; 231 if (e==START_ELEMENT) { 232 e1 = enum.nextElement(); 233 e2 = enum.nextElement(); 234 e3 = enum.nextElement(); 235 int[] namespaces = (int[])e3; 236 emitter.startElement(((Integer)e1).intValue(), 237 (AttributeCollection)e2, 238 namespaces, namespaces.length); 239 240 } else if (e==END_ELEMENT) { 241 e1 = enum.nextElement(); 242 emitter.endElement(((Integer)e1).intValue()); 243 244 } else if (e==CHARACTERS) { 245 e1 = enum.nextElement(); 246 emitter.characters(buffer, ((int[])e1)[0], ((int[])e1)[1]); 247 248 } else if (e==PROCESSING_INSTRUCTION) { 249 e1 = enum.nextElement(); 250 e2 = enum.nextElement(); 251 emitter.processingInstruction((String)e1, (String)e2); 252 253 } else if (e==COMMENT) { 254 e1 = enum.nextElement(); 255 emitter.comment(((String)e1).toCharArray(), 0, ((String)e1).length()); 256 257 } else if (e==ESCAPING_ON) { 258 emitter.setEscaping(true); 259 260 } else if (e==ESCAPING_OFF) { 261 emitter.setEscaping(false); 262 263 } else { 264 throw new InternalSaxonError("Corrupt data in temporary tree: " + e); 265 } 266 } 267 268 } 269 270 273 274 public void display(int level) { 275 System.err.println(indent(level) + "** result tree fragment **"); 276 } 277 278 282 private class FragmentEmitter extends Emitter { 283 284 boolean previousCharacters = false; 285 286 289 290 public void startDocument() { 291 previousCharacters = false; 292 } 293 294 297 298 public void endDocument() { 299 previousCharacters = false; 300 } 301 302 310 311 public void startElement(int name, Attributes attributes, 312 int[] namespaces, int nscount) { 313 events.addElement(START_ELEMENT); 314 events.addElement(new Integer(name)); 315 316 317 318 AttributeCollection atts; 320 int numAtts = attributes.getLength(); 321 if (numAtts==0) { 322 atts = emptyAttributeCollection; 323 } else { 324 atts = new AttributeCollection((AttributeCollection)attributes); 325 } 326 327 events.addElement(atts); 328 329 int[] ns = new int[nscount]; 331 System.arraycopy(namespaces, 0, ns, 0, nscount); 332 events.addElement(ns); 333 334 previousCharacters = false; 335 } 336 337 342 343 public void endElement(int name) { 344 events.addElement(END_ELEMENT); 345 events.addElement(new Integer(name)); 346 previousCharacters = false; 347 } 348 349 352 353 public void characters(char[] chars, int start, int len) { 354 while (used + len >= buffer.length) { 355 char[] newbuffer = new char[buffer.length * 2]; 356 System.arraycopy(buffer, 0, newbuffer, 0, used); 357 buffer = newbuffer; 358 } 359 System.arraycopy(chars, start, buffer, used, len); 360 if (previousCharacters) { 361 int[] v = (int[])events.elementAt(events.size()-1); 363 v[1] += len; 364 } else { 365 events.addElement(CHARACTERS); 366 int[] val = {used, len}; events.addElement(val); 368 } 369 used += len; 370 previousCharacters = true; 371 } 372 373 376 377 public void processingInstruction(String name, String data) { 378 events.addElement(PROCESSING_INSTRUCTION); 379 events.addElement(name); 380 events.addElement(data); 381 previousCharacters = false; 382 } 383 384 387 388 public void comment (char[] chars, int start, int length) { 389 events.addElement(COMMENT); 390 events.addElement(new String(chars, start, length)); 391 previousCharacters = false; 392 } 393 394 398 399 public void setEscaping(boolean escaping) throws TransformerException { 400 events.addElement((escaping ? ESCAPING_ON : ESCAPING_OFF)); 401 previousCharacters = false; 402 } 403 404 } 406 407 } 408 409 428 | Popular Tags |