<title>Connection Tag</title>

<note>This example requires the Resin 1.3 snapshot</note>

<p/>The connection tag provides a robust way for a JSP page to get a
database connection without getting tangled up in the APIs to make
that work.

<p/>The JSP 1.2 TryCatchFinally interface lets tag library designers create
more robust libraries.  For example, database connections must always
be closed, even when exceptions occur.  The TryCatchFinally interface
lets a ConnectionTag automatically close the connection when the tag
completes.

<p/>The connection tag example creates a JSP tag to look up a database
data source in the environment using JNDI.  From that data source, it
creates a new connection and makes it available to the page.  When the
connection tag completes, it automatically closes the connection.

<section title="Using the connection tag">

<example title="houses.jsp">
<example>
&lt;%@ page import="java.sql.*" %>
&lt;%@ taglib prefix="ct" uri="/WEB-INF/conn.tld" %>
&lt;h1>House Scores&lt;/h1>

&lt;ct:connection name="jdbc/hogwarts">
&lt;%
Statement stmt = conn.createStatement();
ResultSet rs;
rs = stmt.executeQuery("select NAME, POINTS from HOUSES");

while (rs.next()) {
  %>&lt;%= rs.getString(1) %> &lt;%= rs.getInt(2) %>&lt;br>&lt;%
}
rs.close();
stmt.close();
%>
&lt;/ct:connection>
</example>
<results>
&lt;h1>House Scores:&lt;/h1>

griffindor 482&lt;br>
ravenclaw 426&lt;br>
hufflepuff 352&lt;br>
slytherin 472&lt;br>
</results>
</example>

<subsection title="&lt;%@ taglib prefix=&quot;ct&quot; ... %&gt;">

The taglib declaration configures <var/ct/> as a tag prefix.  Following tags
with the prefix <var/ct/>, like <var/ct:connection/> map to JSP tag
implementations, in this case to instances of ConnectionTag.

<p/>The taglib uri, <var/WEB-INF/conn.tld/>, specifies the tag library
descriptor file.  The tld tells Resin maps tag names to tag classes and
specifies tag attributes.

</subsection>

<subsection title="&lt;ct:connection name=&quot;jdbc/hogwarts&quot;&gt;">

<ul>
<li>Looks up the DataSource in JNDI.
<li>Creates a new Connection
<li>Creates a variable, <var/conn/>, holding the connection.
<li>Automatically closes the connection at tag close.
</ul>

</subsection>

<subsection title="&lt;/ct:connection&gt;">

When the ct:connection tag closes, the tag closes the connection.  By using
the TryCatchFinally interface, the tag can guarantee it will close the connection with an exception.

</subsection>

</section>

<section title="Implementation of the Connection Tag">

<example title="ConnectionTag.java">
package test;

import java.io.*;
import java.sql.*;

import javax.servlet.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

import javax.naming.*;
import javax.sql.*;

public class ConnectionTag extends TagSupport implements TryCatchFinally {
  private Connection conn;

  // JNDI name of the connection
  private String name;

  public void setName(String name)
  {
    this.name = name;
  }

  public int doStartTag()
    throws ServletException
  {
    try {
      Context env = (Context) new InitialContext().lookup("java:comp/env");

      DataSource ds = (DataSource) env.lookup(name);

      if (ds != null)
        conn = ds.getConnection();
    } catch (Exception e) {
      throw new ServletException(e);
    }

    if (conn == null)
      throw new ServletException("can't open connection " + name);

    pageContext.setAttribute("conn", conn);
    
    return EVAL_BODY_INCLUDE;
  }
  
  public void doCatch(Throwable t)
    throws Throwable
  {
    throw t;
  }

  public void doFinally()
  {
    try {
      Connection conn = this.conn;
      this.conn = null;
      pageContext.removeAttribute("conn");

      conn.close();
    } catch (Exception e) {
    }
  }
}
</example>

<subsection title="implements TryCatchFinally">

The new TryCatchFinally interface of JSP 1.2 lets tags handle exceptions
gracefully.  The ConnectionTag uses the doFinally() method of TryCatchFinally
close the connection even when an exception occurs.

</subsection>

<subsection title="setName(name)">

Attributes in JSP tags use Bean methods to set values.  When Resin evaluates
the ct:connection tag, it will call setName with the <var/name/> value.  In
this example, it will call <var/setName("jdbc/hogwarts")/>.

<p/>The database name, jdbc/hogwarts, matches its configuration in the
resin.conf or web.xml as described in the <a href='db-config.xtp'>database
config</a>
page.

</subsection>

<subsection title="doStartTag()">

Resin calls ConnectionTag's doStartTag method after setting the attributes.
Typically a passthrough tag like ConnectionTag will return 
<var/EVAL_BODY_INCLUDE/> so JSP will interpret the contents as
normal JSP.

