Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Java Tip 74: Build dynamically extensible frameworks - JavaWorld

Java Tip 74: Build dynamically extensible frameworks - JavaWorld

Tutorial Details:

Java Tip 74: Build dynamically extensible frameworks
Java Tip 74: Build dynamically extensible frameworks
By: By Fredrik Rubensson
Make your frameworks data-independent with property objects and dynamic class loading
xtending well-designed, object-oriented frameworks is a simple task. This tip will teach you one way to allow for such extensions. Frameworks written in Java typically have a number of interfaces that are natural extension points. This Java tip shows you how to implement a framework using property files and dynamic class loading that allows extensions. The resulting framework enables both objects and classes to be added dynamically without touching the framework source code. A simple example is provided that illustrates the benefits and drawbacks of this solution.
Example problem
Booking resources is a common problem in different domains. Offices have systems to book conference rooms. Car rental companies have systems for reserving cars. And the system for borrowing books from the library is very similar to the system for booking a conference room or reserving a car.
I will present a simple booking framework that can be used in all such situations.
The framework
The framework has two interfaces, Bookable and BookableStorage , and one coordinating class, Booker . It is the responsibility of the Bookable object, shown below, to keep track of its own bookings and decide whether booking requests can be met.
package bookingframework;
import java.util.Calendar;
/**
* Implementors of this interface represent a bookable item in a
* booking system. Bookable instances are loaded and stored with a
* BookableStorage object. I was thinking about extending java.io.Serializable
* but decided not to since there may be implementations that don't use
* serialization for persistence.
*/
public interface Bookable
{
/**
* Book this bookable for the specified date. (In a real-world
* booking system, we would have a start Calendar and an end Calendar.)
*
* @return boolean True if the booking succeeded, false otherwise.
*/
public boolean book( Calendar aDate );
/**
* Check if this bookable is free the specified date.
*
* @return boolean True if this Bookable object is free, false otherwise.
*/
public boolean isFree( Calendar aDate );
/**
* A name that identifies this bookable can be useful for identification
* and/or presentation.
*/
public String getName();
}
A BookableStorage object is responsible for loading and storing Bookable instances of a specific type as given in a Properties object. Here is the code for BookableStorage :
package bookingframework;
import java.io.IOException;
/**
* This is the interface that deals with persistence of bookables.
* Implementors of this interface must be associated with a Bookable
* implementation to make sense. The implementation must have a constructor with
* one Properties argument where the Properties object has values for one
* corresponding Bookable class and perhaps also setup values.
*
* The responsibility of this interface is to provide means of loading and
* storing Bookable objects.
*/
public interface BookableStorage
{
/**
* Load one Bookable with the specified name. The implementation is
* responsible for ensuring that there is an easy way to identify stored objects.
*
* @param name The name corresponds to the name retrieved from a Bookable
* with the getName method and is the way of identifying a unique
* Bookable object in this BookableStorage.
* @return Bookable If there is a Bookable with the given name, it will
* be returned.
*
* @exception IOException If there is some kind of I/O error while trying
* to find the Bookable.
* @exception BookableNotFoundException If there is no Bookable with the given
* name in this BookableStorage.
*/
public Bookable load( String name ) throws IOException, BookableNotFoundException;
/**
* Load all Bookables in this storage. In a more advanced interface
* there will surely be intermediate versions in between loading all stored
* Bookable objects and loading one. Different types of queries may be
* introduced.
*
* @return Bookable[] Returns an array with all Bookables stored in this
* BookableStorage.
*/
public Bookable[] loadAll();
/**
* Since BookableStorage is responsible for loading Bookables, it is
* natural to give it the responsibility of storing them.
*
* @param aBookable The Bookable to store. The getName method of Bookable
* is used as id for the object.
* @exception IOException If there is an I/O error while storing aBookable.
*/
public void store( Bookable aBookable ) throws IOException;
}
The Booker object is responsible for coordinating the booking. The Booker finds a suitable BookableStorage instance from the information in the Properties object and uses it to load and store Bookable instances.
A single BookableStorage implementation, CarStorage , for example, can be related to one Bookable implementation, let's say Car , or many Bookable implementations, such as Car and Truck . ( Car and CarStorage are implementations provided in the distribution.)
package bookingframework;
import java.util.Properties;
import java.util.Calendar;
import java.io.PrintWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* The coordinating class in this framework. It has the responsibility of
* executing booking requests for different types of Bookable objects. In
* order to accomplish its task, it has to find the BookableStorage
* implementation that supports the given type, dynamically load it,
* and search for a free Bookable in that storage.
*/
public class Booker
{
protected Properties myProperties;
protected PrintWriter myMessageWriter;
/**
* A booker is created with a Properties object and a writer for
* outputing messages.
*
* @param someProperties
* The properties object may originate from a file
* either as text or serialized. In our example, though, we go for
* the easy option of using a text properties file with only
* string values.
*
* @param messageWriter
* The writer can be System.out, a file, or directed to a graphics
* component. By using a writer, user communication is left to the caller
* and not assumed here.
*/
public Booker( Properties someProperties, PrintWriter messageWriter )
{
myProperties = someProperties;
myMessageWriter = messageWriter;
}
/**
* Try to book an item of type for the given date. This method is
* straightforward: Get a BookableStorage, load all bookables in the
* storage, and loop through them in order to find a free bookable for the date.
*
* @return boolean True if the booking succeeded, false otherwise.
* @exception NoStorageFoundException if the storage associated with the
* type doesn't exist. This can be for
* two reasons.
*

    *
  • The Properties object held by
    * this Booker may not have a property
    * with the name dynamic..storage .
    *
  • The class pointed to by the property
    * is either missing or does not
    * implement BookableStorage correctly.
    *

* @param type
* @param date
*/
public boolean book( String type, Calendar date ) throws NoStorageFoundException
{
BookableStorage aStorage = getBookableStorage( type );
if( aStorage == null )
throw new NoStorageFoundException();
Bookable[] someBookables = aStorage.loadAll();
for( int i=0; i < someBookables.length; i++ )
{
if( someBookables[i].isFree( date ) )
{
someBookables[i].book( date );
try
{
aStorage.store( someBookables[i] );
}
catch( IOException e )
{
myMessageWriter.println( "I could not store your request." );
}
return true;
}
}
return false;
}
/**
* Dynamically load a class for the type given and return an instance of that
* class. The method uses the Properties object to decide the class name.
* The property dynamic..storage should hold the class name.
* It furthermore assumes that the dynamically loaded class has a
* constructor with one argument of type Properties to which the properties
* object is sent. The Properties object may hold setup information
* for instance creation.
*
* @return BookableStorage A storage that can be used to load and store
* Bookables of the given type. Null if no storage is
* found.
* @param type
*/
protected BookableStorage getBookableStorage( String type )
{
/*
* Get the class name from the properties object. Use a name standard
* saying that the class supporting the type "car," for example, can be
* found with the key dynamic.car.storage.
*/
String className
= myProperties.getProperty( "dynamic." + type + ".storage" );
/*
* getProperty returns null if there is no value for the key. (Or if
* the value is null...) This check is the closest we come to type
* checking in this framework.
*/
if( className == null )
{
myMessageWriter.println( "It seems that " + type + " isn't supported." );
return null;
}
try
{
/*
* Load the class using the static forName method in Class and then
* create a new instance of the loaded class. We assume that the loaded
* class implements BookableStorage and has a constructor with one
* Properties argument. See the error texts in the many catch blocks
* below to get a feeling for the various exceptions that may rise. If
* the constructor of the loaded class throws an exception it is
* wrapped by newInstance in an InvocationTargetException.
*/
Class storageClass = Class.forName( className );
Constructor storageConstructor
= storageClass.getConstructor( new Class[]{ Properties.class } );
Object aBookableStorage
= storageConstructor.newInstance( new Object[]{ myProperties });
return (BookableStorage)aBookableStorage;
}
catch( ClassNotFoundException e )
{
myMessageWriter.println( "It seems that " + type + " isn't supported." );
myMessageWriter.println( "Couldn't find the class " + className );
}
catch( NoSuchMethodException e )
{
myMessageWriter.println( "It se


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Java Tip 74: Build dynamically extensible frameworks - JavaWorld

View Tutorial:
Java Tip 74: Build dynamically extensible frameworks - JavaWorld

Related Tutorials:

Reloading Applets
Reloading Applets
 
Applet to Applet Communication
Applet to Applet Communication
 
Java Tip 72: Press Escape to close your Swing dialog windows
Java Tip 72: Press Escape to close your Swing dialog windows
 
Generate JavaBean classes dynamically with XSLT
Generate JavaBean classes dynamically with XSLT
 
Take command of your software
Take command of your software
 
Sun boosts
Sun boosts enterprise Java
 
Java Tip 132: The taming of the thread
Java Tip 132: The taming of the thread
 
A first look at JavaServer Faces, Part I
A first look at JavaServer Faces, Part Learn how to implement Web-based user interfaces with JSF
 
AurigaDoclet: Javadoc doclet for generating javadoc in pdf, postscript, etc
What Is AurigaDoclet? AurigaDoclet is a Javadoc doclet which can generate Java API document in fo, pdf, postscript, pcl, and svg format. AurigaDoclet accepts command line options which can be used to further customize the generated output.
 
Filtering and Transforming Digital Images
Filtering and Transforming Digital Images In this Issue Welcome to the Core Java Technologies Tech Tips for April 7, 2004. Here you\'ll get tips on using core Java technologies and APIs, such as those in Java 2 Platform, Standard Edition (J2SE).
 
Extensible Code Generation with Java, Part 1
Extensible Code Generation with Java, Part 1 Code generation is a key new trend in engineering, one that you need to understand well. The reason is simple: today's modern frameworks are extremely code-intensive. Using a code generator to build the code
 
Extensible Code Generation with Java
Extensible Code Generation with Java Part 2 In part 1 of this series, we looked at the idea of generated code, which is code written not by hand but by another application. The appeal of generated code is that it can eliminate drudgery (and mistakes) i
 
Reporting Application Errors by Email
Reporting Application Errors by Email It is common practice for server-side applications to log messages to files on the server's file system. These logs are a vital source of information for system administrators and the application development team. If
 
Using the ASM Toolkit for Bytecode Manipulation
Using the ASM Toolkit for Bytecode Manipulation Sometimes Java developers need to generate or change Java bytecode in the runtime. Is can be necessary for AOP or debugging, or even for performance optimization. There are several frameworks available that
 
Object-Oriented Language: Java / APIs (Classes & Libraries)
The Java Platform APIs are a set of essential interfaces that developers need to build their Java applications and applets. All Java Platfrom APIs are open and extensible, and are created by JavaSoft and industry-wide specialists in each target technology
 
Java Server Pages Dynamically Generated Web Content.
JavaServer PagesTM (JSP TM) technology allows Web developers and designers to rapidly develop and easily maintain, information-rich, dynamic Web pages that leverage existing business systems.
 
Atricle Struts, JavaServer Faces, and Java Studio Creator:
The Evolution of Web Application Frameworks Sun Microsystems' Craig McClanahan, the creator of the Apache Struts Framework, co-specification lead for JavaServer Faces 1.0, and prime architect for Sun Java Studio Creator's new release, explains all three.
 
Struts, JavaServer Faces, and Java Studio Creator:
The Evolution of Web Application Frameworks Sun Microsystems' Craig McClanahan, the creator of the Apache Struts Framework, co-specification lead for JavaServer Faces 1.0, and prime architect for Sun Java Studio Creator's new release, explains all three.
 
What is Persistence Framework?
What is Persistence Framework? What is Persistence Framework? A persistence framework moves the program data in its most natural form (in memory objects) to and from a permanent data store the database. The persistence framework manages the
 
Open Source Web Frameworks in Java
Open Source Web Frameworks in Java Open Source Web Frameworks in Java Struts Struts Frame work is the implementation of Model-View-Controller (MVC) design pattern for the JSP. Struts is maintained as a part of Apache Jakarta project and is open
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.