You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Scott Sayles <sc...@hotmail.com> on 2000/01/07 14:20:40 UTC

proposal for LoadableResource

Hello,

I'm throwing this out here just to see if anyone might think this is
worthwhile for adding to Struts.

I recently created a small web application using Struts to allow users to
upload to predifined directories on the server.  There were two xml resource
files that I had setup a Digester to read and then populate some hashtables
with objects.   Like the Struts form beans, action forwards, etc., I
provided these as application scope resources for the context.  To make a
long story short, I've since been working on another application using
Struts that will fold in that upload application under a single context.
This application is being designed so that additional functions
(subapplications? subfunctions? I hope you get what I mean) like the upload
app can be added in with as little hassle as possible.  In the upload
application I simply extended the ActionServlet and overloaded the init() to
include my specific initilization tasks for adding the resources as context
attributes.  As I pondered over the fact that this other application will
likely expand to incorporate many conceptually different functions with
needs like the upload, I devised a simple mechanism for adding in context
attributes on the fly (and with the Digester it was really easy).

The basic idea is that you've got some kind of object, like a repository of
some sort, that you'd like to set as a context attribute without having to
hardcode it into your ActionServlet init().

I'm sure there are any number of other ways to do this, like having static
initializers or another initializer class, but without getting into the whys
and why nots here's what I did:



- In an xml file (like perhaps struts-config) define the "resources" you
want loaded

 ============================================
  <struts-config>
    (...)
         <!-- loadable application resources -->
     <resources>

         <resource   name="com.saxonmtg.web.internal.ROLE_REPOSITORY"
                   className="com.saxonmtg.web.interna.RoleRepository"
                     loadParm="/usr/local/resources/roles-config.xml"/>

         <resource   name="com.saxonmtg.web.upload.DIRECTORIES"
                   className="com.saxonmtg.web.upload.Directories"

loadParm="/usr/local/resources/upload/directories.xml"/>
    </resources>
     (...)
 </struts-config>
 ============================================

    name - attribute key
    class - class to instantiate
    loadParm - a parameter to pass when loading  (more on that below)


- The attributes could be added (via a Digester) to some kind of mapping
object, but I simply put name/class objects into a hashtable and had the
loadParm passed immediately as an argument

   ================================================
    ... in the ActionServlet ...

    protected Hashtable resources = new Hashtable();

    protected Digester initDigester() {
        ...
        digester.addCallMethod("struts-config/resources/resource",
                                                "addResource", 3);
        digester.addCallParm("struts-config/resources/resource", 0,
                                                "name");
        digester.addCallParm("struts-config/resources/resource", 1,
                                                "className");
        digester.addCallParm("struts-config/resources/resource", 2,
                                                "loadParm");
        ...
    }

    protected void addResource(String name, String className, String
loadParm) {
            (...see below...)
    }

   ================================================



- Each resource would implement a LoadableResource interface

    ================================================
        public interface LoadableResource
        {

            public void load(String loadParm) throws SomeKindOfException;

            public void reload() throws SomeKindOfException;

        }
    ================================================
    The ActionServlet could simply treat each object as a LoadableResource
object and do stuff like loop through the collection and call the load
method on each object.



-  You'd probably want to be able to set and retrieve the loadParm with get
and set methods, but anyway here's one possible implementation of the
addResource method:

    =============================================================
    protected void addResource(String name, String className, String
loadParm)
    {
        try {
            LoadableResource resource =
(LoadableResource)Class.forName(className).newInstance();
            resource.load(loadParm);
            resources.put(name, className);
            getServletConfig().getServletContext().setAttribute(name,
resource);
        }
        catch(SomeExceptions e) {
            ...(log it or something)
        }
    }
    ==============================================================

and then a reload method
    ==============================================================

    protected void reloadResources()
    {
        LoadableResource resource = null;
        ...
        while(keys.hasMoreElements())  {
            resource = resources.get(keys.getNextElement());
            try {
                resource.reload();
            }
            catch(Exception e) {}
        }
    }
    ==============================================================

This could most certainly be polished up, but I'm mainly just trying to get
the idea across.
The bottom line is that you can simply implement the LoadableResource
interface, and then add the appropriate attributes in the config file and
(viola!) the servlet will load it and set it as an context attribute.  You
wouldn't have to hardcode the initialization in your action servlet.

Well, I'm about out of breath now so I'll leave it at that.

Thanks for reading this far.   ;)

Scott



Re: proposal for LoadableResource

Posted by Scott Sayles <sc...@hotmail.com>.
Sorry.  One correction.

resources.put(name, className);
==> should have been:  resources.put(name, resource);

=============================================================
 protected void addResource(String name, String className,
                                                          String loadParm)
 {
     try {
         LoadableResource resource =

(LoadableResource)Class.forName(className).newInstance();
          resource.load(loadParm);
   **   resources.put(name, resource);  **
          getServletConfig().getServletContext().
                       setAttribute(name, resource);
(..)