Re: XPathExpression question

Rolf Lear <[email protected]> Sat, 08 Jun 2013 11:02:28 -0400
Newsgroups gmane.comp.java.jdom.general
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--===============1326925498==
Content-Type: multipart/alternative;
 boundary="------------090404080709010804030501"

This is a multi-part message in MIME format.
--------------090404080709010804030501
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi Wayne.

This is a bug.... thanks. The clone() method of the default (Jaxen) 
implementation does not do a correct clone().

Technically, the Jaxen API requires a Variable 'context', and while the 
clone() operation successfully duplicates the variable context, and 
querying the JDOM wrapper for variable values successfully returns the 
correct data (different sets of variables for the original and the 
clone), the actual Jaxen API is *always* given the context from the 
original instance. The JDOM test cases made sure that the right values 
were set in the new instance, and that they were independant of the 
original instance, but did not run through the Jaxen code that had the 
wrong instance....

I will fix this asap.

If you want a workaround.... it seems that a thread-local is a good option:

     private static final 
ThreadLocal<Map<String,XPathExpression<Element>>> tl_pathMap =
             new ThreadLocal<Map<String,XPathExpression<Element>>>() {
         protected Map<String,org.jdom2.xpath.XPathExpression<Element>> 
initialValue() {
             XPathFactory fac = XPathFactory.instance();
HashMap<String,org.jdom2.xpath.XPathExpression<Element>> init = new 
HashMap<String, XPathExpression<Element>>();
             init.put("method_a", fac.compile(....));
             ......
             return init;
         }
     };

then you can use it with:

XPathExpression<Element> xPath = /tl_pathMap/.get().get(method);

xPath.setVariable("variable", /namespace/, "fString");

List<Element> elems = xPath.evaluate(model.asDocument());


Rolf




