Changeset 385
- Timestamp:
- Apr 11, 2005, 3:05:13 PM (18 years ago)
- Location:
- trunk/src/core/net/sf/basedb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/core/net/sf/basedb/core/PredefinedQuery.java
r192 r385 27 27 import net.sf.basedb.util.XMLUtil; 28 28 29 import org.w3c.dom.Document; 30 import org.w3c.dom.Element; 29 import java.net.URL; 30 import org.jdom.Document; 31 import org.jdom.Element; 32 import org.jdom.JDOMException; 33 import org.jdom.xpath.XPath; 31 34 32 35 /** … … 73 76 The path to the query file with common queries. 74 77 */ 75 private static String commonQueryFile = "/common-queries.xml";78 private static final String commonQueryFile = "/common-queries.xml"; 76 79 77 80 /** … … 79 82 */ 80 83 private static String dialectQueryFile = null; 84 85 /** 86 The DTD which is used to validate the XML file. 87 */ 88 private static final URL dtdFile = PredefinedQuery.class.getResource("/net/sf/basedb/core/dtd/predefined-queries.dtd"); 81 89 82 90 /** … … 89 97 try 90 98 { 91 commonDom = XMLUtil.getValidated Dom(commonQueryFile);99 commonDom = XMLUtil.getValidatedXml(PredefinedQuery.class.getResource(commonQueryFile), dtdFile); 92 100 Application.log("PredefinedQuery", "loadQueryFile", commonQueryFile+" loaded and parsed"); 93 101 if (dialectQueryFile != null) 94 102 { 95 dialectDom = XMLUtil.getValidated Dom(dialectQueryFile);103 dialectDom = XMLUtil.getValidatedXml(PredefinedQuery.class.getResource(dialectQueryFile), dtdFile); 96 104 Application.log("PredefinedQuery", "loadQueryFile", dialectQueryFile+" loaded and parsed"); 97 105 } … … 113 121 { 114 122 Element query = null; 115 if (dialectDom != null) query = dialectDom.getElementById(name); 116 if (query == null) query = commonDom.getElementById(name); 123 try 124 { 125 XPath findQuery = XPath.newInstance("//query[@id='"+name+"']"); 126 127 if (dialectDom != null) query = (Element)findQuery.selectSingleNode(dialectDom); 128 if (query == null) query = (Element)findQuery.selectSingleNode(commonDom); 129 } 130 catch (JDOMException ex) 131 { 132 throw new BaseException(ex); 133 } 117 134 if (query == null) 118 135 { … … 121 138 (dialectQueryFile != null ? " or in file '"+dialectQueryFile+"'" : "")); 122 139 } 123 String sql = query.getElementsByTagName("sql") 124 .item(0).getFirstChild().getNodeValue().trim(); 140 String sql = query.getChildText("sql").trim(); 125 141 return sql; 126 142 } -
trunk/src/core/net/sf/basedb/util/XMLUtil.java
r192 r385 25 25 package net.sf.basedb.util; 26 26 27 27 28 import java.io.InputStream; 29 //import java.io.ByteArrayInputStream; 28 30 import java.io.IOException; 29 31 import java.io.FileNotFoundException; 30 31 import javax.xml.parsers.DocumentBuilderFactory; 32 import javax.xml.parsers.DocumentBuilder; 33 import javax.xml.parsers.ParserConfigurationException; 34 import org.w3c.dom.Document; 35 import org.w3c.dom.Node; 36 import org.w3c.dom.NodeList; 32 import java.io.StringReader; 33 import java.net.URL; 34 35 import org.jdom.Document; 36 import org.jdom.Element; 37 import org.jdom.DocType; 38 import org.jdom.input.SAXBuilder; 39 import org.jdom.JDOMException; 40 37 41 import org.xml.sax.EntityResolver; 38 import org.xml.sax.InputSource;39 42 import org.xml.sax.ErrorHandler; 40 43 import org.xml.sax.SAXException; 41 44 import org.xml.sax.SAXParseException; 45 import org.xml.sax.InputSource; 46 import org.jdom.output.Format; 47 import org.jdom.output.XMLOutputter; 42 48 43 49 /** … … 52 58 53 59 /** 54 Get the value of a named attribute for the specified node. 55 If the attribute with the specified name doesn't exist 56 null is returned. 57 58 @param n The <code>Node</code> 59 @param name The name of the attribute 60 @return The value of the named attribute, with leading 61 and trailing whitespace omitted, or null if the attribute 62 doesn't exist 63 */ 64 public static String getAttribute(Node n, String name) 65 { 66 Node attribute = n.getAttributes().getNamedItem(name); 67 return attribute == null ? null : attribute.getNodeValue().trim(); 68 } 69 70 /** 71 Set the value for the named atribute of the specified node. 72 It is expected that there is an attribute with the specified 73 name or an exception will be thrown. 74 75 @param n The <code>Node</code> 76 @param name The name of the attribute 77 @param value The new value of the attribute 78 */ 79 public static void setAttribute(Node n, String name, String value) 80 { 81 n.getAttributes().getNamedItem(name).setNodeValue(value); 82 } 83 84 /** 85 Get the value of a named attribute for the specified node as 86 an integer. 87 88 @param n The <code>Node</code> 89 @param name The name of the attribute 90 @param defaultValue A default value to return if the 91 attribute doesn't contain a parsable number or if 92 the attribute doesn't exist. 93 @return The value of the named attribute, or the default 94 */ 95 public static int getIntAttribute(Node n, String name, int defaultValue) 96 { 97 try 98 { 99 return Integer.parseInt(getAttribute(n, name)); 100 } 101 catch (Exception ex) 102 {} 103 return defaultValue; 104 } 105 106 /** 107 Get the value of a named attribute for the specified node as 108 a boolean. If the attribute is empty, <code>0</code>, 109 <code>no</code> or <code>false</code> (case ignored), FALSE 110 is returned. All other values will return TRUE. 111 112 @param n The <code>Node</code> 113 @param name The name of the attribute 114 @return FALSE or TRUE 115 */ 116 public static boolean getBooleanAttribute(Node n, String name) 117 { 118 String s = getAttribute(n, name); 119 return (s == null 120 || s.equals("") 121 || s.equals("0") 122 || s.equalsIgnoreCase("no") 123 || s.equalsIgnoreCase("false") 124 ) ? false : true; 125 } 126 127 /** 128 Find a node with a given tagname having an attribute with the specified value. 129 If more than one node matches the critera it is not defined which one is 130 returned. 131 132 @param dom The <code>Document</code> to look in 133 @param tagname The name of the tag to look for 134 @param attribute The attribute to check, or null if we don't want to check attributes 135 @param value The required value of the attribute 136 @return The <code>Node</code> object matching the criteria or null 137 if not found 138 */ 139 public static Node findNode(Document dom, String tagname, String attribute, String value) 140 { 141 NodeList nl = dom.getElementsByTagName(tagname); 142 if (attribute == null) 143 { 144 return nl.item(0); 145 } 146 else 147 { 148 for (int i = 0; i < nl.getLength(); i++) 149 { 150 Node n = nl.item(i); 151 if (value.equals(getAttribute(n, attribute))) return n; 152 } 153 } 154 return null; 155 } 156 157 /** 158 Load and validate an XML file and return it as a 159 <code>Document</code> object. The path to the file should 160 be given as a resource path, not a filesystem path. Ie. the file 161 must be located on the classpath and the path is given in the same 162 way as for Java classes, except that dots are replaced by slashes. 163 Example: /net/sf/basedb/core/the-xml-file.xml 164 165 @param xmlFile The path to the XML file 166 */ 167 public static Document getValidatedDom(String xmlFile) 168 throws IOException, SAXException, ParserConfigurationException 169 { 170 Document dom = null; 171 // We want to use the Xerces XML package, the default (Xalan) will not validate correctly 172 String defaultXmlParser = System.setProperty( 173 "javax.xml.parsers.DocumentBuilderFactory", 174 "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"); 175 try 176 { 177 178 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 179 // System.out.println("dbf="+dbf+"; class="+dbf.getClass()); 180 dbf.setValidating(true); 181 DocumentBuilder db = dbf.newDocumentBuilder(); 182 183 Validator validator = new Validator(xmlFile); 184 // The entity resolver lets us find the correct DTD for validating 185 db.setEntityResolver(validator); 186 // So we can throw our own exception messages if there is a parse error 187 db.setErrorHandler(validator); 188 189 InputStream is = XMLUtil.class.getResourceAsStream(xmlFile); 190 if (is == null) 191 { 192 throw new FileNotFoundException("Can't find the file '"+xmlFile+ 193 "'. Make sure it is in the CLASSPATH"); 194 } 195 dom = db.parse(is); 196 is.close(); 197 } 198 finally 199 { 200 // Reset the system to use the default XML package 201 if (defaultXmlParser != null) 202 { 203 System.setProperty("javax.xml.parsers.DocumentBuilderFactory", defaultXmlParser); 204 } 205 } 60 The parser class we are using. 61 */ 62 private static final String xmlParserClass = "org.apache.xerces.parsers.SAXParser"; 63 64 /** 65 Convert a <code>Document</code> to xml. The encoding is set to ISO-8859-1. 66 @param dom The document 67 @return The XML 68 */ 69 public static String toXml(Document dom) 70 { 71 XMLOutputter out = new XMLOutputter(Format.getCompactFormat().setEncoding("ISO-8859-1")); 72 return out.outputString(dom); 73 } 74 75 /** 76 Create a new <code>Document</code> with root element and System ID 77 declaration. 78 @param rootElement The name of the root element tag 79 @param systemId The system ID in the DOCTYPE section 80 */ 81 public static Document createDom(String rootElement, String systemId) 82 { 83 return new Document(new Element(rootElement), new DocType(rootElement, systemId)); 84 } 85 86 /** 87 Load and validate an XML file against a DTD, and return it as a 88 <code>Document</code> object. The path to the files should 89 be given as a URL, not a filesystem path. For a file on the classpath 90 it is easiest done by the {@link Class#getResource()} method, ie. 91 <code>XMLUtil.class.getResource("/net/sf/basedb/core/the-xml-file.xml")</code>. 92 93 @param xmlFile The URL to the XML file 94 @param dtdFile The URL to the DTD used for validation 95 @return A <code>Document</code> object 96 */ 97 public static Document getValidatedXml(URL xmlFile, URL dtdFile) 98 throws JDOMException, IOException 99 { 100 101 SAXBuilder sax = new SAXBuilder(xmlParserClass, true); 102 Validator validator = new Validator(null, dtdFile); 103 // The entity resolver lets us find the correct DTD for validating 104 sax.setEntityResolver(validator); 105 // So we can throw our own exception messages if there is a parse error 106 sax.setErrorHandler(validator); 107 InputStream is = xmlFile.openStream(); 108 Document dom = sax.build(is); 109 is.close(); 206 110 return dom; 207 111 } 112 113 /** 114 Parse and validate a string containing XML against a DTD, and return it as a 115 <code>Document</code> object. The path to the DTD should 116 be given as a URL, not a filesystem path. For a file on the classpath 117 it is easiest done by the {@link Class#getResource()} method, ie. 118 <code>XMLUtil.class.getResource("/net/sf/basedb/core/the-dtd-file.dtd")</code>. 119 @param xml The string containing the XML 120 @param dtdFile The URL to the DTD used for validation 121 @return A <code>Document</code> object 122 */ 123 public static Document getValidatedXml(String xml, URL dtdFile) 124 throws JDOMException, IOException 125 { 126 SAXBuilder sax = new SAXBuilder(xmlParserClass, true); 127 Validator validator = new Validator(null, dtdFile); 128 // The entity resolver lets us find the correct DTD for validating 129 sax.setEntityResolver(validator); 130 // So we can throw our own exception messages if there is a parse error 131 sax.setErrorHandler(validator); 132 StringReader sr = new StringReader(xml); 133 Document dom = sax.build(sr); 134 sr.close(); 135 return dom; 208 136 } 209 137 … … 218 146 219 147 private final String parsedFile; 148 private final URL dtdFile; 149 220 150 /** 221 151 Create a new instance of this class. 222 152 */ 223 private Validator(String parsedFile )153 private Validator(String parsedFile, URL dtdFile) 224 154 { 225 155 this.parsedFile = parsedFile; 156 this.dtdFile = dtdFile; 226 157 } 227 158 … … 267 198 public InputSource resolveEntity(String publicId, String systemId) 268 199 { 269 // System.out.println("PID:"+publicId+"\tSID:"+systemId); 270 271 int index = systemId.lastIndexOf("/"); 272 if (index >= 0) systemId = systemId.substring(index+1); 273 String dtdFile = "/net/sf/basedb/core/dtd/"+systemId; 274 InputStream is = XMLUtil.class.getResourceAsStream(dtdFile); 275 if (is != null) 200 net.sf.basedb.core.Application.log("XMLUtil", "resolveEntity", "PID:"+publicId+"\tSID:"+systemId+"\tDTD:"+dtdFile); 201 InputStream is = null; 202 try 276 203 { 277 return new InputSource(is);204 is = dtdFile == null ? null : dtdFile.openStream(); 278 205 } 279 else 280 { 281 return null; 282 } 283 } 284 } 285 206 catch (IOException ex) 207 {} 208 return is == null ? null : new InputSource(is); 209 } 210 } 286 211 287 212 }
Note: See TracChangeset
for help on using the changeset viewer.