David Navas wrote:
Oddly, I just started writing pretty much these exact tags yesterday.
Your
timing is impeccable :)
An anecdotal agument for standardization. As an engineer, I would
rather reuse standard solutions than "re-invent the
wheel"; there is no point for 50 developers to develop 50 different
custom tags to do the same thing.
I'm not sure what you're trying to accomplish with <connection>,
exactly.
Is connection going to describe the attributes of a connection, making
it
available to a query?
Yes. Also, <connection timeout="sec"> would allow a database connection
to have a different lifetime than a <query
timedcache="sec"> server-side cached query, an argument against
combining the <connection> and <query> tags together.
I'm not sure you want a JSP author to manage connection pooling, that
seems more back-endish to me.
A separate <connection> tag could encapsulate all the functionality
needed for a database connection (like an API). It may
be possible to implement <connection> using connection pooling in such a
way that the JSP author would never have to
worry about it; it will "just work."
However, combining the <connection> and <query> tags (perhaps by making
connection info as attributes of query) would
make JSP authoring simplier, but at the potential cost of lost
flexibility and reusability. Any comments?
My query tag looks like:
<query name="..." command="..." connection="jdbc/demo">
<command>...</command> //[For building the command attribute]
//[We also support loading a query
from a
// separate file, which removes sql
from your
// jsp/presentation-layout, which
seems like a
// good thing]
Agreed, it is a good thing to have. Why not make it loadable from a
URI? This allows for accessing the SQL statement
from a local file, or from any arbitrary resource on a network.
<param name="destName|Offset" type="destType" value="...">
<value></value> // As you note, we can't nest tags,
which is
// a drag. So, this is how I base a
parameter
// on, say, a nested query value to do
breaking
// [hierarchical] reports.
</param>
There are three ways of implementing variable attributes within a custom
tag:
1) Use a pre-processor to resolve the variable/custom tag into a
constant so it will be XML compliant.
- Unnacceptable: The solution is non-JSP compliant (as of the 1.1
specs). However, having variable attributes in a custom
tag seems to be important; perhaps a mechanism to embed custom tags in
the attribute list of another custom tag should be
allowed in a future JSP spec. Any comments?
2) Convert the custom tag into a page scope variable, and use <%= %>
- Inelegant and daunting to an HTML/JSP author, but it works. The
<setPageData> may provide a standard mechanism to
do this though.
3) Nest the variable attribute in a separate tag (as above)
- Messy and complicated to implement:
1. Violates OO principles of encapsultation (attributes of a tag are
in its attribute list AND/OR (depending on the context,
ie: very bug prone) in one of its children tags)
2. Confusing to the HTML/JSP author: tag attributes should be
attributes, not tags themselves. In HTML 4.0, there are no
tags which modify the attributes of other tags. There should not be any
in JSP either.
2. Nested tags are evaluated in top-down order in JSP and HTML. If
children tags modify the behaviour of parent tags on
run-time, then this would necessitate nested tags to be evaluated in
down-top order. This may be possible in JSP, but it gets
messy very quickly.
I've made loop possible to exist within the query tags. One might
just as
easily
make <query> a pure definition, and force the query attributes of loop
and field
(which default to the parent Query tag if unspecified right now).
Unfortuantely,
once you make query a definition, someone is going to want to put them
in
separate, included jsps, so then we have to talk about what context
the
definition is for, etc.
As you said, allowing <loop> tags inside of <query> tags makes <query>
tags less reusable, especially if queries are cached
to be used in different pages or scopes. <loop>s make sense outside of
a <query> and simplify the application model; I vote
for keeping the tags separate, and in general, keeping tags as context
neutral as possible.
A quick btw -- if someone can 'splain to me how this kind of tag:
<setPageData> <myCustomTag/> </setPageData>
can capture its body, I'd sure appreciate it. Maybe it's just the
engine I'm
using, but I'm not clear as to how that's accomplished. It seems like
all I
have is a writer. I can probably get the contents out of it, but how
do I
prevent the output from ending up on the page?
You have a BodyJspWriter which allows you to get its contents, assign it
a variable, and clear() it during
<setPageData>.doAfterBody(). This all happes before the BodyJspWriter
is flush()'d to the page in doEndTag().
Oh, and while we're on the subject of <setPageData>, I vote for
<setData scope="page"> instead.
Agreed, and I vote for making scope default to "page" since that is the
most common type of variable.
Anyway, back to queries. There are possible ambiguities as to where
the
RowSet gets executed. One might execute on loop entry, but if you
wanted a
table of ten rows, a break, and then ten more rows, etc., one wouldn't
want
the query executed on every loop entry! Similarly, if one wanted the
query
to start at a specific row, one would need the query to be executed
before
you call absolute() on the RowSet.
<loop startRow="specific row" maxRows="10"> would solve the problem. If
startRow and maxRows are variables, then
"Show next 10 Records" functionality can be implemented using session
variables or URL rewriting which redirects to the
same JSP page. startRow and maxRows attributes looks useful, I vote for
them.
Additionally, sql construction is a slightly more sophisticated
proposition
than outlined here. In particular, search pages would call jsps that
would
require complex where clauses to be build. One would prefer to have
something
like:
<command>select * from emp where :whereClause and
deptid=:parent</command>
<param name="whereClause" value="<%= getWhereClause()>"/>
<param name="parent" value="<%= request.getParameter("deptid")"/>
but all we manage to do is add additional ambiguities! The
whereClause
parameter
must be replaced before the command is set on the query, otherwise the
sql is
not standard/parsable. The parent parameter should be set after
command is set,
otherwise the sql isn't reusable/cached-on-server across departments.
And, of course, that's the easy part. People are going to want to
extend these
tags and allow for, say, VCR-like navigation across record sets.
They'll want a
version of loop whose doEndTag() is overridden to output the
first/prev/next/last
buttons, or they might choose to automatically have the loop tag
generate into
a javascript array with the necessary support logic to allow
navigation of the
results purely on the client. Then there's the external-to-app-server
client
who is building n-tiers and uses jsp to deliver an xml stream of the
ResultSet.
But let's not over-complicate matters :)
Agreed that SQL is complicated, perhaps too complicated to encapsulate
in a standard tag. However, <query> SQL
statements here that are unparsable to JSP, but parsable by the backend
database </query> would be a useful standard tag
to have as a starting point anyway.
--
Michael Hu, Paradox Team, Corel Corporation
===========================================================================
To unsubscribe: mailto [EMAIL PROTECTED] with body: "signoff JSP-INTEREST".
FAQs on JSP can be found at:
http://java.sun.com/products/jsp/faq.html
http://www.esperanto.org.nz/jsp/jspfaq.html