Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 7
The consequences of using an XSL Dispatcher include:
It's now time to implement the XSL Dispatcher solution. Below, I've outlined some of Dispatcher's important classes and their responsibilities.
The abstract AbstractDispatcherFactory class employs the Builder pattern to create dispatchers:
package workflow;
/**
* This class creates AbstractDispatchers.
**/
abstract public class AbstractDispatcherFactory {
public abstract AbstractDispatcher getDispatcher(String name) throws
DispatcherCreateException;
}
The abstract AbstractDispatcher class dispatches an object. Its next() method determines the next screen in a workflow:
package workflow;
/**
* This class is an abstracted Dispatcher
**/
import java.util.*;
abstract public class AbstractDispatcher {
/**
* The next method finds the next part of a workflow.
* This part of the workflow is represented as a String.
* @returns the name of the next part of the workflow.
**/
public abstract String next(HashMap parameters, Dispatchable ojb,
String current) throws Exception;
public String getDispatcherName() {
return dispatcherName;
}
public String dispatcherName;
}
The Dispatchable interface represents a dispatchable object. Because it is an interface, you must implement Dispatchable in order for the API to use it:
package workflow;
public interface Dispatchable {
String toXML();
}
The DispatcherCreateException exception throws if the AbstractDispatcherFactory cannot create a dispatcher:
package workflow;
public class DispatcherCreateException extends Exception {
}
Figure 3 illustrates the relationship between the classes.
Figure 3. The Dispatcher class diagram. Click on thumbnail to view full-size image.
Next, let's see how to implement the aforementioned classes.
The XMLDispatcherFactory class creates XMLDispatchers. It retrieves the stylesheet and creates a javax.xml.transform.Transformer useable by the dispatcher:
package workflow.example;
import javax.xml.transform.*;
import org.apache.xalan.processor.TransformerFactoryImpl;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.stream.*;
import java.util.*;
import javax.xml.transform.sax.*;
import java.io.*;
import workflow.*;
/**
* The XMLDispatcherFactor creates instances of XMLDispatchers.
* It reads in the appropriate XSL and
* creates the Transformer object.
*/
public class XMLDispatcherFactory extends AbstractDispatcherFactory {
//The various workflows and the stylesheets associated with them.
static Properties properties = new Properties();
//The Transformer factory
static TransformerFactory factory = new TransformerFactoryImpl();
//Just to keep it simple, add the only workflow we have right now.
static {
properties.put("application", "c:/application.xsl");
System.out.println("added application");
}
public XMLDispatcherFactory()
{
}
/**
* Gets the dispatcher requested and the workflow represented by the name.
* @param name the name of the workflow.
*/
public AbstractDispatcher getDispatcher(String name)
throws DispatcherCreateException {
Transformer transformer = null;
XMLDispatcher dispatcher = null;
try
{
System.out.println("Reading in file");
//Create the transformer object
transformer = factory.newTransformer
(new StreamSource(new FileInputStream
((String)properties.get(name))));
//Create an instance of the XMLDispatcher
dispatcher = new XMLDispatcher(transformer);
}
catch (TransformerConfigurationException transE)
{
System.out.println(transE.getMessage());
throw new DispatcherCreateException();
}
catch (FileNotFoundException noFile)
{
System.out.println(noFile.getMessage());
throw new DispatcherCreateException();
}
dispatcher.dispatcherName = name;
return dispatcher;
}
}
The XMLDispatcher class uses the transformer to determine the next screen. The XMLDispatcher does this by persisting an object to XML before performing the transformation. The class also passes various parameters to
the stylesheet. The stylesheet simply produces a string representing the name of the view the user should see next: