3.5. Referencing Resources

Web applications work over the web and have various resources, such as images or downloadable files, that the web browser has to get from the server. These resources are typically used in Embedded (images) or Link (downloadable files) user interface components. Various components, such as TabSheet, can also include icons, which are also handled as resources.

A web server can handle many of such requests for static resources without having to ask them from the application, or the Application object can provide them. For dynamic resources, the user application must be able to create them dynamically. IT Mill Toolkit provides resource request interfaces for applications so that they can return various kinds of resources, such as files or dynamically created resources. These include the StreamResource class and URI and parameter handlers described in Section 9.3.1, “URI Handlers” and Section 9.3.2, “Parameter Handlers”, respectively.

IT Mill Toolkit provides also low-level facilities for retrieving the URI and other parameters of a HTTP request. We will first look into how applications can provide various kinds of resources and then look into low-level interfaces for handling URIs and parameters to provide resources and functionalities.

Notice that using URI or parameter handlers to create "pages" is not meaningful in IT Mill Toolkit or in AJAX applications generally. Please see Section 9.2, “Special Characteristics of AJAX Applications” for a detailed explanation.

3.5.1. Resource Interfaces and Classes

IT Mill Toolkit has two interfaces for resources: a generic Resource interface and a more specific ApplicationResource interface for resources provided by the application.

Figure 3.7. Resource Interface and Class Diagram

Resource Interface and Class Diagram

ApplicationResource resources are managed by the Application class. When you create such a resource, you give the application object to the constructor. The constructor registers the resource in the application using the addResource method.

Application manages requests for the resources and allows accessing resources using a URI. The URI consists of the base name of the application and a relative name of the resource. The relative name is "APP/"+resourceid+"/"+filename, for example "APP/1/myimage.png". The resourceid is a generated numeric identifier to make resources unique, and filename is the file name of the resource given in the constructor of its class. However, the application using a resource does not usually need to consider its URI. It only needs to give the resource to an appropriate Embedded or Link or some other user interface component, which manages the rendering of the URI.

3.5.2. File Resources

File resources are files stored anywhere in the file system. The use of file resources falls into two main categories: downloadable files and embedded images.

The file that can be retrieved using a file resource is defined with standard java.io.File class. You can create the file either with an absolute or relative path, but the base path of the relative path depends on the installation of the web server. For example, in Tomcat, the default current directory is the installation path of Tomcat.

3.5.3. Class Loader Resources

The ClassResource allows resources to be loaded from the deployed package of the application using Java Class Loader. The one-line example below loads an image resource from the application package and displays it in an Embedded component.

mainwindow.addComponent(new Embedded ("", new ClassResource("smiley.jpg", mainwindow.getApplication())));

3.5.4. Theme Resources

Theme resources are files included in a theme, typically images. See Chapter 6, Themes for more information on themes.

3.5.5. Stream Resources

Stream resources are application resources that allow creating dynamic resource content. Charts are typical examples of dynamic images. To define a stream resource, you need to implement the StreamResource.StreamSource interface and its getStream method. The method needs to return an InputStream from which the stream can be read.

The following example demonstrates the creation of a simple image in PNG image format.

import java.awt.image.*;

public class MyImageSource implements StreamResource.StreamSource {
    ByteArrayOutputStream imagebuffer = null;
    int reloads = 0;
    
    /* Must implement this method that returns the resource as a stream.*/
    public InputStream getStream () {
        /* Create an image and draw something on it. */
        BufferedImage image = new BufferedImage (200, 200, BufferedImage.TYPE_INT_RGB);
        Graphics drawable = image.getGraphics();
        drawable.setColor(Color.lightGray);
        drawable.fillRect(0,0,200,200);
        drawable.setColor(Color.yellow);
        drawable.fillOval(25,25,150,150);
        drawable.setColor(Color.blue);
        drawable.drawRect(0,0,199,199);
        drawable.setColor(Color.black);
        drawable.drawString("Reloads="+reloads, 75, 100);
        reloads++;

        try {
            /* Write the image to a buffer. */
            imagebuffer = new ByteArrayOutputStream();
            ImageIO.write(image, "png", imagebuffer);
            
            /* Return a stream from the buffer. */
            return new ByteArrayInputStream(imagebuffer.toByteArray());
        } catch (IOException e) {
            return null;
        }
    }
}

The content of the generated image is dynamic, as it updates the reloads counter with every call. The ImageIO.write() method writes the image to an output stream, while we had to return an input stream, so we stored the image contents to a temporary buffer.

You can use resources in various ways. Some user interface components, such as Link and Embedded, take their parameters as a resource.

Below we display the image with the Embedded component. The StreamResource constructor gets a reference to the application and registers itself in the application's resources. Assume that main is a reference to the main window and this is the application object.

/* Create an instance of our stream source. */
StreamResource.StreamSource imagesource = new MyImageSource ();
	
/* Create a resource that uses the stream source and give it a name. The
 * constructor will automatically register the resource in the application. */
StreamResource imageresource = new StreamResource(imagesource, "myimage.png", this);
	
/* Create an embedded component that gets its contents from the resource. */
main.addComponent(new Embedded("Image title", imageresource));

The image will look as follows:

Figure 3.8. Screenshot of the stream resource example with an embedded image

Screenshot of the stream resource example with an embedded image

We named the resource as myimage.png. The application adds a resource key to the file name of the resource to make it unique. The full URI will be like http://localhost:8080/testbench/APP/1/myimage.png. The end APP/1/myimage.png is the relative part of the URI. You can get the relative part of a resource's URI from the application with Application.getRelativeLocation().

Another solution for creating dynamic content is an URI handler, possibly together with a parameter handler. See Section 9.3.1, “URI Handlers” and Section 9.3.2, “Parameter Handlers”.