Phew.. I got it to work. Details and discussion below:

Alan Hodgkinson wrote:
>
> I get a compile error from the Java code generated by
> my logicsheet.
>
> I'm trying to implement a logicsheet that looks up
> a value given an id. I'm calling it from an XSP page
> as follows:
>
>   <dbutil:idlookup table="Clients">
>      <xsp-request:get-parameter name="clientId"/>
>   </dbutil:idlookup>
>
> The dbutil logic sheet makes use of the esql logicsheet.
> dbutil:idlookup performs, more or less, the following:
>
>   <xsl:template match="dbutil:idlookup">
>     <esql:collection>
>        ...
>        <esql:query>
>           select name from Clients where clientId =
>             <xsl:value-of select=".|text()"/>
> 
> I had hoped that the idlookup tag would contain
> the text representation my client id (e.g. '1') at evaluation
> time. I find instead that Cocoon is attempting to replace the
> get-parameter with a Java call, which (logically speaking)
> generates a select that looks like this:
> 
>     select name from Clients where clientId =
>       <xsp-request:get-parameter name="clientId"/>
> 
> This would be fine except that the select statement is
> apparently treated internally as a string and when
> processed by the generator, it creates JSP code that
> looks like this (Slightly adjusted and line-wrapped to
> make it more readable):
> 
>   _esql_query =
>       new EsqlQuery(
>         _esql_connection,
>         String.valueOf(
>             "select name from Clients where clientId =
>                (XSPRequestHelper.getParameter(objectModel,
>                   "clientId", null, null, null)
>                )
>             "
>         )
>     );
> 
> Note the embedded Java method call in the literal string.
> This causes the problem. (I suppose I should consider myself
> lucky that the method call generated a syntax error instead
> of failing silently :)

After more thought and searching of the mail archives, I 
wondered if it might be possible to make use of <xsp:expr>
and <xsp:logic> tags that allow me to set a Java variable on 
the fly that. The problem is that I would be trying to 
create a string containing a tag that I need to evaluate.

The answer is yes, but it wasn't as obvious as I thought.

This eventually worked (located in the logicsheet):

  <xsl:template match="dbutil:idlookup">
  
    <xsl:variable name="id-value">
      <xsl:copy-of select="."/>
    </xsl:variable>

    <xsp:logic>
      String idSelect = "select <xsl:value-of select="@value-field"/>
from <xsl:value-of select="@table"/> where <xsl:value-of
select="@id-field"/>  =  " + <xsl:value-of select="$id-value"/> ;
    </xsp:logic>

    <esql:connection>
      <esql:pool><xsl:value-of select="@connection"/></esql:pool>
      <esql:execute-query>
        <esql:query>
          <xsp:expr>idSelect</xsp:expr>
        </esql:query>
        ...

Note the weird quoting in the <xsp:logic> tag. Everything 
up to the id-value is quoted, since all the 'value-of' 
tags up to that point are selecting XML attributes and 
return literals. 

The final 'value-of', which returns $id-value, and should 
contain results of evaluating the tag 
<xsp-request:get-parameter name="clientId"/>. It _must_ not
be quoted because when it is translated into Java/JSP code 
it turns into code not a literal string. In fact it's a 
method call that returns a string.

<background-info related="slightly">
  I got the idea from Stehpan Ng, who described a similar 
  problem. In his case he is trying to get parameter values 
  from the pipeline into his ESQL statement:

  http://www.mail-archive.com/cocoon-users@xml.apache.org/msg15161.html
</background-info>

Christian Haul also supplied a few tips which helped me find
the eventual solution..

> Christian Haul wrote:
<snip/>
> Two options: 
>
> a) create the query dynamically. esql expects just a string. Thus you
> need to 
>          <esql:query>
>             <xsp:expr>"select name from clients where clientid=" +
>                   <xsp-request:get-parameter name="clientId"/>
>         <xsp:expr>
>      </esql:query>

This does not work as is, because the conversion to JSP/Java 
results in a some local definitions, which cannot be simply added 
to an <xsp:expr>. I needed to use the XMST variable as described 
above.
 
> b) use a prepared statement
>          <esql:query>
>             select name from clients where clientid=
>                   <esql:parameter><xsp-request:get-parameter
> name="clientId"/></esql:parameter>
>      </esql:query>
> 
> Preferable is b).

This would work, but requires that my parameter comes from the 
HTML form parameters. Remember how I call my logicsheet:

>>   <dbutil:idlookup table="Clients">
>>      <xsp-request:get-parameter name="clientId"/>
>>   </dbutil:idlookup>

I want a generic logicsheet and don't want to be constrained 
to have to get the clientId parameter from the HTML parameters. 

E.g. I should be free to replace the <xsp-request:get-parameter>
with anything and the logic sheet shouldn't have to worry about 
what it gets. With XSLT this isn't normally a problem. That fact 
that the parameter, which could be XML nodes instead of text, is 
placed in to a Java string that is evaluated by the DB server is 
what causes the problem. In Lisp or Bourne shell you'de use the
an 'eval' function to guarantee that your parameters are 
completely resolved. That's not available here.

Alas, due to my own constraints, solution b is not an option. 

In fact the logicsheet is even more generic than is shown in my 
e-mails. I 'hard coded' a lot of the variable stuff to eliminate 
complexity not directly related to the problem.

Many thanks and best wishes [especially to Christian]..

Alan.

P.S. If interests warrants, I'm willing to publish a clearer
explanation of how/why this works as a Wiki snippit/howto.

---------------------------------------------------------------------
Please check that your question  has not already been answered in the
FAQ before posting.     <http://xml.apache.org/cocoon/faq/index.html>

To unsubscribe, e-mail:     <[EMAIL PROTECTED]>
For additional commands, e-mail:   <[EMAIL PROTECTED]>

Reply via email to