RIFE v0.7.1 has been released.

Below are the highlights of this release.

You can also read the full changelog for more details.

Purging authentication is now the default approach

The shipped authentication elements used a naming scheme that made the automated purging of outdated authentication sessions available through a specialized name. We noticed that people therefore never really looked further and used unpurged authentication schemes without realizing that purging has to be setup independently in that case. The element declarations have thus been renamed like this:

rife/authenticated/database.xml
becomes=>
rife/authenticated/databaseunpurged.xml
rife/authenticated/memory.xml
becomes=>
rife/authenticated/memoryunpurged.xml
rife/authenticated/mixed.xml
becomes=>
rife/authenticated/mixedunpurged.xml
rife/authenticated/databasepurging.xml
becomes=>
rife/authenticated/database.xml
rife/authenticated/memorypurging.xml
becomes=>
rife/authenticated/memory.xml
rife/authenticated/mixedpurging.xml
becomes=>
rife/authenticated/mixed.xml

People that have been consciously using unpurged authentication have to change the names of the element declarations; and those that did it without knowing should do nothing. They will be using purging back-ends from now on without having to change anything.

[ top ]

Major and incompatible changes to 'call' continuations

Continuations that used the call(String exitname) method invocation to execute another element could optionally use the answer(Object value) method invocation to return a value to the caller. Control was automatically returned to the caller when the called element finished processing (a bit like a default return statement at the end of a method).

Initially this seemed like a good idea, but in practise it means that existing elements all have to be rewritten to explicitly keep a continuation going by using pause and call all over the place. This was necessary to prevent that the execution of any element in the flow finishes the processElement method and thus resumes the initial continuation.

The automatic answer at the end of processElement has now been removed and to resume a prior continuation, one has to always use an answer call. This thus means that all 'call' continuations that relied on the automatic answer, should insert answer() calls at the end of their processElement method.

For clarity, the simplest possible call continuation looks like this now:

public class Caller extends Element
{
    public void processElement()
    {
        call("exit_to_callee");
    }
}
public class Callee extends Element
{
    public void processElement()
    {
        answer();
    }
}

[ top ]

Support for URL localization

Localizing content with RIFE is already very versatile, but it's not sufficient to create fully translated versions of applications. URLs are an important part of your web application and make it possible for people to remember and access distinct locations directly. The site structure has thus been extended to allow the usage of different URLs according to the default localization language.

The default localization language is 'en' if it hasn't been defined by the user. You can modify it by providing a value for the L10N_DEFAULT_LANGUAGE configuration parameter.

Instead of regular URLs, you can now use the following definition in your site structure, for example:

<element id="ROOT" file="root.xml" url="fr:/racine,nl:/wortel,/root"/>

This will result in the following behaviour:

[ top ]

Template type-specific default resource bundles

When localizing an application, it's common practice to use a few resourcebundles that are shared by the whole application. Since it's tedious to have to explicitely add them to all the templates that are instantiated, and since sometimes templates are automatically instantiated by reusable elements, it's handy to be able to setup a collection of default resource bundles.

You set this up in your configuration file and it's specific for each template factory type. The latter is important since it makes no sense to add content resource bundles to all SQL templates or Java templates.

For example:

<list name="TEMPLATE_DEFAULT_RESOURCEBUNDLES_ENGINEHTML">
    <item>l10n/graphics</item>
    <item>l10n/text</item>
</list>

will result in executing the following Java code after the instantiation of each enginehtml (the standard type) template:

template.addResourceBundle(Localization.getResourceBundle("l10n/graphics"));
template.addResourceBundle(Localization.getResourceBundle("l10n/text"));

[ top ]

Alternate localization method

While resource bundles offer a good method to isolate localized text snippets, it's sometimes interesting to be able to conditionally display parts of templates with lots of markup. For this purpose, resource bundles are actually awkward to use. Templates are therefore now able to set blocks automatically to values, according to the default localization language (L10N_DEFAULT_LANGUAGE configuration parameter). This can be done with the <!--B 'LANG:id:language'--> block syntax.

For example:

