Changeset 385


Ignore:
Timestamp:
Apr 11, 2005, 3:05:13 PM (18 years ago)
Author:
Nicklas Nordborg
Message:

Now use JDOM

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  
    2727import net.sf.basedb.util.XMLUtil;
    2828
    29 import org.w3c.dom.Document;
    30 import org.w3c.dom.Element;
     29import java.net.URL;
     30import org.jdom.Document;
     31import org.jdom.Element;
     32import org.jdom.JDOMException;
     33import org.jdom.xpath.XPath;
    3134
    3235/**
     
    7376    The path to the query file with common queries.
    7477  */
    75   private static String commonQueryFile = "/common-queries.xml";
     78  private static final String commonQueryFile = "/common-queries.xml";
    7679
    7780  /**
     
    7982  */
    8083  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");
    8189
    8290  /**
     
    8997    try
    9098    {
    91       commonDom = XMLUtil.getValidatedDom(commonQueryFile);
     99      commonDom = XMLUtil.getValidatedXml(PredefinedQuery.class.getResource(commonQueryFile), dtdFile);
    92100      Application.log("PredefinedQuery", "loadQueryFile", commonQueryFile+" loaded and parsed");
    93101      if (dialectQueryFile != null)
    94102      {
    95         dialectDom = XMLUtil.getValidatedDom(dialectQueryFile);
     103        dialectDom = XMLUtil.getValidatedXml(PredefinedQuery.class.getResource(dialectQueryFile), dtdFile);
    96104        Application.log("PredefinedQuery", "loadQueryFile", dialectQueryFile+" loaded and parsed");
    97105      }
     
    113121  {
    114122    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    }
    117134    if (query == null)
    118135    {
     
    121138        (dialectQueryFile != null ? " or in file '"+dialectQueryFile+"'" : ""));
    122139    }
    123     String sql = query.getElementsByTagName("sql")
    124       .item(0).getFirstChild().getNodeValue().trim();
     140    String sql = query.getChildText("sql").trim();
    125141    return sql;
    126142  }
  • trunk/src/core/net/sf/basedb/util/XMLUtil.java

    r192 r385  
    2525package net.sf.basedb.util;
    2626
     27
    2728import java.io.InputStream;
     29//import java.io.ByteArrayInputStream;
    2830import java.io.IOException;
    2931import 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;
     32import java.io.StringReader;
     33import java.net.URL;
     34
     35import org.jdom.Document;
     36import org.jdom.Element;
     37import org.jdom.DocType;
     38import org.jdom.input.SAXBuilder;
     39import org.jdom.JDOMException;
     40
    3741import org.xml.sax.EntityResolver;
    38 import org.xml.sax.InputSource;
    3942import org.xml.sax.ErrorHandler;
    4043import org.xml.sax.SAXException;
    4144import org.xml.sax.SAXParseException;
     45import org.xml.sax.InputSource;
     46import org.jdom.output.Format;
     47import org.jdom.output.XMLOutputter;
    4248
    4349/**
     
    5258
    5359  /**
    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();
    206110    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;
    208136  }
    209137
     
    218146
    219147    private final String parsedFile;
     148    private final URL dtdFile;
     149   
    220150    /**
    221151      Create a new instance of this class.
    222152    */
    223     private Validator(String parsedFile)
     153    private Validator(String parsedFile, URL dtdFile)
    224154    {
    225155      this.parsedFile = parsedFile;
     156      this.dtdFile = dtdFile;
    226157    }
    227158
     
    267198    public InputSource resolveEntity(String publicId, String systemId)
    268199    {
    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
    276203      {
    277         return new InputSource(is);
     204        is = dtdFile == null ? null : dtdFile.openStream();
    278205      }
    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  }
    286211
    287212}
Note: See TracChangeset for help on using the changeset viewer.