Navigation

RSS 2.0 New Entries Syndication Feed Atom 0.3 New Entries Syndication Feed

Show blog menu v

 

General

Use it

Documentation

Support

Sibling projects

RIFE powered

Valid XHTML 1.0 Transitional

Valid CSS!

Blogs : Archives

< RIFE at JavaWUG video by Emmanuel Okyere   Are single element annotations a disaster waiting to happen? >
RIFE 1.4 released

Below are the highlights:

You can read the full changelog for more details.

Real POJO support with meta data merging

RIFE now supports an automated method to add meta data to POJO classes without having any additional code nor annotations inside the POJOs themselves.

Consider a class Foo and another class FooMetaData. When FooMetaData implements the MetaDataMerged interface (which is simply a marker), RIFE will instrument Foo and make it implement all the interfaces that FooMetaData implements. Also, when the default constructor of Foo is called, an instance of FooMetaData will be created and stored in a new hidden member variable. The added method implementations simple delegate execution to this instance of FooMetaData. Optionally, FooMetaData can also implement the MetaDataBeanAware interface, in which case the instance of FooMetaData will receive the instance of Foo that it belongs to right after it has been instantiated. Note that the relationship between Foo and FooMetaData is purely name based (the MetaData suffix). RIFE will look up the meta data class through the classpath, which means that it's possible to augment any class, anywhere, in any package, even without having the source code.

Constraints are a typical usage for this feature. Any POJO is now able to have constraints attached to it, without violating the purity of the POJO class implementation itself. For convenience, you can extend the MetaData abstract base class which implements everything you need to easily specify constraints in a meta data class.

For example, the Person class:

public class Person {
    private String firstname;
    private String lastname;
     
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
     
    public String getFirstname() {
        return firstname;
    }
     
    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
     
    public String getLastname() {
        return lastname;
    }
}

and the PersonMetaData class:

public class PersonMetaData extends MetaData {
    public void activateMetaData() {
        addConstraint(new ConstrainedProperty("firstname")
            .maxLength(10)
            .notNull(true));
        addConstraint(new ConstrainedProperty("lastname")
            .inList("Smith", "Jones", "Ronda"));
    }
}

As long as RIFE's classloader is active, both will be automatically merged into a new Person class. You can access the added interface methods simply by casting an instance of Person to the appropriate interface name.

For example:

Person person = new Person();
Validated validated = (Validated)person;
assertFalse(validated.validate());
 
validated.resetValidation();
 
person.setFirstname("John");
person.setLastname("Smith");
assertTrue(validated.validate());

Note that this is also implicitly available to RIFE/Crud, which means that you can easily generated CRUD web interfaces for existing models, without having to add constraints to their original implementation.

[ top ]

New (X)HTML template tag syntaxes

RIFE's traditional template tag syntaxes don't please everyone, therefore two additional variants have been added.

Traditional syntax:

<!--I 'common.blueprint'/--> 
<!--V 'content'/--> 
<!--BV 'content'--> 
    <form action="[!V 'SUBMISSION:FORM:myData'/]" method="post"> 
        <!--V 'SUBMISSION:PARAMS:myData'/--> 
        <input name="name" value="[!V 'PARAM:name'][!/V]" /> 
        <input type="submit" value="That's who I am!" /> 
    </form> 
<!--/BV--> 
<!--B 'welcome'--> 
    <div>Hi <!--V 'PARAM:name'/-->, it's <!--V 'day'/-->!</div>
<!--/B-->

Velocity inspired variant:

These tags should look somewhat familiar to people that are used to Velocity. Sadly they will not become invisible if the template is viewed in a browser:

${i common.blueprint/}
${v content/}
${bv content}
    <form action="${v SUBMISSION:FORM:myData:/}" method="post">
        ${v SUBMISSION:PARAMS:myData/}
        <input name="name" value="${v PARAM:name}${/v}" />
        <input type="submit" value="That's who I am!" />
    </form>
${/bv}
${b welcome}
    <div>Hi ${v PARAM:name/}${v day/}!</div>
${/b}

Regular tags inspired variant:

This version uses custom XHTML tags that look exactly the same as the rest of the layout code and that can easily get validation and auto-completion support in IDEs:

<r:i name="common.blueprint"/>
<r:v name="content"/>
<r:bv name="content">
    <form action="[!V 'SUBMISSION:FORM:myData'/]" method="post"> 
        <r:v name="SUBMISSION:PARAMS:myData"/>
        <input name="name" value="[!V 'PARAM:name'][!/V]" /> 
        <input type="submit" value="That's who I am!" />
    </form>
</r:bv>
<r:b name="welcome">
    <div>Hi <r:v name="PARAM:name"/>, it's <r:v name="day"/>!</div>
</r:b>

To make it convenient to use the regular tag variant, you can download the following support files:

[ top ]

Experimental Ajax support with DWR integration

The DWR team has worked hard to make their project as modular as possible and to abstract it away as much as possible from the Servlet API. While their effort is still in progress and there hasn't been an official DWR release with these features yet, we already integrated a DWR snapshot with RIFE to provide easy Ajax capabilities will all the power of RIFE's element components. To make this work you have to use the DWR jar file that's shipped with the rife-sumo distribution archive.

Standard DWR Ajax element

RIFE ships with a new standard element declaration that can be accessed through the file "rife/ajax/dwr.xml".

For example:

<element id="DwrService" file="rife/ajax/dwr.xml" url="dwr/*"/>

That element will by default look for "dwr.xml" in the classpath. This is a standard DWR configuration file and you can find the details about it in their documentation.

Customize the configuration

However, you can also specify a specific DWR configuration file for each Ajax element through the xmlConfiguratorPath property.

For example:

<element id="DwrDate" file="rife/ajax/dwr.xml" url="dwr/jdate/*">
    <property name="xmlConfiguratorPath">jdate.xml</property>
    <property name="debug">true</property>
</element>

Notice the debug property which, when set to true, allows you to access the root URL of the element ("dwr/jdate/" in this case) and get a nifty DWR test page. It's recommended to turn this on during development.

Let's look at the content of this example's "jdate.xml" file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
                     "http://www.getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
  <allow>
    <create creator="new" javascript="JDate">
      <param name="class" value="java.util.Date"/>
    </create>
  </allow>
</dwr>

Your element will now expose the methods of the java.util.Date class through Ajax.

Enable Ajax in your HTML

The purpose of DWR is to easily provide remote access to your Java classes and methods through Ajax. However, to access these remoted methods from within your HTML, you have to include certain Javascript files. This is very easy to do with embedded elements.

For example:

<!--V 'ELEMENT:DwrDate'-->
names = JDate
includeUtil = true
<!--/V-->

The default value of this embedded element tag is a property list, where the "name" key specifies a comma separated list that refers to the "javascript" attributes of your DWR "create" tags. The "includeUtil" key indicates whether the general purpose DWR Javascript utilities should be included or not.

The example above will generate the following Javascript inclusions. Note that as with everything in RIFE, when your element or application is relocated, the URLs will automatically adapt accordingly.

<script type="text/javascript" src="http://yoursite/dwr/jdate/interface/JDate.js"> </script>
<script type="text/javascript" src="http://yoursite/dwr/jdate/engine.js"> </script>
<script type="text/javascript" src="http://yoursite/dwr/jdate/util.js"> </script>

Use Ajax in your layout

The only thing that's now left to do is to use the newly available Javascript functions from within your layout.

The following example calls the "init" Javascript function when the page is loaded. This is only needed to setup DWR so that it shows a message while it's loading data asynchronously through Ajax.

The actual magic happens in the "update" function, which is called when the button on the page is clicked. This method uses the Javascript "JDate" class that has been generated by DWR and calls its "toGMTString" method. This method maps directly to the Java implementation on the server. The single argument, "loadinfo" refers to the function that will be called when the Ajax call returns. Here, it simply displays the data in the HTML span tag with the id "reply".

<script type="text/javascript">
    function update() {
        JDate.toGMTString(loadinfo);
    }
       
    function loadinfo(data) {
        DWRUtil.setValue("reply", data);
    }
     
    function callOnLoad(init) {
        if (window.addEventListener) window.addEventListener("load", init, false);
        else if (window.attachEvent) window.attachEvent("onload", init);
        else window.onload = init;
    }
 
    function init() {
        DWRUtil.useLoadingMessage();
    }
     
    callOnLoad(init);
