[Image] EchoPoint
Helping you build truly dynamic and stateful web applications!
nothing

Web Resources In Echo Applications

By Brad Baker
Saturday, March 13, 2004

Monitoring the NextApp Echo forums at http://forum.nextapp.com/forum I have notice that a few people are having trouble finding web application resources in their Echo applications.  So in response, I have written this article to explain how to find you application's resources and ways to ensure they are presented in a consistent and manageable way.

I don't want to go over all the finer details on J2EE web application packaging.  I will assume you know the basics of how to get access to image, html and JSP files. 

However Echo is a such a rich web framework, that it opens up opportunities for using resources that most page based web frameworks can not contemplate.

Our Example Web Application

For the purposes of this article I am going to outline the structure of a web application, specifically the EchoPoint Demo web application.  On my development system it resides in a directory as follows :

 c:\java\echopoint\projects\demo\
                               \echo-jsp   <-- jsp resources here
                               \images     <-- image resources here
                               \src\
                                   \echopoint\demo\panels
                                                  \resource\
                                                           \images      <-- images here
                                                           \stylesheets <-- stylsheets here
                                                           \templates   <-- html templates here
                                                           
                               \stylesheet <-- stylsheet resources here
                               \swf        <-- flash resources here
                               \WEB-INF\
                                       \lib
                                       \classes\   <-- compile classes here

This directory structure is what I put in CVS, except, of course, for the compiled .class files. Then when I deploy to Tomcat, the directory structure looks like this :

 c:\java\tomcat-4.1.24\webapps\echopointdemo\
                                           \echo-jsp
                                           \images
                                           \stylesheet
                                           \swf
                                           \WEB-INF\
                                           \lib
                                           \classes\
                                                   \echopoint\demo\panels\
                                                                         \resource\
                                                                                  \images
                                                                                  \stylesheets
                                                                                  \templates
                                                                                  

So the challenge then is to gain access to the web application resources, such as the JSP pages in \echo-jsp or the GIF images in \images or even the templates that are contained in WEB-INF\classes\echopoint\demo\resource\templates. 

Notice how in my development directory structure, resources are under /src, while once its deployed to Tomcatm the resources get moved to /WEB-INF/classes.  We will talk about this more later on.

Simple Access Provided By The Application Server

Your J2EE application server of choice, in my case Tomcat, will provide access to the resources starting from the root context of your web application. For example to access image astronaut.jpg, which is located at \echopointdemo\images\astronaut.jpg, one would do this in Echo :

ImageReference icon = new HttpImageReference("images/astronaut.jpg")

This resource is found from the "root context" of the web application and is served to the browser using standard HTTP web serving.

But suppose you want to read the actual JPEG byte stream, perhaps to filter it first? How would you do that?

Or suppose you wanted to get access to the CSS stylesheet data and apply it to web application at startup? How would you do that?

Programatic Access Provided By The Application Server

The J2EE application server also expose a ServletContext interface that allows you to access to resources in your web application, starting at the "root context" directory. To gain access to this interface, you would do something like this in Echo :

ServerContext serverC = (ServerContext) getEchoInstance().getAttribute(ServerContext.ATTRIBUTE_NAME);
ServletContext sc = serverC.getServletConfig().getServletContext();

To quickly explain, the EchoInstance has a list of attributes associated with it, one of which is the nextapp.echoservlet.ServerContext object. This in turn has a link to the underlying javax.servlet.ServletConfig and then to the javax.servlet.ServletContextFor more info look here.

You can then access resources under the root ServletContext like this :

java.net.URL url;
url = sc.getResource(
"/stylesheet/echopoint.css");
url = sc.getResource("/WEB-INF/classes/echopoint/demo/resource/templates/test1.html");
url = sc.getResource(
"/images/astronaut.jpg");

This gives you back a java.net.URL whcih you can then open as a stream to read the contents of these resources. So for example to use the echopoint.css stylesheet resource, you could write code like this :

url = sc.getResource("/stylesheet/echopoint.css");
try {
     CssStyleSheet styleSheet = CssStyleSheet.getInstance(url);
     styleSheet.applyTo(myWindow,true);
} catch (StyleSheetParseException e) {
     e.printStackTrace();
}

The same applies to HTML templates, since the HtmlTemplatePanel has method to set the template via an URL as well :

url = sc.getResource("/WEB-INF/classes/echopoint/demo/resource/templates/test1.html");
HtmlTemplatePanel htmlPanel = new HtmlTemplatePanel();
htmlPanel.setTemplate(url);