On 07/06/2013 2:35 PM, Keeney, Wayne wrote:
>
> Here's hoping this question gets to the right place.
>
> We are using JDOM2 (2.0.3) and it's my understanding that instances of 
> XPathExpression are not thread safe.  We were using clone as a 
> (hopefully) more efficient method of getting our "own" instance of a 
> pre compiled XPathExpression safe from other thread access.  This is 
> not my main question, but is it more efficient?
>
> My main question has to do with setting variables on the 
> XPathExpression.  I could not get the variable setting to work on a 
> cloned copy of an XPathExpression, but it works if I set the variable 
> before cloning.  The problem with this, is of course, thread safety.
>
> Is this a known bug, maybe fixed?
>
> This works (but opens an opportunity for threading problems since 
> we're using precompiled static instances):
>
> XPathExpression<Element> xPath = /pathMap/.get(method);
>
> xPath.setVariable("variable", /namespace/, "fString");
>
> List<Element> elems = xPath.clone().evaluate(model.asDocument());
>
> But this doesn't work, it doesn't seem to recognize the variable 
> replacement:
>
> XPathExpression<Element> xPath = /pathMap/.get(method).clone();
>
> xPath.setVariable("variable", /namespace/, "fString");
>
> List<Element> elems = xPath.evaluate(model.asDocument());
>
> pathmap is just a map of precompiled XPathExpressions.
>
> Thanks,
>
> Wayne Keeney
>
> SAT Services
>
>
>
> _______________________________________________
> To control your jdom-interest membership:
> http://www.jdom.org/mailman/options/jdom-interest/[email protected]


--------------090404080709010804030501
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Hi Wayne.<br>
      <br>
      This is a bug.... thanks. The clone() method of the default
      (Jaxen) implementation does not do a correct clone().<br>
      <br>
      Technically, the Jaxen API requires a Variable 'context', and
      while the clone() operation successfully duplicates the variable
      context, and querying the JDOM wrapper for variable values
      successfully returns the correct data (different sets of variables
      for the original and the clone), the actual Jaxen API is *always*
      given the context from the original instance. The JDOM test cases
      made sure that the right values were set in the new instance, and
      that they were independant of the original instance, but did not
      run through the Jaxen code that had the wrong instance....<br>
      <br>
      I will fix this asap.<br>
      <br>
      If you want a workaround.... it seems that a thread-local is a
      good option:<br>
      <br>
      <small><font face="Courier">&nbsp;&nbsp;&nbsp; private static final
          ThreadLocal&lt;Map&lt;String,XPathExpression&lt;Element&gt;&gt;&gt;
          tl_pathMap = </font><br>
        <font face="Courier">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; new
          ThreadLocal&lt;Map&lt;String,XPathExpression&lt;Element&gt;&gt;&gt;()
          {</font><br>
        <font face="Courier">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; protected
          Map&lt;String,org.jdom2.xpath.XPathExpression&lt;Element&gt;&gt;
          initialValue() {</font><br>
        <font face="Courier">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; XPathFactory fac =
          XPathFactory.instance();</font><br>
        <font face="Courier">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
          HashMap&lt;String,org.jdom2.xpath.XPathExpression&lt;Element&gt;&gt;
          init = new HashMap&lt;String,
          XPathExpression&lt;Element&gt;&gt;();</font><br>
        <font face="Courier">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; init.put("method_a",
          fac.compile(....));<br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<br>
        </font><font face="Courier">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return init;</font><br>
        <font face="Courier">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</font><br>
        <font face="Courier">&nbsp;&nbsp;&nbsp; };</font><br>
      </small><br>
      then you can use it with:<br>
      <br>
      <p class="MsoNormal" style="text-autospace:none"><span
          style="font-size:10.0pt;font-family:Consolas;color:black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          XPathExpression&lt;Element&gt; xPath = </span><i><span
            style="font-size:10.0pt;font-family:Consolas;color:#0000C0">tl_pathMap</span></i><span
          style="font-size:10.0pt;font-family:Consolas;color:black">.get().get(method);</span><span
          style="font-size:10.0pt;font-family:Consolas"><o:p></o:p></span></p>
      <p class="MsoNormal" style="text-autospace:none"><span
          style="font-size:10.0pt;font-family:Consolas;color:black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          xPath.setVariable(</span><span
          style="font-size:10.0pt;font-family:Consolas;color:#2A00FF">"variable"</span><span
          style="font-size:10.0pt;font-family:Consolas;color:black">, </span><i><span
            style="font-size:10.0pt;font-family:Consolas;color:#0000C0">namespace</span></i><span
          style="font-size:10.0pt;font-family:Consolas;color:black">, </span><span
          style="font-size:10.0pt;font-family:Consolas;color:#2A00FF">"fString"</span><span
          style="font-size:10.0pt;font-family:Consolas;color:black">);</span><span
          style="font-size:10.0pt;font-family:Consolas"><o:p></o:p></span></p>
      <p class="MsoNormal"><span
          style="font-size:10.0pt;font-family:Consolas;color:black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          List&lt;Element&gt; elems =
          xPath.evaluate(model.asDocument());<o:p></o:p></span></p>
      <span style="font-size:10.0pt;font-family:Consolas;color:black"><o:p></o:p></span><br>
      Rolf<br>
      <br>
      <br>
      <br>
      <br>
      On 07/06/2013 2:35 PM, Keeney, Wayne wrote:<br>
    </div>
    <blockquote
cite="mid:1C8985E6271A2E4AAD3D9F2C5BEE5E9031FEFFC0B5@RTL-MAIL01.Integ.Local"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      <meta name="Generator" content="Microsoft Word 14 (filtered
        medium)">
      <style><!--