</script>
<div class="content">
    <p>Current date: <input value="Execute" type="button" onclick="update()"/>
    <span id="reply" style="background:#eeffdd; padding-left:4px; padding-right:4px;"></span></p>
</div>

[ top ]

Embedded element priorities

Normally, embedded elements are processed when the template that contains them is instantiated. In most situations this is exactly what you want, however sometimes it's important to be able to defer the processing to the end of your view handling, ie. when the template is printed. So instead of being processed early, those embedded elements will then be processed late.

You simply do this by prefixing the ID of the embedded element in the value tag with a + (for late processing) or - (for early processing).

For example, these embedded elements:

<!--V 'ELEMENT:+PRIORITIES_EMBEDDED_LATE1'/-->
<!--V 'ELEMENT:PRIORITIES_EMBEDDED_NORMAL1'/-->
<!--V 'ELEMENT:+PRIORITIES_EMBEDDED_LATE2'/-->
<!--V 'ELEMENT:PRIORITIES_EMBEDDED_NORMAL2'/-->
<!--V 'ELEMENT:-PRIORITIES_EMBEDDED_EARLY'/-->

Will be processed in the following order:

  • PRIORITIES_EMBEDDED_EARLY
  • PRIORITIES_EMBEDDED_NORMAL1
  • PRIORITIES_EMBEDDED_NORMAL2
  • PRIORITIES_EMBEDDED_LATE1
  • PRIORITIES_EMBEDDED_LATE2

Note that you can of course still process embedded elements explicitly with the processEmbeddedElement method. The embedded ements that have already been processed like that will not be automatically re-processed later.

[ top ]

Strict pathinfo mapping

Path info mapping provides a powerful way to easily support structured path info URLs and receive their values as inputs.

By default however, even if none of the mappings matches the provided pathinfo, the element will be executed. No values will have been extracted from the pathinfo and you're responsible for taking the appropriate action yourself. Usually, this is exactly what you want as a fall back. However, sometimes you might want to have elements that will only be processed if at least one of the declared mappings matches the pathinfo. This can be achieve by setting the "pathinfo" attribute of the element tag to "strict".

For example:

<element id="ShowPaste" implementation="elements.ShowPaste"
         url="paste/*" pathinfo="strict">
    <pathinfo mapping="$key/show/$id(\d+)"/>
    <pathinfo mapping="show/$id(\d+)"/>
</element>
 
 
<element id="DiffPastes" implementation="elements.DiffPastes"
         url="paste/*" pathinfo="strict">
    <pathinfo mapping="$key/diff/$oldid(\d+)/$id(\d+)"/>
    <pathinfo mapping="diff/$oldid(\d+)/$id(\d+)"/>
</element>

Both elements above handle the same pathinfo URL. However, only when the "show" keyword is present, the ShowPaste element will be executed and when the "diff" keyword is present the DiffPastes element will be executed.

So these will go to ShowPaste:

  • mypaste/show/1232
  • show/1232

These will go to DiffPastes:

  • mypaste/diff/1221/1244
  • diff/241/521

These will however be executed by neither:

  • mypaste/show/notanumber
  • diff/2141/4421/additionalpart

[ top ]

Deprecated CmfProperty and CmfValidation

The CmfProperty and CmfValidation classes are now deprecated.

You should use ConstrainedProperty and MetaData instead. All the methods from the deprecated classes have been moved to their alternatives.

[ top ]

Flowlink-specific datalinks

Normally you declare flowlinks and datalinks next to each-other and whenever the logic follows a flowlink, the related datalinks are looked up and all the output values will be provided to the target inputs. This can however create problems if you have different flowlinks that go to the same target element, but that should connect different outputs to the same input. You are now able to tie datalinks to a specific flowlink.

For example:

<element id="ShowPaste" implementation="elements.ShowPaste"
         url="paste/*" pathinfo="strict">
    <flowlink srcexit="show current" destid="ShowPaste">
        <datalink srcoutput="currentid" destinput="id"/>
    </flowlink>
 
    <flowlink srcexit="show parent" destid="ShowPaste">
        <datalink srcoutput="parentid" destinput="id"/>
    </flowlink>
 
    <flowlink srcexit="show amendment" destid="ShowPaste">
        <datalink srcoutput="amendmentid" destinput="id"/>
    </flowlink>
