<head>
<title>Resin 1.2 beta</title>
<meta name='robots' content='foo'/>
</head>

This is a general summary of beta changes.  Any or all of these may change
at any time.  You have been warned.

<section title='resin.conf reload'>

The plugins for Apache and IIS now detect changes in the resin.conf
automatically.  So you don't need to restart Apache or IIS each time
you change a servlet mapping.

</section>

<section title='system-property'>

System properties may now be set in resin.conf:

<example>
&lt;caucho.com>
  &lt;system-property foo='bar'/>
  ...
</example>

</section>

<section title='security-provider'>

Security provides can now be added in resin.conf:

<example>
&lt;caucho.com>
  &lt;security-provider id='com.sun.net.ssl.internal.ssl.Provider'/>
  ...
</example>

</section>

<section title='SSL'>

SSL is now available with JSSE.  You'll need to download JSSE from
java.sun.com.

<p/>To enable SSL, you'll just add some attributes to http.
<var/key-store-file/> is the name of the server certificate you want to use.
<var/key-store-password/> is its password.

<example>
&lt;caucho.com>
&lt;security-provider id='com.sun.net.ssl.internal.ssl.Provider'/>

&lt;http-server>
  &lt;http port='8443'>
    &lt;ssl>true&lt;/ssl>
    &lt;key-store-type>pkcs12&lt;/key-store-type>
    &lt;key-store-file>keys/test.p12&lt;/key-store-file>
    &lt;key-store-password>changeit&lt;/key-store-password>
  &lt;/http>
  ...
&lt;/http-server>
</example>

</section>

<section title='Persistent Sessions'>

Sessions are now persistent across server restarts, including
application restarts when classes change.  This is very convenient when
working with sections needing use login.

<subsection title='File Based'>

<p/>Persistent sessions are configured in the <var/web-app/>.
File-based sessions use <var/file-store/>

<example>
&lt;web-app>
  &lt;session-config>
    &lt;file-store>sessions&lt;/file-store>
  &lt;/session-config>
&lt;/web-app>
</example>

<p/>Sessions are stored as files in the <var/file-store/>
directory.  When the session changes, the updates will be written to
the file.  After Resin loads an Application, it will load the stored
sessions.

</subsection>
<subsection title='Database Based'>

<p/>Sessions can also be stored in a database.  The database must be
specified using one of Resin's DBPool.  The database store will automatically
create a <var/session/> table.

<example>
&lt;web-app>
  &lt;session-config>
    &lt;jdbc-store>test&lt;/jdbc-store>
  &lt;/session-config>
&lt;/web-app>
</example>

<deftable>
<tr><td>data-source<td>data source name for the table
<tr><td>table-name<td>database table for the session data
<tr><td>blob-type<td>database type for a blob
<tr><td>timestamp-type<td>database type for a blob
<tr><td>session-timeout<td>cleanup time
</deftable>

<example>
CREATE TABLE session (
  id VARCHAR(64) NOT NULL,
  data BLOB,
  mod_time TIMESTAMP,
  PRIMARY KEY(id)
)
</example>
</subsection>

<subsection title='always-load-session'>

The <var/always-load-session/> attribute forces sessions to check the store for
each request.  By default, sessions are only loaded from persistent
store when they are created.  In a configuration with multiple symmetric
web servers, sessions can be loaded on each request to ensure consistency.

</subsection>
</section>

<section title='Distributed Sessions'>

A simple implementation of distributed sessions is now available.

<p/>The configuration is in the <var/web-app/>

<example>
&lt;web-app>
  &lt;session-config>
    &lt;distributed-ring/>
  &lt;/session-config>
&lt;/web-app>
</example>

<p/>The &lt;srun> and &lt;srun-backup> hosts are treated as a ring.  Each
host will use the following host as a backup.  When the session changes,
the updates will be sent to the following host.  When the host starts, it
looks up old sessions in the following host before using its own saved
state.

<p/>In conjunction with the <var/reload/> flag, symmetric (non-sticky)
load-balanced servers can now use the distributed-ring.

</section>

<section title='JNDI'>

InitialContext is now available and configures the java:comp
as with EJB or the servlet spec.  The DBPool can now be configured as a
DataSource.

<example>
&lt;resource-ref res-ref-name='jdbc/bar' res-type='javax.sql.DataSource'>
  &lt;init-param driverName="org.gjt.mm.mysql.Driver"/>
  &lt;init-param URL="jdbc:mysql://localhost:3306/test"/>
  &lt;init-param user=""/>
  &lt;init-param password=""/>
  &lt;init-param pingTable="TEST"/>
  &lt;init-param pingOnReuse="true"/>
  &lt;init-param foo="bar"/>
&lt;/resource-ref>

</example>

Parameters are assigned using beans, so any 'setXXX' method can be
automatically set.

<p/>Also, any property not matching a 'setXXX' method will call
'setProperty', as in the foo='bar' example.  In other words, you
can set arbitrary JDBC properties.

<p/>Also, you can configure any bean using the full bean class
as the res-type.

<subsection title='servlet/Application'>

The Application (ServletContext) is available in JNDI as
java:comp/servlet/Application.

</subsection>

<subsection title='global'>

Most of the time, JNDI configuration will be per web-app.  However, in
many cases, like a DB pool, it may be useful to share JNDI configuration
across the whole web server.  Just put the same env-entry and resource-ref
inside the &lt;caucho.com>

