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

< LGPL for Java, but with Apache's blessing   Improved RIFE in-depth session movie >
RIFE 1.0 released

Update: RIFE 1.0 has been announced on The ServerSide and a nice discussion is going on there, join us!

After four years of development and seventy releases, we finally consider RIFE to be feature-complete.

The project has come a long way over the years and the goals have been constantly re-evaluated against production projects and newly introduced technologies. RIFE is now running on sites with 300000 daily page views, it is used for critical systems in a leading telephony company and has scaled down to embedded usage in mobile phones. We have also developed several other open-source projects with it like a forum (Bamboo), a blog (Elephant), an information bot (Drone), and a to-do list tracker (Bla-bla List).

Below are the highlights:

You can also read the full changelog for more details.

Congratulations and many thanks to everyone who contributed to make this milestone happen.

Greatly improved documentation

We spent a lot of time writing javadocs for those early core parts that never had any. Not everything is documented yet, but most of it is done and we will continue increasing the documented source code ratio.

The official site is now http://rifers.org. It has been properly designed, contains a lot of additional information and provides the basis for building a vibrant RIFE community.

[ top ]

Backwards incompatible changes

Since version 1.0 marks a stability milestone, we went over most of the sources to identify parts that would benefit from permanent consistency changes. These are the parts that changed:

  • All standard RIFE elements that use a datasource property now don't expect a datasource name anymore, but an actual Datasource instance through IoC. This is an easy fix, just surround the datasource name with the <datasource> tag.

    For example:

    <property name="datasource">postgresql</property>

    becomes:

    <property name="datasource"><datasource>postgresql</datasource></property>
  • We renamed the "identity" request attribute to prevent name clashes. It now follows the recommendations of the servlet spec. The new name is:
    com.uwyn.rife.authentication.credentialsmanagers.RoleUserIdentity
    However, it's best accessed through the Identified.IDENTITY_ATTRIBUTE_NAME static variable.
  • All dao packages have been removed since we ended up creating managers and putting them into dam packages (data access managers). The beans inside the dao packages simply moved up a level in the package hierarchy.
  • We made disruptive changes to the fillSubmissionBean method. Previously, this method took all submission parameters that had values and filled these into an already existing bean. The new version however also takes the non-submitted parameters into account and will reset those to the bean's default values of these properties. The reason for this is that it's otherwise not possible to uncheck checkboxes with fillSubmissionBean without manual interaction. After thinking more about it though, the new behavior also makes the most sense since the submission is able to receive all these parameters anyway, even if you didn't specify them as form fields. Only taking the actually existing in submission parameter values into account can give a false sense of security since anyone can easily fake a post request.
  • The API of the getContentForHtml method has slightly changed to make it possible to take the gate URL into account when generating URLs.
  • The authentication framework doesn't restrict access anymore to the host IP that initiated the authentication session. This is needed because a lot of institutions and corporations have round-robin IP address allocations that make the same computer have different IP addresses to the outside within a couple of minutes. The previous behavior can be restored by setting the SESSION_RESTRICT_HOSTIP config parameter to true.
  • JRuby support has been removed due to its slowness and the impossibility of recent versions to be integrated.

[ top ]

Content syndication

RSS 2.0 and Atom 0.3 are now natively supported and can be generated in real-time. The data can be provided in a streaming fashion, which makes the memory footprint very low.

To provide feed entries, you have to implement the EntryProvider interface.

For example:

public class DemoEntryProvider implements EntryProvider
{
    private Calendar mCalendar = null;
    
    public SimpleEntryProvider()
    {
        mCalendar = GregorianCalendar.getInstance();
        mCalendar.set(2005, Calendar.JANUARY, 1, 0, 0, 0);
        mCalendar.set(Calendar.AM_PM, Calendar.AM);
    }
    