<!--V 'LANG:value1'-->default<!--/V--> [!V 'LANG:value2'/]
<!--B 'LANG:value1:nl'-->ja ja<!--/B-->
[!B 'LANG:value2:fr']oui oui[!/B]
[!B 'LANG:value2:en ']yes yes[!/B]

will display this when the default language is 'en'

default yes yes

or this when the default language is 'fr'

default oui oui

or this when the default language is 'nl'

ja ja [!V 'LANG:value2'/]

[ top ]

Deferred validation initialization

Before, it was recommended to initialize the static bean validation rules and constraints in the default constructor of the bean so that they were always available when needed. With large collections of beans with a complex validation rules setup, this however creates quite a performance and memory overhead. Therefore, you can now optionally move all your validation initialization logic to the dedicated activateValidation() method. This method will only be called the first time any validation-related method is called on a particular bean instance and thus not at every instantiation of the bean.

It's thus recommended to transform this:

public class Credentials extends Validation
{
    private String mLogin = null;
    private String mPassword = null;
    private String mLanguage = null;
    
    public Credentials()
    {
        addConstraint(new ConstrainedProperty("login").maxLength(6).notNull(true));
        addConstraint(new ConstrainedProperty("password").maxLength(8).notNull(true));
        addConstraint(new ConstrainedProperty("language").notNull(true));
    }

    /* ... accessors ... */
}

into this:

public class Credentials extends Validation
{
    private String mLogin = null;
    private String mPassword = null;
    private String mLanguage = null;
    
    public Credentials()
    {
    }

    protected void activateValidation()
    {
        addConstraint(new ConstrainedProperty("login").maxLength(6).notNull(true));
        addConstraint(new ConstrainedProperty("password").maxLength(8).notNull(true));
        addConstraint(new ConstrainedProperty("language").notNull(true));
    }

    /* ... accessors ... */
}

[ top ]

Support for more constraints

Two new constraints have been added to the constraints facility:

displayedRaw

This indicates that the value of the property should be displayed as-is when it's being output. No encoding or transformation will be performed.

A typical use of this is when you allow administrators to write HTML snippets, you don't want the actual HTML tags to be encoded and the source code to be displayed. Instead, you want to output the submitted data exactly as it was entered so that all HTML formatting does its usual work.

By default, this is set to false.

editable

This indicates that the value of the property can't be changed or edited by a user.

A typical use of this is when you have a bean with a number of properties that should be filled in directly through a form, but with some other properties that are not allowed to be modified by the user (id, modification date, ...). If you use submission beans or input beans, you only want the application to accept values for the properties that can be edited and not for the others. Like this, you're sure that no malicious or accidental outside data modification can occur.

By default, this is set to true.

[ top ]

Embedded element definitions can now provide values

When embedding elements in templates, you can now access the default value from within the embedded elements. This is handy when you have modular embedded elements that have to be setup for different uses when they are inserted in the templates.

For example, consider this template snippet:

The element "<!--V 'ELEMENT:.SIMPLE'-->this is the value<!--/V-->" is being embedded.

Inside the SIMPLE element's implementation, you can now use the getEmbedValue() method, which will in this case return:

this is the value

[ top ]

Reworked database transactions

The DbQueryManager now has a new inTransaction(DbTransactionUser) method. It ensures that all the instructions in the provided DbTransactionUser instance are executed inside a transaction and committed afterwards. This doesn't mean that a new transaction will always be created. If a transaction is already active, it will simply be re-used. The commit will also only take place if a new transaction has actually been started by the active inTransaction invocation, otherwise it's the responsibility of the enclosing code to execute the commit. If a runtime exception occurs during the execution and a new transaction has been started beforehand, it will be automatically rolled back.

If you need to explicitly roll back an active transaction, use the rollback method of the DbTransactionUser class. If you use a regular rollback method, it's possible that you're inside a nested transaction and that after the rollback other logic continues to be executed outside the transaction. Using the correct rollback method, stops the execution of the active DbTransactionUser and breaks out of any number of them nesting.

Since you sometimes use a transaction without being interested in returning a result, you can use the DbTransactionUserWithoutResult class which doesn't require you to write a meaningless 'return null;' statement at the end of the implemented method.

