leosimons 2002/07/08 10:42:16 Modified: tweety default.properties tweety/src/xdocs avalon-container-howto.xml avalon-for-beginners.xml tweety/src/java/org/apache/avalon/excalibur/tweety Egg.java Main.java package.html Tweety.java tweety/src/java/org/apache/avalon/excalibur/tweety/demos package.html Log: more docs Revision Changes Path 1.4 +1 -1 jakarta-avalon-excalibur/tweety/default.properties Index: default.properties =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/tweety/default.properties,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- default.properties 3 Jul 2002 20:21:03 -0000 1.3 +++ default.properties 8 Jul 2002 17:42:16 -0000 1.4 @@ -8,7 +8,7 @@ name=excalibur-tweety Name=Excalibur Tweety dir-name=tweety -version=1.0.1-alpha +version=1.0-beta package-version=0.99 year=2000-2002 1.2 +16 -6 jakarta-avalon-excalibur/tweety/src/xdocs/avalon-container-howto.xml Index: avalon-container-howto.xml =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/tweety/src/xdocs/avalon-container-howto.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- avalon-container-howto.xml 27 Jun 2002 16:57:18 -0000 1.1 +++ avalon-container-howto.xml 8 Jul 2002 17:42:16 -0000 1.2 @@ -8,13 +8,23 @@ </authors> </header> <body> - <s1 title="Introduction"> - <p>TBD</p> - </s1> + <s1 title="So you want to build your won container, huh?"> + <p>Well, you're mostly on your own for now. We're still working + on the entire concept of container and on the various containers + that ship with avalon.</p> - <s1 title="Table of Contents"> - <p>TBD</p> + <p>For now, I suggest you check out the sources for Tweety + (inside the <code>jakarta-avalon-excalibur</code> CVS module), + <a href="http://tambora.zenplex.org/cgi-bin/cvsweb.cgi/plexus/">Plexus</a>, + Containerkit (also inside the <code>jakarta-avalon-excalibur</code> + CVS module), Fortress (same CVS module) and Phoenix + (inside the <code>jakarta-avalon-phoenix</code> CVS module) to see + how it is done.</p> + + <p>Finally, take a peak at the avalon-dev mail archives or ask some + questions on that list,</p> </s1> + </body> <footer> <legal> 1.3 +239 -5 jakarta-avalon-excalibur/tweety/src/xdocs/avalon-for-beginners.xml Index: avalon-for-beginners.xml =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/tweety/src/xdocs/avalon-for-beginners.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- avalon-for-beginners.xml 5 Jul 2002 08:27:04 -0000 1.2 +++ avalon-for-beginners.xml 8 Jul 2002 17:42:16 -0000 1.3 @@ -8,18 +8,252 @@ </authors> </header> <body> - <s1 title="Introduction"> + <s1 title="Work in Progress!"> + <p>This manual is quite far from finished. While you are free to read it, I recommend + you don't.</p> + </s1> + + <s1 title="Introduction"> <p>Avalon has <b>a lot</b> of documentation (it has a lot of code, too, but most users don't see this as that much of a problem). It might be difficult for you to see where you should get started. That's why I wrote this little document.</p> <p>The place you get started is what we call the avalon framework. This little bit of code (the jar file is about 60k), combined with quite a bit of documentation, will revolutionize - (in time) the way you write software.</p> - </s1> + (in time) the way you write software. Tweety is here to help you figure out what avalon + framework is all about.</p> + </s1> <s1 title="Table of Contents"> - <p>TBD</p> + <ol> + <li>Introduction</li> + <li>Table of Contents</li> + <li>Your first component</li> + <li>The CartoonCreator application + <ol> + <li>Determining application goals and features</li> + <li>Determining the components we need</li> + <li>Your average CartoonCreator application + <ol> + <li>Cartoon</li> + <li>CartoonBuilder</li> + <li>CartoonItem</li> + <li>CartoonBird</li> + <li>CartoonCat</li> + <li>CartoonCage</li> + </ol> + </li> + <li>Refactoring: "use the lifecycle, Luke!" + <ol> + <li>Cartoon</li> + <li>CartoonBuilder</li> + <li>CartoonItem</li> + <li>CartoonBird</li> + <li>CartoonCat</li> + <li>CartoonCage</li> + </ol> + </li> + </ol> + </li> + </ol> + </s1> + + <s1 title="Your first component"> + <p>We're gonna start reaally simple. Consider this class:</p> + + <s3 title="BirdSong1.java"> + <source> + package avalon.tutorial; + + public class BirdSong1 + { + private int m_numberOfChilps; + private String m_chilpMessage; + private String m_chilpSeparator; + + public void BirdSong1( int numberOfChilps, chilpMessage, chilpSeparator ) + { + m_numberOfChilps = numberOfChilps; + m_chilpMessage = chilpMessage; + m_chilpSeparator = chilpSeparator; + } + + public sing() + { + for( int i = 0; i != m_numberOfChilps; i++ ) + { + if( i != 0 && i != (m_numberOfChilps-1) ) + System.out.print( m_chilpSeparator ); + + System.out.print( m_chilpMessage ); + } + } + + public static void main(String args[]) + { + BirdSong1 birdSong = new BirdSong1( new Integer( args[0] ).intValue(), + args[1], args[2] ); + + BirdSong.sing(); + } + } + </source> + </s3> + + <p>I'm sure you've figured out what that clas does. The command + <code>java avalon.tutorial.BirdSong1 20 chilp *</code> will print out something like</p> + + <source> + chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp*chilp + </source> + + <p>The steps to making this class into a component are as follows:</p> + + <ul> + <li>Define an interface and an implementation instead of just a class</li> + <li>Refactor to use avalon framework lifecyle methods</li> + <li>Refactor more to use a setup optimized for lots of reuse</li> + </ul> + + <p>This results in something like this:</p> + + <s3 title="BirdSong.java"> + <source> + package avalon.tutorial; + + import org.apache.avalon.framework.parameters.Parameterizable; + import org.apache.avalon.framework.parameters.Parameters; + import org.apache.avalon.framework.activity.Startable; + import org.apache.avalon.framework.logger.LogEnabled; + + public interface BirdSong extends Parameterizable, Startable, LogEnabled; + { + public static final String PARAM_NUMBER_OF_CHILPS = "numberOfChilps"; + public static final String PARAM_CHILP_MESSAGE = "chilpMessage"; + public static final String PARAM_CHILP_SEPARATOR = "chilpSeparator"; + + /** + * Provide us with the parameters it needs to work. Required are: + * >ul< + * >li<numberOfChilps>/li< + * >li<chilpMessage>/li< + * >li<chilpSeparator>/li< + * >/ul< + * >/pre< + * + */ + public void parameterize( Parameters parameters ); + } + </source> + </s3> + + <s3 title="BirdSongImpl.java"> + <source> + package avalon.tutorial; + + import org.apache.avalon.framework.parameters.Parameters; + import org.apache.avalon.framework.parameters.ParameterException; + import org.apache.avalon.logger.AbstractLoggable; + + import avalon.tutorial.BirdSong; + import avalon.tutorial.BirdSongRunner; + + public class BirdSongImpl extends AbstractLoggable implements BirdSong + { + private int m_numberOfChilps; + private String m_chilpMessage; + private String m_chilpSeparator; + + private Thread m_runnerThread; + + + public void BirdSongImpl() + { + } + + public void parameterize( Parameters parameters ) throws ParameterException + { + getLogger().debug( "got parameters" ); + + m_numberOfChilps = m_parameters.getParameterAsInteger( PARAM_NUMBER_OF_CHILPS ); + m_chilpMessage = m_parameters.getParameter( PARAM_CHILP_MESSAGE ); + m_chilpSeparator = m_parameters.getParameter( PARAM_CHILP_SEPARATOR ); + } + public void start() + { + getLogger().debug( "starting" ); + + Runnable runnable = new BirdSongImplRunner( this ); + + m_runnerThread = new Thread( runnable ); + m_runnerThread.setDaemon( true ); + m_runnerThread.run(); + } + public void stop() + { + getLogger().debug( "stopping" ); + + m_runnerThread.notify(); + } + + int getNumberOfChilps() + { + return m_numberOfChilps; + } + String getChilpMessage() + { + return m_chilpMessage; + } + String getChilpSeperator() + { + return m_chilpSeparator; + } + } + </source> + </s3> + + <s3> + <source> + package avalon.tutorial; + + import avalon.tutorial.BirdSongImpl; + + public class BirdSongRunner implements Runnable + { + BirdSongImpl m_bs; + + public void BirdSongRunner( BirdSongImpl bs ) + { + m_bs = bs; + } + + public void run() + { + int max = bs.getNumberOfChilps(); + String msg = bs.getChilpMessage(); + String separator = bs.getSeparator(); + + for( int i = 0; i != max; i++ ) + { + if( i != 0 && i != (max-1) ) + System.out.print( separator ); + + System.out.print(msg ); + } + } + } + </source> + </s3> + + <p>There's quite a few things different about this component compared to the BirdSong1 class. + The constructor doesn't take any arguments; those are passed in at a later point instead through + the use of parameterize(). sing() has been renamed to start(), and a stop() method has been + added. Also, logging statements have been added throughout the code. Finally, the + actual printing of the messages is handled in a separate thread.</p> + + <p>All the added complexity is of course not really justified for this simple demo component; it + just serves to illustrate typical evolution from an 'average' java class into a typical avalon + component.</p> </s1> </body> <footer> 1.2 +26 -20 jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/Egg.java Index: Egg.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/Egg.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Egg.java 8 Jul 2002 13:16:02 -0000 1.1 +++ Egg.java 8 Jul 2002 17:42:16 -0000 1.2 @@ -43,9 +43,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation. For more information on the + on behalf of the Apache Software Foundation. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. - + */ package org.apache.avalon.excalibur.tweety; @@ -62,18 +62,24 @@ import org.apache.avalon.framework.parameters.*; import org.apache.avalon.framework.service.*; import org.apache.avalon.framework.container.*; - + /** - * This is a stripped down - collapsed version of Tweety+Main. + * This is a stripped down and collapsed version of + * {@link org.apache.avalon.excalibur.tweety.Tweety Tweety} combined with + * {@link org.apache.avalon.excalibur.tweety.Main Main}. * It reads the configuration file, and creates the components. * Then it disposes them. * - * Useful to understand what Lifecycle is, without getting yet into - * what a Container is; this is application+Container all in one. + * <p>Useful to understand what Lifecycle is, without getting yet into + * what a Container is; this is application+Container all in one.</p> + * + * <p>After you understand this, look at Main and Tweety.</p> * - * After you understand this, look at Main and Tweety. + * <p><b>note:</b> Egg does not support the contextualize(), configure() or + * parameterize() lifecycle stages. * *@author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> + *@author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a> *@created June 20, 2002 *@version 1.0 */ @@ -84,27 +90,27 @@ Logger sharedLogger = new ConsoleLogger(); Context sharedContext = new DefaultContext(); DefaultComponentManager sharedComponentManager = new DefaultComponentManager(); - DefaultServiceManager sharedServiceManager = new DefaultServiceManager(); - + DefaultServiceManager sharedServiceManager = new DefaultServiceManager(); + try { - - //load properties + + //load properties Properties properties = new Properties(); properties.load(new FileInputStream("tweety.properties")); - + //this will keep references to components so we know what to shutdown at the end Object[] components = new Object[properties.size()]; - + //All the roles Enumeration roles = properties.propertyNames(); - //create and setup all the component + //create and setup all the component for (int i=0; roles.hasMoreElements(); i++) { //Get the role of the component being setup String role = (String )roles.nextElement(); - - //create the component instance + + //create the component instance Object component = Class.forName((String) properties.get(role)); //setup the component by running the appropriate lifecycle methods in order @@ -122,15 +128,15 @@ sharedServiceManager.put(role, component); if(component instanceof org.apache.avalon.framework.component.Component){ sharedComponentManager.put(role, (Component) component); - } - + } + components[i]=component; } - + // // Here components that create threads continue operation till they wish // - + //shutdown all the components that were set up for (int i=0 ; i<components.length; i++ ) { 1.3 +12 -10 jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/Main.java Index: Main.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/Main.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Main.java 8 Jul 2002 13:16:26 -0000 1.2 +++ Main.java 8 Jul 2002 17:42:16 -0000 1.3 @@ -65,26 +65,29 @@ import org.apache.avalon.framework.container.*; /** - * This is the tweety 'bootstrapper'. It is used to run Tweety from the - * commandline. The single main() method calls all of Tweety's lifecycle - * methods. + * This is the tweety 'bootstrapper'. It is used to run + * {@link org.apache.avalon.excalibur.tweety.Tweety Tweety} from the + * commandline. The single {@link #main(String[] args) main()} method calls all of + * Tweety's lifecycle methods. * * - *@author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> - *@author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a> - *@created July 4, 2002 - *@version 1.0 + * @author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a> + * @created July 4, 2002 + * @version 1.0.1 + * @since 1.0-alpha + * @see <a href="http://jakarta.apache.org/avalon/excalibur/tweety">Online Tweety documentation</a> */ public class Main { - /** + /** * We've marked the constructor as protected to prevent instantiation. * Main is not a real 'object' or 'component', but rather a container * for some procedural code (inside the main() method). There is no * need to create an instance of it. */ protected Main() { - } + } //// COMMANDLINE ENTRY POINT //// /** @@ -167,5 +170,4 @@ System.exit(-2); } } - } 1.2 +11 -22 jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/package.html Index: package.html =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/package.html,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- package.html 23 Jun 2002 22:09:12 -0000 1.1 +++ package.html 8 Jul 2002 17:42:16 -0000 1.2 @@ -1,26 +1,15 @@ <html><body> -<p> -Very simple container for avalon components, written for educational purposes. -Tweety is not intended for use in production environments, though there is -nothing preventing you from using it for that purpose. -</p> +<p>Tweety is a minimalist container explicitly designed for educational purposes, and +educational purposes only.</p> -<h3>Goals</h3> -<li>be well documented</li> -<li>provide full support for the avalon framework interfaces</li> -<li>provide support for nothing else</li> -<li>use default framework implementations where possible</li> -<li>sacrifice flexibility for readable code wherever possible</li> -<li>sacrifice reusability for readable code wherever possible</li> -<li>use the most simple configuration possible</li> -<li>support only minimal metainfo (for example, no dependency mapping)</li> -<li>no security</li> -<li>minimal thread management</li> -<li>no classloader management</li> -<li>separation of engine and (mainable) embeddor</li> -<h3>Use Case</h3> -<p>An example of an avalon container for simple components, to use in -teaching avalon concepts.</p> +<p>In other words, if you want to learn the concepts behind avalon, and see some examples +of how to apply them, tweety is your starting point. If you need to actually write really +cool components for a production environment, look elsewhere.</p> -</body></html> \ No newline at end of file +@author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> +@author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a> +@created June 20, 2002 +@since 1.0-alpha +@see <a href="http://jakarta.apache.org/avalon/excalibur/tweety">Online Tweety documentation</a> +</body></html> 1.7 +37 -36 jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/Tweety.java Index: Tweety.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/Tweety.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- Tweety.java 8 Jul 2002 13:16:26 -0000 1.6 +++ Tweety.java 8 Jul 2002 17:42:16 -0000 1.7 @@ -21,7 +21,7 @@ developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. - + 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact @@ -68,18 +68,19 @@ * to run and manage other Avalon Components. Because it is an Avalon * Component itself as well, it can easily be used in any Avalon Application. * - * <p>The only reason tweety implements <code>Configurable</code> and - * <code>Contextualizable</code> is that it doesn't feel much like managing + * <p>The only reason tweety implements {@link org.apache.avalon.framework.configuration.Configurable Configurable} + * and {@link org.apache.avalon.framework.context.Contextualizable Contextualizable} + * is that it doesn't feel much like managing * contexts or configurations for the components it manages. Instead, it * simply forwards the configuration and context provided to its components.</p> * - * <p><b>Note: </b> Tweety has a <code>main()</code> method to allow it to be - * run from the commandline. - * - *@author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> - *@author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a> - *@created June 20, 2002 - *@version 1.2 + * @author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a> + * @created June 20, 2002 + * @version 1.2.1 + * @since 1.0-alpha + * @see <a href="http://jakarta.apache.org/avalon/excalibur/tweety">Online Tweety documentation</a> + * @see <a href="http://jakarta.apache.org/avalon/framework">Online Avalon Framework documentation</a> */ public class Tweety implements LogEnabled, Contextualizable, Configurable, Initializable, Parameterizable, Startable @@ -112,9 +113,9 @@ protected DefaultServiceManager m_serviceManager; /** - * this field is filled during <code>parameterize()</code> with a parameters + * this field is filled during {@link #parameterize(Parameters parameters) parameterize()} with a parameters * object that describes everything <code>Tweety</code> needs to run. - * Usually, it contains information loaded from a tweety.properties file. A + * Usually, it contains information loaded from a <code>tweety.properties</code> file. A * sample <code>tweety.properties</code> file might look like this: <pre> ######################################################################## @@ -135,7 +136,7 @@ /** * This map will be used to store a reference to all the components - * that tweety will manage; We fill it up during initialize(). + * that tweety will manage; We fill it up during {@link #initialize() initialize()}. */ protected Map m_components; @@ -143,7 +144,7 @@ /** * Tweety has a single, public, no arguments constructor; We supply arguments * at a later point in the form of an instance of <code>Parameters</code> - * during parameterize(). + * during {@link #parameterize(Parameters parameters) parameterize()}. * * <p>The constructor initializes our properties with default values.</p> */ @@ -164,37 +165,37 @@ logger.debug( "Tweety: Tweety got a logger" ); } - /** - * Provide tweety with a context; This context will also be used for all the + /** + * Provide tweety with a context; This context will also be used for all the * components that tweety manages. - * - * @param context the context - */ - public void contextualize( Context context ) + * + * @param context the context + */ + public void contextualize( Context context ) { m_context = context; m_logger.debug( "Tweety: Tweety got a context" ); } - /** - * Provide tweety with a configuration; This configuration will also be used for all the + /** + * Provide tweety with a configuration; This configuration will also be used for all the * components that tweety manages. - * - * @param configuration the class configurations. - */ - public void configure( Configuration configuration ) - { + * + * @param configuration the class configurations. + */ + public void configure( Configuration configuration ) + { m_configuration = configuration; m_logger.debug( "Tweety: Tweety got a configuration" ); - } + } - /** - * Provide tweety with the parameters it needs to run; Each pair of name and - * value defines a <b>Role</b> and a component that implements that role. - * - * @param parameters the parameters - * @throws ParameterException if parameters are invalid - */ + /** + * Provide tweety with the parameters it needs to run; Each pair of name and + * value defines a <code>Role</code> and a component that implements that role. + * + * @param parameters the parameters + * @throws ParameterException if parameters are invalid + */ public void parameterize( Parameters parameters ) throws ParameterException { // check whether the supplied parameters object is valid @@ -293,7 +294,7 @@ } /** - * Start up tweety; We setup all the components tweety contains, add them to + * Start up tweety; We set up all the components tweety contains, add them to * the global componentmanager and servicemanager, and finally we call start() * on each of them. */ 1.2 +7 -1 jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/demos/package.html Index: package.html =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/tweety/src/java/org/apache/avalon/excalibur/tweety/demos/package.html,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- package.html 23 Jun 2002 22:09:12 -0000 1.1 +++ package.html 8 Jul 2002 17:42:16 -0000 1.2 @@ -1,4 +1,10 @@ <html><body> Trivial avalon components to demonstrate the use of tweety and illustrate its features (or lack thereof). -</body></html> \ No newline at end of file + +@author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> +@author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a> +@created June 20, 2002 +@since 1.0-alpha +@see <a href="http://jakarta.apache.org/avalon/excalibur/tweety">Online Tweety documentation</a> +</body></html>
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>