You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by le...@apache.org on 2002/05/03 12:19:54 UTC
cvs commit: jakarta-avalon/src/xdocs/framework features.xml for-developers-changes.xml for-developers-project-structure.xml getting-started.xml guide-cop-in-avalon.xml guide-cop-what-is.xml guide-oop-best-practices.xml guide-patterns-in-avalon.xml guide-patterns-ioc-security.xml guide-patterns-ioc.xml guide-patterns-soc.xml guide-patterns-soii.xml guide-patterns-what-are.xml guide-where-to-go-from-here.xml reference-the-lifecycle.xml announcement.xml book.xml designing-a-component.xml index.xml changes.xml inversion-of-control.xml lifecycle.xml patterns.xml reuse-standards.xml security.xml separation-of-concerns.xml separation-of-interface-and-implementation.xml what-is-a-component.xml what-is-a-composer.xml
leosimons 02/05/03 03:19:54
Modified: src/xdocs/framework announcement.xml book.xml
designing-a-component.xml index.xml
Added: src/xdocs/framework features.xml for-developers-changes.xml
for-developers-project-structure.xml
getting-started.xml guide-cop-in-avalon.xml
guide-cop-what-is.xml guide-oop-best-practices.xml
guide-patterns-in-avalon.xml
guide-patterns-ioc-security.xml
guide-patterns-ioc.xml guide-patterns-soc.xml
guide-patterns-soii.xml guide-patterns-what-are.xml
guide-where-to-go-from-here.xml
reference-the-lifecycle.xml
Removed: src/xdocs/framework changes.xml inversion-of-control.xml
lifecycle.xml patterns.xml reuse-standards.xml
security.xml separation-of-concerns.xml
separation-of-interface-and-implementation.xml
what-is-a-component.xml what-is-a-composer.xml
Log:
complete overhaul of the framework documentation. Changed the organisation, added some new information, removed quite a bit of duplication.
Revision Changes Path
1.2 +59 -59 jakarta-avalon/src/xdocs/framework/announcement.xml
Index: announcement.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon/src/xdocs/framework/announcement.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- announcement.xml 31 Jan 2002 15:43:52 -0000 1.1
+++ announcement.xml 3 May 2002 10:19:53 -0000 1.2
@@ -1,59 +1,59 @@
-<?xml version="1.0"?>
-
-<announcement>
- <title>@Name@ @version@</title>
- <abstract>The Avalon team is proud to announce the @version@ @status@ release
-of the @Name@.</abstract>
-
- <project site="http://jakarta.apache.org/avalon">
- <title>Avalon</title>
- <description>
- The Avalon project is Apache's Java Server Framework. It is
- separated into five sub projects: Framework, Excalibur, LogKit,
- Cornerstone, and Phoenix. Its purpose is to simplify
- server side programming for Java based projects. It
- formalizes serveral best of breed practices and patterns for
- server side programming.
- </description>
- </project>
-
- <project site="http://jakarta.apache.org/avalon/@name@">
- <title>@Name@ @version@</title>
- <description>
- <para>
- The Avalon Framework formalizes the contracts and patterns used in the
- other Avalon projects. It is derived from modern software engineering
- techniques and aims to provide a solid basis on which to build server
- products.
- </para>
- <para>
- What that means is that we define the central interface Component. We
- also define the relationship (contract) a component has with peers,
- ancestors and children. This documentation introduces you to those
- patterns, interfaces, and relationships.
- </para>
- <para>
- The Avalon Framework raises the abstraction level from Object-Oriented
- Programming concept one notch to the Component-Oriented Programming
- model. This enables programmers to concern themselves with assemblies
- of classes, rather than the classes themselves--thus reducing the
- number of things the programmer must keep in mind, and speeding up
- application development.
- </para>
- <para>
- The Avalon Framework is already used in
- <ulink uri="http://xml.apache.org/cocoon">Cocoon</ulink>, an XML
- publishing framework. The Avalon Framework is also used in
- <ulink uri="http://jakarta.apache.org/james">Apache JAMES</ulink>, a
- Java(tm) Mail Server. Another project that is built on Avalon Framework
- is <ulink uri="http://www.jesktop.org">Jestkop</ulink>, a cross-platform
- replacement for your ordinary desktop. If you are evaluating Avalon
- and want the proof that it's claims are valid check them out.
- </para>
- </description>
- <changes version="@version@" file="changes.xml"/>
- <downloads name="Avalon" base="http://jakarta.apache.org/builds/jakarta-avalon/release/@name@"/>
- </project>
-
-</announcement>
-
+<?xml version="1.0"?>
+
+<announcement>
+ <title>@Name@ @version@</title>
+ <abstract>The Avalon team is proud to announce the @version@ @status@ release
+of the @Name@.</abstract>
+
+ <project site="http://jakarta.apache.org/avalon">
+ <title>Avalon</title>
+ <description>
+ The Avalon project is Apache's Java Server Framework. It is
+ separated into five sub projects: Framework, Excalibur, LogKit,
+ Cornerstone, and Phoenix. Its purpose is to simplify
+ server side programming for Java based projects. It
+ formalizes serveral best of breed practices and patterns for
+ server side programming.
+ </description>
+ </project>
+
+ <project site="http://jakarta.apache.org/avalon/@name@">
+ <title>@Name@ @version@</title>
+ <description>
+ <para>
+ The Avalon Framework formalizes the contracts and patterns used in the
+ other Avalon projects. It is derived from modern software engineering
+ techniques and aims to provide a solid basis on which to build server
+ products.
+ </para>
+ <para>
+ What that means is that we define the central interface Component. We
+ also define the relationship (contract) a component has with peers,
+ ancestors and children. This documentation introduces you to those
+ patterns, interfaces, and relationships.
+ </para>
+ <para>
+ The Avalon Framework raises the abstraction level from Object-Oriented
+ Programming concept one notch to the Component-Oriented Programming
+ model. This enables programmers to concern themselves with assemblies
+ of classes, rather than the classes themselves--thus reducing the
+ number of things the programmer must keep in mind, and speeding up
+ application development.
+ </para>
+ <para>
+ The Avalon Framework is already used in
+ <ulink uri="http://xml.apache.org/cocoon">Cocoon</ulink>, an XML
+ publishing framework. The Avalon Framework is also used in
+ <ulink uri="http://jakarta.apache.org/james">Apache JAMES</ulink>, a
+ Java(tm) Mail Server. Another project that is built on Avalon Framework
+ is <ulink uri="http://www.jesktop.org">Jestkop</ulink>, a cross-platform
+ replacement for your ordinary desktop. If you are evaluating Avalon
+ and want the proof that it's claims are valid check them out.
+ </para>
+ </description>
+ <changes version="@version@" file="changes.xml"/>
+ <downloads name="Avalon" base="http://jakarta.apache.org/builds/jakarta-avalon/release/@name@"/>
+ </project>
+
+</announcement>
+
1.12 +28 -20 jakarta-avalon/src/xdocs/framework/book.xml
Index: book.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon/src/xdocs/framework/book.xml,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- book.xml 2 Apr 2002 16:52:20 -0000 1.11
+++ book.xml 3 May 2002 10:19:53 -0000 1.12
@@ -5,33 +5,41 @@
copyright="@year@ The Apache Software Foundation"
xmlns:xlink="http://www.w3.org/1999/xlink">
- <project label="Jakarta main" href="/" />
- <project label="Avalon main" href="../index.html" />
+ <project label="Jakarta main" href="http://jakarta.apache.org/" />
+ <project label="Avalon main" href="@AVALON_BASE@" />
- <menu label="About">
+ <menu label="Essentials">
<menu-item label="Overview" href="index.html"/>
- <menu-item type="changes" label="Changes" href="changes.html"/>
+ <menu-item label="Features" href="features.html"/>
+ <menu-item label="Getting started" href="getting-started.html"/>
<menu-item type="external" id="downloads" label="Download" href="http://jakarta.apache.org/builds/jakarta-avalon/release/framework"/>
- <menu-item type="external" id="api-docs" label="API Docs" href="@AVALON_BASE@/api/index.html"/>
- <menu-item type="external" id="diagrams" label="Diagrams Docs" href="diagrams/index.html"/>
</menu>
- <menu label="Patterns and Design">
- <menu-item label="Patterns" href="patterns.html"/>
- <menu-item label="Reuse Standards" href="reuse-standards.html"/>
- <menu-item label="Inversion of Control" href="inversion-of-control.html"/>
- <menu-item label="Separation of Concerns" href="separation-of-concerns.html"/>
- <menu-item label="Separation of interface & impl" href="separation-of-interface-and-implementation.html"/>
- <menu-item label="Security" href="security.html"/>
+ <menu label="Guide">
+ <menu-item label="OOP best practices" href="guide-oop-best-practices.html"/>
+ <menu-item label="What are patterns?" href="guide-patterns-what-are.html"/>
+ <menu-item label="Patterns in Avalon" href="guide-patterns-in-avalon.html"/>
+ <menu-item type="hidden" href="guide-patterns-soii.html"/>
+ <menu-item type="hidden" href="guide-patterns-soc.html"/>
+ <menu-item type="hidden" href="guide-patterns-ioc.html"/>
+ <menu-item type="hidden" href="guide-patterns-ioc-security.html"/>
+ <menu-item label="What is COP?" href="guide-cop-what-is.html"/>
+ <menu-item label="COP in Avalon" href="guide-cop-in-avalon.html"/>
+ <menu-item label="Where to go from here" href="guide-where-to-go-from-here.html"/>
+ </menu>
+
+ <menu label="Reference">
+ <menu-item type="external" id="api-docs" label="API Docs" href="@AVALON_BASE@/api/index.html"/>
+ <menu-item type="external" id="diagrams" label="Diagrams Docs" href="diagrams/index.html"/>
+ <menu-item label="The Lifecycle" href="reference-the-lifecycle.html"/>
</menu>
- <menu label="The API">
- <menu-item label="What is a Component?" href="what-is-a-component.html"/>
- <menu-item label="What is a Composer?" href="what-is-a-composer.html"/>
- <menu-item label="The Component Lifecycle" href="lifecycle.html"/>
- <menu-item label="Designing a Component" href="designing-a-component.html"/>
-<!-- <menu-item label="Understanding the Composer" href="composer.html"/>
- <menu-item label="The components Life-Cycle" href="life-cycle.html"/>-->
+ <menu label="For Developers">
+ <menu-item type="changes" label="Changes" href="for-developers-changes.html"/>
+ <menu-item type="external" id="coding-standards" label="Coding standards" href="@AVALON_BASE@/code-standards.html"/>
+ <menu-item label="Project Structure" href="for-developers-project-structure.html"/>
+ <menu-item type="external" id="cvs" label="CVS" href="http://jakarta.apache.org/site/cvsindex.html"/>
+ <menu-item type="external" id="mailing-lists" label="Mailing Lists" href="http://jakarta.apache.org/site/mail.html"/>
</menu>
</book>
1.7 +2 -2 jakarta-avalon/src/xdocs/framework/designing-a-component.xml
Index: designing-a-component.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon/src/xdocs/framework/designing-a-component.xml,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- designing-a-component.xml 2 Apr 2002 11:20:19 -0000 1.6
+++ designing-a-component.xml 3 May 2002 10:19:53 -0000 1.7
@@ -8,7 +8,7 @@
<version>1.0</version>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
- <person id="LS" name="Leo Simons" email="mail@leosimons.com"/>
+ <person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
@@ -82,7 +82,7 @@
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
- $Revision: 1.6 $ $Date: 2002/04/02 11:20:19 $
+ $Revision: 1.7 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.10 +48 -35 jakarta-avalon/src/xdocs/framework/index.xml
Index: index.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon/src/xdocs/framework/index.xml,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- index.xml 2 Apr 2002 11:20:19 -0000 1.9
+++ index.xml 3 May 2002 10:19:53 -0000 1.10
@@ -8,6 +8,7 @@
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
<person name="Peter Donald" email="peter@apache.org"/>
+ <person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
@@ -18,51 +19,63 @@
best-of-practice pattern enforcements, and several
lightweight convenience implementations of the generic components.
</p>
- <s2 title="Target Audience">
+ <p>
+ If that sounds a bit abstract to you, we suggest you start by reading
+ the guide (see below). If you want to see the code first, either
+ <link href="http://jakarta.apache.org/builds/jakarta-avalon/release/framework">Download</link>
+ it or
+ <link href="http://jakarta.apache.org/site/cvsindex.html">get it from CVS</link>.
+ The <link href="getting-started.html">Getting started</link> document
+ provides more pointers.
+ </p>
+ </s1>
+ <s1 title="Guide to Avalon Framework">
<p>
- This documentation is aimed towards developers who:
- <ul>
- <li>are interested in the design principles of Avalon</li>
- <li>wish to develop code that will be incorporated into Avalon</li>
- <li>wish to reuse Avalon concepts in their own application</li>
- </ul>
+ The Avalon Framework is based on several important programming
+ concepts (design patterns and COP) which are applied throughout
+ Avalon. This documentation first introduces each of these, providing
+ links to external sources for more elaborate documentation. Then,
+ we look at how these concepts are used within Avalon.
</p>
- </s2>
- <s2 title="Theoretical Aspects of Component Development">
<p>
- The following documents provide basic theoretical concepts that are applied
- through-out Avalon's framework. It would be good for a prospective developer to
- be at least passingly familiar with the concepts outlined in this document.
- The documentation also provides links to outside sources which can be consulted
- for further information.
+ This is more a theoretical introduction than a hands-on guide. If you
+ prefer looking at code while learning, try our
+ <link href="@AVALON_BASE@/developing">Developing with Avalon</link> paper.
</p>
- <ol>
- <li><link href="patterns.html">Patterns</link></li>
- <li><link href="reuse-standards.html">Reuse Standards</link></li>
- <li><link href="inversion-of-control.html">Inversion of Control</link></li>
- <li><link href="separation-of-concerns.html">Separation of Concerns</link></li>
- <li><link href="separation-of-interface-and-implementation.html">Separation of Interface and Implementation</link></li>
- <li><link href="security.html">Security</link></li>
- </ol>
- </s2>
- <s2 title="Concrete Descriptions of the Avalon Component model">
+ <s2 title="Target Audience">
+ <p>
+ This documentation is aimed towards developers who:
+ <ul>
+ <li>are interested in the design principles of Avalon</li>
+ <li>wish to develop code that will be incorporated into Avalon</li>
+ <li>wish to reuse Avalon concepts in their own application</li>
+ </ul>
+ </p>
+ </s2>
+ <s2 title="Contents">
+ <ol>
+ <li><link href="guide-oop-best-practices.html">OOP best practices</link></li>
+ <li><link href="guide-patterns-what-are.html">What are design patterns?</link></li>
+ <li><link href="guide-patterns-in-avalon.html">Design patterns in Avalon</link></li>
+ <li><link href="guide-cop-what-is.html">What is Component-Oriented Programming?</link></li>
+ <li><link href="guide-cop-in-avalon.html">COP in Avalon</link></li>
+ <li><link href="guide-where-to-go-from-here.html">Where to go next</link></li>
+ </ol>
+ </s2>
+ </s1>
+ <s1 title="Avalon Framework Reference Documentation">
<p>
- This section describes concrete examples of how the theoretical ideas
- are applied within the context of Avalon.
+ Besides the
+ <link href="@AVALON_BASE@/api/index.html">Javadocs</link>, we have
+ <link href="diagrams/index.html">Class diagrams</link> and the
+ <link href="reference-the-lifecycle">The Lifecycle specification</link>.
</p>
- <ol>
- <li><link href="what-is-a-component.html">What is a Component?</link></li>
- <li><link href="what-is-a-composer.html">What is a Composer?</link></li>
- <li><link href="lifecycle.html">The Component Lifecycle</link></li>
- <li><link href="designing-a-component.html">Designing a Component</link></li>
- </ol>
- </s2>
- </s1>
+ </s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
- $Revision: 1.9 $ $Date: 2002/04/02 11:20:19 $
+ $Revision: 1.10 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.4 +29 -25 jakarta-avalon/src/xdocs/framework/features.xml
1.1 jakarta-avalon/src/xdocs/framework/for-developers-changes.xml
Index: for-developers-changes.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE changes SYSTEM "dtd/changes-v10.dtd">
<changes title="Avalon Framework - History of Changes">
<devs>
<person name="Federico Barbieri" email="fede@apache.org" id="FB"/>
<person name="Berin Loritsch" email="bloritsch@apache.org" id="BL"/>
<person name="Peter Donald" email="peter@apache.org" id="PD"/>
<person name="Jeff Turner" email="jefft@apache.org" id="JT"/>
<person name="Paul Hammant" email="hammant@apache.org" id="PH"/>
<person name="Leif Mortenson" email="leif@apache.org" id="LM"/>
<person name="Carston Ziegeler" email="cziegeler@apache.org" id="CZ"/>
<person name="Leo Simons" email="leosimons@apache.org" id="LS"/>
</devs>
<release version="4.1.2" date="January 31, 2002">
<action dev="BL" type="udpate">
Updated the build jars.
</action>
<action dev="CZ" type="add">
Add EMPTY_PARAMETERS constant object to the Parameters object.
</action>
<action dev="PD" type="update">
Made it configurable whether you print nested exceptions or not,
and specify the depth that the AvalonFormatter will go with nested
exceptions (defaults to 8).
</action>
<action dev="LM" type="update">
Update build to have a "compress.jars" property (defaults to
true by default).
</action>
</release>
<release version="4.1.1" date="December 21, 2001">
<action dev="BL" type="fix">
Force build process to produce JDK 1.2 compliant class files.
The last release had JDK 1.4 compliant class files, causing
some classloaders to not work with the Framework.
</action>
</release>
<release version="4.1" date="December 12, 2001">
<action dev="JT" type="update">
Improve and update the configuration javadocs to reflect the new
namespace support.
</action>
<action dev="BL" type="remove">
Deprecate the Loggable and AbstractLoggable classes, and replace
them with LogEnabled and AbstractLogEnabled.
</action>
<action dev="BL" type="add">
Add an abstraction layer to the Logging implementation. Thanks
to Peter Donald for supplying the interface.
</action>
<action dev="BL" type="add">
Add Namespace support to Configuration files.
</action>
<action dev="BL" type="add">
Add AvalonFormatter that was in LogKit's heirarchy. This way, we
avoid circular dependancies.
</action>
<action dev="PD" type="fix">
Previously resolve did not throw a ContextException. This made it
difficult to indicate errors resolving objects. It now throws an
exception thus allowing errors to be propogated and recorded.
</action>
<action dev="BL" type="add">
New ConfigurationSerializer to have your configuration objects persist.
</action>
<action dev="BL" type="update">
Upgrade DefaultConfigurationBuilder to be JAXP compliant,
with the option to pass in your own XMLReader.
</action>
<action dev="PD" type="update">
Configuration objects are now Serializable.
</action>
<action dev="BL" type="add">
Add new support to ask a component manager if it has a component.
</action>
<action dev="PD" type="fix">
Bug fixes for documentation
</action>
<action dev="BL" type="update">
Update developers docs to support new configuration methods.
</action>
<action dev="PH" type="add">
Improved "Hello World" documentation.
</action>
<action dev="PD" type="add">
Add UML diagrams supplied by Dieter Wimberger
</action>
<action dev="BL" type="update">
Add new author bios.
</action>
<action dev="BL" type="update">
Update build process to proposed standard.
</action>
<action dev="PD" type="add">
Added a method to Version to parse a Version from a string. Added accessor
methods to Version to allow access to major/minor/micro components of version.
</action>
<action dev="PD" type="change">
Updated Version class to refer to micro version rather than revision. This
is to match the terminology for JDK versioning. This is just documentation
changes.
</action>
<action dev="JT" type="fix">
Changed access of Enum and ValuedEnum constructors from public to
protected, to prevent Enum users from breaking type-safety by adding new
Enum items. This breaks backwards-compatibility in cases where Enum
and ValuedEnum were being incorrectly used.
</action>
</release>
<release version="4.0" date="July 30, 2001">
<action dev="BL" type="add">
Added new method to Component Manager and Selector for discovering
if a Component exists inside or not. Also augmented the default
versions with the basic implementation to discover them.
</action>
<action dev="BL" type="add">
Added stylesheet to convert Stylebook markup to DocBook markup.
</action>
<action dev="BL" type="change">
Changed the documentation build process to use Cocoon to build
the site.
</action>
<action dev="BL" type="add">
Added new "Developing with Avalon" book in DocBook format.
</action>
<action dev="PD" type="add">
Added Executable interface to activity package.
</action>
<action dev="PD" type="fix">
Updated Resolvable interface to allow a ContextException to be thrown
on failure.
</action>
<action dev="PD" type="update">
Add a makeReadOnly() method to the default implementations of Configuration,
Context and ComponentManager. Calling this method after the respective
object has been filled will make the object read-only. This is a safety
precaution to stop code performing unwanted operations.
</action>
<action dev="PD" type="update">
Updated the javadocs of many of the classes.
</action>
<action dev="BL" type="update">
Update documentation so that it is more accurate and descriptive.
</action>
</release>
<release version="4.0b3" date="June 6, 2001">
<action dev="BL" type="update">
Release 4.0b3
</action>
<action dev="PD" type="fix">
Made DefaultComponentManager/Selector, DefaultContext, and
DefaultConfiguration read-only to avoid bad programming
practices by clients.
</action>
</release>
<release version="4.0b2" date="June 4, 2001">
<action dev="BL" type="update">
Release 4.0b2
</action>
<action dev="PD" type="add">
Add makeReadOnly() method to default implementations to prevent
alteration after they are set up.
</action>
<action dev="BL" type="update">
Removed the "throws Exception" from Disposable interface. That was
inadvertently left in the previous release.
</action>
<action dev="BL" type="add">
Added extra methods to Parameters to throw exceptions if the value
does not exist. They are the "no default value" methods.
</action>
<action dev="PD" type="update">
Updated javadocs for Framework.
</action>
</release>
<release version="4.0b1" date="May 11, 2001">
<action dev="BL" type="update">
Official release
</action>
</release>
</changes>
1.1 jakarta-avalon/src/xdocs/framework/for-developers-project-structure.xml
Index: for-developers-project-structure.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Project Structure</title>
<authors>
<person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>Avalon Framework is not very big, codewise. It is usually quite easy to find
what you need. This document provides an overview of the project structure. It
is still under construction.</p>
</s1>
<s1 title="Package structure">
<source>
org.apache.avalon.framework
|
|- activity
|- component
|- configuration
|- context
|- logger
|- parameters
|- service
|- thread
</source>
</s1>
<s1 title="CVS Directory structure">
<source>
jakarta-avalon
|
|- lib : for third party libraries
|
|- src
| |
| |- compat : deprecated stuff
| |- conf : jar manifest
| |- documentation : cocoon configuration
| |- java : java sources
| |- logos : avalon logo sources
| |- make : no idea
| |- proposal : place for ideas to nurture
| |- scratchpad : place for nonsupported, unstable code
| |- skins : cocoon configuration
| |- test : unit tests
| |- xdocs : site documentation in xml format
|
|- tools
| |
| |- bin : scripts to run our personal ant and cocoon copies
| |- documentation : cocoon configuration
| |- etc : misc stuff
| |- ext : optional libraries used in the build process
| |- lib : libraries used in the build process
|
|- build.xml
|
|- BUILDING.txt
|- LICENSE.txt
|- README.txt
|- TODO.txt
</source>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/getting-started.xml
Index: getting-started.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Getting Started</title>
<authors>
<person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>If you are completely new to Avalon, the Framework subproject is not
the easiest place to start. We suggest you take a look at the
<link href="@AVALON_BASE@/phoenix/getting-started.html">Avalon Phoenix getting started document</link>
first, as it will take you through downloading, installing and then
running something (a very simple server program) much more concrete.</p>
<p>Probably the next smart step is to learn by example. Take a look at
one or two of the <link href="@AVALON_BASE@/apps">applications</link>
that use avalon and at how well these are set up, and at some of the
available <link href="@AVALON_BASE@/excalibur">components (in Excalibur)</link>
and <link href="@AVALON_BASE@/cornerstone">services (in Cornerstone)</link>
Avalon offers.</p>
<p>You will find that the Framework has an important role in each and
every one of these. To learn what that role is and how it fulfills this
role, you should read our guide, which starts with a summary of
<link href="guide-oop-best-practices.html">OOP best practices</link>.</p>
<p>When you get stuck in sources, documentation, and the mailing list archive,
post your questions to the mailing list (information on it is
<link href="http://jakarta.apache.org/site/mail.html">here</link>). For
many, Avalon poses a steep learning curve, and we'll try and help you
flatten it as much as we can.</p>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-cop-in-avalon.xml
Index: guide-cop-in-avalon.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - COP in Avalon</title>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
<person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
<s1 title="Components in Avalon">
<p>
At the core of the Avalon framework is the Component. We define it as "a
passive entity that performs a specific role". This is important to grasp
because it requires a specific way of thinking.
</p>
<s2 title="A passive API">
<p>
A passive entity must employ a passive API. A passive API is one that is
acted upon, versus one that acts itself. See the
<link href="guide-patterns-ioc.html">Inversion of Control</link> pattern
for an explanation.
</p>
</s2>
<s2 title="A specific Role">
<p>
The concept of roles come from the theater. A play, musical,
or movie will have a certain number of roles that actors play.
Although there never seems to be a shortage of actors, there
are a finite number of roles. I am not going to make reference
to different types of roles at this point, but simply bring
the concept to light. The function or action of a role is
defined by it's script.
</p>
<p>
We are introducing this concept now because you need to have it
in mind when you are designing your system architecture. Think
of the different roles in your system, and you will have your
"cast" of components so to speak.
</p>
<p>
For each role, you need to specify it's script, or interface to
the rest of the system. To be honest the interface is not enough.
There are specific contracts that you must define and keep in mind
when you specify your interfaces. In other words, what users
of the Component must provide, and what the Component produces.
When the interface and contract are defined, you can work on your
implementation.
</p>
</s2>
</s1>
<s1 title="The Component">
<p>
John Donne wrote, "No man is an island." to communicate that we
are all interdependent. The same is true for the Component. That
is why there are different concerns regarding the Component. In
the section on roles we specified one of the concerns: the role.
The concerns directly supported by the Avalon Framework are:
configuration, external component use, management, and execution.
</p>
<note>
We used to have an marker interface Component. This has been deprecated
because requiring all components extend this interface makes
integrating Avalon with other component systems like
<link href="http://www.corba.org">CORBA</link> very cumbersome.
</note>
<p>
As you might of guessed, each one of these concerns has a separate
interface that describes that concern. We will delve deeper into
the interfaces and the reasoning behind them in other sections. It
is important to know the order of precedence for the concerns so
that you know the overall contracts of how they are put together.
</p>
<ol>
<li>
<strong>Configurable:</strong> marks an object that can be configured.
</li>
<li>
<strong>Composable:</strong> marks an object that uses Components.
</li>
<li>
<strong>Initializable:</strong> marks an object that can be initialized.
</li>
<li>
<strong>Disposable:</strong> marks an object that can be disposed.
</li>
<li>
<strong>Stoppable:</strong> marks an object that can be started and stopped.
</li>
</ol>
<p>
The contract surrounding this order means that the methods defined
by each of those interfaces are called in a specific order by the object
that created the Component. Each interface represents a narrow view
of the Component or object being controlled.
</p>
<note>
Notice that each interface is separate from Component, so you can use
them for simple objects.
</note>
</s1>
<s1 title="The Composable">
<p>
In Avalon, Composable is defined as an active entity that controls
or uses Components. Its best analogy is that of a musical composer.
The musical composer chooses what instruments (Components) by their
role in the symphony (system) and tells them which notes to play.
</p>
<p>
The Avalon Composable follows the principles of Inversion of Control,
and is assigned a Component Manager. Within this section we will
discuss how to look up specific Components, and then how to prepare
the ComponentManager for the Composable.
</p>
<note>
The Composable has a specific contract that must be enforced for security
reasons. The ComponentManager must only be set once. That means that
the <code>compose</code> method must ignore all subsequent
requests to set the ComponentManager after it is successfully set.
</note>
</s1>
<s1 title="Finding your Component">
<s2 title="The Component Manager">
<p>
For the majority of all cases, you will need to use the ComponentManager
get the instance of the Component you need. If you recall the discussion
on Component Roles in the Component documentation, you already have
a head start. In Avalon, Roles are defined by the work interface a
Component has. A work interface is different from any other interface
because it is the interface that defines the Component's Role. Composable
and Component are concern interfaces because they address specific
concerns about the Component.
</p>
<p>
The ComponentManager has one method to retrieve all of your Components.
The <code>lookup</code> method will look up the Component based on the
fully qualified name (FQN) of the work interface (Role). It is important
to realize that the ComponentManager returns Components, and therefore
you must recast the Component to the Role you need. See the following
example:
</p>
<source>
final MyComponent component = (MyComponent)manager.
lookup( "com.mycompany.myproject.MyComponent" );
</source>
<p>
It is important to note that Role is not the same thing as functional
equivalence. In other words, if you have a MailSpooler that is functionally
equivalent to a FileStore (they do the same thing), it does not mean that
they perform the same Role. The FileStore is used to store objects to
files, and the MailSpooler is used to temporarily store messages until
they are sent. Thus they are separate roles. Sometimes you need to
create a new interface name that does nothing more than allow access to
alternate roles who have the same role.
</p>
</s2>
<s2 title="The Component Selector">
<p>
Sometimes you will have several Components that function in the same role.
For those cases, you will use the ComponentSelector to choose the exact
one you need. The best way to describe its proper use is the scenario
described here. You have several formatters that have the same Role:
to take an input document and format it according to the rules in the
individual Component implementations. One formatter may take a text file
and remove all tabs and replace them with four spaces. Another formatter
may reverse the formerly mentioned one. Yet another takes the text file
and formats it for a canvas object. For the Composable, it makes no difference
what the implementation does--just that it formats the text.
</p>
<p>
Using the processing chain example in the previous paragraph, we realize
the unsuitability of the ComponentManager for getting the right Component.
The Component addresses the concern of one Component per role. Fortunately,
the ComponentSelector is a Component. That means we use the ComponentManager
to lookup the ComponentSelector. The ComponentSelector is designed to choose
the specific Component out of many that perform the <strong>same</strong>
Role. The following code will help:
</p>
<source>
final ComponentSelector selector = (ComponentSelector)manager.
lookup( "org.mycompany.myproject.FormatterSelector" );
final Formatter formatter = (Formatter)selector.select( myURL );
</source>
<p>
The selector does not discriminate against lookup keys. In that respect it
acts much like a hashtable lookup. Keep in mind that the implementation of the
selector does not limit you to a hashtable lookup--you can dynamically
instantiate objects as well. It takes an object (a hint), and returns the
specific Component based on that hint.
</p>
</s2>
<s2 title="When you are done with the Component">
<p>
Both the ComponentManager and the ComponentSelector require you to
release your Component when you are done with it. The method used
to do this is "release". One way of handling this is to use the
try/catch/finally construct. For your convenience, the following
code can help:
</p>
<source>
MyComponent component = null;
try
{
component = (MyComponent) manager.lookup("org.mycom.MyComponent");
component.myMethod();
}
catch (Exception e)
{
getLogger().debug("Error using MyComponent", e);
}
finally
{
if (component != null) manager.release(component);
}
</source>
<p>
The reason for this is so that smart Component Managers that
select Components from a pool can properly manage the resources.
</p>
</s2>
</s1>
<s1 title="Populating the ComponentManager">
<p>
It is the responsibility of the entity that creates the Composable to give it a
ComponentManager with all of the Roles populated. If you create your own
implementations of the ComponentManager and ComponentSelector then you have
the liberty of deciding how to populate them. Keep in mind that there are
default implementations included, and you should model their behavior as
much as possible.
</p>
<s2 title="DefaultComponentManager">
<p>
The DefaultComponentManager is nothing more than a Hashtable lookup of roles
and Components. It even gives you the method <code>put</code> to populate
the ComponentManager. One feature of the DefaultComponentManager is that
it can cascade. In other words, if the role is not found in this ComponentManager,
the default implementation will look in the parent ComponentManager.
</p>
<p>
For the paranoid developer, the Cascading feature of the ComponentManager
can be seen as a security hole as opposed to a usability enhancement. You
are free to create your own implementation that does not use the Cascading
feature--but you have to manually populate it with anything that would
have been in the parent ComponentManager that your child Composable needs.
Truth be told, there is very little risk due to the set-once contract for
ComponentManagers. The method is never exposed to hostile agents before
the ComponentManager is set.
</p>
</s2>
<s2 title="DefaultComponentSelector">
<p>
The DefaultComponentSelector again is simply a Hashtable selection of Components
based on hints. It gives the method <code>put</code> to populate the ComponentSelector.
The ComponentSelector does not have the cascading feature of the ComponentManager,
nor should it. A ComponentSelector simply holds a number of Components that
implement the same role--there really is no need to cascade.
</p>
<p>
After the ComponentSelector is populated, you must put it in the ComponentManager.
Please use the role of the Component you are selecting, not the role of the selector
itself. An acceptable convention is to add the "Selector" name to the end of the
Role you are looking up. Just be consistent.
</p>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-cop-what-is.xml
Index: guide-cop-what-is.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - What is COP?</title>
<version>1.0</version>
<authors>
<person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
Component Oriented Programming, or COP for short, takes Object Oriented
Programming one step further. Regular OOP organizes data object into
entities that take care of themselves. There are many advantages to this
approach. I'll assume that you, being a java programmer, are familiar
with those.
</p>
<p>
It also has a big limitation: that of object co-dependency. To remove that
limitation, a more rigid idea had to be formalized: the Component. The key
difference between a regular object and a component is that a component is
completely replaceable.
</p>
</s1>
<s1 title="COP is not just a buzzword">
<p>
There is a lot of buzz in the industry touting Component Based Design
(CBD). You will find, that the definition of a Component in Avalon
is more formal than most companies' definition of a Component. Any
system developed with the principles of Avalon can claim CBD. In
fact the Avalon Framework formalizes CBD more rigidly than the marketing
definition. Do not be fooled though, CBD and COP aren't necessarily
the same thing. Component Based Design refers to how a system is
designed and not how it is implemented. Component Oriented Programming,
on the other hand, refers to how a system is implemented and not how
it is designed. In practice, you can't implement COP without first
designing with Components in mind.
</p>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-oop-best-practices.xml
Index: guide-oop-best-practices.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - OOP best practices</title>
<authors>
<person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
While Avalon is not really about Object-Oriented Programming (OOP)
(we go much further), some of its concepts are important in
any programming project, so we summarise the 12 rules for code reuse
as given in
<link href="http://www.laputan.org/drc/drc.html">
"Designing Reusable Classes"
</link> by Ralph E. Johnson and Brian Foote (an excellent book).
</p>
<p>
Note that a good knowledge of the basic OOP concepts is a requirment for
understanding any of this. Many books deal with this, one that is freely
available online is
<link href="http://www.mindview.net/Books/TIJ/">
"Thinking in Java"
</link> by Bruce Eckel (also a recommended read).
</p>
</s1>
<s1 title="Recursion Introduction">
<p>
Use the same interface for communication with components of
the same type. It allows the swapping of those components
for other components of the same type without breaking existing
code.
</p>
<p>
If you need additional functionality, either create proxy
objects that implement the interface, or add it by subclassing
(hence the name "Recursion Introduction". Even if
there is no recursion happening, it appears to operate in the
same manner.
</p>
</s1>
<s1 title="Eliminate Case Analysis">
<p>
Avoid testing to see if an object is an instance of a particular
class. Usually, if you think you need that approach then a
redesign will help immensely.
</p>
</s1>
<s1 title="Reduce the Number of Arguments">
<p>
Methods with a half-dozen arguments are hard to read, and can
usually be accomplished with an object that represents that
set of arguments. It also makes it easier to track down the
problems.
</p>
</s1>
<s1 title="Reduce the Size of Methods">
<p>
Most of your methods should only need to be a few lines long.
Methods that are very long (like 50 lines or so) are too complex,
and should be considered guilty of bad design until proven
innocent.
</p>
</s1>
<s1 title="The Top of the Class Heirarchy Should be Abstract">
<p>
In many cases it is beneficial to provide an abstract base class
to extend for your specializations. The majority of the
functionality and behavior is well defined. This makes it easier
to decipher what the intents of the interface designer were.
</p>
</s1>
<s1 title="Minimize Accesses to Variables">
<p>
This point formalizes the principles of data hiding. Try not
to expose class attributes to other classes, but protect them
by methods. If an attribute changes name, then you only have
one place to update the code instead of hundreds.
</p>
</s1>
<s1 title="Subclasses Should be Specializations">
<p>
A [subclass] "is a" [superclass]. If what you
are trying to do is make a Component into a ComponentManager,
then you are violating the spirit of the framework. A better
approach is to use containment in that case (i.e. a [class]
"has a" [external class]).
</p>
</s1>
<s1 title="Split Large Classes">
<p>
If a class has 50+ methods, then it is most likely trying to
do too much. Look at separating the functionality into
separate components. Like methods that are too long, classes
that violate this rule should be considered guilty of wrong
design until proven innocent.
</p>
</s1>
<s1 title="Factor Implementation Differences Into Subcomponents">
<p>
If a subclass implements a method completely different from
the superclass, then it is not really a specialization. It
should be split off from that class hierarchy tree.
</p>
</s1>
<s1 title="Separate Methods that Do Not Communicate">
<p>
Sometimes in building a framework you run into a case where
you have different views of the same data. In these cases,
you can have some attributes that describe how to generate
the data, and some attributes that describe the data itself.
It is better to separate these two views into separate classes.
The semantics are different enough to justify this solution.
</p>
</s1>
<s1 title="Send Messages to Components instead of to This">
<p>
The point of this point is that you want to build your framework
based on Components, and not inheritance. Avalon takes this
point to heart. In order to illustrate, I will give two examples
of the same thing. The scenario is that we have a data structure
that we want to output to an arbitrary format.
</p>
<p>
In the following example, we will use the java <code>this</code>
object and an inheritance based framework. As you can see, this
would be a bear to maintain, and it won't easily be extended.
</p>
<source>
abstract class AbstractExampleDocument
{
// skip some code ...
public void output(Example structure)
{
if( null != structure )
{
this.format( structure );
}
}
protected void format(Example structure);
}
</source>
<p>
In the next example, we will use the Avalon Component based
architecture. There is a clean separation between the purpose
of the objects, and you can exchange and extend formatting
without worrying about any other concerns.
</p>
<source>
class DefaultExampleDocument
{
// skip some code ...
public void output(Example structure)
{
ExampleFormatter formatter =
(ExampleFormatter) manager.lookup(Roles.FORMATTER);
if( null != structure )
{
formatter.format(structure);
}
}
}
</source>
<p>
An inheritance based framework (White Box) can be converted
into a component based framework (Black Box) structure by
replacing overridden methods by method calls (message sends)
to components. Component based architecture is much more
flexible in this regard.
</p>
</s1>
<s1 title="Eliminate Implicit Parameter Passing">
<p>
Just because two methods share the same information within the
class does not mean that it should be done in that manner.
Many times, that attribute that is shared should be passed
as a parameter of the method instead of directly accessing
the attribute.
</p>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-patterns-in-avalon.xml
Index: guide-patterns-in-avalon.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - Patterns in Avalon</title>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
<person name="Leo simons" email="leosimons@apache.org"/>
<person name="Paul Hammant" email="Paul_Hammant@yahoo.com"/>
<person name="Peter Donald" email="peter@apache.org"/>
</authors>
</header>
<body>
<s1 title="Getting Started with Patterns">
<p>
Avalon takes many design patterns and architectural mindsets, and
implements the best ones for Servers. There are different kinds of
patterns that represent different aspects of Avalon. Avalon uses four
main conceptual patterns called Separation of Interface and
Implementation, Inversion of Control, Multi-Dimensional Separation
of Concerns, and Aspect Oriented Programming. Avalon also uses several
architectural patterns like the Singleton and the Factory.
</p>
</s1>
<s1 title="The Avalon Patterns in short">
<p>
We provide you with a short description of the patterns first, with a
detailed description of each pattern on a separate page.
</p>
<s2 title="Separation of Interface and Implementation">
<p><b>Summary:</b> The Separation of Interface and Implementation is
a core feature of the Java language. However, it is misused so that we
list it as one of the Avalon patterns, as our use of it is extensive.
</p>
<p><link href="guide-patterns-soii.html">
More Information...
</link></p>
</s2>
<s2 title="Inversion of Control">
<p><b>Summary:</b> Avalon not only has an inheritance hierarchy, but also a
Component hierarchy. In this hierarchy, the control of program flow is
completely in the hands of the parent component(s), as soldiers in the
military take orders from their officers.
</p>
<p><link href="guide-patterns-ioc.html">
More Information...
</link></p>
</s2>
<s2 title="Multi-Dimensional Separation of Concerns">
<p><b>Summary:</b> You just read the introduction about patterns before
reading about Avalon's patterns because that enables you to reuse the
knowledge you gained about patterns in context other than that of
Avalon. We do this with software as well.
</p>
<p><link href="guide-patterns-soc.html">
More Information...
</link></p>
</s2>
<s2 title="Aspect-Oriented Programming">
<p><b>Summary:</b> this is the next logical step ofter Separation of
Concerns. Many concerns cannot be centrally addressed using the standard
OOP mechanisms. Using AOP (which is an extension to OOP), we would be
able to do so in a simple fashion. As there is no good AOP facility
in java, we use "aspect marker interfaces" and COP instead.
</p>
</s2>
<s2 title="Component-Oriented Programming">
<p><b>Summary:</b> The Avalon framework promotes black-box reuse at
every level. Doing so is commonly known as COP. This is so important
in Avalon we devote an
<link href="guide-cop-what-is.html">
entire section
</link>
to it.
</p>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-patterns-ioc-security.xml
Index: guide-patterns-ioc-security.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - Security Concerns</title>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
One major concern for many companies is the security of a system.
In this context security is defined as protection of data, and
quality of service (QOS). Both of these fall under security because
a system must protect itself from these two forms of attack. When
a company loses a system, they lose business, and the money they
lose can reach scary amounts.
</p>
<p>
For the purpose of this discussion, we will address the first
aspect (protection from crackers and system infiltration). Many
times, the same fixes for this type of protection inherently fix
the other (QOS). System security has three distinct concerns
that have been well defined: authentication, authorization, and
architecture. Why didn't I say encryption? It is because
encryption does not equal security. It is only part of the whole
system.
</p>
<s2 title="Authentication">
<p>
Authentication is the process of identifying parties. In a completely
trusted system, authentication is as simple as grabbing a reference
to the object or entity you want to manipulate. However, sometimes
you have trusted systems running in hostile environments (e.g. the
internet). In those cases you have to make sure that the entity
is the correct one.
</p>
<p>
There are two sides of authentication. On one side, you are
authenticating an entity you want to do business with. On the other
side, there is an entity wanting to do business with you. This is
best understood when you bring it into a financial realm. Let's say
you want to get a loan from XYZ bank. If you initiate the exchange
at their facility, you have already authenticated them--although you
will have to jump through hoops to authenticate yourself. If a
telemarketer calls from ACME Loan Machine, Inc., they know who you
are--although if you are smart, you will make them jump through
hoops to authenticate themselves.
</p>
<p>
Currently, Avalon identifies Blocks as trusted parties. In other
words, the fact that they are installed correctly in the proper
directory is enough to mark them as authenticated. Much like a
good friend--you know them by their voice. Because of the architecture
of Avalon, Blocks define their own authentication system. That
means that whether the Block assumes all Components are trusted
or it forces the blocks to authenticate themselves is up to the
block.
</p>
<p>
For systems that deal with sensitive information, authentication
becomes more of an issue. You must validate that the Components
in use are the ones you have authorized for use. The more open a
system is, the more authentication and authorization play an important
role. If you have Components that are transmitted over some form
of communications system (wire, air, etc.) you must verify that
they are who they say they are.
</p>
<p>
For this purpose, protocols like Kerberos and Leighton-Micali have
been defined. It is beyond the scope of this page to discuss the
pros and cons of each system.
</p>
</s2>
<s2 title="Authorization">
<p>
Once a Component has been authenticated (in other words it's identity
has been authoritatively validated), then you must decide what access
it has to your systems. A fully trusted Component can do what it likes.
An untrusted Component must be denied functions it is not allowed.
</p>
<p>
Authorization is part of the architecture, but is significant enough
to warrant it's own concern. The best rule of thumb is to hide access
to everything unless the Component is trusted. When hiding is not
an option, then you have to resort to denying access. For the security
conscious, all denied accesses should be logged along with the Component's
identifier.
</p>
</s2>
<s2 title="Architecture">
<p>
Avalon already has the framework for the proper secure architecture.
With proper planning, security can be added without recoding the Components.
However there are some rules of thumb for paranoid programming.
</p>
<ol>
<li>
Never expose anything that does not need to be exposed. Information
hiding is as important in security as it is in Component
Oriented Programming (COP).
</li>
<li>
Any Component that originates from your own jar should be trusted--you
provided it after all.
</li>
<li>
Any Component that originates from another source, and especially over
a wire, should be treated with suspicion. Authenticate it, and if it
checks out, trust it. Otherwise, don't give it access--you don't know
where it's been or who created it.
</li>
<li>
Encrypt <strong>all</strong> communications. Period.
</li>
</ol>
</s2>
</s1>
<s1 title="From the Sublime to the Ridiculous">
<p>
Throughout my short career I have been exposed to a wide range of security
implementations. Having worked for a DoD contractor, I learned about physical
security requirements (how to manage paper files, and the rules and regulations
regarding secure information). However in a recent attempt to install a
solution at our customer's site, I learned more about computer security
than I have at any other time.
</p>
<p>
Our customer, a well known corporation whom I will call ACME for
anonymity, is in custody of sensitive information. Product movement data,
financial data, and demographic data are all stored in one of a couple
huge server farms. Our application was to reside in the De-Militarize
Zone (DMZ), and talk to a database behind the firewall. When they discovered
that the application server we chose required Remote Procedure Calls (the
subject of many CERT advisories in the Unix world), we hit a brick wall. Our
application was no longer trusted, and was not to be installed. Luckily
the next version of the application server fixed that problem.
</p>
<p>
In the midst of this, I decided to learn as much as I could about operating
in a hardened environment. Hardening involves turning off access to anything
that is not needed, and only allowing what is needed. All mail servers, ftp
servers, rpc services, telnet, and any other clear text communications ports need
to be removed. All communication into and out of the box needs to be
encrypted, with the exception of HTTP (although we were using HTTPS).
</p>
<p>
All of this was necessary. I understand the principles behind it. However,
I decided to ask their security analyst how to learn more--so we don't run
into this problem again. He gave me a link to
<link href="http://www.sans.org">SANS institute</link> and a word of
advice: "Be paranoid. Don't trust anything."
</p>
<p>
There is a point where the aforementioned philosophy goes a bit too far. The
case in point relates to a story I heard working with the DoD. During the
height of the "Cold War" between the US and Russia, a US commanding
officer required that all the computers be placed on these huge power
conditioners to reduce the Electro-Magnetic Interference (EMI) coming from the
power line feedback of the computers. His rationalization was that he was
positive KGB agents had the technology that they could read the EMI interference
on the power lines and read the bits on the computers. In hind sight this is
improbable; no one can identify the bits travelling on a computer from EMI in the
power lines due to the level of noise (clocks, addressing lines,
<em>encrypted data</em>, and other computers on the network).
</p>
<p>
The security industry have a general rule of thumb to ensure that you don't spend
too much time in this area: The cost of cracking the server should
be more than
the information that is protected is worth. Basically it boils down to this:
sites like Slashdot and SourceForge do not require as much security as a Bank.
Protecting free information is not as critical as protecting peoples bank accounts.
I am not minimizing the contributions of the aforementioned sites to the world
as a whole, but people become much more agitated if their bank account is wiped
clean than if their news article is defaced. This is not to say that if you are
protecting free information then you can safely ignore security. While the information
is monetarily free to customers, it has value that can be measured in pride, respect,
and accountability.
</p>
<p>
The moral of the story is be paranoid to a point. Avalon is designed to be
a trusted system, and will be improved to work in an untrusted network.
</p>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-patterns-ioc.xml
Index: guide-patterns-ioc.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - Inversion of Control</title>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
<person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
One of the key design principles behind Avalon is the principle
of <em>Inversion of Control</em>. <em>Inversion of Control</em> is
a concept promoted by one of the founders of the Avalon project,
<link href="mailto:stefano@apache.org">Stefano Mazzocchi</link>. The
principle enforces security by design.
</p>
<p>
It is difficult to track down one paper that defines this pattern
at length, so here are a couple of different definitions of
<em>Inversion of Control</em>.
</p>
</s1>
<s1 title="What it Means">
<p>
The Framework plays the role of the main program in coordinating
and sequencing events and application activity.
</p>
<p>
A designer sets up a chain among objects that can all react
to certain messages in a delegation hierarchy. There is one
major semantic detail: Inversion of Control refers to a parent
object <em>controlling</em> a child object. With this distinction,
the SAX API is not considered Inversion of Control because its
purpose is to send <em>information</em> from a source to a handler.
</p>
<s2 title="Definition by Analogy">
<p>
There are a couple of different analogies that make
understanding <em>Inversion of Control</em> easier. We
experience this in many different ways in regular life,
so we are borrowing the form in code. One analogy is called
the "Chain of Command" in the military.
</p>
<s3 title="Chain of Command">
<p>
This is probably the clearest parallel to <em>Inversion
of Control</em>. The military provides each new recruit
with the basic things they need to operate at their rank,
and issues commands that recruit must obey. The same
principle applies in code. Each Component is given the
provisions they need to operate by the instantiating
entity (i.e. Commanding Officer in this analogy). The
instantiating entity then acts on that Component how it
needs to act.
</p>
<p>
There are some deficiencies in this analogy as some military
or ex-military people have explained to me. In the military,
<strong>any</strong> Commanding Officer can issue commands to
anyone under his or her rank. In the development world, to
ensure proper security, this is not a pattern you want in your
software. In Avalon, Inversion of Control (IoC) is from one
parent (controlling) object to a child (controlled) component.
A parent may have many children, but children only have one
parent.
</p>
</s3>
</s2>
</s1>
<s1 title="How to Apply It">
<p>
<em>Inversion of Control</em> is applied in a very simple
manner. Basically, it means that the Component architecture
employs a <em>passive</em> structure. See the following code:
</p>
<source>
class MyComponent
implements Component, LogEnabled
{
Logger logger;
public enableLogging(Logger newLogger)
{
this.logger = newLogger;
}
myMethod()
{
logger.info("Hello World!");
}
}
</source>
<p>
The parent of MyComponent instantiates MyComponent, sets the
Logger, and calls myMethod. The Component is not autonomous,
and is given a Logger that has been configured by the parent.
</p>
<p>
The MyComponent class has no state apart from the parent, and
has no way of obtaining a reference to the Logger implementation
without the parent giving it the implementation it needs.
</p>
</s1>
<s1 title="IOC promotes Security">
<p>A big advantage of IOC for server applications is that it promotes
security. You can read an analysis about this
<link href="guide-patterns-ioc-security.html">
here
</link>.</p>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-patterns-soc.xml
Index: guide-patterns-soc.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - Multi Dimensional Separation of Concerns</title>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
The concept of using different points of view within the the system
goes a long way in the overall comprehension of the system.
</p>
<p>You can get more formal information in this paper:
<link href="http://www.research.ibm.com/hyperspace/MDSOC.htm">Multi-Dimensional Separation of Concerns</link>.
</p>
<s2 title="What it Means">
<p>
"Separation of Concerns" in its simplest form is separating
a problem into different points of view. For instance, the documentation
uses the "Separation of Concerns" pattern to make the documents
comprehensible (we have separate documents for Developers, Administrators,
and Block Implementers). The documents also use the pattern with XML and
XSL so that the look is separated from the content. Either can change
without breaking the other.
</p>
<p>
This pattern is less clear to point out in the code, however the concept
is evident. There are several interfaces included in Avalon that identify
an object's role within the system. For instance, all Components have certain
contracts -- therefore any object that implements the Component interface
must comply with those Contracts. This allows developers to manipulate
Components using a standard interface, without worrying about the semantics
of the implementation. They are separate concerns.
</p>
</s2>
<s2 title="How to Use It">
<p>
There are many ways to separate concern areas, but in Avalon
we use interfaces to define the concern areas addressed in
code.
</p>
<p>
Every time you use interfaces within Object Oriented Programming (OOP),
you are using the "Separation of Concerns" Pattern. The interface
separates the concern of the implementation from the concern of the user
of the interface. For example, every Object that can be configured
implements the Configurable interface. The contract surrounding the
Configurable interface is that the instantiator of the object passes a
Configuration object to the Configurable object (see "Inversion
of Control"). Just what the Configurable object does with the
passed Configuration object is irrelevant to the instantiator.
</p>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-patterns-soii.xml
Index: guide-patterns-soii.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - Separation of Interface and Implementation</title>
<authors>
<person name="Paul Hammant" email="Paul_Hammant@yahoo.com"/>
<person name="Peter Donald" email="peter@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
The core concept of interface and implementation separation is built into
Java itself in that it has interfaces and classes. Many toolkits have
been developed along the lines of an API / implementation separation.
One such toolkit is the SAX API and the multiple XML parsers that implement
it. Developers are quite happy using Apache's Xerces via the SAX API and
understand that SAX represents the interface and Xerces an implementation.
We notice that a lot of developers are happy to use interface/impl
separated tools, but not to make them. We will try to justify in this
document why we think people making applications should define
interface/impl boundaries early in the design cycle.
</p>
<s2 title="Justification">
<p>
The main reason we do it is because:
<ol>
<li>it forces you to decouple different modules/components/objects</li>
<li>if specified correctly allows you to easily change the implementation of
the interface/contract in the future</li>
<li>makes it possible for a user to read documentation about interface
without having the implementation details clutter up their perception</li>
<li>increases the possibility of reuse in a larger application</li>
</ol>
</p>
<p>
If you are building objects with the aim of reuse then [2] is important but
most people don't build for reuse (and most XP advocates say you should just
plan to use not reuse) and thus [1] and [2] are more important. If you feel
like documenting that and expanding this then feel free to.
</p>
</s2>
<s2 title="Example">
<p>
Let us hope this is not necessary:
</p>
<source>
package helloworld;
public interface HelloWorld {
void sayHello(String greeting);
}
package helloworld.impl.default;
public class DefaultHelloWorld implements HelloWorld {
void sayHello(String greeting) {
System.out.println("HelloWorld Greeting: " + greeting);
}
}
package helloworld.impl.remote;
public class RemoteHelloWorld implements HelloWorld {
private RemoteMessager mRemoteMessager;
public RemoteHelloWorld(RemoteMessager rm) {
RemoteMessager = rm;
}
void sayHello(String greeting) {
rm.sendMessage("HelloWorld Greeting: " + greeting);
}
}
</source>
</s2>
<s2 title="History">
<p>
We are referring to this pattern at <strong>interface/impl separation</strong>.
Wiley's Patterns in Java book refers to it simply as 'Interface', but we feel
that the word interface is overloaded enough in English and computing.
</p>
<p>
It might be true to say that this is 'API/implementation separation', but
this too could be confusing as the aforementioned SAX is not quite a
pure set of interfaces. It has a static factory that thunks in an
implementation that all subsequent calls to the factory method will be
forced to use. See Anti-patterns below.
</p>
<p>
Better might be 'separation of implementation and the interface/contract' as
that is quite correct, but a tad unwieldy.
</p>
</s2>
</s1>
<s1 title="Related topics">
<s2 title="Implementation hiding">
<p>
Once a tool is split into interface and impl, it is possible for a container
to hide the implementation. Most containers already use dynamic proxys
(Available in the JDK since 1.3), but we are talking about having the classes
of the implementation hidden from classes using the interface.
</p>
<p>
To do this, it is easiest to mount the impl classes in a separate classloader
to the classloader that the interface-using classes are mounted in. The
interfaces being mounted in a classloader that is visible to both.
</p>
<p>
This is not a new proposition. Sun defined the servlet spec, and included
rules about implementation hiding for hosted servlets. Essentially,
instantiated servlets are only allowed to 'see' classes from the JDK, their
own WAR file and those of the Servlet API itself. Tomcat correctly hides
the implementation of the Servlet API from the hosted servlets.
</p>
<p>
To actually achieve this separation, many containers (including those from
the Avalon project) require that the interface and impl are in separate jars.
Or to put it another way, there is no point separating your interface and impl
classes if you are going to distribute them in the same jar.
</p>
</s2>
<s2 title="Kernel, Client API, Hosted Components">
<p>
This is building the previous section, and in short is referred to as K/CAPI/HC.
Basically the Kernel mounts hosted components and satisfies their need for a
client API. However the kernel wants to hide its implementation from the hosted
components.
</p>
<p>
An EJB container is another good example of this. EntityBean, SessionBean etc is
the client API. The hosted components are the beans, and the container has a
kernel. It builds a complex tree of classloaders to separate its implementation,
the client API, the JDK's runtime jar (that always being in the system or
primordial classloader), and the hosted components.
</p>
<p>
The central message of this is that it you have interface/impl separated your
tool, and are doing tricky things with more classloaders in the implementation,
please make sure you do not assume that the parent classloader of any classloader
is the system classloader. If your reusable tool has been taken by another team
and at some non root place in a classloader tree, then the tools will fail if
you have made such assumptions.
</p>
</s2>
<s2 title="Anti-patterns">
<p>
SAX, mentioned in multiple contexts in this document, is also an example of
where the design can go wrong. The Factory is static (that in itself is an
anti-pattern to IoC). Despite giving the appearance of having the ability
to generate a parser based on the implementation's class name, only the first
caller of that method will register a parser for the whole environment to use.
</p>
<p>
Given that the SAX API is now in the JDK, the environment we allude to above
is the whole JVM. This is a problem because in a very complex application
with differing concurrent needs for implementation of parsers, not all can be
met if the SAX API is used for making parsers.
</p>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-patterns-what-are.xml
Index: guide-patterns-what-are.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - What are Design Patterns?</title>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
<person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
<s1 title="Getting Started with Patterns">
<p>
I highly recommend reading the
<link href="http://www6.software.ibm.com/developerworks/education/j-patterns/index.html">
"Java Design patterns 101"
</link> tutorial, and its follow-up
<link href="http://www6.software.ibm.com/developerworks/education/j-patterns201/index.html">
"Java Design patterns 201"
</link>, if you are unfamiliar with the concept of Design Patterns (and
see below for more information). Note that you have to register at the
IBM DeveloperWorks site in order to read these, but that's a good idea
anyway.
</p>
</s1>
<s1 title="Where to learn more">
<p>
You can find more information about patterns from the following links:
</p>
<ol>
<li>Brian Foote's <link href="http://www.laputan.org/foote/papers.html">Pattern documents</link></li>
<li><link href="http://www6.software.ibm.com/developerworks/education/j-patterns/index.html">
"Java Design patterns 101"
</link> at DeveloperWorks</li>
<li><link href="http://www6.software.ibm.com/developerworks/education/j-patterns201/index.html">
"Java Design patterns 201"
</link> at DeveloperWorks</li>
<li><link href="http://cseng.aw.com/book/0,3828,0201633612,00.html">
"Java Design patterns: Elements of Reusable Object-Oriented Software"
</link> by the GoF (printed book)</li>
</ol>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/guide-where-to-go-from-here.xml
Index: guide-where-to-go-from-here.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - Guide - Where to go next</title>
<authors>
<person name="Leo Simons" email="leosimons@apache.org"/>
</authors>
</header>
<body>
<s1 title="There's a lot more to study">
<p>
Each of the pages in this short guide deserves an entire book, and
indeed, most of them have a lot of documentation devoted to them.
Here we provide you with pointers where else to look for more
information, within and outside of Avalon.
</p>
</s1>
<s1 title="Creating components">
<p>
After all the information in this guide has sunk in, you're probably
itching to write an Avalon Component. Our
<link href="@AVALON_BASE@/developing">
Developing with Avalon guide
</link> takes you through doing just that. You can download it as a PDF
and read at your leisure (it comes down to 56 printed pages). If that's
too much for you, we suggest you get the latest
<link href="@AVALON_BASE@/excalibur">excalibur</link> release and
take those components as an example. One application that uses a lot of
those components and is in widespread daily use is
<link href="http://xml.apache.org/cocoon">Cocoon</link>.
</p>
</s1>
<s1 title="More on Avalon's design concepts">
<p>A collection of links to interesting projects elsewhere on the web.</p>
<s2 title="Design patterns">
TODO
</s2>
<s2 title="Aspect-Oriented Programming">
TODO
</s2>
<s2 title="Component-Oriented Programming">
TODO
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/reference-the-lifecycle.xml
Index: reference-the-lifecycle.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Framework - The Component Lifecycle</title>
<authors>
<person id="BL" name="Berin Loritsch" email="bloritsch@apache.org"/>
<person id="PD" name="Peter Donald" email="peter@apache.org"/>
<person id="LS" name="Leo Simons" email="mail@leosimons.com"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
A Component lives within something called a container. Avalon provides an
application that functions as a container for Applications (which are
Components) called <link href="@PHOENIX_BASE@/index.html">Phoenix</link>.
You can also create your own Components that function as a container.
</p>
<p>
The contract between a container and a contained Component is simple: the
container is required to take a Component through what is called its
<strong>lifecycle</strong>.
</p>
</s1>
<s1 title="The Lifecycle">
<p>
The lifecycle of a Component specifies the methods that can be called on it,
and the order in which this may happen. Some methods can be called only once
in a specific <code>Phase</code> of a Component its lifecycle, others may
be called multiple times. These methods are called the lifecycle methods.
</p>
<p>
It is up to each container to indicate which lifecycle methods it will honor.
This should be clearly documented together with the description of the
container. Phoenix supports all of the lifecycle methods defined in the
Avalon Framework API.
</p>
</s1>
<s1 title="The Lifecycle interfaces">
<p>
A Component exposes its lifecycle methods by implementing the lifecycle
interfaces. Each of these defines one or more methods that represent a
specific Phase in a Component's lifecycle. The defined interfaces are:
</p>
<ol>
<li>LogEnabled</li>
<li>Contextualizable</li>
<li>Composable</li>
<li>Configurable</li>
<li>Parameterizable</li>
<li>Initializable</li>
<li>Startable</li>
<li>Suspendable</li>
<li>Recontextualizable</li>
<li>Recomposable</li>
<li>Reconfigurable</li>
<li>Reparameterizable</li>
<li>Stoppable</li>
<li>Disposable</li>
</ol>
<note>
<strong>Note:</strong>java.lang.Runnable has also been in use as a lifecycle
interface. This is not recommended and is not supported by Avalon. Instead,
the run() method is the responsibility of the Component itself. If you wish
to use it, call it from within start() or another method.
</note>
</s1>
<s1 title="Phase order">
<p>
The order in which the various lifecycle methods are called is very specific.
While none are required (it is possible to have a Component implementing
none of the lifecycle methods, although the use of that would be limited),
some can only be used when others are as well. This is best explained using
a few examples.
</p>
<s2 title="simple examples">
<p>The lifecycle of a <code>Component</code> implementing only Configurable for
example will be:</p>
<ol>
<li>constructor</li>
<li>configure</li>
<li>finalize</li>
</ol>
<p>The lifecycle of a <code>Component</code> implementing only Composable will be:</p>
<ol>
<li>constructor</li>
<li>compose</li>
<li>finalize</li>
</ol>
</s2>
<s2 title="complete">
<p>
If a <code>Component</code> implements more than one interface the order of
the events (compose, configure etc.) follow a specific order. A Component
implementing all above interfaces (including Runnable) will follow this
specific path:
</p>
<ol>
<li>constructor</li>
<li>contextualize</li>
<li>compose</li>
<li>configure</li>
<li>parameterize</li>
<li>initialize</li>
<li>start</li>
<li>
<ol>
<li>suspend</li>
<li>recontextualize</li>
<li>recompose</li>
<li>reconfigure</li>
<li>reparameterize</li>
<li>resume</li>
</ol>
</li>
<li>stop</li>
<li>dispose</li>
<li>finalize</li>
</ol>
</s2>
<s2 title="Phases executed once">
<p>
These lifecycle methods are only called once in the entire life of a
Component:
</p>
<ul>
<li>contextualize</li>
<li>compose</li>
<li>configure</li>
<li>parameterize</li>
<li>initialize</li>
<li>dispose</li>
</ul>
</s2>
<s2 title="Phases executed once or more">
<p>
These lifecycle methods are called at least once and possibly more, depending
on the container:
</p>
<ul>
<li>start</li>
<li>stop</li>
</ul>
</s2>
<s2 title="The Suspendable Interface">
<p>
The methods suspend() and resume() are not guaranteed to be called at all,
even when implemented. They can be called more than once, but only after
one another and between start() and stop(). The reason they exist is so
the container can notify the Component it needs to come to temporary stop
any operations. The container may need to perform some synchronized operation
on one of the Components used by this Component, or it may wish to call any
of the following methods, which can also be called zero or more times, and
only between a suspend() and a resume().
</p>
<ul>
<li>recontextualize()</li>
<li>recompose()</li>
<li>reconfigure()</li>
<li>reparameterize()</li>
</ul>
</s2>
<!--
<s2 title="The Command Pattern">
<p>
The most advanced, most complicated and most flexible option is to use
the Command pattern by having your Component implement the Commandable
interface. This is experimental; you'll find the Commandable and its
related classes in the excalibur package.
</p>
<p>
It is recommended that if your Component implements Commandable, it should
not implement Executable or Interruptable. When you do choose to combine the
two, the order in which the different steps must happen is very specific:
<code>
// inside container...<br />
// ...<br />
myComponent.initialize();<br />
myComponent.start();<br />
Iterator commands = myComponent.getCommands();<br />
runAll(commands);<br />
myComponent.suspend();<br />
myComponent.resume();<br />
myComponent.suspend();<br />
myComponent.resume();<br />
myComponent.stop();<br />
myComponent.dispose();<br />
// ...<br />
// on shutdown...<br />
stopAll(commands);<br />
commands = null;<br />
myComponent = null;<br />
System.gc(); // finalize() is called on myComponent, which allows it to perform some<br />
// final operation on its Commands.<br />
</code>
</p>
<p>
The advantage of using Commands is that you can have multiple processes running
outside your Component that can manipulate it. These will run until completion
even if you Component has already been disposed of.
</p>
<p>
You should note that the Command interface we use extends Runnable, which means
Commands can be (and usually are) run() using standard pooling utilities for
threads.
</p>
</s2>
-->
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2002/05/03 10:19:53 $
</legal>
</footer>
</document>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>