Access API
The access API classes are located in package de.odysseus.calyxo.base.access. The API allows application developers to implement their own accessors and add them to the hierarchy. The fundamental types are Accessor and AccessorMap. Roughly, these two keep the whole secret of how accessors work.
Accessors
The central interface is Accessor. It acts as a provider for objects, usually Java beans, Maps or Collections. The
public Object get(HttpServletRequest request)
method will be called during expression evaluation for that purpose. The
public boolean isCacheable()
method should answer true iff the object returned by get() may be cached during a request. In other words, if the method doesn't use data which may change during the request. In this case, the get() method will be called only once per request.
Accessor Maps
An AccessorMap collects Accessors in a map. As such, it provides methods to put or remove accessors. Since it implements the Accessor interface itself, it may even contain nested AccessorMaps.
Its get(HttpServletRequest) method answers a map whose get(Object) method selects an Accessor by key and delegates to its get(HttpServletRequest) method.
Access Support
The AccessSupport class will be instantiated once per module and encapsulates the root AccessorMap. The class provides several static getInstance(...) methods to retrieve the module's instance. The put(Object, Accessor) method is used to add an accessor. The create(HttpServletRequest) method delegates to get(HttpServletRequest) of the wrapped AccessorMap.
Access Exceptions
The Accessor's get(HttpServletRequest) method does not declare an Exception. This is because accessors usually delegate to other objects, especially to maps and since the Map.get(Object) method doesn't declare an exception either.
The API defines the runtime exception class AccessException, which should be thrown by accessors or by beans and maps returned by accessors.
Other Classes
The package contains a couple of other classes, which may serve as base classes for accessor implementations. Please refer to the API documentation for information on these.
Quick Example
To provide your own accessors, do the following:
-
Implement the Accessor interface.
public class FooAccessor implements Accessor { public Object get(HttpServletRequest request) { return "bar"; } public boolean isCacheable() { return true; } } -
Implement a plugin (either Calyxo Control or Struts, depending on your environment).
During initialization, add your accessor to the module's AccessSupport
under a unique key. The following code puts an accessor map, containing our
FooAccessor under key "foo", into key
"sunshine":
ModuleContext moduleContext = ... AccessSupport accessSupport = AccessSupport.getInstance(moduleContext); AccessorMap accessors = new AccessorMap(); accessors.put("foo", new FooAccessor()); accessSupport.put("sunshine", accessors);As an alternative (and probably much cooler), you could express the above in a configuration file with<use> <member class="de.odysseus.calyxo.base.access.AccessSupport"> <method name="getInstance"> <arg value="${moduleContext}"/> </method> </member> <method name="put"> <arg value="sunshine"/> <arg> <object class="de.odysseus.calyxo.base.access.AccessorMap"> <method name="put"> <arg value="foo"/> <arg> <object class="...FooAccessor"/> </arg> </method> </object> </arg> </method> </use>
The <base:access> tag calls AccessSupport.create(HttpServletRequest) and stores the returned map into request scope. This map will delegate to your accessor's get(HttpServletRequest) method, when its key is requested as in the following code:
<base:access var="calyxo"/>
...
Let's go to the ${calyxo.sunshine.foo}...
For more realistic code, see the various accessor implementations in package de.odysseus.calyxo.base.misc.