    public Feed getFeedDescriptor(ElementSupport element)
    {
        Feed feed = new Feed();
        feed
            .title("feed_title")
            .author("feed_author")
            .copyright("feed_copyright")
            .description("feed_description")
            .language("feed_language")
            .link("feed_link")
            .publishedDate(mCalendar.getTime());
        
        return feed;
    }
    
    public void provideEntries(ElementSupport element, EntryProcessor processor)
    {
        for (int i = 0; i < 10; i++)
        {
            mCalendar.set(Calendar.HOUR, i+1);
            Entry entry = new Entry();
            entry
                .author("entry_author"+(i+1))
                .content("entry_content"+(i+1))
                .link("entry_link"+(i+1))
                .publishedDate(mCalendar.getTime())
                .title("entry_title"+(i+1));
            
            processor.setEntry(entry);
        }
    }
}

All that's now left to do is to register an element in your site structure that is aware of this EntryProvider, like this for example:

<element file="rife/feed/feedprovider.xml" id="RSS" url="/rss">
    <property name="feedtype">rss_2.0</property>
    <property name="classname">my.pakkage.DemoEntryProvider</property>
</element>

[ top ]

Callbacks

Callbacks are hooks that are being called when beans are manipulated through the GenericQueryManager or other query managers that are based on it (ContentQueryManager, for instance). They can either be implemented directly by implementing the Callbacks interface, or they can be provided by a bean by implementing the CallbacksProvider interface. The latter allows a bean to use the convenience AbstractCallbacks class and to only implement the methods that are needed. Callbacks can for example be used to delete associated and dependent objects when delete is called (by implementing beforeDelete(int)), or to clear a cache when an object has been modified (by implementing afterSave(Object, boolean) and afterDelete(int, boolean)). The return value of callbacks can be used to cancel actions. When the before* callbacks return false, the associated actions are cancelled. When the after* callbacks return false, the execution of the action is interrupted at that step and no further callbacks will be called.

We use this for example in Bamboo to update the message and topic counts each time a message is saved or deleted, like this:

public class Message extends Validation<ConstrainedBean, ConstrainedProperty> implements CallbacksProvider<Message>
{
    ...
    
    public Callbacks<Message> getCallbacks()
    {
        return new AbstractCallbacks<Message>() {
            private Datasource          mDatasource = ...;
            private MessageQueryManager mMessages = MessageQueryManagerFactory.getInstance(mDatasource);
            private Message             mDeletedMessage = null;
            
            public boolean afterSave(Message object, boolean success)
            {
                if (success)
                {
                    mMessages.updateCachedObjectCounts(object);
                }
                return true;
            }
            
            public boolean beforeDelete(int objectId)
            {
                mDeletedMessage = mMessages.getMessage(objectId);
                
                return true;
            }
            
            public boolean afterDelete(int objectId, boolean success)
            {
                if (success)
                {
                    mMessages.updateCachedObjectCounts(mDeletedMessage);
                }
                
                return true;
            }
        };
    }

    ...
}

[ top ]

SOAP improvements

Axis 1.1 used to be the SOAP framework that was integrated with RIFE. The integration was very hackish to say the least since there were no easily replaceable and reusable parts that could be used with another servlet-like gateway in front of it. Since Axis 1.1 doesn't work with Java 5.0, we really had to remove it and either support version 1.2 or use another solution. We decided to move over to XFire and made creating SOAP elements even easier thanks to it.

All that's needed to setup a SOAP webservice in RIFE with XFire now are two properties, like this:

<element extends="rife/soap/xfire.xml">
    <property name="home-class">com.uwyn.rife.engine.testwebservices.soap.xfire.Echo</property>
    <property name="home-api">com.uwyn.rife.engine.testwebservices.soap.xfire.EchoApi</property>
</element>

The Java source code is very simple:

public class Echo implements EchoApi
{
    public String echo(String value)
    {
        return "I got : '"+value+"'";
    }
}

public interface EchoApi
{
    public String echo(String value);
}

SOAP services now also support the ElementService interface.

[ top ]

Attachment and HTML support for mail queue