</subsection>

<subsection title="new InitialContext()">

The database is stored using JNDI, the Java Naming and Directory Interface.
Don't worry; there's no need to learn a whole new API.  The lookup() method
used in this example is sufficient for 90% of projects.

<p/>JNDI provides a global singleton, InitialContext, and namespace, letting
applications grab configuration information from any class.  JNDI is nice
since you don't need to pass around a configuration variable.  You can just
use InitialContext where you need it.

<p/>In the example, the database source is stored in
java:comp/env/jdbc/hogwarts.  The <a href='db_form.xtp'>database form</a>
example uses the same JNDI pattern to grab its database.

</subsection>

<subsection title="ds.getConnection()">

With Java's database interface, JDBC, applications grab connections from
a data source.  With Resin, the data source automatically pools database
connections.

</subsection>

<subsection title="pageContext.setAttribute">

<var/ct:connection/> creates a new Java variable, <var/conn/>.  ConnectionTag
passes the connection to the JSP page by setting the conn attribute in the
pageContext.  pageContext is a protected variable inherited from the
TagSupport class and set by the JSP page before calling any other methods.

</subsection>

<subsection title="doFinally()">

Applications must always close connection objects.  Failing to close the
connection will give the connection pool fits.  By using the
TryCatchFinally interface and implementing doFinally(), ConnectionTag can
make sure the connection is always closed even when exceptions happen.

</subsection>

</section>

<section title="Declaring Variables">

Because the ct:connection tag creates new variables in the JSP page, the
tag library needs to create a tag info class to declare the variables.

<p/>The tag info class returns an array of all the variables.  This example
has a single variable, conn, which has the type java.sql.Connection.  The
variable is only valid inside the tag, so its scope is VariableInfo.NESTED.

<example title="Tag Info">
package test;

import javax.servlet.jsp.tagext.*;

public class ConnectionTagInfo extends TagExtraInfo  {
  public VariableInfo []getVariableInfo(TagData data)
  {
    VariableInfo []info = new VariableInfo[1];
    info[0] = new VariableInfo("conn", "java.sql.Connection",
                               true, VariableInfo.NESTED);

    return info;
  }
}
</example>

</section>

<section title="Taglib Configuration">

<p/>The tag library descriptor (tld) associates the tag name, connection, with
the tag class test.ConnectionTag and the tag info class
test.ConnectionTagInfo.

<p/>The tag has a single attribute, name, which is required.

<example title="WEB-INF/conn.tld">
&lt;taglib>
  &lt;tag>
    &lt;name>connection&lt;/name>
    &lt;tagclass>test.ConnectionTag&lt;/tagclass>
    &lt;teiclass>test.ConnectionTagInfo&lt;/teiclass>
    &lt;attribute>
      &lt;name>name&lt;/name>
      &lt;required>true&lt;/required>
    &lt;/attribute>
  &lt;/tag>
&lt;/taglib>
</example>

</section>

<section title="Database Configuration">

<p/>The <a href="db-config.xtp">database configuration</a> example more
fully describes the database configuration.

<example title='resin.conf'>
&lt;caucho.com&gt;

&lt;resource-ref>
  &lt;res-ref-name>jdbc/hogwarts&lt;/res-ref-name>
  &lt;res-type>javax.sql.DataSource&lt;/res-type>
  &lt;init-param driver-name="org.gjt.mm.mysql.Driver"/>
  &lt;init-param url="jdbc:mysql://localhost:3306/test_hogwarts"/>
  &lt;init-param user="ferg"/>
  &lt;init-param password="changeit"/>
&lt;/resource-ref>

&lt;http-server>
  ...
&lt;/http-server>

&lt;/caucho.com&gt;
</example>

<subsection title='resource-ref'>

A resource-ref describes a factory resource.  When Resin initializes, it will
create the factory and store it in the JNDI context.

</subsection>

<subsection title='res-ref-name'>

res-ref-name gives the JNDI name.  The value of res-ref-name is appended to
java:comp/env.  So this example will produce the full JNDI name of
java:comp/env/jdbc/hogwarts.

</subsection>

<subsection title='res-type'>

res-type describes the type of the resource.  This example is a JDBC data
source, so it uses the name javax.sql.DataSource.  An applications could
replace res-type with an arbitrary bean names; Resin would instantiate,
initialize and bind the bean to the JNDI context.

</subsection>

<subsection title='init-param'>

init-param uses Bean introspection to initialize the new resource.  The
parameter name is converted to a method name.  For example, driver-name maps
to setDriverName and url maps to setURL.  After creating the new resource,
Resin will call all the initializers to configure it.


</subsection>

</section>
