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:

  1. Implement the Accessor interface.
    public class FooAccessor implements Accessor {
      public Object get(HttpServletRequest request) {
        return "bar";
      }
      public boolean isCacheable() {
        return true;
      }
    }
    
  2. 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.