# InputModules

## Introduction

Input modules are generic components that let one map a key to one or more values. In concept and API, input modules are closest to the java.util.Properties class. An input module has a number of named attributes, each of which has an associated value or values, which will be computed or looked up when requested.

        |       InputModule          |
        |----------------------------|
        | PropName   | PropValue(s)  |
        |----------------------------|
        | prop1      | value1        |
        | prop2      | value2        |
        | ...        | ...           |
        | propn      | valuen        |
        +----------------------------+

Three operations are defined by the InputModule interface:

getAttributeNames
  Retrieve a list of all available attributes (the set prop1, prop2, ..., propn).
getAttribute
  Retrieve the value of an attribute. For instance, `getAttribute(prop1)` would return value1
GetAttributeValues
  Retrieve an Iterator for a list of values for an attribute.

## Usage

Input modules are used in various places in Cocoon, notably from within the sitemap, XSPs, and matchers.

In the sitemap, input modules are made available through a {modulename:attributename} syntax. For instance, if a RequestParameterModule named `request-param` is defined in cocoon.xconf, then `{request-param:user}` will in effect be replaced by the value of the `user` request parameter (e.g. index.html?user=joe). Similarly, a SystemPropertyModule named `system-property` would allow `{system-property:user.home}` to represent user's home directory path.

## Configuration

Input modules are declared in cocoon.xconf. There is a section dedicated to input modules:

      <input-modules>
        <component-instance name="global"
                 class="org.apache.cocoon.components.modules.input.GlobalInputModule"
                 logger="core.modules.input"/>
        <component-instance name="request"
                 class="org.apache.cocoon.components.modules.input.RequestModule"
                 logger="core.modules.input"/>
        <component-instance name="session"
                 class="org.apache.cocoon.components.modules.input.SessionModule"
                 logger="core.modules.input"/>
        <component-instance name="request-param"
                 class="org.apache.cocoon.components.modules.input.RequestParameterModule"
                 logger="core.modules.input"/>
        ...
        <component-instance name="defaults"
                 class="org.apache.cocoon.components.modules.input.DefaultsModule"
                 logger="core.modules.input">
          <values>
            <skin>defaultSkin</skin>
            <base-url>http://localhost:8080/cocoon</base-url>
          </values>
        </component-instance>
      <input-modules>

### Static/dynamic configuration

In cocoon.xconf, each input module can take a static configuration. This is made available to the class via the `configure()` method, called once on startup. In the example above, an Avalon `Configuration` object representing the <values> node will be passed to the DefaultsModule.

In addition, every time an input module is used, a dynamic configuration is passed to it, as well as the current "object model". You can see these in the InputModule interface definition for all three methods. This dynamic, per-request configuration will usually override the static configuration. This dual static/dynamic configuration makes input modules useful in a wide variety of circumstances.

## Meta Modules

So-called "meta" modules are modules that act on other modules. The simplest example of a meta module is the SimpleMappingMetaModule, which will query another module with a modified version of an attribute name. For instance, if configured with:

    <component-instance name="mappingmodule"
        class="org.apache.cocoon.components.modules.input.SimpleMappingMetaModule"
        logger="core.modules.mapper">
      <input-module name="xmlmodule"/>
      <prefix>/site/</prefix>
      <suffix>/@href</suffix>
    </component-instance>

Then a key `foo` will cause `xmlmodule` to be queried for attribute `/site/foo/@href`, and that value will be returned.

Another useful example is ChainMetaModule, which will query a set of input modules until one returns a non-null value for an attribute, providing "fall-back" behaviour.

The machinery for meta modules is provided in AbstractMetaModule.

## JXPath use in Input Modules

Many input modules make use of the JXPath library, which lets one traverse Java object structures with an XPath-like syntax. Support for this is mostly located in the JXPathMetaModule and AbstractJXPathModule superclasses, which should be kept synchronised.

## Further Information

The best way to learn what can be done with input modules is by examining the samples that come with the Cocoon application. The main Cocoon documentation and Cocoon Wiki should have further information.