Programatic Access Provided By Java Class Loaders

There is another way to get access to resources in Java, and that by using the java.lang.Class.getResource() method. This method will using the class's class loader to find the resource and then return an URL to it.

url = getClass().getResource("/echopoint/demo/resource/images/astronaut.jpg");

Again this returns a java.net.URL that allows you to open the resource as a stream. The java.net.URL class is so handy as a "moniker" for an application resource, that most of the APIs in Echo that require a resource use URLs.

This class resource loading strategy is great if you have "static" resources that "logically belong" with the class that uses them. For example the echopoint.ExpandableSection class has a "toggle image" that is the visual artifact with which users "expand" or "collapse" the component. This "toggle image" resource logically belongs with the code, rather than as web application resource starting from context root. If it sits alongside its class file, then it wont be lost during the build process and its name can be known without special configuration. You dont need to leave instructions like "copy this file to special location A" to use this class.

This also has advantages when using a source control system like CVS. All source and resource files can be stored in their logical areas, managed in CVS as units and then resources can still be found at run time via a reliable mechanism.

Loading HTML Templates in EchoPoint

One of the most common uses of the EchoPoint library is the use of HtmlTemplatePanels for application visuals.  This is fully explained in this article.

The HTML template functionality works by reading the template data from an object that implements echopoint.template.DataSource. The most common DataSource implementor class is echopoint.template.CachedFileDataSource.  This will class will take a java.io.File object or a java.net.URL object.

url = sc.getResource("/WEB-INF/classes/echopoint/demo/resource/templates/test1.html");
HtmlTemplatePanel htmlPanel = new HtmlTemplatePanel();
DataSource dataSource = new CachedFileDataSource(url);

htmlPanel.setTemplate(dataSource);

So using the URL loading facilities discussed above, you can provide a java.net.URL to a echopoint.template.CachedFileDataSource.

However there is an advantage of using a java.io.File instead because the templating feature can know "when the template data has changed" based on the last modified date of the file.  Whereas when you use a java.net.URL, the last modified date of the template data is unknown.

This is most useful when you are in development.  You might to "edit" a template resource while running the web application, say to fix a small bug in presentation.  However if you use a java.net.URL as the template data source input, then the templating function wont know its changed and this dynamic "change" nature will be lost.  How can you get around this I hear you ask?

Well there is a new DataSource implementing class called echopoint.template.SwitchedDataSource.  It uses a 3 step strategy to getting template data.  It constructor has a fileDirectoryPrefix, a fileOrResourceName and optionally an EchoInstance as parameters.

public SwitchedDataSource(String fileDirectoryPrefix, String fileOrResourceName, EchoInstance echoInstance) throws IOException  {
   ...
   ...
}

ds = new SwitchedDataSource("/java/echopoint/projects/demo/src", "/echopoint/demo/resource/templates/test1.html", getEchoInstance());

The first thing is does is look for a file called fileDirectoryPrefix + fileOrResourceName.  If it exists then it uses that as the template data source.  The directory prefix you use is probably the directory structure to your project.  So in the above example it will look for a file called :

"/java/echopoint/projects/demo/src/echopoint/demo/resource/templates/test1.html"

If it step doesnt succeed, then it looks in the EchoInstance for a ServletContext and tries to find the resource using only the fileResourceName.  In this case it would be equivalent to :

servletContext.getRsource("/echopoint/demo/resource/templates/test1.html");

And if that doesnt succeed, it uses java class loading on the resource, as in :

getClass().getRsource("/echopoint/demo/resource/templates/test1.html");

This is great when changing the template data in development.  The original "source" template file can be changed, under CVS control.  And when you move to a production deployment, the template data will reside somewhere in the web root context directory.   As long as you keep the "relative" path names the same, then SwitchedDataSource will pick them up.

Loading Images in EchoPoint with URLs

There is a new class in EchoPoint called echopoint.image.URLImageReference.  It allows you to get an nextapp.echo.ImageReference to any resource you can get an URL to.  In someways is the same as the nextapp.echo.ResourceImageReference class.  However it is more generic in that it uses any URL not just java class loaded URLs, which is what ResourceImageReference does.

So if you can get an URL to an image resource, then echopoint.image.URLImageReference can display it in an Echo application.  And since you can get and URL from just about anywhere, include classes and files, it makes it really useful.  URLS rock!

 


Home

SourceForge Logo

The EchoPoint project is kindly hosted by SourceForge