It's recommended to always use transactions through the inTransaction method since it ensures that transactional code can be re-used and enclosed in other transactional code. Correctly using the regular transaction-related methods requires great care and planning and often results in error-prone and not reusable code.

For example:

final Insert insert = new Insert(mDatasource).into("valuelist").field("value", 232);
final DbQueryManager manager = new DbQueryManager(datasource);
manager.inTransaction(new DbTransactionUserWithoutResult() {
        public void useTransactionWithoutResult()
        throws InnerClassException
        {
            manager.executeUpdate(insert);
            manager.executeUpdate(insert);
        }
    });
 

You can throw regular exceptions inside the transaction with the DbTransactionUser's throwException(Throwable) method. The transaction will be rolled back if the active inTransaction method started a new transaction. An instance of InnerClassException will be thrown and can be caught outside the inTransaction method. The original exception you wanted to throw is then available through the InnerClassException's getCause() method.

[ top ]

Alternate site structure and element declaration methods

Element declarations and site structures have up to now always been defined in one fixed XML format. A first step has been made to enable the transparent integration of other declaration methods. Each declaration method is identified through a unique identifier which allows you to mix them freely. This identifier can be added in front of the declaration name of the element or site (the file attribute in the XML format). If no identifier is added, it defaults to the 'corexml' declaration method which is what you've always been using. RIFE currently ships with one others declaration method: 'manual'. This essentially means that the rest of the declaration is up to you and that the declaration name will not be automatically processed (with corexml, the declaration name is parsed as an XML document that builds the structure). We'll provide some documentation later about how to define your own identifiers and we're in the process of implementing other structure builders for various purposes.

Here is a small example of how to declare an entire site structure with all the elements in Java only. You'll see this is the same as what's done by the 4 XML files in the basic numberguess example.

/*
 * file: src/tutorial/numberguess/Site.java
 */
package tutorial.numberguess;

import com.uwyn.rife.engine.SiteBuilder;
import com.uwyn.rife.rep.BlockingParticipant;

public class Site extends BlockingParticipant
{
    private Object    mSite = null;

    protected void initialize()
    {
        SiteBuilder    builder = new SiteBuilder("manual:numberguess", getResourceFinder());
        builder
            .setArrival("START")
            
            .enterElement("manual:START")
                .setImplementation("tutorial.numberguess.Start")
                .setUrl("/start")
            
                .addInput("gameid")
                .addExit("started")
                .addOutput("gameid")
            
                .addFlowLink("started", "GUESS")
                .addDataLink("gameid", "GUESS", "gameid")
            .leaveElement()
            
            .enterElement("manual:GUESS")
                .setImplementation("tutorial.numberguess.Guess")
                .setUrl("/guess")
            
                .addInput("gameid")
                .enterSubmission("perform_guess")
                    .addParameter("guess")
                .leaveSubmission()
                .addExit("start")
                .addExit("success")
                .addOutput("gameid")

                .addFlowLink("start", "START")
                .addDataLink("gameid", "START", "gameid")

                .addFlowLink("success", "SUCCESS")
                .addDataLink("gameid", "SUCCESS", "gameid")
            .leaveElement()
            
            .enterElement("manual:SUCCESS")
                .setImplementation("tutorial.numberguess.Success")
            
                .addInput("gameid")
                .addExit("start")

                .addFlowLink("start", "GUESS")
            .leaveElement();
        
        mSite = builder.getSite();
    }
    
    protected Object _getObject(Object key)
    {
        return mSite;
    }
}
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
  - file: classes/rep/participants.xml
  -->

<!DOCTYPE rep SYSTEM "/dtd/rep.dtd">

<rep>
    <participant name="ParticipantSite">tutorial.numberguess.Site</participant>
</rep>

[ top ]

Major speed optimizations

Several areas of the framework have been profiled and reworked to get much better speed. Most notably, many standard collections that store primitives have been replaced by their primitive counterparts of PCJ (Primitive Collections for Java) and the StringUtils.encode* methods have been rewritten to get a 5x better encoding speed (which should affect almost all web applications).

[ top ]

Full changelog