<example>
&lt;caucho.com>
&lt;resource-ref res-ref-name='jdbc/bar' res-type='javax.sql.DataSource'>
  &lt;init-param driverName="org.gjt.mm.mysql.Driver"/>
  &lt;init-param URL="jdbc:mysql://localhost:3306/test"/>
  &lt;init-param user=""/>
  &lt;init-param password=""/>
  &lt;init-param pingTable="TEST"/>
  &lt;init-param pingOnReuse="true"/>
  &lt;init-param foo="bar"/>
&lt;/resource-ref>

&lt;http-server>
&lt;/http-server>
  
&lt;/caucho.com>
</example>

To use the data source, you'll use JNDI:

<example>
&lt;%@ page import='javax.sql.*, java.sql.*, java.naming.*'>
&lt;%
InitialContext ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup("java:comp/jdbc/bar");
Connection conn = ds.getConnection();
try {
  ...
} finally {
  if (conn != null) conn.close();
}
%>
...
</example>

</subsection>

<subsection title='ejb'>

EJB clients are created using a ClientFactory (com.caucho.ejb.ClientFactory).
A RmiClientFactory is already available.  Just like the JDBC
configuration, you can set factory properties as a bean before
the object create is called.

<p/>Other, non-RMI, client factories for various EJB servers should be easy
to make.

<example>
&lt;caucho.com>
&lt;http-server>

&lt;ejb-ref ejb-ref-name='ejb/test'
            ejb-ref-factory='com.caucho.ejb.RmiClientFactory'>
  &lt;init-param url="//localhost/rmiTest"/>
&lt;/ejb-ref>

&lt;/http-server>
&lt;/caucho.com>
</example>

<p/>The ejb-ref is not restricted to EJB.  You could use the RmiClientFactory
to obtain a reference to any RemoteObject.  Other factories can create
any object they wish.

</subsection>

<subsection title='linking to other jndi'>

You can link a portion of the JNDI tree to another JNDI.  For example, you
might have an external EJB client that expects its own JNDI space:

<example>
&lt;web-app id='/'>
  &lt;jndi-link>
    &lt;jndi-name>java:comp/env/ejb/traderHome&lt;/jndi-name>
    &lt;jndi-factory>weblogic.jndi.WLInitialContextFactory&lt;/jndi-factory>
    &lt;init-param java.naming.provider.url="t3://localhost:7001"/>
    &lt;jndi-lookup>statelessSession.TraderHome&lt;/jndi-lookup>
  &lt;/jndi-link>
&lt;/web-app>
</example>

In your servlet or JSP, you can then use:

<example>
&lt;%@ page import='javax.naming.*' %>
&lt;%@ page import='javax.rmi.*' %>
&lt;%@ page import='examples.ejb.basic.statelessSession.*' %>
&lt;%

Context context = new InitialContext();

Object homeObj = context.lookup("java:comp/env/ejb/traderHome");
TraderHome home;
home = (TraderHome) PortableRemoteObject.narrow(homeObj, TraderHome.class);

%>
</example>

</subsection>

</section>

<section title='UserTransaction'>

UserTransaction is now supported in the DBPool driver.  The UserTransaction
variable is in JNDI as java:comp/env/UserTransaction

<example>
UserTransaction trans;
trans = (UserTransaction) ic.lookup("java:comp/UserTransaction");
trans.begin();

Connection conn = dataSource.getConnection();

...

trans.commit();

conn.close();
</example>

</section>

<section title='DBPool'>

The DBPool can now 'ping' the server to see if the connection is
still alive.  setPingTable(), setPingOnReuse(), and setPingOnFree(),
determine when the connection is checked.

</section>

<section title='multipart/form-data; file upload'>

getParameter now handles multipart/form-data, just like normal forms.

<p/>Assuming browsers properly set the Content-Type charset, Resin will
read the form using the proper i18n encoding.

<p/>For file uploads, getParameter returns the filename where Resin has
stored the uploaded file.  You must retrieve the file by the end of the
request before Resin automatically deletes it.

</section>

<section title='User Tracking'>

The <a href='ref/http-config.xtp#access-log'>access log</a> can now
track cookies:

<example>
&lt;access-log id='log/cookie.log' 
        format='%h %l %u %t "%r" %s %b "%{Referer}i" "%{JSESSIONID}c"'/>
</example>

</section>

<section title='XSL'>

<subsection title='API changes'>

The XSL API has changed to make it more compatible with future XSL
standards.  You can now transform directly to a stream as well as
transforming into a DOM node.  See the
<a href="javadoc/com/caucho/transform/package-summary.html">com.caucho.transform</a> package for
more details.

<example>
StylesheetFactory factory = new Xsl();
Stylesheet stylesheet = factory.newStylesheet("test.xsl");

StreamTransformer transformer = stylesheet.newStreamTransformer();
WriteStream os = Vfs.openWrite("test.html");

transformer.transform("test.xml", os);
os.close();

</example>

</subsection>
<subsection title='StyleScript'>

<p/>"XSL-lite" has been renamed "StyleScript" (possibly to become
XStyleScript).  To parse as StyleScript use <a href="javadoc/com/caucho/xsl/StyleScript.html">com.caucho.xsl.StyleScript</a> as the stylesheet factory.

<p/>StyleScript has been enhanced to support a scripting syntax:

<example>
$template(chapter) &lt;&lt;
  $if(@title = 3) &lt;&lt;
    Chapter 3: $apply-templates();
  >>
  $else &lt;&lt;
    Other Chapter: $apply-templates();
  >>
>>
</example>

<p/>For all the xsl:foo elements, $foo(a=>b) &lt;&lt; ... >> expands into

<example>
  &lt;xsl:foo a="b">
    ...
  &lt;/xsl:foo>
</example>
</subsection>

</section>