The MailQueueManager is now able to queue complete JavaMail messages. This provides all the features of JavaMail with the stability benefits of using a mail queue.

[ top ]

More production configuration parameters

We added a number of additional configuration parameters that are intended for production environments:

RESPONSE_REQUIRES_SITE

Is true by default which means that the responses will wait for the site structure to be processed and initialized.

When it's false, the site initializes in the background and a response is sent immediately with a 503 status code when the initialization isn't finished.

SITE_INITIALIZING_REDIRECT_URL

Instead of showing a 503 status code, you can provide a relative or absolute URL in this parameter that will cause the visitor to be redirected to a page that can give a user-friendly message (ie. site is restarting, thanks for your patience, ...).

SITE_INITIALIZING_PASSTHROUGH_SUFFIXES

By default, URLs with the following suffixes will be accessed directly and are not subject to the behaviour that's configured through RESPONSE_REQUIRES_SITE:

.gif, .png, .jpg, .jpeg, .bmp, .ico, .css, .js, .swf, .html, .htm, .htc, .class, .jar, .zip, .arj, .gz, .z, .wav, .mp3, .wma, .mpg, .avi, .ogg, .txt

By providing items for the configuration list you can reconfigure these suffixes.

[ top ]

posted by Geert Bevin in RIFE on Aug 31, 2005 12:35 PM : 7 comments [permalink]
 

Comments

Re: RIFE 1.0 released
Congrats! Thanks alot for all the hard work involved in making this great framework.
Re: RIFE 1.0 released
The little section of code above "We renamed the "identity" request attribute ".. is very hard to read on IE 6.0.
Re: RIFE 1.0 released
Thanks for pointing that out, it should be better now.
Re: RIFE 1.0 released
Great work guys! I'm working with the rife/laszlo version. I found one error though. The build path refers to rife-1.0rc2.jar instead of rife-1.0.jar. Easy to fix if you know what your doing.
Re: RIFE 1.0 released
Thanks a lot for pointing that out. I forgot that eclipse stores those in a hidden file in the root project directory and that a recursive grep thus will not find it in there. I'll upload a fixed version shortly.
Re: RIFE 1.0 released
Great work Geert! I really think that Rife is one of the most well thought out Java web frameworks, however there are a couple things which I am really hoping it will include (or maybe already does):

1- Spring integration (along with all the persistence options: Hibernate, JDO...). I see that it is listed under integration but there are no examples that I could find such as Rife with Spring and Hibernate.
2- Tapestry/Wicket like html templates support
3- Annotations to replace XML configuration, and more convention over configuration so that if a 'default' Rife setup is used the configuration needed will be very minimal.

Keep up the great work!
Re: RIFE 1.0 released
Hi Abdullah,

thanks for the compliments.

Here are the answers to your suggestions:
1. there is nothing that prevents you from using Spring as you're used to using it now, there's also nothing that prevents you from using Hibernate and JDO, they are just not integrated with the constraints since they provide the same kind of abstraction layer with another approach. You can very easily interface with the Spring application context, this is explained here: http://rifers.org/wiki/display/RIFE/Spring+integration and then you can use it with RIFE's IoC: http://rifers.org/wiki/display/RIFE/IoC+support

2. what do you mean with that? The fact that special tag attributes are used to declare blocks and the ${} is used for the values? The problem with that is that RIFE's template engine is multi-format and not specific to HTML. We use it for text (mail), SQL, ... too. If you mean that you would like a templating engine without any embedded logic, then that's there already ;)

3. Righto for annotations, this is indeed planned. We will always require the registration of elements in a site structure though, since we don't want risk to unknowingly open up non-public code to the exterior world. Also, it's in our opinion very important out of a maintenance point-of-view that there's one centralized location where everything starts from. Like that's it's very easily to read what an application does and how to use it.

Best regards,

Geert

Add a new comment

Comments on this blog entry have been closed.

< LGPL for Java, but with Apache's blessing   Improved RIFE in-depth session movie >
 
 
 
Google
rifers.org web