You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by do...@apache.org on 2001/02/27 09:03:06 UTC
cvs commit: jakarta-avalon/src/xdocs/phoenix administrator-guide.xml assemblers-guide.xml block-developers-guide.xml deployers-guide.xml index.xml
donaldp 01/02/27 00:03:06
Modified: src/xdocs book.xml features.xml getting-started.xml
install.xml todo.xml
Added: src/xdocs/framework code-standards.xml components.xml
composer.xml index.xml inversion-of-control.xml
life-cycle.xml patterns.xml reuse-standards.xml
security.xml separation-of-concerns.xml
src/xdocs/history index.xml
src/xdocs/phoenix administrator-guide.xml
assemblers-guide.xml block-developers-guide.xml
deployers-guide.xml index.xml
Removed: src/xdocs administrator-guide.xml assemblers-guide.xml
block-developers-guide.xml code-standards.xml
deployers-guide.xml design.xml history.xml
phoenix.xml
src/xdocs/design components.xml composer.xml
inversion-of-control.xml life-cycle.xml
patterns.xml reuse-standards.xml security.xml
separation-of-concerns.xml
Log:
Started rearranging concerns into appopriate directory structures.
ie Phoenix docs occur in phoenix,
avalon docs in framework
etc.
Todo: Migrate the Todo/API/Features/Install/Getting started to apporpriate concerns.
Revision Changes Path
1.4 +35 -36 jakarta-avalon/src/xdocs/book.xml
Index: book.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon/src/xdocs/book.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- book.xml 2001/02/26 13:45:21 1.3
+++ book.xml 2001/02/27 08:03:01 1.4
@@ -5,59 +5,58 @@
copyright="@year@ The Apache Software Foundation">
<section label="About">
- <page id="index" label="Overview" source="index.xml"/>
- <page id="history" label="History" source="history.xml"/>
- <page id="features" label="Features" source="features.xml"/>
- <page id="geting-started" label="Getting Started" source="getting-started.xml"/>
- <page id="install" label="Installation" source="install.xml"/>
- <page id="license" label="License" source="license.xml"/>
+ <page label="Overview" source="index.xml"/>
+ <page label="History" source="history/index.xml"/>
+ <page label="Features" source="features.xml"/>
+ <page label="Getting Started" source="getting-started.xml"/>
+ <page label="Installation" source="install.xml"/>
+ <page label="License" source="license.xml"/>
<separator/>
- <page id="mail" label="Mail Archive" source="mail.xml"/>
- <page id="contributors" label="Contributors" source="contributors.xml"/>
- <changes id="changes" label="Changes" source="changes.xml"/>
+ <page label="Mail Archive" source="mail.xml"/>
+ <page label="Contributors" source="contributors.xml"/>
+ <changes label="Changes" source="changes.xml"/>
</section>
<section label="Framework">
- <page id="design" label="Patterns and Design" source="design.xml"/>
- <page id="code-standards" label="Coding Standards" source="code-standards.xml"/>
- <page id="todo" label="Todo" source="todo.xml"/>
+ <page label="Patterns and Design" source="framework/index.xml"/>
+ <page label="Coding Standards" source="framework/code-standards.xml"/>
+ <page label="Todo" source="todo.xml"/>
<external id="api-docs" label="API Docs" href="api/index.html"/>
</section>
<section label="Phoenix">
- <page id="phoenix" label="What is Phoenix?" source="phoenix.xml"/>
- <page id="administrators" label="Administrators Guide" source="administrator-guide.xml"/>
- <page id="deployers" label="Deployers Guide" source="deployers-guide.xml"/>
- <page id="assemblers" label="Assemblers Guide" source="assemblers-guide.xml"/>
- <page id="developers" label="Block Developers Guide" source="block-developers-guide.xml" />
+ <page label="What is Phoenix?" source="phoenix/index.xml"/>
+ <page label="Administrators Guide" source="phoenix/administrator-guide.xml"/>
+ <page label="Deployers Guide" source="phoenix/deployers-guide.xml"/>
+ <page label="Assemblers Guide" source="phoenix/assemblers-guide.xml"/>
+ <page label="Block Developers Guide" source="phoenix/block-developers-guide.xml" />
</section>
<!-- history pages -->
- <hidden id="call-to-vote" source="history/call-to-vote.xml" />
- <hidden id="what-is-a-server" source="history/what-is-a-server.xml" />
- <hidden id="need-for-avalon" source="history/need-for-avalon.xml" />
+ <hidden source="history/call-to-vote.xml" />
+ <hidden source="history/what-is-a-server.xml" />
+ <hidden source="history/need-for-avalon.xml" />
<!-- design pages -->
- <hidden id="patterns" source="design/patterns.xml" />
- <hidden id="components" source="design/components.xml" />
- <hidden id="composer" source="design/composer.xml" />
- <hidden id="life-cycle" source="design/life-cycle.xml" />
- <hidden id="inversion-of-control" source="design/inversion-of-control.xml" />
- <hidden id="reuse-standards" source="design/reuse-standards.xml" />
- <hidden id="security" source="design/security.xml" />
- <hidden id="separation-of-concerns" source="design/separation-of-concerns.xml" />
+ <hidden source="framework/patterns.xml" />
+ <hidden source="framework/components.xml" />
+ <hidden source="framework/composer.xml" />
+ <hidden source="framework/life-cycle.xml" />
+ <hidden source="framework/inversion-of-control.xml" />
+ <hidden source="framework/reuse-standards.xml" />
+ <hidden source="framework/security.xml" />
+ <hidden source="framework/separation-of-concerns.xml" />
<!-- phoenix pages -->
- <hidden id="what-is-a-block" source="phoenix/what-is-a-block.xml" />
- <hidden id="blockinfo-specification" source="phoenix/blockinfo-specification.xml" />
- <hidden id="creating-a-block" source="phoenix/creating-a-block.xml" />
- <hidden id="what-is-a-server-application" source="phoenix/what-is-a-server-application.xml" />
- <hidden id="assembly-xml-specification" source="phoenix/assembly-xml-specification.xml" />
- <hidden id="server-xml-specification" source="phoenix/server-xml-specification.xml" />
- <hidden id="creating-a-server-application"
- source="phoenix/creating-a-server-application.xml" />
+ <hidden source="phoenix/what-is-a-block.xml" />
+ <hidden source="phoenix/blockinfo-specification.xml" />
+ <hidden source="phoenix/creating-a-block.xml" />
+ <hidden source="phoenix/what-is-a-server-application.xml" />
+ <hidden source="phoenix/assembly-xml-specification.xml" />
+ <hidden source="phoenix/server-xml-specification.xml" />
+ <hidden source="phoenix/creating-a-server-application.xml" />
</book>
1.2 +2 -0 jakarta-avalon/src/xdocs/features.xml
Index: features.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon/src/xdocs/features.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- features.xml 2001/02/23 10:47:47 1.1
+++ features.xml 2001/02/27 08:03:01 1.2
@@ -1,5 +1,7 @@
<?xml version="1.0"?>
+<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
+
<document>
<header>
1.2 +4 -3 jakarta-avalon/src/xdocs/getting-started.xml
Index: getting-started.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon/src/xdocs/getting-started.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- getting-started.xml 2001/02/23 10:47:47 1.1
+++ getting-started.xml 2001/02/27 08:03:01 1.2
@@ -17,7 +17,7 @@
<p>
This document provides developers with simple documentation for getting
started with Avalon. For information about the overall structure of
- Avalon, please refer to the <link href="design.html">Design</link> document.
+ Avalon, please refer to the <link href="framework/index.html">Design</link> document.
</p>
<p>
@@ -38,12 +38,13 @@
To generate a full set of detailed API documentation for Avalon, go to the base
directory of source distribution and run the appropriate build script for your
platform with the parameter 'javadocs'.
-
+
<source><![CDATA[
> build.[bat|sh] javadocs
- ]]></source>
+]]></source>
+
</p>
</s1>
1.2 +4 -2 jakarta-avalon/src/xdocs/install.xml
Index: install.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon/src/xdocs/install.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- install.xml 2001/02/23 10:47:47 1.1
+++ install.xml 2001/02/27 08:03:02 1.2
@@ -1,5 +1,7 @@
<?xml version="1.0"?>
+<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
+
<document>
<header>
@@ -38,8 +40,8 @@
</p>
<p>
- Executing this script will create a <filename>dist</filename> directory within the Avalon
- distribution directory. The <filename>dist</filename> directory will contain the
+ Executing this script will create a <em>dist</em> directory within the Avalon
+ distribution directory. The <em>dist</em> directory will contain the
compiled class files packaged into jars.
</p>
1.2 +2 -0 jakarta-avalon/src/xdocs/todo.xml
Index: todo.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon/src/xdocs/todo.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- todo.xml 2001/02/23 10:47:47 1.1
+++ todo.xml 2001/02/27 08:03:02 1.2
@@ -1,5 +1,7 @@
<?xml version="1.0"?>
+<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
+
<document>
<header>
1.1 jakarta-avalon/src/xdocs/framework/code-standards.xml
Index: code-standards.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Coding Standards</title>
<authors>
<person name="Avalon Documentation Team" email="bloritsch@apache.org"/>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
<person name="Peter Donald" email="donaldp@apache.org"/>
<person name="Roberto Lo Giacco" email="rlogiacco@mail.com"/>
</authors>
</header>
<body>
<s1 title="Coding Standards">
<p>
This document describes a list of coding conventions that are required
for code submissions to the project. By default, the coding conventions
for most Open Source Projects should follow the existing coding conventions
in the code that you are working on. For example, if the bracket is on
the same line as the if statement, then you should write all your code
to have that convention.
</p>
<p>
<strong>If you commit code that does not follow these conventions and you
are caught, you are responsible for also fixing your own code.</strong>
</p>
<ol>
<li>Brackets should begin and end on a new line. Examples:
<source><![CDATA[
if( foo )
{
// code here
}
try
{
// code here
}
catch( final Exception bar )
{
// code here
}
finally
{
// code here
}
while( true )
{
// code here
}
]]></source>
</li>
<li><p>The preference is to include extra spaces between parenthesis and expression.
For example;</p>
<source><![CDATA[
if( foo )
]]></source>
</li>
<li>
<p>
4 spaces. <strong>NO</strong> tabs. Period. We understand that a lot of you like
to use tabs, but the fact of the matter is that in a distributed development
enviroment, when the cvs commit messages get sent to a mailing list, they
are almost impossible to read if you use tabs.
</p>
<p>
In Emacs-speak, this translates to the following command:
(setq-default tab-width 4 indent-tabs-mode nil)
</p>
</li>
<li>
Unix linefeeds for all .java source code files. Other platform specific
files should have the platform specific linefeeds.
</li>
<li>
Javadoc <strong>SHOULD</strong> exist on all your methods. Also, if you are working
on existing code and there currently isn't a javadoc for that method/class/variable
or whatever, then you should contribute and add it. This will improve the
project as a whole.
</li>
<li>
The Jakarta Apache/Avalon License <strong>MUST</strong> be placed at the top
of each and every file.
</li>
<li>
If you contribute to a file (code or documentation), add yourself to the
top of the file. For java files the preferred Javadoc format is:
<source><![CDATA[
@author <a href="mailto:user@domain.com">John Doe</a>
]]></source>
</li>
<li>
Indent comments on an 80 column basis and the code on a
100 column using a two more indention when you're constrained
to wrap a line.
</li>
<li>
We focus on readability over performance, at least in the first
phase, leaving source code optimization the last resource to give
out some milliseconds from my code. If the code is not performing then
it is better to re-engineer it rather than to expand loops, take
out variable declarations and such things. If the code is
performing well and you know what the core methods are then, in the
end of the process, try to give out the best from them.
</li>
<li>
Try to javadoc-comment all methods and public/default/protected
attributes adding code comments only when you think it's really
needed (like assumptions).
</li>
<li>
Variables are declared in the inner scope regardless of
performances unless the code really needs for performances
(2 thousand loops every 5 seconds for example) like:
<source>
while( myListIterator.hasNext() )
{
final String myString = (String)myLstIterator.nextElement();
}
</source>
</li>
<li>
Variable names are every time descriptive. The cases where this rule is
not applied include; manipulating exceptions (only uppercase class
exception letters), loop declaring variables (mostly I use i,j,k and t)
and other established shortenings (like init() for initialize, sb for
StringBuffer etc). ie.
<source><![CDATA[
try
{
for( int i = 0; i < 10; i++ )
{
// some stuff
}
}
catch( final FileNotFoundException fnfe )
{
// some stuff
}
catch( final IndexOutOfBoundsException ioobe )
{
// some stuff
}
]]></source>
</li>
<li>
Use only String concatenation unlesss you really need
StringBuffer methods leaving to the compiler optimization
the stuff to replace it with StringBuffer, so use:
<source>
final String myString = "test " + "for " + "performances";
</source>
</li>
<li>
Indent comments on an 80 column basis and the code on a
100 column using a two more indention when you're constrained
to wrap a line.
</li>
<li>
Try not to declare a method as 'synchronized'. If a method accesses
a shared resource then surround accesses to that resource with
a synchronized block. Ideally the synchronized block should surround
the smallest possible area. For example:
<source>
public void sharedMethod()
{
String display = null;
synchronized( this )
{
display = mySharedObject.getHelloWorld();
}
System.out.println( display );
}
</source>
If you are within a static method, then you may have to create
a static object whose sole purpose in life is to provide the
lock you need.
</li>
</ol>
<p>
Thanks for your cooperation.
</p>
<p>
-The Avalon Team
</p>
</s1>
</body>
</document>
1.1 jakarta-avalon/src/xdocs/framework/components.xml
Index: components.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Design Documentation</title>
<subtitle>Designing a Component</subtitle>
<version>3.0</version>
<authors>
<person id="BL" name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
<notice>
Avalon documentation is under construction. Everything you can find
outside this page is to be considered obsolete.
</notice>
</header>
<body>
<s1 title="Introduction">
<p>
In Avalon, a Component is defined as a passive entity that performs
a specific role. This is an important concept to grasp because
it forces you to think in a specific manner when designing a system
using Components. First, a Component employs a passive API (one
that is acted upon). Second, the Component's purpose is narrowed
to perform one function.
</p>
<p>
The difference between Object Oriented Programming (OOP) and Component
Oriented Programming (COP) is the Black Box idea. Regular OOP goes
so far as to organize data objects into entities that take care of
themselves. It has many powerful features that make things that
used to be difficult to impossible relatively easy. However, its
limitation is one of object codependency. That doesn't mean that
all OOP is horrid and previous OO programmers didn't have a clue.
It means that over time a more rigid idea had to be formalized:
the Component. The key difference between a Component and an
Object is that the Component is a completely replaceable entity.
</p>
<p>
The idea of programming for replaceability is an intriguing one,
and it requires careful planning. The first point is that a
Component is not just an object by itself, but a combination of
an interface and one or more objects to perform the task at hand.
</p>
</s1>
<s1 title="Roles">
<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>
</s1>
<s1 title="Writing the Component">
<p>
John Milton 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 Avalon are: configuration,
external component use, management, and execution.
</p>
<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>Composer:</strong> marks an object that uses Components.
</li>
<li>
<strong>Initializable:</strong> marks an object that can be initialized
and destroyed.
</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>
<s2 title="How is the Component Going to be Used?">
<p>
The first step in writing the Component is determining how it is going
to be used. There will be a number of times where you have a powerful
Component that can be used in many different contexts. Those contexts
may include executing the Component from the command line (separate
from Avalon), using it as a part of a sub system, or using it as an
integral part of Avalon.
</p>
<s3 title="Part of Avalon">
<p>
All Components are an integral part of Avalon, so there is really
nothing to be done beyond specifying its interface (role). It is
important to identify and document it's social contract with the
rest of the system. What I mean by social contract is the order
of dependencies, what it needs to function, and what it supplies
to the rest of the system.
</p>
</s3>
<s3 title="Part of a Sub System">
<p>
A sub system can either be part of Avalon, or live in a separate
context. A perfect example would be a Component that can function
within a Servlet or Enterprise Application. Neither of those
contexts are native to Avalon (though they can easily be built
on top of Avalon).
</p>
<p>
It is important to do even more careful planning than in the
first scenario. The reason is that you want the interface to be
as generic as possible and still accurately represent its role.
</p>
<p>
Because the contexts that may not be an integral part of Avalon,
you must take care to use the Component in the same manner as
Avalon would. That means that you follow the order of concerns
that Avalon has specified for those concerns.
</p>
</s3>
<s3 title="A Stand Alone Program">
<p>
When you are designing a Component to be run from the command
line (or directly by the operating system), try to separate
the main function from the Component itself. This is imperative
in order to maintain the passive API of Avalon. By designing
you Component in the manner stated in the previous section,
you have effectively minimized what the main function has to
do.
</p>
<p>
Follow the practice of having an object dedicated to the main
function that includes the parsing of the command line parameters
and initialization of the Component. When the Component is used
the exact same way in every context (including the command line),
you minimize the number of locations to look while debugging.
</p>
<note>
A common mistake is to combine the main function in the
implementation of the Component. This requires violating the
contracts and principles that Avalon is built upon. This
violation of the pattern of "Inversion of Control" is
aptly dubbed "Subversion of Control" (thanks to Steven Coffman
for the name of the anti-pattern).
</note>
</s3>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:03 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/composer.xml
Index: composer.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Design Documentation</title>
<subtitle>Understanding the Composer</subtitle>
<version>3.0</version>
<authors>
<person id="BL" name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
<notice>
Avalon documentation is under construction. Everything you can find
outside this page is to be considered obsolete.
</notice>
</header>
<body>
<s1 title="Introduction">
<p>
In Avalon, a Composer is defined as an active entity that controls
or uses Components. It's 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 Composer 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 Composer.
</p>
<note>
The Composer 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. Composer
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 it's 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 Composer, 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>
</s1>
<s1 title="Populating the ComponentManager">
<p>
It is the responsibility of the entity that creates the Composer 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 Composer 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: 2001/02/27 08:03:03 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/index.xml
Index: index.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Developer Design Documentation</title>
<subtitle>Introduction</subtitle>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
<person name="Peter Donald" email="donaldp@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
Avalon is among other things a repository of established patterns and
design standards. Developers will appreciate the thought put into the
framework, because it eases development. This documentation covers the
overall principles behind Avalon, and the patterns involved.
</p>
<s2 title="Target Audience">
<p>
This documentation is aimed towards developers who are interested
in the design principles of Avalon, or wish to develop code that
will be incorporated into Avalon.
</p>
</s2>
<s2 title="Theoretical Aspects of Component Development">
<p>
The following documents provide basic theoretical concepts that are applied
through-out Avalons 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.
</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="security.html">Security</link></li>
</ol>
</s2>
<s2 title="Concrete Descriptions of the Avalon Component model">
<p>
This section describes concrete examples of how the theoretical ideas
are applied within the context of Avalon. It describes the lifecycle of
a component and how the interfaces contribute to defining the lifecycle.
</p>
<ol>
<li><link href="components.html">Designing a Component</link></li>
<li><link href="composer.html">Understanding the Composer</link></li>
<li><link href="life-cycle.html">The components life-cycle</link></li>
</ol>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:03 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/inversion-of-control.xml
Index: inversion-of-control.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Developer Documentation</title>
<subtitle>Patterns</subtitle>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
</header>
<body>
<s1 title="Inversion of Control">
<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>
<s2 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.
</p>
<s3 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. The best analogy,
however, is called "Chain of Command" in the
military.
</p>
<s4 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>
</s4>
</s3>
</s2>
<s2 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, Composer {
ComponentManager manager;
MyComponent() {
// Nothing to do here.
}
setComponentManager(ComponentManager manager){
this.manager = manager;
}
myMethod() {
Logger logger = (Logger) manager.getComponent("org.apache.avalon.blocks.Logger");
logger.log("MyComponent", "Hello World!", Logger.INFO);
}
}
</source>
<p>
The parent of MyComponent instantiates MyComponent, sets the
ComponentManager, and calls myMethod. The Component is not
autonomous, and is given a ComponentManager that has an instance
of the Logger object that is called by role.
</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 telling it which implementation it can receive.
</p>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:03 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/life-cycle.xml
Index: life-cycle.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Component Developers Documentation</title>
<subtitle>Lifecycle methods</subtitle>
<authors>
<person id="BL" name="Berin Loritsch" email="bloritsch@apache.org"/>
<person id="PD" name="Peter Donald" email="donaldp@apache.org"/>
</authors>
</header>
<body>
<s1 title="Lifecycle">
<p>A <code>Component</code>'s lifecycle depends on the specific interface
implemented by the <code>Component</code> and the interfaces honored by it's
container. Note that it is up to each individual Component Container to indicate
which lifecycle methods it will honor. These should be documented along with a
description of the container.</p>
<p>Each of the following interfaces add some lifecycle stages to the
component lifecycle. The interfaces related to lifecycle are:</p>
<ol>
<li>Loggable</li>
<li>Contextualizable</li>
<li>Composer</li>
<li>Configurable</li>
<li>Initializable</li>
<li>Startable</li>
<li>Runnable</li>
<li>Suspendable</li>
<li>Recontextualizable</li>
<li>Recomposer</li>
<li>Reconfigurable</li>
<li>Resumeable</li>
<li>Stoppable</li>
<li>Disposable</li>
</ol>
<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 Composer will be:</p>
<ol>
<li>constructor</li>
<li>compose</li>
<li>finalize</li>
</ol>
<p>If a <code>Component</code> implements more than one interface the order of
the events (compose, configure etc.) follow a specific order. A <code>Component
</code> implementing all above interfaces for example will follow the specific
path:</p>
<ol>
<li>constructor</li>
<li>contextualize</li>
<li>compose</li>
<li>configure</li>
<li>init</li>
<li>start</li>
<li>run</li>
<li>
<ol>
<li>suspend</li>
<li>reconfigure</li>
<li>recontextualize</li>
<li>recompose</li>
<li>resume</li>
</ol>
</li>
<li>stop</li>
<li>dispose</li>
<li>finalize</li>
</ol>
<p>This is a possible lifecycle. By definition the [start,run,stop] can occur one
or more times while [reconfigure] [recompose] [recontextualize] can occur
zero or more times in any order inside the [suspend,resume] cycle.
So another possible life can be:</p>
<ol>
<li>constructor</li>
<li>setLogger</li>
<li>contextualize</li>
<li>compose</li>
<li>configure</li>
<li>init</li>
<li>start</li>
<li>run</li>
<li>suspend</li>
<li>recontextualize</li>
<li>reconfigure</li>
<li>resume</li>
<li>suspend</li>
<li>recompose</li>
<li>reconfigure</li>
<li>resume</li>
<li>stop</li>
<li>dispose</li>
<li>finalize</li>
</ol>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:03 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/patterns.xml
Index: patterns.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Developer Documentation</title>
<subtitle>Patterns</subtitle>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction to Design Patterns">
<p>
I highly recommend reading the essay
<link href="http://xent.ics.uci.edu/~khare/Alexander.htmld/">
"On the diffusion of Christopher Alexander's <em>A Pattern
Language</em> into Software Architecture"
</link>
by Rohit Khare. That essay is a good primer on the principles
behind Design Patterns and how they came into being.
</p>
<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 three main conceptual patterns called Inversion
of Control, Multi-Dimensional Separation of Concerns, and
Aspect Oriented Programming. Avalon also uses several architectural
patterns like the Singleton and the Factory. Detailed information
about all of these patterns will be included in their respective
pages.
</p>
<p>
You can find more information about patterns from the following links:
</p>
<ol>
<li><link href="http://www.laputan.org/foote/papers.html">Brian Foote's Pattern documents</link></li>
</ol>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:03 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/reuse-standards.xml
Index: reuse-standards.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Developer Documentation</title>
<subtitle>Designing for Reuse</subtitle>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
</header>
<body>
<s1 title="Rules for Reuse">
<p>
If you are asking yourself why this section is even included,
the answer is that a well designed framework is designed to
be modular and black-box in nature. If you are new to Object
Oriented Programming (OOP), then I suggest you read
<link href="http://www.laputan.org/drc/drc.html">
"Designing Reusable Classes"
</link> by Ralph E. Johnson and Brian Foote. It provides a
good primer on OOP techniques.
</p>
<p>
Within this chapter, I will summarize the 12 rules for designing
for code reuse (what frameworks promote).
</p>
<s2 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 opperate in the
same manner.
</p>
</s2>
<s2 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 emmensely.
</p>
</s2>
<s2 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>
</s2>
<s2 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>
</s2>
<s2 title="Class Heirarchies Should be Deep and Narrow">
<p>
Basically, this rule is saying it is better to start with an
Abstract object, and specialize off of that than it is to
reimplement the interface for each object. For example, in
a GUI you will have an HTMLTextBox that extends PlainTextBox
that extends AbstractTextBox that extends AbstractControl.
You do that instead of an HTMLTextBox that implements the
Control interface. (You get the point).
</p>
</s2>
<s2 title="The Top of the Class Heirarchy Should be Abstract">
<p>
Always provide an abstract base class to extend for your
specializations. The majority of the functionality and
behavior is well defined in those cases--making it easier
to deciphor what the intents of the interface designer were.
</p>
</s2>
<s2 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>
</s2>
<s2 title="Subclasses Should be Specializations">
<p>
Think 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>
</s2>
<s2 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>
</s2>
<s2 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 heirarchy tree.
</p>
</s2>
<s2 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>
</s2>
<s2 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 (structure != null) {
this.format(Example 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 output = (ExampleFormatter) manager.lookup(Roles.FORMATTER);
if (structure != null) {
output.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>
</s2>
<s2 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>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:03 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/security.xml
Index: security.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Developer Documentation</title>
<subtitle>Security Concerns</subtitle>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
</header>
<body>
<s1 title="Security Concerns">
<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 the
lose are 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 is only part of the architecture.
</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
world wide web). In those cases you have to make sure that the entity
is the correct one.
</p>
<p>
There are two sides of authentication. There is the side that you
are authenticating an entity you want to do business with. Then there
is the side of 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 Kosher.
</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 much an important part of 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 Rediculous">
<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 the most about computer security
than I have at any other time.
</p>
<p>
Our customer, being 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
result 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, or any other clear text communications port needs
to be removed. All communications 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="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 and 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
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 absurd, no one can
identify the bits traveling on a computer from EMI due to the level of noise
(clocks, addressing lines, <em>encrypted data</em>, and other computers on the
network).
</p>
<p>
The morale 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: 2001/02/27 08:03:03 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/framework/separation-of-concerns.xml
Index: separation-of-concerns.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Developer Documentation</title>
<subtitle>Multi Dimensional Separation of Concerns</subtitle>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
</header>
<body>
<s1 title="Separation of Concerns">
<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: 2001/02/27 08:03:03 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/history/index.xml
Index: index.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>History of Avalon</title>
<authors>
<person name="Avalon Documentation Team" email="bloritsch@apache.org"/>
<person name="Peter Donald" email="donaldp@apache.org"/>
</authors>
</header>
<body>
<s1 title="History">
<p>
This document tracks the history of the Avalon project. Originally started with
a realisation that java was a great platform for developing server products and a
<link href="call-to-vote.html">call to vote</link>. There was a lot of work
formalizing what exactly a <link href="what-is-a-server.html">server</link> consists
of and why Avalon was <link href="need-for-avalon.html">needed</link>. Theses
discussions led to the initial development of Avalon framework.
</p>
<p>
Overtime the Java Apache Server Framework project was renamed Avalon. This was in
recognition that the original ideas have evolved over time. Avalon became a
repository of general utility code, a design and testing ground for component based
solutions, a micro kernel and generalized server orientated services. This combined
with a move from the Java Apache project to the jakarta project promted the revision.
At this time the kernel code was repackaged under the name phoenix, core services
under the name cornerstone and the avalon-independent code was moved to util package.
</p>
</s1>
</body>
</document>
1.1 jakarta-avalon/src/xdocs/phoenix/administrator-guide.xml
Index: administrator-guide.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Avalon Phoenix Administrator Documentation</title>
<subtitle>Introduction</subtitle>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
Avalon is a Server Framework that provides or will provide for
central administration, server pooling, and quicker time to market.
The framework defines a standard method of piecing together server
components and creating a server.
</p>
<s2 title="Target Audience">
<p>
This documentation describes the care and feeding of the Avalon
Phoenix kernel from the point of view of the administrator.
It will be expanded as the system becomes more complete.
</p>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:04 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/phoenix/assemblers-guide.xml
Index: assemblers-guide.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Server Assemblers Guide</title>
<subtitle>Introduction</subtitle>
<authors>
<person name="Avalon Documentation Team" email="bloritsch@apache.org"/>
</authors>
</header>
<body>
<s1 title="Who Should Read This Book?">
<p>
The Server Assemblers Guide is written for assemblers who want to assemble a
Server Application for Phoenix. It is assumed that you are familiar with
the basic concepts of the Phoenix framework.
</p>
<p>
This book concentrates on assembly, and as such requires no knowledge of
java programming. It does however assume you are familiar with server
fundamentals, basic security measures, and performance tuning.
</p>
</s1>
<s1 title="Organization">
<p>
The information is organized into sections detailing a specifc aspect of
assembling ServerApplications.
</p>
</s1>
<s1 title="Sections">
<ol>
<li>
<link href="what-is-a-server-application.html">
What is a Server Application?
</link>
</li>
<li>
<link href="creating-a-server-application.html">
How do I create a Server Application?
</link>
</li>
<li>
<link href="assembly-xml-specification.html">assembly.xml specification</link>
</li>
<li>
<link href="server-xml-specification.html">server.xml specification</link>
</li>
</ol>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:04 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/phoenix/block-developers-guide.xml
Index: block-developers-guide.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Block Developers Guide</title>
<subtitle>Preface</subtitle>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
</authors>
<abstract>
The Block Developer's Guide (BDG) is written to bring an overview
of how to create and deploy a Block. The Block is the component that
is hosted in the Phoenix micro-kernel.
</abstract>
</header>
<body>
<s1 title="Who Should Read This Book?">
<p>The BDG is written for developers who want to create
blocks for Phoenix. It is assumed that you are familiar with Java, XML, Avalon
patterns and server side security issues. This book provides an overview of
the underlying technology, Java classes and interfaces, component model, and
behavior of server Blocks within Phoenix.</p>
<p>While this book concentrates on server fundamentals, it should not
be construed as a “dummy's” book. Server side programming
is complex because of the performance and security issues you must
balance.</p>
<p>You should be well versed in the Java language and have some
practical experience developing server solutions. If you need a stronger
background on server side programming, I suggest finding a good book on the
subject (any suggestions?).</p>
</s1>
<s1 title="Organization">
<p>
Here is how the information is presented. The first X chapters are
foundational material, and describe the basic concepts you can use in your
own blocks. The later chapters specify in detail the formal requirements of
Block implementations.
</p>
</s1>
<s1 title="Sections">
<ol>
<li><link href="what-is-a-block.html">What is a block?</link></li>
<li><link href="creating-a-block.html">How do I create a block?</link></li>
<li><link href="blockinfo-specification.html">BlockInfo specification</link></li>
</ol>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:04 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/phoenix/deployers-guide.xml
Index: deployers-guide.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Deployers Guide</title>
<subtitle>Introduction</subtitle>
<authors>
<person name="Peter Donald" email="donaldp@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
Currently deploying a server application under Phoenix is simply a matter
of dropping the .sar file into the appropriate directory (<code>apps/</code>)
and restarting Phoenix. In the future there will be more advanced methods
of deploying and undeploying Server Applications without restarting Phoenix.
</p>
<s2 title="Target Audience">
<p>
This documentation describes the methods through which you can deploy
Server Applications under the Phoenix kernel. It will be expanded as
the system becomes more complete.
</p>
</s2>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:05 $
</legal>
</footer>
</document>
1.1 jakarta-avalon/src/xdocs/phoenix/index.xml
Index: index.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "../dtd/document-v10.dtd">
<document>
<header>
<title>Phoenix Developer Documentation</title>
<subtitle>Introduction</subtitle>
<authors>
<person name="Berin Loritsch" email="bloritsch@apache.org"/>
<person name="Peter Donald" email="donaldp@apache.org"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>
Phoenix is a micro-kernel designed and implemented on top of the Avalon
framework. It is both an API to program to and a reference implementation.
The reference implementation provides a number of facilities to manage the
environment of Server Applications. Such facilities include log management,
classloading, thread management and security. In the future it will
conditionally offer support extra facilities such as central server management,
server pools, and other facilities aimed at reducing the time to market. The API
defines a standard method of piecing togther server components and creating a server.
</p>
</s1>
</body>
<footer>
<legal>
Copyright (c) @year@ The Jakarta Apache Project All rights reserved.
$Revision: 1.1 $ $Date: 2001/02/27 08:03:05 $
</legal>
</footer>
</document>