/* Font Definitions */
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
	{font-family:Consolas;
	panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0in;
	margin-bottom:.0001pt;
	font-size:11.0pt;
	font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
	{mso-style-priority:99;
	color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{mso-style-priority:99;
	color:purple;
	text-decoration:underline;}
span.EmailStyle17
	{mso-style-type:personal-compose;
	font-family:"Calibri","sans-serif";
	color:windowtext;}
.MsoChpDefault
	{mso-style-type:export-only;
	font-size:10.0pt;}
@page WordSection1
	{size:8.5in 11.0in;
	margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
	{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
      <div class="WordSection1">
        <p class="MsoNormal">Here&#8217;s hoping this question gets to the
          right place.&nbsp; <o:p></o:p></p>
        <p class="MsoNormal"><o:p>&nbsp;</o:p></p>
        <p class="MsoNormal">We are using JDOM2 (2.0.3) and it&#8217;s my
          understanding that instances of XPathExpression are not thread
          safe.&nbsp; We were using clone as a (hopefully) more efficient
          method of getting our &#8220;own&#8221; instance of a pre compiled
          XPathExpression safe from other thread access.&nbsp; This is not my
          main question, but is it more efficient?<o:p></o:p></p>
        <p class="MsoNormal"><o:p>&nbsp;</o:p></p>
        <p class="MsoNormal">My main question has to do with setting
          variables on the XPathExpression.&nbsp; I could not get the
          variable setting to work on a cloned copy of an
          XPathExpression, but it works if I set the variable before
          cloning.&nbsp; The problem with this, is of course, thread safety.<o:p></o:p></p>
        <p class="MsoNormal"><o:p>&nbsp;</o:p></p>
        <p class="MsoNormal">Is this a known bug, maybe fixed?&nbsp; <o:p></o:p></p>
        <p class="MsoNormal"><o:p>&nbsp;</o:p></p>
        <p class="MsoNormal">This works (but opens an opportunity for
          threading problems since we&#8217;re using precompiled static
          instances):<o:p></o:p></p>
        <p class="MsoNormal" style="text-autospace:none"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            XPathExpression&lt;Element&gt; xPath = </span><i><span
              style="font-size:10.0pt;font-family:Consolas;color:#0000C0">pathMap</span></i><span
            style="font-size:10.0pt;font-family:Consolas;color:black">.get(method);</span><span
            style="font-size:10.0pt;font-family:Consolas"><o:p></o:p></span></p>
        <p class="MsoNormal" style="text-autospace:none"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            xPath.setVariable(</span><span
            style="font-size:10.0pt;font-family:Consolas;color:#2A00FF">"variable"</span><span
            style="font-size:10.0pt;font-family:Consolas;color:black">,
          </span><i><span
              style="font-size:10.0pt;font-family:Consolas;color:#0000C0">namespace</span></i><span
            style="font-size:10.0pt;font-family:Consolas;color:black">,
          </span><span
            style="font-size:10.0pt;font-family:Consolas;color:#2A00FF">"fString"</span><span
            style="font-size:10.0pt;font-family:Consolas;color:black">);</span><span
            style="font-size:10.0pt;font-family:Consolas"><o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            List&lt;Element&gt; elems =
            xPath.clone().evaluate(model.asDocument());<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black"><o:p>&nbsp;</o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">But
            this doesn&#8217;t work, it doesn&#8217;t seem to recognize the variable
            replacement:<o:p></o:p></span></p>
        <p class="MsoNormal" style="text-autospace:none"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            XPathExpression&lt;Element&gt; xPath = </span><i><span
              style="font-size:10.0pt;font-family:Consolas;color:#0000C0">pathMap</span></i><span
            style="font-size:10.0pt;font-family:Consolas;color:black">.get(method).clone();</span><span
            style="font-size:10.0pt;font-family:Consolas"><o:p></o:p></span></p>
        <p class="MsoNormal" style="text-autospace:none"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            xPath.setVariable(</span><span
            style="font-size:10.0pt;font-family:Consolas;color:#2A00FF">"variable"</span><span
            style="font-size:10.0pt;font-family:Consolas;color:black">,
          </span><i><span
              style="font-size:10.0pt;font-family:Consolas;color:#0000C0">namespace</span></i><span
            style="font-size:10.0pt;font-family:Consolas;color:black">,
          </span><span
            style="font-size:10.0pt;font-family:Consolas;color:#2A00FF">"fString"</span><span
            style="font-size:10.0pt;font-family:Consolas;color:black">);</span><span
            style="font-size:10.0pt;font-family:Consolas"><o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            List&lt;Element&gt; elems =
            xPath.evaluate(model.asDocument());<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black"><o:p>&nbsp;</o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">pathmap
            is just a map of precompiled XPathExpressions.<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black"><o:p>&nbsp;</o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">Thanks,<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black"><o:p>&nbsp;</o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">Wayne
            Keeney<o:p></o:p></span></p>
        <p class="MsoNormal"><span
            style="font-size:10.0pt;font-family:Consolas;color:black">SAT
            Services</span><o:p></o:p></p>
        <p class="MsoNormal"><o:p>&nbsp;</o:p></p>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
To control your jdom-interest membership:
<a class="moz-txt-link-freetext" href="http://www.jdom.org/mailman/options/jdom-interest/[email protected]">http://www.jdom.org/mailman/options/jdom-interest/[email protected]</a></pre>
    </blockquote>
    <br>
  </body>
</html>

--------------090404080709010804030501--

--===============1326925498==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
To control your jdom-interest membership:
http://www.jdom.org/mailman/options/jdom-interest/[email protected]
--===============1326925498==--