Axualize Documentation |
Visit the Axualize Sourceforge Project. |
Intoduction |
Axualize Tutorial
version 1.1.0
Axualize is a tool for creating applications by actualizing java
objects using XML. Axualize is based on JSR-57,
and is intended to allow developers to create Java applications
dynamically using XML. To understand how this could be useful imagine a
J2EE application with multiple client UIs being generated from web
applications. Using Axualize you can present multiple form-based GUI
front ends to your application by dropping in a web application which
builds your GUI applications using Axualize. The XML could be
generated using JSP and whatever application framework you please.
Axualize does not rely on the JSR-57 XMLDecoder or XMLEncoder, but is
capable processing XML which adheres to the JSR-57 Schema. See Sun's
documentation on the JSR-57
schema here.To see that Axualize is capable of processing a JSR-57 document simply run Axualize and point it to the browser example from Sun as follows: java -jar dist/axualize.jar http://java.sun.com/products/jfc/tsc/articles/persistence3/Browse.xml Axualize builds on the JSR-57 and extends on its schema and capabilities to provide a full fledged application building environment. It adds powerful features such as form based interaction with web applications, and powerful event handling as well as aliases which make creating and maintaining documents far easier than with JSR-57 tools alone. You can even use flexible programiing constructs such as <if>, <else>, <while>, <for>, <try-catch>, and much more. Axualize is fully extendable with a straight forward API. You can easily add custom tag handlers for custom tag processing by simply implementing the TagHandler interface. Axualize also includes its own class loader which allows you to refer to class libraries at run time to further increase the options available to the developer. This gives you the ability to distibute applications similar to, but certainly not the same as JNLP (Java Web Start) applications. In practice I have used JNLP to launch Axualize applications which then are fully dynamic. Managing state in Axualize
The Container and The Model Axualize creates object models, but where do we keep the state of objects we are modeling? The answer is in a ModelMap or in more than one ModelMap. A ModelMap is simply a map where we can store objects by name. That is not the whole story however. We want to name our Models and have them live somewhere too, so they also have names and they are stored in the Container. The model and the container have some other uses as well, but their chief responsibility is simply in maintaining the state of our Axualize application. Since Java is object oriented and XML is not, Axualize utilizes our model to store object state as map entries as opposed to fields or properties in a class. The container is the class which is responsible for building and storing models. When you wish to create an application with axualize an instance of the Container class is created. Almost always the root element of an Axualize document is the <model> tag. <?xml version="1.0" encoding="UTF-8"?> <model id="myModel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://axualize.sourceforge.net" xsi:schemaLocation="http://axualize.sourceforge.net ../schema/axualize.xsd"> ... </model> The <model> tag usually has an "id" attribute. If you omit the id attribute the model will be assigned an id of "default". You use the id attribute in the model tag to identify the model since you may want to have many models, and not just one. If Axualize encounters a model tag with an id which already exists, it will simply refer to that existing model. By using multiple models with IDs you can easily move from model to model.. The use of multiple named models is helpful in creating modular applications. NOTE: JSR-57 uses the <java> tag as the root element. Axualize treats this <java> tag as if it were a <model> tag with an "id" attribute of "java" unless another "id" is explicitly specified. Running the examples on
this page
Running the examples is easy. You can simply start
the "dynamic-thing" application by executing /axualize/bin/run.bat or
by running axualize "dynamic thing" application manually like this:java -jar ../dist/axualize.jar file:../src/xml/examples/dynamic-thing.xml This will produce a simple application with a large scrollable text area. You can paste example Axualize code into the text area and the press the execute button. This is a simple way to execute
the examples on this page.
In Axualize there are really only two tag types that do the bulk of the things you want to do. Those tags types are the "void" type tag and the "object" type tag. The bottom line is this: Both tags types do exactly the same thing except that objects generated or produced by tags of the object type are used as arguments and objects produced by tags of the void type are not. This allows us to distinguish between arguments to methods or constructors and operations to be performed on the object that is in context. When a tag is processed it results in an object or a null value, when child tags are processed they are processed in the context of the result of the parent tag.
Now that we have a model defined, we need to put some objects in it and build a trivial application. The example above is examples/simple-frame.xml. To run the example type java -jar path-to-axualize/dist/axualize.jar file:path-to-axualize/src/xml/examples/simple-frame.xml or simply paste the XML into your "dynamic thing" as shown is the "Running the Examples" section . The JFrame object is stored in the model "myModel" with the id "myFrame." If we had not specified an id here the JFrame instance would not be stored in the model. You may have noticed our JFrame tag includes the <string> tag which we have not yet mentioned. The <string> tag is one of the wrapper tags for java types. There are wrappers for string, int, short, byte, long, float, double, boolean, and char as well as a the <true> and <false> tags which are aliases for their respective boolean values. In all cases the wrapper tags are object type tags which can be used as arguments. For all of the java primitive types we return instances of the java wrapper classes for those types. So based on the above XML Axualize will create a JFrame instance using the single argument constructor which takes a string argument. Next we set some bean properties on the JFrame instance. We do this by referencing the JFrame instance in void tags using the "idref" attribute. This allows us to get and set bean properties on "myFrame." Because we are passing an argument as a child element to the void tag the property is set to the value of the argument. Axualize uses a heirarchical scoping mechanism. The result of processing the tag is retained in the context of the tag which generated the result. That is to say if a tag produces an object instance that instance is in scope until the tag which generated it is closed. This is true even if you do not store the object instance in the model by giving your tag in "id" attribute. This allows us to nest operations in a context.
The document above produces the same result as as simple-frame.xml, but the tags which set the bean properties are nested, which groups them with the object instance to which they belong. Notice that in this case we did not give the JFrame an "id." This is because we have no need to refer to it later. This style is more compact and less redundant.. All of this functionality is virtually the same as JSR-57 long term bean persistance. You may want to read more there. Working with arrays
Arrays are handled as they are with JSR-57. The <array> tag is
used to create an array of the specified type and size. If arguments are
passed to the tag then they must all be of the same type. If the type is
ommited from the <array> tag and arguments are given, an array of
the same type as the arguments is created. The examples below both have
result in a String array that has a length of two:<array class="String" length="2"/> <array> <string/> <string/> </array> In the first case the array will contain nulls, while in the second the array will contain empty strings. The "index" object
attribute and the <echo> tag.
<array
id="myArray">If you wish to refer to an
individual element of an array or of any class which implements java.util.List you simply use the
"index" attribute in a tag when the array/List is in context. The
<echo> tag is a simple way to send text to the console. Any
arguments passed to the tag are printed to System.out in order.For example:
<string>Russ</string> <string>White</string> </array> <echo> <object idref="myArray" index="0"/> </echo> Will result in "Russ" being sent to the console. Null values
Should you ever need to pass a null value as an argument you would
simple include the <null/> tag as a child to the tag in context.The <if> tag
The <if> tag is used much as
it is in standard java syntax. Notice that the <else> tag is a
child of the <if> tag so that the else is nested within the
<if> which will be evaluated.
The following document shows its use:
The <while> tag
The while tag works like a standard java while statement. While the
expression is true the body of the tag will be processed. Notic the use
of the <continue> and <break> tags which work as they would
in Java.Here is a simple example:
The <do-while> tag
The while tag works like a standard java do/while construct. The body
of the while loop is performed at least once, and is repeated while the
expression is true. Notice the use of the <continue> and
<break> tags which work as they would in Java.Here is a simple example:
Scripting
Sometimes the most practical way
to do things is with natural Java syntax. Axualize utilizes BeanShell to accomplish this
through the use of the <void-script> and <object-script>
tags. The <void-script> tag executes a script and treats it as
void. The <object-script> tag also executes a script, but is
treated as an object. In the case of the <object-script> tag the
script should return a value. Scripts have access to all objects in the
current model, and any object created in the script is also made part of
the model. The example below illustrates the use of both tags. As with
objects created using the <object> and <void> tags, objects
created in scripts are subject to be overwtitten in the model. That is
to say if you have an object in the model with the id of "i"and you
create a now object with an id of "i" in the script or with an
<object> or <void> tag the original object will be replaced
in the model map with the new object. So be sure that if you reuse
object names that you intend to overwrite that object.
Building forms from models
Axualize wouldn't be very powerful if all it did was replicate JSR-57
XMLDecoder functionality, but in fact Axualize extends JSR-57 to
provide an XML based application language. One aspect of this fact is
that using Axualize you can create web applications which produce GUI
applications. In order to model this behaviour Axualize needs a
mechanism for producing HTTP requests including form data to be passed
to web applications.The first requirment is fulfilled by two void type tags <get> and <post> which both have a single attribute "href." These tags correspond to HTTP GET and HTTP POST requests to an HTTP server. The get/post tags may have child object tags which should be of the type java.util.Map.When the contrainer processes the get/post tag it combines the maps which are passed to it and passes them as form data along with the request. The container then process the resulting XML from the response. The <get>, <post>, and <process> tags also allow for the storage of cookies (in memory) so that you may maintain session state even when your application is made up of documents which came from multiple hosts or web aplications. There is also a <process> tag which works like the <get> tag but it never sends any form data to the server. It is used like an include to process additional Axualize documents. Axualize extends the purpose of the model so that it is not just a repository for named object instances, but also a repository for meta data about how to obtain useful values from those objects which it holds. Imagine you have created a UI with Axualize and it contains several text fields which will contain the form data which you want to submit to the server. It would be no good to send the JTextField objects themselves, instead it would be better to be able to mark objects with a value method attribute which both denotes that there will be a value to obtain, and how to obtain it. The <values> tag is used to obtain a map of the values to be extracted from the model map. Each value in the <values> map has the same "id" as the object which generated the value.
The document above will send two form values to the HTTP server. One called "hiddenValue" and one called "searchField". Notice the use of the value "this" for the attribute "value-method" for the "hiddenValue" string. The "this" marks that the object itself (or the result object's toString() method) will be used for the form value. For the JTextField the "getText" method is marked as the method to invoke to get the value we want to include in the form. The <values> tag is used to marshal the values togther into a map for the get/post tag. For the above example to work there should be a jsp at the URL specified in the post tag to process the request and return Axualize xml. Here is an example:
Aliases in Axualize A document with a lot of <void> and <object> tags can be somewhat hard to follow. Axualize allows you to assign aliases for any object attribute to a tag. There are special tags for creating aliases. Void
Aliases
The <void-alias> tag creates an alias which will be processed as a void. Remember that <void> tags are processed as objects but are not used as arguments to constructors or methods. If I plan on calling the "add" method of swing components many times I may want to create an alias to the "add" method. In that case I would include the following tag in my document: <void-alias method="add" tag="add"/> Now wherever Axualize encounters the <add> tag it will call the add method of the enclosing or referenced object. Processing the <add> tag now is the some as processing <void method="add"/> Object
Aliases
The <object-alias> tag likewise creates an alias which will be
used as an object. Remeber that <object> tags result in objects
which are used as arguments to constructors or methods.If you wanted to create an alias for a custom class which you will use with Axualize you would do the following: <object-alias class="com.acme.MyClass" tag="MyClass"/> Now the <MyClass/> tag will be processed as if it where an <object class="com.acme.MyClass"/> tag. Proxy
Aliases
The <proxy-alias> tag creates an alias which will be processed as
a <proxy> tag. Remeber that the proxy tag results in a proxy
instance for the specified interface is handled like an <object>
tag as an argument..To create an alias for a custrom listener interface I would do the following: <proxy-alias class="com.acme.event.MyListener" tag="MyListsner"/> Now the <MyListener> tag is handled as if it where <proxy class="com.acme.event.MyListener"/> How Aliases Relate to Namespaces When assigning aliases it is possible that you may need to create a tag alias which uses a tag which has already been mapped in Axualize. To handle this Axualize is namespace aware. The axualize distibution comes with documents which create aliases for most of the classes in the java runtime libraries. Axualize also includes XML schema documents for each of the alias documents to aid the developer in finding alias tags which they may wish to use. This is especially helpful if the developer has a schema-aware XML editor like XMLSpy. Below is an example of one of the documents which sets up aliases for the classes and interfaces within the javax.accesibility package along with its supporting schema. Both files are located in the /src/xml/schema directory of the distribution. Also included is an example axualize document which utilizes aliases. Notice the use of namespaces.
The xml file which sets up the aliases is a standard Axualize document. The alias tags in the standard aliases are contained within a <container> tag. The <container> tag contains tags which apply to the container in general and therefore to all models. Alias tags are applied to the entire container. You may include an alias any place in a document, but the alias tag must be processed before you can make use of the alias itself. In other words if I wish to alias the "add" method with a <void-aliase> to the <add> tag I need to be sure my <void-alias> tag is processed before I use the <add> tag. Using Axualize to
Implement Interfaces
Often a developer will need to implement one or more Java Interfaces in Axualize. There could be any number of reasons for this, but one that occurs quite frequently is in creating listeners which in Java would be classes which implement their respective listener interfaces. In Axualize you implement an interface by using the <proxy> tag which will generate a dynamic proxy which will stand in for the interface(s). The proxy tag is an object type tag which means that it can be used as an argument. The proxy tag allows you to process xml blocks for specific methods of an interface, or for all methods of an interface. Lets look at a <proxy> tag which will process a few methods invoked on an interface: <proxy class="java.awt.event.WindowListener" id="listener"> <method name="windowActivated"> <parameter class="java.awt.event.WindowEvent" id="e"/> <echo>window activated</echo> <echo> <object idref="e"/> </echo> </method> <method name="windowOpened"> <parameter class="java.awt.event.WindowEvent" id="e"/> <echo>window open</echo> <echo> <object idref="e"/> </echo> </method> <method name="windowClosing"> <parameter class="java.awt.event.WindowEvent" id="e"/> <echo>window closing</echo> <echo> <object idref="e"/> </echo> </method> </proxy> The "class" attribute describes the interface(s) for which we are creating a proxy. It can either be the name of one interface, or more than one each seperated by a comma. This proxy tag will result in a proxy instance which will process axualize segments when certain methods are invoked. Notice that we specify method not only by name, but by what parameters the method takes. This allows for very specific use of method signitures. You can also signal the Axualize container that you wish to retain the argument passed to the method by specifying an "id" attribute along with the paramter's class. The argument will then be stored in the model in context for later reference. In the example above we store the event objects passed to this listener in the model as "e." Sometime you may wish a proxy to respond to any method invocation. In this case you simply place the elements to be processed directly inside the proxy element as Follows: <proxy class="java.awt.event.MouseListener" id="mouseListener"> <method name="*"> <parameters id="params"/> <void id="e" index="0" idref="params"/> <if expr="e.isPopupTrigger"> ... </if> </method> </proxy> Notice the new tag <parameters> this tag applies only in this use of proxies, and it simply places a refernce to the entire array of arguments passed to the proxy when a method is invoked. You can then store that array of parameters in the model by giving it an "id." The example below uses a proxy.
Try - Catch Blocks
Axualize includes a <try-catch> tag which allows you to use
<try> and <catch> tags much like the try-catch logic in
java. Below is an example.
Loading Class Libraries at
Run Time
Axualize allows you to load classes at runtime using the
<load-classes> tag. This tag should be processed before you refer
to classes you are trying to load.The load classes tag is used as follows: <load-classes href="http://yourdomain.com/myLibs/myJar.jar"/> or alternatively: <load-classes> <object class="java.net.URL"> <string>http://yourdomain.com/myLibs/myJar.jar</string> </object> </load-classes> Relative URLs
<load-classes> <relative-url href="/myLibs/myJar.jar"/> </load-classes> This is just one use of the <relative-url> tag. There are many others I am sure you will find as you build web applications with Axualize. I am sure you can see how this can help make your Axualize client application much more portable. Serialized Objects
At some point you may have occasion to serialize an object using
standard Java serialization. Axualize supports the use of objects which
can be represented in the Axualize document as a BASE64 string
representation of the serialized object. The <serialized-object>
tag is used for this purpose and is treated as an "object" type tag. One
potential use of this feature is that you can serialize an object at the
time an Axualize document is being generated (say in a J2EE web
application) and embed the serialized form of the object directly into
the document. The abaility to handle objects serialized in this way can
make dealing with objects which do not encode well using XMLEncoder from
JSR-57 a lot easier. See the example below:
For loops
The <for> tag is used to produce java style for loops in
Axualize. You may use the <continue> and <break> tags just
as you would in Java. Here is an example of a for loop:
Exiting an application
The <exit/> tag provides a simple way to exit an application. It
is the same as invoking System.exit(0) in Java.Threads and the "later"
attribute
Effective use of Threads is key to writting efficient applications.
this is especially true when writing GUI applications. It is important
to do non-UI work in threads that are seperate from the UI thread. The
<thread> tag creates a Thread instance and optionally allows you
to start it running right away. Notice the use of the "later" attribute
on tags which will modify UI components. When the "later" attribute is
true the tag will be processed in the UI thread using
SwingUtilities.invokeLater(). This approach helps to simplify the
process of creating thread safe GUI applications especially when using
Swing. Here is a simple example.
GridBagConstraints
Axualize includes a handler for the <GridBagConstraints> tag. The
tag is a simple way to create instances of GridBagConstraint instances.
It is used as follows:<GridBagConstraints gridx="0" gridy="0" anchor="NORTH" fill="BOTH" ipadx="1" ipady="1" gridheight="1" gridwidth="1" weightx="1" weighty="1"/> The "anchor" and "fill" attributes use the constant names of there respective values. XML
Elements
The <element> tag is used to return an instance of com.sequenet.dom4russ.Element which
is an simple DOM tool for Java. This is useful if you wish to work with
XML elements in a DOM tree programatically.TimerTask
Sometimes you may want to execute something as a timed event. Axualize
includes support for the java.util.TimerTask class by implementing it
with the TimerTaskHandler. This allows you to easily add timed events to
Axualize applications. See the example below:
The <switch> tag allows a developer to use switch logic in a way similar to standard Java code. The <switch> tag has an "idref" attribute which is used to refer to an object which we will use to control the switching. The <switch> tag contains child <case> tags which are used to compare a value against the object referred to in the <switch> tag. The <case> tag will have either a "value" attribute or an "idref" attribute. If the "value" attribute is used the result of the <switch> object's toString() method is compared to the "value" attribute. If the two mach then the body of that <case> tag is processed. If the "idref" attribute is used then the object referred to by the "idref" is directly compared to the <switch> object. If the two match then the body of that <case> tag is processed. In either case if the <case> tag has a "break" attribute value of "true" no further case tags are evaluated, otherwise the next <case> is evaluated. Here is a simple example:
Adding TagHandlers at run
time with <handler>
The <handler> tag is used to put a TagHanlder instance in the
Container to process tags of the specifed tag name. TagHanlders are
responsible for handling every tag which is processed by Axualize. Each
TagHandler instance is registered with the Conatiner with the name of
the tag which it is supposed to handle. The <handler> tag takes as
an argument the instance of TagHandler to register with the Container.
The <handler> tag specifies the name of the tags which will be
handled by this TagHandler by specifying the name of those tags in the
"tag" attribute. You also must let the container know if the tag is an
object type tag, or a void type tag by specifying either "object" or
"void" in the "type" attribute. Below is a simple example. Notice that
it implements the TagHanlder interface with a <proxy>. You may
want to refer back to the section on implementing interfaces with the
<proxy> tag.
|