Home
Download
Lobo Browser
Cobra Toolkit
JavaFX/Java
Source Code
Contact Us
SF Services
Donations
Thanks

 
SourceForge.net Logo
Lobo@SF
 
 
Support This Project
 
 

Warrior Platform as an API

Note: This API is deprecated. See the new browser API.
This page explains how to use Warrior as an XML UI Framework, without having to run the Warrior platform self-extracting installer.

Possible uses of Warrior as an API are the following:

  1. Customizable GUIs.- Existing Swing applications that need to be extended with a customizable mechanism for defining additional GUIs, particularly GUI specifications served over HTTP (with security considerations) can include the Warrior platform for that purpose.
  2. New GUI applications.- The Warrior platform may be used in new Java applications that need a high-productivity mechanism for defining GUIs. In our own experience, using XAMJ is much easier than writing Swing code.
  3. Browser for a new content type.- The Warrior platform can be customized to handle new content types. Warrior is not only a XAMJ platform. For example, authors of other XML UI languages could deploy Warrior with clientlet selectors for those languages. The platform takes care of HTTP requests and navigation.

Requirements

The Warrior Platform requires Java 5 (JDK 1.5+). XAMJ APIs rely on Java 5 features such as generics.

Library Files

The JAR files needed are available in files named warrior*-files.zip (version 0.93.2 or newer) which you will find in our archive. (They are also available in the directory created by the self-extracting installer.) Yes, you will need all the JARs shipped with a release. They include warrior.jar (the Warrior Platform), xamj.jar (the XAMJ APIs), security.jar (Warrior security policy), plus open source externals used for logging, XML parsing, Java compilation, etc.

Note that XAMJ invokes the JDT compiler with the default assumption that xamj.jar and warrior.jar are in the same directory as the first entry in your classpath. This will be the case, for example, if your application is an executable JAR file and Warrior JARs are in the same directory. In order to override this, you may define the path to xamj.jar with property xamj.clientlet.class.path and the path to warrior.jar with property xamj.engine.class.path.

Warrior is released under a BSD licence. Please check the file named ACKNOWLEDGMENTS for licensing of external libraries.

API Documentation

Check the Javadoc-generated Warrior Platform API Documentation. Note that XAMJ documents don't have access to this API. Their access is restricted to the XAMJ DOM and Clientlet API.

Access to your Code by XAMJ Documents

The primary mechanism for having XAMJ documents link a JAR file or directory by default is that of defining the xamj.clientlet.class.path property in the application that invokes Warrior. The value of this property has CLASSPATH format, and it must include the location of xamj.jar.

XAMJ documents can also include one or more archive elements below the head element, which specify relative or absolute URLs to JAR files to be linked during compilation and loaded by the runtime.

An internal URL protocol, res, may be used to access resources in the application's classpath, such as images and XAMJ documents included with your application. It could also be used to load JAR files included as resources (i.e. JAR files within your classpath JARs or directories --- which is not the same as JARs in your classpath.) XAMJ code could then look as follows:



<xamj>
  <head>
     <archive>res:/path/to/file.jar</archive>
     <import>my.package.*</import>
  </head>
  ...
</xamj>


Platform API Overview

You will need to instantiate the PlatformAccess singleton as follows:


import org.xamjwg.platform.*;

import org.xamjwg.event.*;
import org.xamjwg.clientlet.*;
import org.xamjwg.dom.*;
import org.xamjwg.io.*;
...
PlatformAccess warrior = PlatformAccess.getInstance();

In order to initialize the platform with a security policy and default Look & Feel, call:


warrior.initPlatform();

This is an optional step in applications that are (1) not concerned with security or that (2) wish to install their own security policy. The former is not recommended because XAMJ documents easily served via HTTP would have full access to the system running your application, but this up to you. In the latter scenario, check method createHostPermission which is necessary for managed stores to work.

To launch a XAMJ document in a platform window or browser (depending on document disposition) use:


warrior.launchLocal(new String[] { "http://path/to/document.xamj" });

If instead you prefer to embed a Warrior browser frame in your own Swing/AWT component, your code should look as follows:


XFrameElement frame = warrior.createFrame();
Component frameComponent = warrior.getComponent(frame);
// Add frameComponent to your Swing code
frame.navigate("http://path/to/document.xamj");

The addXamjListener method can be helpful in receiving frame on-progress events or on-property-change events for the href property of a frame.

Alternatively, you can request a lightweight component asynchronously from a XAMJ document URL.


AsyncResult<java.awt.Component> asyncResult = warrior.requestComponent("http://path/to/document.xamj");
final PlatformAccess finalWarrior = warrior;
asyncResult.addResultListener(new AsyncResultListener<XDocument>() {
    public void resultReceived(AsyncResultEvent<XDocument> event) {
        // This is invoked in the Warrior event dispatch thread,
        // which happens to be the same as the AWT thread. 
        java.awt.Component component = event.getResult();
	// Now you can add component to your Swing application.
        // Note that invalidating the parent may be necessary.
    }

    public void exceptionReceived(AsyncResultEvent<Throwable> event) {
	// Handle web response error: event.getResult()
    }
});

The main difference between frames and widgets requested asynchronously is that navigation can occur in frames.

Custom Content Types

The Warrior Platform can be extended to handle additional content types by adding clientlet selectors. A clientlet is an interface that is implemented to process a web request response. A clientlet selector is set up by calling addClientletSelector as follows:


import org.xamjwg.platform.*;

import org.xamjwg.event.*;
import org.xamjwg.clientlet.*;
import org.xamjwg.dom.*;
import org.xamjwg.io.*;
...
PlatformAccess warrior = PlatformAccess.getInstance();
warrior.addClientletSelector(new MyClientletSelector());
warrior.launch();

Let's say the clientlet selector MyClientletSelector only cares about mime type application/x-text. You can start by writing it as follows:


import org.xamjwg.platform.*;
import org.xamjwg.clientlet.*;

public class MyClientletSelector implements ClientletSelector {
    public Clientlet select(ClientletRequest request, ClientletResponse response) {
        String mimeType = response.getMimeType();
        if("application/x-text".equals(mimeType)) {
            return MyTextClientlet();
        }
        else {
            return SKIP;
        }
    }
}


Now you need to write the clientlet referred in the code above, MyTextClientlet. This clientlet needs to convert the web response content into something renderable by Warrior. In this example, we will convert the response into a Swing JTextArea component.


import org.xamjwg.clientlet.*;
import javax.swing.*;

public class MyTextClientlet implements Clientlet {
    public void process(ClientletContext context) throws ClientletException {
        try {
            InputStream in = context.getResponse().getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuffer textBuffer = new StringBuffer();
            while((String line = reader.readLine()) != null) {
                textBuffer.append(line);
                textBuffer.append("\r\n");
            }
            JTextArea textArea = new JTextArea(textBuffer.toString());
            ClientletContent content = context.createComponentContent(textArea);
            content.setTitle("My Text Document");
            context.setContent(content);
        } catch(IOException ioe) {
            throw new ClientletException(ioe);
        }
    }
}


The ClientletContext interface contains methods that allow clientlets to navigate to other documents, to asynchronously request files such as images, and so on.

Note that any security requirements of custom content handlers added this way are the responsibility of each clientlet implementation. For example, if the clientlet allows arbitrary Java code to be executed, the clientlet should use a secure class loader with an appropriate security policy. (Calling defineClass with a proper CodeSource will work well most of the time, as it will use Warrior's primary policy.)