</element>

In the example above, three flowlinks point to the same ShowPaste element. However, depending on the triggered exit, different entries need to be shown. This means that the IDs of either the current paste, the parent paste or an amendment need to be provided to the "id" input of ShowPaste.

[ top ]

Mail queue support for authentication and SSL

The mail queue executor is now able to connected to authenticated SMTP servers and to use SSL for encryption.

The following task options are now available:

<task classname="com.uwyn.rife.mail.executors.DatabaseMailQueueExecutor"
      frequency="*/5 * * * *">
    <option name="name">...</option>
    <option name="datasource">...</option>
    <option name="smtp_server">...</option>
    <option name="smtp_port">...</option>
     
    <!-- new options -->
    <option name="smtp_ssl"><!-- true or false --></option>
    <option name="smtp_username"><!-- the username for the SMTP server --></option>
    <option name="smtp_password"><!-- the associated password --></option>
</task>

[ top ]

Support for setting reflexive outputs and globalvars across submissions

When your element has outputs that link to inputs of the element itself, or if globalvars are present, you are now able to set an output value before generating the submission URL and parameters. After the submission is sent, that output value will be provided to the input of the element. Of course, as before, all other inputs will automatically preserved during submissions.

This feature allows you to continue to rely on inputs to receive data for your element. However, you now don't have to handle changing input values by adding additional parameters to your submission and adapting your logic to them, you can simply set an output and continue to use the data that the input provides.

[ top ]

Bug fixes

A collection of bug fixes have been performed to:

  • the classloader
  • element property injection
  • error reporting
  • JDK 1.4 support through RetroWeaver
  • embedded elements
  • authentication and identification
  • validation contexts
  • Derby and MySQL support

[ top ]

Full changelog

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

  * RELEASE 1.4

  * RIFE-262 : Add full POJO support for constraints declarations.
  Finalized the implementation by adding support for auto-implementation or
  modification of the clone() method so that the bean instance and the
  meta-data instance always stay together and that clones are properly
  isolated.

  * Updated changelog and project files.

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

  * Added javadocs.

  * Renamed some methods to prevent them from being seen as bean properties

  * Updated project files.

  * Upgraded Groovy

  * Fixed MetaData bugs.

  * Made MetaData fully lazy instantiating.

  * Added ValidatedConstrained interface.

  * Changed JavaDocs version 1.3.2 into 1.4

2006-02-24  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added first working version of pure POJO support with automatic meta data
  merging

  * Added DTD for regular tag template syntax.

  * Added taglib descriptor for making the regular template tag syntax
  understood by tools.
  
  * Updated all DTDs to be in UTF-8 encoding.

  * Updated all examples to use the Velocity template syntax instead.

2006-02-23  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added experimental Ajax DWR support

  * Added support for the Velocity-inspired tag syntax

  * Added support for regular html tags for doing RIFE markup in the xhtml,
  xml, html templates.

  * Optimized the parsing algorithm to work a lot faster with numerous configs:
  an initial scan is first performed to detect the syntax variationts that are
  in use, and only those will remain for the actual parsing.

2006-02-22  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Explicit embedded element processing bugfix

  * NPE fix

2006-02-21  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Updated highlighting of example sources

  * Friend example update

2006-02-17  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Minor test suite fixes.

  * CMF fixes for RAW content storage with Derby and MySQL.

  * RIFE-244 : Add API for "manually" invoking authentication

  * RIFE-193 : Add public API for filling bean with submission values
  (name-value pairs)

2006-02-16  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * RIFE-253 : <site> should not require "file" attribute

  * Added some convenience methods to the CMF

  * Added support for dynamic repository names to the ServeContent element.

  * RIFE-264 : Embedded elements do not received pathinfo inputs : Embedded
  elements now receive all inputs of the embedding elements as if they were
  regular request parameters.

  * Added support for strict pathinfo mapping.

  * Added support for several elements with the same pathinfo URL.

2006-02-15  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Reduced memory usage for wordwrap

2006-02-14  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added wordWrap method to StringUtils.

2006-02-13  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Deprecated CmfProperty and CmfValidation, moving all their logic into the
  base classes.

2006-02-13  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Refactoring to dissociate Gate completely from the servlet api

2006-02-12  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Incredibly stupid classloader bugfix. The context classloader was only set
  in the init() method of the RIFE servlet/filter, but not in the service and
  destroy methods.

2006-02-10  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Fixed bug where arrival elements didn't properly rewrite reflective
  datalinks and flowlinks

2006-02-09  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Made the type of the template property not mandatory anymore and defaulted
  it to enginehtml

2006-02-08  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added support for flowlink-specific datalinks

2006-02-07  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added test for raw content storage of byte arrays

2006-02-06  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Additional tests for embedded element support in OOC testing framework

  * Added tests for embedded response support in out-of-container testing
  framework

  * Added tests for embedded element priorities

  * Updated copyright year

  * Made error reporting templates xhtml compliant and use css for formatting.

  * Adapted the formatting to correctly display template syntax errors in a
  pre formatted style.

  * Made getEmbeddedResponse a bit more user friendly

  * Implemented embedded element priorities.

  * Added support for embedded element retrieval in MockResponse.

2006-02-04  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added RAW content store support for byte[] as well as InputStream.

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

  * Added getResourceFinder() to Site

  * Changed order of automatic value replacement in processTemplate to make it
  possible to use data elements in form building valuesm

  * Fixed bug where the active element threadlocal is not cleared after an
  exception and thus template property injection creates a stack overflow
  exception.

  * Bugfix related to element property injection that only has to kick in after
  a valid ElementContext

  * Added isEmbedded method to ElementSupport

  * Minor bugfix related to embedded element inside templates that are
  instantiated through property injection.

  * Minor bugfix wrt to the order of the validation with a ValidationContect
  and Callbacks.

  * Fixed callbacks NPE with Derby

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

  * Added Tyler's mail queue ssl + auth support. Had to re-enable the old way
  of sending the messages without auth, otherwise the socket connection would
  just stay open and never close in the local test. The ssl and auth should be
  tested again.

  * Added blankValue() to Template

2006-02-01  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added warning to the log to indicate when auto compilation is not
  supported.

  * Made servlet containers that return null for
  ServletContext.getRealPath("/") not support auto compilation.

  * Removed TemplateClassLoaderClasspath since Templates have been generated
  directly to bytecode since quite a while.

2006-01-31  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Fixed RetroWeaver JDK 1.4 issue.

  * Renamed alias to catalog in the XML entity resolver. Still need to find an
  acceptable way to setup current and old versions of the DTD catalog, probably
  by including the rife_catalog.xml file, parsing it and including all the DTDs
  of the older versions.

  * Trial to support ClassPath for XML entity resolving.

2006-01-27  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Set EOL property to LF

2006-01-26  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * RIFE-265: Add a method for width/height/ratio of a scaled image to be
  forced via CmfProperty. The behavior of the CMF content attributes has
  changed. If both width and height are specified, they'll indicate a maximum
  bounding box and the image will be rescaled by preserving its aspect to fit
  the bounding box as closely as possible.

  * Changed template unittests to use to embedded derby instead

2006-01-24  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Fixed performance issue with UniqueIDGenerator

  * Upgraded ASM 2.2.1.
  
  * Updated continuations engine for new ASM behaviour.

2006-01-20  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Classloader fixed for integration with other libraries and filters that are
  loaded through web.xml

2006-01-17  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Minor bugfix to ensure that identified elements continue to prolongue the
  authentication session.

2005-12-31  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Upgraded HttpUnit to 1.6.0

2005-12-30  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Added support for setting reflexive outputs and globalvars accross
  submissions.

2005-12-29  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Fixed GQM install(CreateTable) methods for derby and mysql driver support

2005-12-24  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * Removed dependancy on Sun's JDK in the HTTP tool classes.

2005-12-23  Geert Bevin  <gbevin[remove] at uwyn dot com>

  * RELEASE 1.3.1

[ top ]

posted by Geert Bevin in RIFE on Mar 2, 2006 2:07 PM : 0 comments [permalink]
 

Comments

Add a new comment

Comments on this blog entry have been closed.

< RIFE at JavaWUG video by Emmanuel Okyere   Are single element annotations a disaster waiting to happen? >
 
 
 
Google
rifers.org web