Avalon AMTAGS version 1.0
Javadoc tags and the avalon container-component contract
This paper documents the tags currently in use and the tags that will likely be used in the feature to encode the semantics of the avalon container-component contract above and beyond the semantics encoded in avalon framework. These semantics are not neccessarily supported by all avalon containers. A container will normally indicate suppport for these tags by stating it supports (a subset or superset of) AMTAGS.
Here's a basic example of a component which has AMTAGS added to it:
/**
{{{ * Avalon component which does things and goes places.
*
* @author Avalon Development Team
* @see <a href="http://avalon.apache.org/amtags">AMTAGS</a> for info on
* the javadoc tags used.
*
* @avalon.service
* type="com.leosimons.my.MyService1"
* @avalon.service
* type="com.leosimons.my.MyService2"
*/ public class MyComponent implements MyService1, MyService2, Servicable { SocketManager m_socketManager;
/** {{{ * @avalon.dependency
type="org.apache.avalon.cornerstone.services.sockets.SocketManager"
- optional=false
*/
public void service(ServiceManager serviceManager)
throws ServiceException
m_socketManager = (SocketManager) serviceManager.lookup(
"org.apache.avalon.cornerstone.services.sockets.SocketManager");
}
- }}}
Basic Grammar
Grammar is basically the same augment BNF as used in RFC 2616.
- (a|b) is used to indicate a choice must be made to include either a or b
- [a] is used to identify that a can be optionally included
- a* is used to indicate zero or more elements can be present
- a+ is used to indicate one or more elements can be present
- whitespace is disregarded; if it must be present, it is indicated using a special marker
SP = space character
HT = tab character
FS = dot character, or full stop
CRLF = newline character(s)
LWS = (SP | HT | CRLF)*
FQCN = fully qualified classname as per java language spec. May be enclosed with double quotes.
RCN = classname which is resolvable to a FQCN within the current file based on the classname resolution as per the java language spec. Note that any FQCN is a RCN, but not all RCNs are FQCNs. May be enclosed with double quotes
WI = work interface as defined in avalon-framework 4, normally a FQCN, can be a RCN in some containers
ROLE = normally a WI, can be a shorthand identifier which is registered in some way with the container
string = valid java string, with continuation across lines as per the javadoc specs, ie the string is continued after a newline if the character following the newline is a a space (disregarding any '*' on that line and the spaces preceding it)
quoted-string = string surrounded by double quotes, '"'
line = valid java string which does not contain newlines as per java language spec
word = valid java string which does not contain LWS as per perl-compatible regular expressions
namespace = word. Identifies a well-known prefix which defines some kind of additional semantics related to the tag
name = word. Identifies a unique tag within a certain namespace which normally defines some kind of additional semantics.
value = (line|quoted-string). Identifies a value to be associated with a certain namespace/name pair.
version = word. Identifies a numerical representation of a version with up to three sections separated by a dot character.
enum = word. The word has to be one option from a predefined list.
General Tag Format
AMTAGS follows the convention set forward by XDoclet. A property is defined as
PROPERTY = word LWS* = LWS* value CRLF
an attribute is defined as
ATTRIBUTE = @ namespace FS name (SP PROPERTY)*
examples of syntactically valid properties are
@avalon.dependency name="hi!"
@color.light.green
@text.message
{{{ key=greeting
value="How are you doing? nice weather today
don't you think?"
The avalon namespace
This namespace is for encoding of semantics which are automatically implied by avalon-framework.
Fail early
Containers SHOULD report an error when they find a tag or property in the avalon namespace they do not understand, and they SHOULD NOT continue setting up the component the unknown property or tag applies to.
component
general format:
@avalon.component
name=(name)
[version=(version)]
lifestyle=(enumeration) applies to: the class of a component
description:
identifies a class as a component. It provides additional information that is important to the container for how to manage the component. The type information is taken from the class name of the component.
properties:
name - the name used in configuration files to represent this component type.
version - the version used for this component implementation. The version is not required but recommended. The information is used in containers that can upgrade components at run time.
lifestyle - the lifestyle that the component was designed for. The lifestyle may be one of four predefined values. If a container does not support the selected value it will not deploy the component.
- 'singleton' - one instance shared between all clients
- 'thread' - one instance per thread
- 'pooled' - each client has a unique instance managed by a pool
- 'transient' - each client has a unique instance created on demand
example:
/**
{{{ * @avalon.component
* version="1.0.0"
* name="my-component"
* lifecycle="singleton"
*/ public class MyComponent implements MyService {
- }}}
dependency
general format:
@avalon.dependency
type=(ROLE|value)
[version=(version)]
[key=(value)]
[optional=(true|false)] applies to: either the service() or the compose() method of a component implementation
description:
identifies an entry in a ServiceManager or ComponentManager this component expects. Whether this tag applies to the ServiceManager or ComponentManager is to be determined from whether the component implements Serviceable (implying the former) or Composable (implying the latter). The component MUST implement exactly one of those two interfaces as per the AF4 contracts.
A container which does not support dependency validation SHOULD ignore this property.
properties:
type - specify the work interface of which the component requires an implementation by setting the name property. A container MUST support a FQCN as a valid value, it MAY support RCN or shorthand names as valid values.
version - specify the version of the work interface we expect to use. this information is not necessary, but recommended.
key - specify the lookup key given to the lookup method. The property defaults to the value of the type property.
optional - specify whether the dependency is needed for proper operation of the component or not. A container MAY ignore this property.
example:
/**
{{{ * @avalon.dependency
* type="org.apache.avalon.cornerstone.services.sockets.SocketManager"
* version="1.0.0"
* key="socket-manager"
* optional=false
*/ public void service(ServiceManager serviceManager) {{{ throws ServiceException {
- }}}
service
general format:
@avalon.service
type=WI
[version=(version)] applies to: either the class of a component implementation or the interface of a service definition
description:
identifies a WI exposed by this component. It's use is similar to the common practice in avalon-framework components to specify a public final static String ROLE member. If this tag is used in the JavaDocs for an interface, then the interface name will be automatically used for the type.
properties:
type - specify the work interface this component exports. version - specify the version of the work interface for the exported service.
example:
/**
{{{ * @avalon.service
* type="com.leosimons.my.MyService1"
* version="1.0.1"
* @avalon.service
* type="com.leosimons.my.MyService2"
*/ public class MyComponent implements MyService1, MyService2 {
- }}}
Alternatively, we can use this approach:
/**
{{{ * @avalon.service version="1.0.1"
*/ public interface MyService1 {
- }}}
The phoenix namespace
This namespace is for encoding of semantics which are implied by Avalon-Phoenix. See http://avalon.apache.org/phoenix/bdg/doclet-tags.html, which is currently out of date.
The merlin namespace
This namespace is for encoding of semantics which are implied by Avalon-Merlin. See http://avalon.apache.org/sandbox/merlin/meta/index.html.
The ecm namespace
This namespace is for encoding of semantics which are implied by Excalibur's Component Manager (ECM). It is currently empty.
The fortress namespace
This namespace is for encoding of semantics which are implied by Avalon-Fortress. It is currently still undocumented.