The MMBase Resource loader


Table of Contents

1. What is a Resourceloader?
2. Reading one specific Resource
3. Fall back mechanism and shadowing
4. Multiple resources
5. Resource writing, and existance checking.
6. Resource builder
7. Resource editor

As every application, MMBase has very many configuration options. Most of these configurations are defined by means of XML Documents. Naively, one associates XML documents with files, and the XML Document objects are created by opening those files from the file system.

MMBase is however based on java and java servlet technology, where the more generic concept of 'resource' may be used in stead of files. E.g. a 'jar' is a compressed file containing a set of 'resources' which can be used rather like files in java code. A complete 'web application' can be packed into a so called 'war' ('web application archive') file. A war is a special kind of jar file with the purpose to contain all necessary resources for a web application.

A typical example of a resource is a java class. The 'ClassLoader' of a java web application knows how to load these from all jars in WEB-INF/lib and from all files in WEB-INF/classes. You do that with the method 'getResource(String name)' of ClassLoader. This returns an URL object by the name of the resource.

getClass().getClassLoader().getResource("java/lang/String.class").toString());
Such an URL typically looks like this then:
jar:file:/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/classes.jar!/java/lang/String.class

Actually ClassLoaders are not restricted to loading classes, but they can load any type of 'resource', as long as they are presented in the 'CLASS PATH' of the JVM. Which in practice means that these resources must be either present in a 'jar' in WEB-INF/lib or as a file in WEB-INF/classes. You can e.g. place configuration like so. The result of

getClass().getClassLoader().getResource("oscache.properties").toString());
file:/Users/mmbase/mmbase18/WEB-INF/classes/oscache.properties

Resources that cannot be loaded by the ClassLoader of a web application but are part of the web-application, can be loaded with the 'getResource(String)' method on the ServletContext object. E.g. lets get the same resource, but now on this way. Like this, with a jsp scriptlet:

pageContext.getServletContext().getResource("/WEB-INF/classes/oscache.properties")
jndi:/localhost/mm18/WEB-INF/classes/oscache.properties
.

So, there are several methods to load resources, and every method has its own advantages and disadvantages. A file can easily be changed and 'watched' for changes, a classloader has a provision for 'multiple' resources with the same name (every jar can contain a copy of the same file), and the servletContext method can access resources, even if the 'war' is still packed .

The idea of the MMBase Resource Loader is now, that MMBase decides which way of loading a certain resource is the best. A good way is a way that works, so methods that don't work are ignored. If for example the MMBase resource 'builders/core/object.xml' is not available as a File (which we like most, because they can easily be changed and updated), then the resource can be accessed as such. If it is not available as a file, then it tries to do it with a ClassLoader or with a ServletContext. For more details, see also the javadoc of org.mmbase.util.ResourceLoader

The MMBase Resource Loader itself extends from ClassLoader. So, it works like a Class Loader, and it basicly serves to produces URL's or InputStreams for you. We add a few convience methods like getting a Document immediately (because we have to deal with XML so much...)

MMBase resources come in several different flavours, whith which different ResourceLoader instances are associated. The most important one is the 'ConfigurationLoader', because we mainly think of configuration.

ResourceLoader configLoader = ResourceLoader.getConfigurationRoot();
There are also ResourceLoaders for resolving relative to the web-application root, or the file system root. Furthermore new ResourceLoaders can be instantiated which are relative to one of these staticly defined root ResourceLoaders:
ResourceLoader builderLoader = ResourceLoader.getConfigurationRoot().getChildResourceLoader("builders");

Because a resource with certain name can be represented with several URL's, corresponding to the several strategies which are applied by the ResourceLoader, a kind of conflict resolution mechanism is required. If multiple resources with the same name are available, then they have a certain order, and the first one is obtained when you request one Resource.

The precise mechanism is documented in the javadoc of ResourceLoader.

The implementor can also decide that conflict resolution is not actually needed, but that simply all URL's can be used. The resulting resources can probably be merged. A lot of configuration XML's for example merely state a list of things ('all caches', 'all datatypes', 'all functionset' etc), so it is quite trivial to deal with a multiple of such XML Documents (Create one List containing all those things).

As said, resource-loading is based on URL's. Urls also have a way to acquire an output stream, so they can actually also be used to write something to a certain Resource.

Therefore a resource URL is never null, because even if it doesn't exist, you may want to create it. You can check however if a resource exists, by checking getDoInput on a connection to that URL, or getDoOutput to check for write possibility. This is a bit different from the standard class loader implementation, which returns 'null' as the URL for non-existing resources.

If the application server has no (sufficient) write-access to the file-system, then, because ResourceLoader is not necessarily out of luck when it wants to write a resource, because being an MMBase tool it can of course relatively easily use MMBase nodes to store blobs. It can use the 'resources' builder for that (if installed). It works by using bridge, and class-security, to gain rights, for writing.

In the mmbase/admin pages a 'resource' editor can be found. It can be used to browse through existing resources, and even to edit them. Whether one wants to actually use this tool is disputable, but at least it serves as a good example of the features of the MMBase Resource Loader.


This is part of the MMBase documentation.

For questions and remarks about this documentation mail to: [email protected]