[jsword-devel] ActionFactory and ResourceBundles

DM Smith jsword-devel@crosswire.org
Sat, 03 Apr 2004 17:26:27 -0500


This is a multi-part message in MIME format.

------=_NextPart_000_475c_787e_4aa0
Content-Type: text/plain; format=flowed

I have created a few new classes:
ActionFactory, creates actions from a ResourceBundle
CWAction, a custom action that implements delegation
CWClassLoader, a custom class loader needed to load resource bundles

I used CW as an abbreviation for CrossWire (I could not figure out what the 
prefix Eir meant. But I guess that it was from another project.)

I chose to implement independent classes so that they could be evaluated 
without affecting existing code.

ActionFactory and CWAction are as I described them earlier.

To use ActionFactory create one after calling Project.instance(). This 
allows for overrides to be gotten from ~/.jsword.

Since it is not attached to the program, to see its behavior set breakpoints 
in ActionFactory and step away to your heart's content.

I initially started with Properties and using ResourceUtil worked like a 
charm. It would load resources from files located in resource.jar named 
a.b.c.xxx.properties or from a jar along a path a/b/c/xxx.properties.

However, ResourceUtil is fine for directly loading resources into 
properties, but ResourceBundle uses its classloader to find and get 
resources. And it tries for more than one resource. It also accepts calls of 
the form "ActionFactory" and "org.crosswire.common.swing.ActionFactory" to 
load the same file when called from org.crosswire.common.swing classes.

But it chokes on absolute paths. The reason is that ResourceBundle 
interprets the names and then calls on its classloader in such a way that 
cannot find them. The net effect of this is that without providing a custom 
classloader, the resource had to be in the same directory as the class.

Bummer.

I figured we wanted to have a file 
org.crosswire.common.swing.ActionFactory.properties in the resource 
directory and that a developer could place a copy of it in ~/.jsword and 
modify it.

This required a custom classloader. In reading up on Java 2 class loaders, I 
found that it is only necessary to override findResource. I also wanted to 
use the calling classes getResource if possible. With some more reading I 
found a technique to get the call context. [ I still need to test this in a 
WebStart environment to see if it works. If not I need to going back to 
passing the calling class into the constructor for the custom class loader ]

At first I used ResourceUtil to get the resources, but I found some 
scenarios that it would not handle. The biggest was getting a ResourceBundle 
for a class by simple name (e.g. "ActionFactory").
When I did this it expanded it in a way that ResourceUtil was not set up to 
handle. And then the form org.crosswire.common.swing.ActionFactory was 
re-interpreted into that same form. I started to add code to ResourceUtil, 
but ripped it back out. I did leave in some internal refactoring that makes 
the class more self documenting.

I am using ResourceUtil.getHomeResource from the new classloader.

To use the classloader pass it as the third argument to 
ResourceBundle.getBundle.
I did it like this:
ResourceBundle resources =
    ResourceBundle.getBundle(getClass().getName(),
         Locale.getDefault(),
         new CWClassLoader());

_________________________________________________________________
Tax headache? MSN Money provides relief with tax tips, tools, IRS forms and 
more! http://moneycentral.msn.com/tax/workshop/welcome.asp

------=_NextPart_000_475c_787e_4aa0
Content-Type: application/x-zip-compressed; name="patchloader.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="patchloader.zip"

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
dFBLBQYAAAAAAQABAD0AAABUJAAAAAA=


------=_NextPart_000_475c_787e_4aa0--