2004-04-21  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * RELEASE 0.7.1
  
2004-04-20 Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Examples updates.

2004-04-19 Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Javadocs fixes.

2004-04-16 Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added support for parametrizable limit and offset clauses in Select query
  builder.

2004-04-15  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * GQM api additions.
  
  * BBcode fixes.
  
2004-04-13  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added inList constraint support for float and double.
  
  * Added redirect element.
  
  * Added support for using the print template element with properties instead
  of init params.
  
2004-04-13  JR Boyens  <gnu-jrb[remove] at gmx dot net>

  * Added restoreFirst(RestoreQuery) to the GQM
  
  * Updated Hessian support
  
2004-04-08  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added support for defensive html encoding.
  
2004-04-01  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Made purging authentication the default authentication method.
  
  * Made BBCode URL conversion a bit more intelligent.
  
  * Authentication additions and refactoring.
  
  * Added listSessions to SessionManager.
  
2004-03-31  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Fix to correctly support relative element ids in site definitions.

2004-03-27  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added support for URL localization.
  
2004-03-25  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added possibility to evaluation l10n and config tags explicitely.
  
  * Renamed evaluateOgnl to evaluateOgnlTags.
  
2004-03-24  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added template factory specific default resource bundles.
  
2004-03-22  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * NPE bug.

2004-03-19  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * GQM cache bugfix.
  
2004-03-16  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added getEmbedValue() ElementSupport method.
  
  * Added displayedRaw(boolean) constraint.
  
2004-03-15  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added support for cascading validation groups.

2004-03-13  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Changed roleusers manager retriever API.
  
2004-03-12  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added support for form field attribute setting through :ATTRIBUTES blocks.
  
2004-03-10  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Embedded element triggerlist bugfix.
  
  * Added reinitializeProperties to ValidationGroup.
  
2004-03-07  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Reworked transactions and added new recommended way of ensuring that code
  is executed in a transaction.
  
  * Database connection pool finalization fixes.
  
  * Updated buildfile for cgjavac which should be present in PATH to be
  picked up.
  
2004-03-06  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Element injection support and arrival id regression bugfix.
  
  * Introspection fixes for global exits.
  
  * Made ConstrainedProperty constraints integration more flexible in
  Validation.
  
  * Xml parsing tools flexibility improvements.
  
  * Added support for default content type specification.
  
  * Added support for file upload size exceeding detection.
  
  * Multipartrequest fixes.

2004-03-05  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added WaitingImageObserver.
  
  * Making sure that answer without a call functions as a regular return.
  
  * Continuation call fixes.
  
2004-03-04  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Various useful little additions.
  
  * Made identifier value retrieval public in GQM.
  
  * Made call continuation answer calls mandatory to resume to original
  continuation.

2004-03-02  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Optimized String encoding speed, amongst others html encoding.

2004-03-01  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Integrated and generified PCJ for speed improvements.
  
  * Added a concise log formatter.
  
  * Added support for template dependencies retrieval.

2004-02-29  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added Element and Sql debug tracing.
  
  * Added template cache map and integrated it with OGNL expression parsing
  caching.

2004-02-28  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added support for editable constraints.
  
  * GQM fixes.

2004-02-27  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added activateValidation() method.
  
  * Template content transformation bugfix.
  
  * Added convenience sitebuilder methods.

  * Added support for inspectable global exits.
  
  * Site structure introspection fixes.
  
  * Rep fixes.
  
  * Some site builder API convenience additions.
  
  * Added check to ensure that call() verifies that a flowlink is attached to
  the exit.

2004-02-26  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Some template engine changes to make it easy to construct a new template
  factory from an existing one.
  
  * Small fixes and changes to form building, engine and templates.

2004-02-25  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added support for SiteBuilder which allows alternative methods for site
  structure declaration, with immediate support for a java-only api.
  
  * manyToOne constraint fixes.

2004-02-23  JR Boyens  <gnu-jrb[remove] at gmx dot net>

  * Added a manyToOne constraint to create foreign keys automatically.
  
2004-02-23  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added field support to RestoreQuery.
  
2004-02-22  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * RELEASE 0.7.0

[ top ]