<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    On 01/20/2012 12:28 PM, Rolf Lear wrote:
    <blockquote cite="mid:e631efb52dbb6ed044e3862c2b979991@tuis.net"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <meta name="Generator" content="MS Exchange Server version
        6.5.7036.0">
      <title>Re: [jdom-interest] suggested JDOM2 improvements</title>
      <!-- Converted from text/plain format --> 
      <p><font size="2">On the other hand, because XPathFactory
          instances are specified to be</font>
        <br>
        <font size="2">thread-safe, there is nothing stopping you from
          doing:</font>
      </p>
      <p><font size="2">public static final XPathFactory XPATH =</font>
        <br>
        <font size="2">XPathFactory.newInstance("com.example.xpath20.XPathFactory");</font>
      </p>
      <p><font size="2">Then in your code you can freely use:</font>
      </p>
      <p><font size="2">XPathCompiled<Object> xp =
          XPATH.compile("//*");</font>
      </p>
      <font size="2">...</font>
      <p><font size="2">The best practice would be for you to get your
          own instance of your own</font>
        <br>
        <font size="2">factory, then use that instance from wherever you
          need it.</font>
      </p>
      <br>
    </blockquote>
    <br>
    I'd like to use a custom factory as you describe above, but right
    now, that makes all public methods on org.jdom2.xpath.XPath useless,
    because they use a static threadlocal factory which can only be the
    result of XPathFactory.newInstance(), which is the DEFAULTFACTORY
    from XPathFactory, which is settable only by the System property:<br>
    <br>
    public abstract class XPath {<br>
    <br>
        private static final ThreadLocal<XPathFactory>
    localfactory =<br>
                new ThreadLocal<XPathFactory>();<br>
    <br>
        public static List<?> selectNodes(final Object context,
    final String path)<br>
                throws JDOMException {<br>
            return newInstance(path).selectNodes(context);<br>
        }<br>
    <br>
        public static final XPath newInstance(final String path) throws
    JDOMException {<br>
            XPathFactory fac = localfactory.get();<br>
            if (fac == null) {<br>
                fac = XPathFactory.newInstance();<br>
                localfactory.set(fac);<br>
            }<br>
            return fac.compile(path);<br>
        }<br>
    }<br>
    <br>
    The reason I use a custom factory is to work around a performance
    problem with Jaxen:
    org.jaxen.saxpath.helpers.XPathReaderFactory.createReader() does an
    expensive synchronized System.getProperty() that causes concurrency
    bottlenecks, and it's done frequently, and there's no way to
    configure Jaxen or JDOM to use a specific implementation class
    rather than consult System.getProperty every time.<br>
    <br>
    To fix this, I have to split apart a whole stack of factory code
    from JDOM and Jaxen, just in order to get at the createReader()
    method.<br>
    <br>
    Another reason to use a custom XPath factory would be to use the
    JDOM API for XPath to get the work done with Saxon.<br>
    <br>
    So, to summarize, my complaint is that if I want to use a custom
    XPath factory for whatever reason (and I've given two above), I
    cannot use any of the XPath public static methods. <br>
    <br>
    Leigh.<br>
  </body>
</html>