1 21 22 package org.apache.derby.iapi.types; 23 24 import org.apache.derby.iapi.error.StandardException; 25 import org.apache.derby.iapi.reference.SQLState; 26 import org.apache.derby.iapi.services.io.Formatable; 27 import org.apache.derby.iapi.services.io.StoredFormatIds; 28 import org.apache.derby.iapi.services.sanity.SanityManager; 29 30 import java.util.Properties ; 31 import java.util.ArrayList ; 32 33 import java.io.IOException ; 34 import java.io.ObjectOutput ; 35 import java.io.ObjectInput ; 36 import java.io.StringReader ; 37 38 40 import org.w3c.dom.Attr ; 41 import org.w3c.dom.Document ; 42 import org.w3c.dom.Element ; 43 import org.w3c.dom.Node ; 44 import org.w3c.dom.NodeList ; 45 import org.w3c.dom.Text ; 46 47 import org.xml.sax.ErrorHandler ; 48 import org.xml.sax.InputSource ; 49 import org.xml.sax.SAXException ; 50 import org.xml.sax.SAXParseException ; 51 52 import javax.xml.parsers.DocumentBuilder ; 53 import javax.xml.parsers.DocumentBuilderFactory ; 54 55 import javax.xml.transform.OutputKeys ; 56 import javax.xml.transform.TransformerException ; 57 58 60 import org.apache.xpath.XPath; 61 import org.apache.xpath.XPathContext; 62 import org.apache.xpath.objects.XObject; 63 import org.apache.xpath.objects.XNodeSet; 64 65 import org.apache.xml.utils.PrefixResolverDefault; 66 67 import org.apache.xalan.serialize.DOMSerializer; 68 import org.apache.xalan.serialize.Serializer; 69 import org.apache.xalan.serialize.SerializerFactory; 70 import org.apache.xalan.templates.OutputProperties; 71 72 116 117 public class SqlXmlUtil implements Formatable 118 { 119 private DocumentBuilder dBuilder; 122 123 private Serializer serializer; 126 127 private XPath query; 130 private XPathContext xpContext; 131 132 private String queryExpr; 135 private String opName; 136 private boolean recompileQuery; 137 138 145 public SqlXmlUtil() throws StandardException 146 { 147 try { 148 149 171 172 DocumentBuilderFactory dBF = null; 173 try { 174 175 dBF = DocumentBuilderFactory.newInstance(); 176 177 } catch (Throwable e) { 178 179 199 throw StandardException.newException( 200 SQLState.LANG_MISSING_XML_CLASSES, "JAXP"); 201 202 } 203 204 dBF.setValidating(false); 205 dBF.setNamespaceAware(true); 206 207 dBuilder = dBF.newDocumentBuilder(); 209 dBuilder.setErrorHandler(new XMLErrorHandler()); 210 211 loadSerializer(); 214 215 } catch (StandardException se) { 216 217 throw se; 219 220 } catch (Throwable t) { 221 222 235 throw StandardException.newException( 236 SQLState.LANG_UNEXPECTED_XML_EXCEPTION, t, t.getMessage()); 237 238 } 239 240 query = null; 243 } 244 245 253 public void compileXQExpr(String queryExpr, String opName) 254 throws StandardException 255 { 256 try { 257 258 267 query = new XPath(queryExpr, null, 268 new PrefixResolverDefault(dBuilder.newDocument()), 269 XPath.SELECT); 270 271 this.queryExpr = queryExpr; 272 this.opName = opName; 273 this.recompileQuery = false; 274 275 } catch (Throwable te) { 276 277 292 throw StandardException.newException( 293 SQLState.LANG_XML_QUERY_ERROR, te, opName, te.getMessage()); 294 295 } 296 } 297 298 310 protected String serializeToString(String xmlAsText) 311 throws Exception 312 { 313 ArrayList aList = new ArrayList (); 314 315 323 try { 324 325 final InputSource is = new InputSource (new StringReader (xmlAsText)); 326 aList.add(java.security.AccessController.doPrivileged( 327 new java.security.PrivilegedExceptionAction () 328 { 329 public Object run() throws IOException , SAXException 330 { 331 return dBuilder.parse(is); 332 } 333 })); 334 335 } catch (java.security.PrivilegedActionException pae) { 336 337 346 throw pae.getException(); 347 348 } 349 350 357 return serializeToString(aList, null); 358 } 359 360 384 protected String serializeToString(ArrayList items, 385 XMLDataValue xmlVal) throws java.io.IOException 386 { 387 if ((items == null) || (items.size() == 0)) 388 return ""; 390 391 java.io.StringWriter sWriter = new java.io.StringWriter (); 392 393 if (SanityManager.DEBUG) 395 { 396 SanityManager.ASSERT(serializer != null, 397 "Tried to serialize with uninitialized XML serializer."); 398 } 399 400 serializer.setWriter(sWriter); 401 DOMSerializer dSer = serializer.asDOMSerializer(); 402 403 int sz = items.size(); 404 Object obj = null; 405 406 412 413 boolean lastItemWasString = false; 415 for (int i = 0; i < sz; i++) 416 { 417 obj = items.get(i); 418 if (obj instanceof String ) 421 { 422 426 427 if (lastItemWasString) 428 { 429 433 sWriter.write(" "); 434 } 435 436 442 sWriter.write((String )obj); 443 lastItemWasString = true; 444 } 445 else if (obj instanceof Attr ) 446 { 447 474 if (xmlVal != null) 475 xmlVal.markAsHavingTopLevelAttr(); 476 dSer.serialize((Node )obj); 477 lastItemWasString = false; 478 } 479 else 480 { Node n = (Node )obj; 482 if (n instanceof Text ) 483 { 484 498 sWriter.write(n.getNodeValue()); 499 } 500 else 501 { 502 510 dSer.serialize(n); 511 } 512 513 lastItemWasString = false; 514 } 515 } 516 517 521 sWriter.flush(); 522 return sWriter.toString(); 523 } 524 525 558 protected ArrayList evalXQExpression(XMLDataValue xmlContext, 559 boolean returnResults, int [] resultXType) throws Exception 560 { 561 if (recompileQuery) 563 { 564 compileXQExpr(queryExpr, opName); 565 } 566 567 if (SanityManager.DEBUG) { 569 SanityManager.ASSERT( 570 (query != null) && (query.getExpression() != null), 571 "Failed to locate compiled XML query expression."); 572 } 573 574 582 if (xmlContext.getXType() != XML.XML_DOC_ANY) 583 { 584 throw StandardException.newException( 585 SQLState.LANG_INVALID_XML_CONTEXT_ITEM, 586 (returnResults ? "XMLQUERY" : "XMLEXISTS")); 587 } 588 589 Document docNode = null; 590 docNode = dBuilder.parse( 591 new InputSource ( 592 new StringReader (xmlContext.getString()))); 593 594 getXPathContext(); 596 xpContext.reset(); 597 XObject xOb = query.execute(xpContext, docNode, null); 598 599 if (!returnResults) 600 { 601 if ((xOb instanceof XNodeSet) && 605 (((XNodeSet)xOb).nodelist().getLength() > 0)) 606 { return new ArrayList (0); 610 } 611 else if (!(xOb instanceof XNodeSet)) 612 return new ArrayList (0); 615 else { 616 return null; 619 } 620 } 621 622 NodeList nodeList = null; 624 int numItems = 0; 625 if (!(xOb instanceof XNodeSet)) 626 numItems = 1; 628 else { 629 nodeList = xOb.nodelist(); 630 numItems = nodeList.getLength(); 631 } 632 633 ArrayList itemRefs = new ArrayList (); 635 if (nodeList == null) 636 itemRefs.add(xOb.str()); 639 else { 640 for (int i = 0; i < numItems; i++) 641 itemRefs.add(nodeList.item(i)); 642 } 643 644 nodeList = null; 645 646 652 if ((numItems == 1) && (itemRefs.get(0) instanceof Document )) 653 resultXType[0] = XML.XML_DOC_ANY; 654 else 655 resultXType[0] = XML.XML_SEQUENCE; 656 657 return itemRefs; 658 } 659 660 663 664 668 private XPathContext getXPathContext() 669 { 670 if (xpContext == null) 671 xpContext = new XPathContext(); 672 673 return xpContext; 674 } 675 676 681 private void loadSerializer() throws java.io.IOException 682 { 683 java.io.StringWriter sWriter = new java.io.StringWriter (); 684 685 Properties props = OutputProperties.getDefaultMethodProperties("xml"); 687 688 props.setProperty(OutputKeys.METHOD, "xml"); 690 691 716 props.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 717 718 props.setProperty(OutputKeys.ENCODING, "UTF-8"); 721 722 serializer = SerializerFactory.getSerializer(props); 724 return; 725 } 726 727 730 731 736 public void writeExternal(ObjectOutput out) 737 throws IOException 738 { 739 if (query == null) 741 { 742 out.writeBoolean(false); 743 } 744 else 745 { 746 out.writeBoolean(true); 747 out.writeObject(queryExpr); 748 out.writeObject(opName); 749 } 750 } 751 752 758 public void readExternal(ObjectInput in) 759 throws IOException , ClassNotFoundException 760 { 761 if (in.readBoolean()) 762 { 763 queryExpr = (String )in.readObject(); 764 opName = (String )in.readObject(); 765 recompileQuery = true; 766 } 767 } 768 769 774 public int getTypeFormatId() 775 { 776 return StoredFormatIds.SQL_XML_UTIL_V01_ID; 777 } 778 779 784 private class XMLErrorHandler implements ErrorHandler 785 { 786 public void error (SAXParseException exception) 787 throws SAXException 788 { 789 throw new SAXException (exception); 790 } 791 792 public void fatalError (SAXParseException exception) 793 throws SAXException 794 { 795 throw new SAXException (exception); 796 } 797 798 public void warning (SAXParseException exception) 799 throws SAXException 800 { 801 throw new SAXException (exception); 802 } 803 } 804 } 805 | Popular Tags |