You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by do...@apache.org on 2002/11/10 00:23:57 UTC
cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
donaldp 2002/11/09 15:23:57
Added: container/src/java/org/apache/excalibur/container/lifecycle
AbstractLifecycleExtensionManager.java
LifecycleExtensionManager.java
Log:
Migrate across the rest of the lifecycle extension stuff
Revision Changes Path
1.1 jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle/AbstractLifecycleExtensionManager.java
Index: AbstractLifecycleExtensionManager.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) @year@ The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
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
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
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
Apache Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.excalibur.container.lifecycle;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.container.lifecycle.Accessor;
import org.apache.excalibur.container.lifecycle.Creator;
/**
* <code>AbstractLifecycleExtensionManager</code> class.
*
* @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/11/09 23:23:56 $
*/
public abstract class AbstractLifecycleExtensionManager
extends AbstractLogEnabled
{
// Lifecycle method constants, these are passed to executeExtensions()
protected static final int ACCESS = 0;
protected static final int RELEASE = 1;
protected static final int CREATE = 2;
protected static final int DESTROY = 3;
/**
* <code>executeExtensions</code> method, executes a given array of
* lifecycle interfaces on a given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @param type a constant, referencing which phase the
* extensions array adheres to
*
* @exception Exception if an error occurs
*/
protected void executeExtensions( final Object[] extensions,
final Object component,
final Context context,
final int type )
throws Exception
{
switch( type )
{
case ACCESS:
for( int i = 0; i < extensions.length; ++i )
{
( (Accessor)extensions[ i ] ).access( component, context );
}
break;
case RELEASE:
for( int i = 0; i < extensions.length; ++i )
{
( (Accessor)extensions[ i ] ).release( component, context );
}
break;
case CREATE:
for( int i = 0; i < extensions.length; ++i )
{
( (Creator)extensions[ i ] ).create( component, context );
}
break;
case DESTROY:
for( int i = 0; i < extensions.length; ++i )
{
( (Creator)extensions[ i ] ).destroy( component, context );
}
break;
default:
if( getLogger().isErrorEnabled() )
{
final String message =
"Incorrect extension phase specified: " + type;
getLogger().error( message );
}
}
}
}
1.1 jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle/LifecycleExtensionManager.java
Index: LifecycleExtensionManager.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) @year@ The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
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
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
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
Apache Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.excalibur.container.lifecycle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.avalon.framework.context.Context;
import org.apache.excalibur.container.lifecycle.Accessor;
import org.apache.excalibur.container.lifecycle.Creator;
/**
* <code>LifecycleExtensionManager</code> class. This class manages a list
* of extensions objects that are executed on components during the various
* stages of their lifecycles.
*
* <p>
* It provides methods for adding extension objects to the system,
* and a method for executing them on a particular component object. The
* current context is also passed in to the extension objects to facilitate
* the communication of any global values.
* </p>
*
* <p>
* Extensions are stored internally in a list. This guarentees that the
* order in which they are executed matches the order in which they are
* inserted.
* </p>
*
* @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/11/09 23:23:56 $
*/
public class LifecycleExtensionManager
extends AbstractLifecycleExtensionManager
{
// extensions objects
private final CachedArrayList m_accessorExtensions = new CachedArrayList();
private final CachedArrayList m_creatorExtensions = new CachedArrayList();
/**
* <code>executeAccessExtensions</code> method, executes all access
* level extensions on the given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void executeAccessExtensions( Object component, Context context )
throws Exception
{
executeExtensions( m_accessorExtensions.toArray(), component, context, ACCESS );
}
/**
* <code>executeReleaseExtensions</code> method, executes all release
* level extensions on the given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void executeReleaseExtensions( Object component, Context context )
throws Exception
{
executeExtensions( m_accessorExtensions.toArray(), component, context, RELEASE );
}
/**
* <code>executeCreationExtensions</code> method, executes all creation
* level extensions on the given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void executeCreationExtensions( Object component, Context context )
throws Exception
{
executeExtensions( m_creatorExtensions.toArray(), component, context, CREATE );
}
/**
* <code>executeDestructionExtensions</code> method, executes all
* destruction level extensions on the given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void executeDestructionExtensions( Object component, Context context )
throws Exception
{
executeExtensions( m_creatorExtensions.toArray(), component, context, DESTROY );
}
// The following methods define operations that modify the internal list
// of extensions. I've refrained from returning the List directly, via a
// getExtensions() method for the following reasons:
//
// 1. Returning List breaks encapsulation, implicitly exposing all of List's
// current and future operations to the client
// 2. List operates with type Object, not LifecycleExtension which means we need
// more error handling code if we make it possible for the user to add instances
// of any type to the extension lists.
// 3. Wrapping add/remove methods allow us to add optimizations to improve performance
// (eg. to convert the List to an array upon each add/remove, and not upon each
// execute operation)
// 4. The book 'Refactoring' says we shouldn't do it :-)
//
// I'm open to suggestions though if there's any better ideas ?
/**
* Adds an accessor extension to the manager
*
* @param extension a <code>Accessor</code> instance
*/
public void addAccessorExtension( Accessor extension )
{
m_accessorExtensions.add( extension );
}
/**
* Adds a creator extension to the manager
*
* @param extension a <code>Creator</code> instance
*/
public void addCreatorExtension( Creator extension )
{
m_creatorExtensions.add( extension );
}
/**
* Inserts an accessor extension at a given index in the manager
*
* @param position an <code>int</code> index value
* @param extension a <code>Accessor</code> instance
*/
public void insertAccessorExtension( int position, Accessor extension )
{
m_accessorExtensions.insert( position, extension );
}
/**
* Inserts a creator extension at a given index in the manager
*
* @param position an <code>int</code> index value
* @param extension a <code>Creator</code> instance
*/
public void insertCreatorExtension( int position, Creator extension )
{
m_accessorExtensions.insert( position, extension );
}
/**
* Removes a particular accessor extension from the manager
*
* @param position an <code>int</code> index value
* @return a <code>Accessor</code> instance
*/
public Accessor removeAccessorExtension( int position )
{
return (Accessor)m_accessorExtensions.remove( position );
}
/**
* Removes a particular creator extension from the manager
*
* @param position an <code>int</code> index value
* @return a <code>Creator</code> instance
*/
public Creator removeCreatorExtension( int position )
{
return (Creator)m_creatorExtensions.remove( position );
}
/**
* Obtain an iterator.
*
* @return an <code>Iterator</code> instance
*/
public Iterator accessorExtensionsIterator()
{
return m_accessorExtensions.iterator();
}
/**
* Obtain an iterator.
*
* @return an <code>Iterator</code> instance
*/
public Iterator creatorExtensionsIterator()
{
return m_creatorExtensions.iterator();
}
/**
* Find out the total number of accessor extensions registered with this manager
*
* @return an <code>int</code> value
*/
public int accessorExtensionsCount()
{
return m_accessorExtensions.size();
}
/**
* Find out the total number of creator extensions registered with this manager
*
* @return an <code>int</code> value
*/
public int creatorExtensionsCount()
{
return m_creatorExtensions.size();
}
/**
* Obtain the particular accessor extension at the given index
*
* @param index an <code>int</code> index value
* @return a <code>Accessor</code> instance
*/
public Accessor getAccessorExtension( int index )
{
return (Accessor)m_accessorExtensions.get( index );
}
/**
* Obtain the particular creator extension at the given index
*
* @param index an <code>int</code> index value
* @return a <code>Creator</code> instance
*/
public Creator getCreatorExtension( int index )
{
return (Creator)m_creatorExtensions.get( index );
}
/**
* Clears all accessor extensions registered with this manager
*/
public void clearAccessorExtensions()
{
m_accessorExtensions.clear();
}
/**
* Clears all creator extensions registered with this manager
*/
public void clearCreatorExtensions()
{
m_creatorExtensions.clear();
}
/**
* <code>CachedArrayList</code> class.
*
* <p>
* This class wraps a synchronized ArrayList to provide an optimized
* <code>toArray()</code> method that returns an internally cached array,
* rather than a new array generated per <code>toArray()</code>
* invocation.
* </p>
*
* <p>
* Use of the class by the Manager results in <code>toArray()</code>
* being invoked far more often than any other method. Caching the value
* <code>toArray</code> normally returns is intended to be a performance
* optimization.
* </p>
*
* <p>
* The cached array value is updated upon each write operation to the
* List.
* </p>
*
* <p>
* REVISIT(MC): investigate using FastArrayList from collections ?
* </p>
*/
private final class CachedArrayList
{
// Empty array constant
private final Object[] EMPTY_ARRAY = new Object[ 0 ];
// Actual list for storing elements
private final List m_proxy = Collections.synchronizedList( new ArrayList() );
// Proxy cache, saves unnecessary conversions from List to Array
private Object[] m_cache = EMPTY_ARRAY;
/**
* Add an object to the list
*
* @param object an <code>Object</code> value
*/
public void add( final Object object )
{
m_proxy.add( object );
m_cache = m_proxy.toArray();
}
/**
* Insert an object into a particular position in the list
*
* @param position an <code>int</code> value
* @param object an <code>Object</code> value
*/
public void insert( final int position, final Object object )
{
m_proxy.add( position, object );
m_cache = m_proxy.toArray();
}
/**
* Remove an object from the list
*
* @param position an <code>int</code> value
* @return a <code>Object</code> value
*/
public Object remove( final int position )
{
final Object object = m_proxy.remove( position );
m_cache = m_proxy.toArray();
return object;
}
/**
* Obtain an iterator
*
* @return an <code>Iterator</code> value
*/
public Iterator iterator()
{
return m_proxy.iterator();
}
/**
* Obtain the size of the list
*
* @return an <code>int</code> value
*/
public int size()
{
return m_proxy.size();
}
/**
* Access an object that is in the list
*
* @param index an <code>int</code> value
* @return a <code>Object</code> value
*/
public Object get( final int index )
{
return m_proxy.get( index );
}
/**
* Find out the index of an object in the list
*
* @param object an <code>Object</code> value
* @return an <code>int</code> value
*/
public int indexOf( final Object object )
{
return m_proxy.indexOf( object );
}
/**
* Clear the list
*/
public void clear()
{
m_proxy.clear();
m_cache = EMPTY_ARRAY;
}
/**
* Obtain the list as an array. Subsequents calls to this method
* will return the same array object, until a write operation is
* performed on the list.
*
* @return an <code>Object[]</code> value
*/
public Object[] toArray()
{
return m_cache;
}
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle
AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Nicola Ken Barozzi <ni...@apache.org>.
Peter Donald wrote:
> On Sun, 10 Nov 2002 21:34, Paul Hammant wrote:
>
>>Should not we split avalon-framework.jar into avalon-framework.api.jar
>>and avalon-framework-refimpl.jar ?
+1
> I don't think there is any need to separate implementations that have no
> external dependencies as often most of my "client" objects are also "server"
> objects and use DefaultComponentManager etc.
>
> However currently I am using a separation based on whether or not the classes
> have external dependencies. For example the following classes all got moved
> to the "-ext" jar.
>
> So essentially anything that directly refences Logkit/Log4j/Xalan will get
> migrated to this jar. I figured that the SAX stuff is broadly deployed enough
> that we need not bother separating it out.
>
> The reason for this separation is that it enables clean classloader trees. I
> have a Phoenix fork that does this to good effect and have a tree in avalon
> that already has the changes. I want to let it settle for a while and
> experiment with things before committing it though.
+1
--
Nicola Ken Barozzi nicolaken@apache.org
- verba volant, scripta manent -
(discussions get forgotten, just code remains)
---------------------------------------------------------------------
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Peter Donald <pe...@apache.org>.
On Sun, 10 Nov 2002 21:34, Paul Hammant wrote:
> Should not we split avalon-framework.jar into avalon-framework.api.jar
> and avalon-framework-refimpl.jar ?
I don't think there is any need to separate implementations that have no
external dependencies as often most of my "client" objects are also "server"
objects and use DefaultComponentManager etc.
However currently I am using a separation based on whether or not the classes
have external dependencies. For example the following classes all got moved
to the "-ext" jar.
So essentially anything that directly refences Logkit/Log4j/Xalan will get
migrated to this jar. I figured that the SAX stuff is broadly deployed enough
that we need not bother separating it out.
The reason for this separation is that it enables clean classloader trees. I
have a Phoenix fork that does this to good effect and have a tree in avalon
that already has the changes. I want to let it settle for a while and
experiment with things before committing it though.
--
Cheers,
Peter Donald
*------------------------------------------------------*
| An expert is someone who knows everything about the |
| topic except for its place in the world. |
*------------------------------------------------------*
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/l
ifecycle AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Stephen McConnell <mc...@apache.org>.
Leo Simons wrote:
>Steve, Pete, Paul,
>
>if you ask me, Paul is right with regard to the seperation of spec and
>default impl -- putting it at the jar level is nice, and consistent with
>A-F.
>
>Also, I don't think the excalibur container package should neccessarily
>be limited to only default impls of the client side; it's very name
>implies it is also about the other side, doesn't it?
>
>
Yes - that's correct. It is intended to be a set of classes that are
reusable across containers.
>Next, I think putting the classes in the container package sort-of
>'forces' more convergence between merlin and fortress as the container
>package is sort-of common ground. Which I like ;) And when that
>convergence happens, there is nothing to prevent modification of the
>classes in container to match the changed implementation. right?
>
I disagree that putting those two particular classes there forces any
convergence. The particular implementation isn't something that makes
sence relative to Merlin - it only makes sence relative to Fortress.
The Fortress approach basically istantiates all extension handlers for a
component and then these are passed to the extension manager
collectively and applied to the component. In Merlin the application of
the handler is the point where a handler is assembled (if and only if
the extension meta data indicates that the handler is required).
Getting a common solution on this requires more work on the meta side -
in fact that's what I'm working on today - getting the excalibur/meta
updates in place so Marcus can use this in the xfc package.
Cheers, Steve.
>Finally, I think regardless of all that I like the setup that will be
>quickest to get fortress to release quality best, if that matters in any
>direction. I'm very happy to see Pete work on fortress :)
>
>cheers,
>
>- Leo
>
>
>
>--
>To unsubscribe, e-mail: <ma...@jakarta.apache.org>
>For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>
>
>
>
--
Stephen J. McConnell
OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/l
ifecycle AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Paul Hammant <Pa...@yahoo.com>.
Leo,
>Also, I don't think the excalibur container package should neccessarily
>be limited to only default impls of the client side; it's very name
>implies it is also about the other side, doesn't it?
>
<pedant>
A-F stuff is not just about client/server. Its interfaces and impls
(hidden by proxy or not, remote or local) can be used anywhere :-)
</pedant>
- Paul
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit:
jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/l
ifecycle AbstractLifecycleExtensionManager.java
LifecycleExtensionManager.java
Posted by Leo Simons <le...@apache.org>.
Steve, Pete, Paul,
if you ask me, Paul is right with regard to the seperation of spec and
default impl -- putting it at the jar level is nice, and consistent with
A-F.
Also, I don't think the excalibur container package should neccessarily
be limited to only default impls of the client side; it's very name
implies it is also about the other side, doesn't it?
Next, I think putting the classes in the container package sort-of
'forces' more convergence between merlin and fortress as the container
package is sort-of common ground. Which I like ;) And when that
convergence happens, there is nothing to prevent modification of the
classes in container to match the changed implementation. right?
Finally, I think regardless of all that I like the setup that will be
quickest to get fortress to release quality best, if that matters in any
direction. I'm very happy to see Pete work on fortress :)
cheers,
- Leo
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle
AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Paul Hammant <Pa...@yahoo.com>.
> Maybe the best thing would be for Tweety to be part of the A-F
> refimpl jar.
Or maybe just the distro... the point being that Tweety is tightly
coupled to the ref impls of the lifecycle interfaces.
- Paul
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle
AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Paul Hammant <Pa...@yahoo.com>.
Stephen,
> <chuckle/>
>
> I was thinking about you when I wrote my reply to Pete.
Yup, I'm compulsed to mediate...
> Yes - I think the framework is valid case for this - it is sufficient
> small that we can be explicit about which files are client side and
> which represent implementation and include this in the build file
> during jar generation (i.e. we don't need to change any implemetation
> package names). I also think this would be a good move in that it
> gives us a little more flexibility to evolve the implementation content.
>
> Other suggestions for jar filenames ...
>
> <product>-api.jar -- the interfaces
> <product>-impl.jar -- the implemetation
> <product>.jar -- the combination
Agree if thats as far as you and others travel. The -impl suffix may be
a practical summary of "Reference Implementation". That is as long as
the Reference Implementation term is stamped prominently against
thedescription of the download. My angle on this is that newbies get
very confused as is. I am for increases is precision. when it comes to
naming.
> On defaults - I don't think there should defaults unless there is a
> clear case for the default. In the example of the container/lifecycle
> case we have the appropriate defaults already in place to support
> convinient development for the client. However, defaults related to
> implemetations at the container levels is a lot trickier. With
> continued work on the Foress meta handling, its much easier to see a
> default implemetation emerging as a result of convergence between
> Fortress and Merlin. So what I'm saying is that some cases make sence
> and other's don't.
Meta: All our containers use different component lacing schemes and
there is nothing wrong with that.
The term 'default' I object to unless it is used in context
"Avalon-Framework Reference Implementation Default Configuration" (an
example). If just expressed as "Default Configuration" then it will add
to confusion. It gives it a level of authority it does not have if used
with imprecise naming. When used with Ref-Impl, people will know it is
not going to be used everywhere. It is almost an example of use. Maybe
the best thing would be for Tweety to be part of the A-F refimpl jar.
Regards,
- Paul
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle
AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Stephen McConnell <mc...@apache.org>.
Paul Hammant wrote:
> Peter, Stephen,
>
>>> I think that the AbstractLifecycleExtensionManager and
>>> LifecycleExtensionManager classes should stay with Fortress. They are
>>> both part of the Fortress implementation of lifecycle extensions. If
>>> you take a look at the Merlin implemetation approach is is quite
>>> different. Classes within the container/lifecycle package are intended
>>> to be only those interfaces and abstract implemetations that are
>>> required for extension interoperability.
>>>
>>
>>
>> They are a reasonable default implementation. Much like
>> DefaultComponentManager is a reasonable default implementation of
>> ComponentManager.
>>
>>
> Should not we split avalon-framework.jar into avalon-framework.api.jar
> and avalon-framework-refimpl.jar ?
>
> If there is a case for having simple defaults for all (Peter), and
> that those defaults may be ignored by one or all of our excellent
> containers (Stephen) and that no client side A-F coder should cast to
> a default, then jar separation could be a good thing that pleases
> all. Actually we should make three jars if we include the current one.
<chuckle/>
I was thinking about you when I wrote my reply to Pete.
Yes - I think the framework is valid case for this - it is sufficient
small that we can be explicit about which files are client side and
which represent implementation and include this in the build file during
jar generation (i.e. we don't need to change any implemetation package
names). I also think this would be a good move in that it gives us a
little more flexibility to evolve the implementation content.
Other suggestions for jar filenames ...
<product>-api.jar -- the interfaces
<product>-impl.jar -- the implemetation
<product>.jar -- the combination
On defaults - I don't think there should defaults unless there is a
clear case for the default. In the example of the container/lifecycle
case we have the appropriate defaults already in place to support
convinient development for the client. However, defaults related to
implemetations at the container levels is a lot trickier. With
continued work on the Foress meta handling, its much easier to see a
default implemetation emerging as a result of convergence between
Fortress and Merlin. So what I'm saying is that some cases make sence
and other's don't.
Cheers, Steve.
>
>
> Regards,
>
> - Paul
>
>
>
> --
> To unsubscribe, e-mail:
> <ma...@jakarta.apache.org>
> For additional commands, e-mail:
> <ma...@jakarta.apache.org>
>
>
>
--
Stephen J. McConnell
OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Peter Royal <pr...@apache.org>.
On Sunday, November 10, 2002, at 05:34 AM, Paul Hammant wrote:
> Should not we split avalon-framework.jar into avalon-framework.api.jar
> and avalon-framework-refimpl.jar ?
>
> If there is a case for having simple defaults for all (Peter), and
> that those defaults may be ignored by one or all of our excellent
> containers (Stephen) and that no client side A-F coder should cast to
> a default, then jar separation could be a good thing that pleases all.
> Actually we should make three jars if we include the current one.
+1
-pete
--
peter royal -> proyal@apache.org
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle
AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Paul Hammant <Pa...@yahoo.com>.
Peter, Stephen,
>>I think that the AbstractLifecycleExtensionManager and
>>LifecycleExtensionManager classes should stay with Fortress. They are
>>both part of the Fortress implementation of lifecycle extensions. If
>>you take a look at the Merlin implemetation approach is is quite
>>different. Classes within the container/lifecycle package are intended
>>to be only those interfaces and abstract implemetations that are
>>required for extension interoperability.
>>
>>
>
>They are a reasonable default implementation. Much like
>DefaultComponentManager is a reasonable default implementation of
>ComponentManager.
>
>
Should not we split avalon-framework.jar into avalon-framework.api.jar
and avalon-framework-refimpl.jar ?
If there is a case for having simple defaults for all (Peter), and that
those defaults may be ignored by one or all of our excellent containers
(Stephen) and that no client side A-F coder should cast to a default,
then jar separation could be a good thing that pleases all. Actually we
should make three jars if we include the current one.
Regards,
- Paul
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle
AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Stephen McConnell <mc...@apache.org>.
Peter Donald wrote:
>On Sun, 10 Nov 2002 15:44, Stephen McConnell wrote:
>
>
>>I think that the AbstractLifecycleExtensionManager and
>>LifecycleExtensionManager classes should stay with Fortress. They are
>>both part of the Fortress implementation of lifecycle extensions. If
>>you take a look at the Merlin implemetation approach is is quite
>>different. Classes within the container/lifecycle package are intended
>>to be only those interfaces and abstract implemetations that are
>>required for extension interoperability.
>>
>>
>
>They are a reasonable default implementation. Much like
>DefaultComponentManager is a reasonable default implementation of
>ComponentManager.
>
The container/lifecycle package only includes the client classes.
Container implementations that support those classes only need the
Accessor and Creator interfaces (the interoperability points). The
abstract classes already in the container/lifecycle package are client
side - abstract implementations of the creator and assessor extensions.
This is equivalent to the DefaultComponentManager scenario.
If the AbstractLifecycleExtensionManager and LifecycleExtensionManager
classes were truly default implementations, then it would be reasonable
to assume that they would be used in more than one container. Until
then, I think we should keep the classes with Fortress. If we get to a
point where the implementation of extension management is sufficiently
common then it would make sense to bring such content in - until then I
don't think we can call these classes default. In the longer term I
think you are more likely to see a meta based default extension handler
with support for full components as extension providers. In other words
- its simply premature to be push the AbstractLifecycleExtensionManager
and LifecycleExtensionManager classes into the container/lifecycle package.
Cheers, Steve.
>
--
Stephen J. McConnell
OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Peter Donald <pe...@apache.org>.
On Sun, 10 Nov 2002 15:44, Stephen McConnell wrote:
> I think that the AbstractLifecycleExtensionManager and
> LifecycleExtensionManager classes should stay with Fortress. They are
> both part of the Fortress implementation of lifecycle extensions. If
> you take a look at the Merlin implemetation approach is is quite
> different. Classes within the container/lifecycle package are intended
> to be only those interfaces and abstract implemetations that are
> required for extension interoperability.
They are a reasonable default implementation. Much like
DefaultComponentManager is a reasonable default implementation of
ComponentManager.
--
Cheers,
Peter Donald
A right is not what someone gives you; it's what no one can take from you.
-- Ramsey Clark
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle
AbstractLifecycleExtensionManager.java LifecycleExtensionManager.java
Posted by Stephen McConnell <mc...@apache.org>.
Pete:
I think that the AbstractLifecycleExtensionManager and
LifecycleExtensionManager classes should stay with Fortress. They are
both part of the Fortress implementation of lifecycle extensions. If
you take a look at the Merlin implemetation approach is is quite
different. Classes within the container/lifecycle package are intended
to be only those interfaces and abstract implemetations that are
required for extension interoperability.
Cheers, Steve.
donaldp@apache.org wrote:
>donaldp 2002/11/09 15:23:57
>
> Added: container/src/java/org/apache/excalibur/container/lifecycle
> AbstractLifecycleExtensionManager.java
> LifecycleExtensionManager.java
> Log:
> Migrate across the rest of the lifecycle extension stuff
>
> Revision Changes Path
> 1.1 jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle/AbstractLifecycleExtensionManager.java
>
> Index: AbstractLifecycleExtensionManager.java
> ===================================================================
> /*
>
> ============================================================================
> The Apache Software License, Version 1.1
> ============================================================================
>
> Copyright (C) @year@ The Apache Software Foundation. All rights reserved.
>
> Redistribution and use in source and binary forms, with or without modifica-
> tion, are permitted provided that the following conditions are met:
>
> 1. Redistributions of source code must retain the above copyright notice,
> this list of conditions and the following disclaimer.
>
> 2. Redistributions in binary form must reproduce the above copyright notice,
> this list of conditions and the following disclaimer in the documentation
> and/or other materials provided with the distribution.
>
> 3. The end-user documentation included with the redistribution, if any, must
> include the following acknowledgment: "This product includes software
> 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
> apache@apache.org.
>
> 5. Products derived from this software may not be called "Apache", nor may
> "Apache" appear in their name, without prior written permission of the
> Apache Software Foundation.
>
> THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
> INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
> DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
> OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
> ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> 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
> Apache Software Foundation, please see <http://www.apache.org/>.
>
> */
> package org.apache.excalibur.container.lifecycle;
>
> import org.apache.avalon.framework.context.Context;
> import org.apache.avalon.framework.logger.AbstractLogEnabled;
> import org.apache.excalibur.container.lifecycle.Accessor;
> import org.apache.excalibur.container.lifecycle.Creator;
>
> /**
> * <code>AbstractLifecycleExtensionManager</code> class.
> *
> * @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
> * @version CVS $Revision: 1.1 $ $Date: 2002/11/09 23:23:56 $
> */
> public abstract class AbstractLifecycleExtensionManager
> extends AbstractLogEnabled
> {
> // Lifecycle method constants, these are passed to executeExtensions()
> protected static final int ACCESS = 0;
> protected static final int RELEASE = 1;
> protected static final int CREATE = 2;
> protected static final int DESTROY = 3;
>
> /**
> * <code>executeExtensions</code> method, executes a given array of
> * lifecycle interfaces on a given component.
> *
> * @param component a <code>Component</code> instance
> * @param context a <code>Context</code> instance
> * @param type a constant, referencing which phase the
> * extensions array adheres to
> *
> * @exception Exception if an error occurs
> */
> protected void executeExtensions( final Object[] extensions,
> final Object component,
> final Context context,
> final int type )
> throws Exception
> {
> switch( type )
> {
> case ACCESS:
> for( int i = 0; i < extensions.length; ++i )
> {
> ( (Accessor)extensions[ i ] ).access( component, context );
> }
> break;
>
> case RELEASE:
> for( int i = 0; i < extensions.length; ++i )
> {
> ( (Accessor)extensions[ i ] ).release( component, context );
> }
> break;
>
> case CREATE:
> for( int i = 0; i < extensions.length; ++i )
> {
> ( (Creator)extensions[ i ] ).create( component, context );
> }
> break;
>
> case DESTROY:
> for( int i = 0; i < extensions.length; ++i )
> {
> ( (Creator)extensions[ i ] ).destroy( component, context );
> }
> break;
>
> default:
> if( getLogger().isErrorEnabled() )
> {
> final String message =
> "Incorrect extension phase specified: " + type;
> getLogger().error( message );
> }
> }
> }
> }
>
>
>
> 1.1 jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/lifecycle/LifecycleExtensionManager.java
>
> Index: LifecycleExtensionManager.java
> ===================================================================
> /*
>
> ============================================================================
> The Apache Software License, Version 1.1
> ============================================================================
>
> Copyright (C) @year@ The Apache Software Foundation. All rights reserved.
>
> Redistribution and use in source and binary forms, with or without modifica-
> tion, are permitted provided that the following conditions are met:
>
> 1. Redistributions of source code must retain the above copyright notice,
> this list of conditions and the following disclaimer.
>
> 2. Redistributions in binary form must reproduce the above copyright notice,
> this list of conditions and the following disclaimer in the documentation
> and/or other materials provided with the distribution.
>
> 3. The end-user documentation included with the redistribution, if any, must
> include the following acknowledgment: "This product includes software
> 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
> apache@apache.org.
>
> 5. Products derived from this software may not be called "Apache", nor may
> "Apache" appear in their name, without prior written permission of the
> Apache Software Foundation.
>
> THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
> INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
> DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
> OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
> ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> 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
> Apache Software Foundation, please see <http://www.apache.org/>.
>
> */
> package org.apache.excalibur.container.lifecycle;
>
> import java.util.ArrayList;
> import java.util.Collections;
> import java.util.Iterator;
> import java.util.List;
> import org.apache.avalon.framework.context.Context;
> import org.apache.excalibur.container.lifecycle.Accessor;
> import org.apache.excalibur.container.lifecycle.Creator;
>
> /**
> * <code>LifecycleExtensionManager</code> class. This class manages a list
> * of extensions objects that are executed on components during the various
> * stages of their lifecycles.
> *
> * <p>
> * It provides methods for adding extension objects to the system,
> * and a method for executing them on a particular component object. The
> * current context is also passed in to the extension objects to facilitate
> * the communication of any global values.
> * </p>
> *
> * <p>
> * Extensions are stored internally in a list. This guarentees that the
> * order in which they are executed matches the order in which they are
> * inserted.
> * </p>
> *
> * @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
> * @version CVS $Revision: 1.1 $ $Date: 2002/11/09 23:23:56 $
> */
> public class LifecycleExtensionManager
> extends AbstractLifecycleExtensionManager
> {
> // extensions objects
> private final CachedArrayList m_accessorExtensions = new CachedArrayList();
> private final CachedArrayList m_creatorExtensions = new CachedArrayList();
>
> /**
> * <code>executeAccessExtensions</code> method, executes all access
> * level extensions on the given component.
> *
> * @param component a <code>Component</code> instance
> * @param context a <code>Context</code> instance
> * @exception Exception if an error occurs
> */
> public void executeAccessExtensions( Object component, Context context )
> throws Exception
> {
> executeExtensions( m_accessorExtensions.toArray(), component, context, ACCESS );
> }
>
> /**
> * <code>executeReleaseExtensions</code> method, executes all release
> * level extensions on the given component.
> *
> * @param component a <code>Component</code> instance
> * @param context a <code>Context</code> instance
> * @exception Exception if an error occurs
> */
> public void executeReleaseExtensions( Object component, Context context )
> throws Exception
> {
> executeExtensions( m_accessorExtensions.toArray(), component, context, RELEASE );
> }
>
> /**
> * <code>executeCreationExtensions</code> method, executes all creation
> * level extensions on the given component.
> *
> * @param component a <code>Component</code> instance
> * @param context a <code>Context</code> instance
> * @exception Exception if an error occurs
> */
> public void executeCreationExtensions( Object component, Context context )
> throws Exception
> {
> executeExtensions( m_creatorExtensions.toArray(), component, context, CREATE );
> }
>
> /**
> * <code>executeDestructionExtensions</code> method, executes all
> * destruction level extensions on the given component.
> *
> * @param component a <code>Component</code> instance
> * @param context a <code>Context</code> instance
> * @exception Exception if an error occurs
> */
> public void executeDestructionExtensions( Object component, Context context )
> throws Exception
> {
> executeExtensions( m_creatorExtensions.toArray(), component, context, DESTROY );
> }
>
> // The following methods define operations that modify the internal list
> // of extensions. I've refrained from returning the List directly, via a
> // getExtensions() method for the following reasons:
> //
> // 1. Returning List breaks encapsulation, implicitly exposing all of List's
> // current and future operations to the client
> // 2. List operates with type Object, not LifecycleExtension which means we need
> // more error handling code if we make it possible for the user to add instances
> // of any type to the extension lists.
> // 3. Wrapping add/remove methods allow us to add optimizations to improve performance
> // (eg. to convert the List to an array upon each add/remove, and not upon each
> // execute operation)
> // 4. The book 'Refactoring' says we shouldn't do it :-)
> //
> // I'm open to suggestions though if there's any better ideas ?
>
> /**
> * Adds an accessor extension to the manager
> *
> * @param extension a <code>Accessor</code> instance
> */
> public void addAccessorExtension( Accessor extension )
> {
> m_accessorExtensions.add( extension );
> }
>
> /**
> * Adds a creator extension to the manager
> *
> * @param extension a <code>Creator</code> instance
> */
> public void addCreatorExtension( Creator extension )
> {
> m_creatorExtensions.add( extension );
> }
>
> /**
> * Inserts an accessor extension at a given index in the manager
> *
> * @param position an <code>int</code> index value
> * @param extension a <code>Accessor</code> instance
> */
> public void insertAccessorExtension( int position, Accessor extension )
> {
> m_accessorExtensions.insert( position, extension );
> }
>
> /**
> * Inserts a creator extension at a given index in the manager
> *
> * @param position an <code>int</code> index value
> * @param extension a <code>Creator</code> instance
> */
> public void insertCreatorExtension( int position, Creator extension )
> {
> m_accessorExtensions.insert( position, extension );
> }
>
> /**
> * Removes a particular accessor extension from the manager
> *
> * @param position an <code>int</code> index value
> * @return a <code>Accessor</code> instance
> */
> public Accessor removeAccessorExtension( int position )
> {
> return (Accessor)m_accessorExtensions.remove( position );
> }
>
> /**
> * Removes a particular creator extension from the manager
> *
> * @param position an <code>int</code> index value
> * @return a <code>Creator</code> instance
> */
> public Creator removeCreatorExtension( int position )
> {
> return (Creator)m_creatorExtensions.remove( position );
> }
>
> /**
> * Obtain an iterator.
> *
> * @return an <code>Iterator</code> instance
> */
> public Iterator accessorExtensionsIterator()
> {
> return m_accessorExtensions.iterator();
> }
>
> /**
> * Obtain an iterator.
> *
> * @return an <code>Iterator</code> instance
> */
> public Iterator creatorExtensionsIterator()
> {
> return m_creatorExtensions.iterator();
> }
>
> /**
> * Find out the total number of accessor extensions registered with this manager
> *
> * @return an <code>int</code> value
> */
> public int accessorExtensionsCount()
> {
> return m_accessorExtensions.size();
> }
>
> /**
> * Find out the total number of creator extensions registered with this manager
> *
> * @return an <code>int</code> value
> */
> public int creatorExtensionsCount()
> {
> return m_creatorExtensions.size();
> }
>
> /**
> * Obtain the particular accessor extension at the given index
> *
> * @param index an <code>int</code> index value
> * @return a <code>Accessor</code> instance
> */
> public Accessor getAccessorExtension( int index )
> {
> return (Accessor)m_accessorExtensions.get( index );
> }
>
> /**
> * Obtain the particular creator extension at the given index
> *
> * @param index an <code>int</code> index value
> * @return a <code>Creator</code> instance
> */
> public Creator getCreatorExtension( int index )
> {
> return (Creator)m_creatorExtensions.get( index );
> }
>
> /**
> * Clears all accessor extensions registered with this manager
> */
> public void clearAccessorExtensions()
> {
> m_accessorExtensions.clear();
> }
>
> /**
> * Clears all creator extensions registered with this manager
> */
> public void clearCreatorExtensions()
> {
> m_creatorExtensions.clear();
> }
>
> /**
> * <code>CachedArrayList</code> class.
> *
> * <p>
> * This class wraps a synchronized ArrayList to provide an optimized
> * <code>toArray()</code> method that returns an internally cached array,
> * rather than a new array generated per <code>toArray()</code>
> * invocation.
> * </p>
> *
> * <p>
> * Use of the class by the Manager results in <code>toArray()</code>
> * being invoked far more often than any other method. Caching the value
> * <code>toArray</code> normally returns is intended to be a performance
> * optimization.
> * </p>
> *
> * <p>
> * The cached array value is updated upon each write operation to the
> * List.
> * </p>
> *
> * <p>
> * REVISIT(MC): investigate using FastArrayList from collections ?
> * </p>
> */
> private final class CachedArrayList
> {
> // Empty array constant
> private final Object[] EMPTY_ARRAY = new Object[ 0 ];
>
> // Actual list for storing elements
> private final List m_proxy = Collections.synchronizedList( new ArrayList() );
>
> // Proxy cache, saves unnecessary conversions from List to Array
> private Object[] m_cache = EMPTY_ARRAY;
>
> /**
> * Add an object to the list
> *
> * @param object an <code>Object</code> value
> */
> public void add( final Object object )
> {
> m_proxy.add( object );
> m_cache = m_proxy.toArray();
> }
>
> /**
> * Insert an object into a particular position in the list
> *
> * @param position an <code>int</code> value
> * @param object an <code>Object</code> value
> */
> public void insert( final int position, final Object object )
> {
> m_proxy.add( position, object );
> m_cache = m_proxy.toArray();
> }
>
> /**
> * Remove an object from the list
> *
> * @param position an <code>int</code> value
> * @return a <code>Object</code> value
> */
> public Object remove( final int position )
> {
> final Object object = m_proxy.remove( position );
> m_cache = m_proxy.toArray();
> return object;
> }
>
> /**
> * Obtain an iterator
> *
> * @return an <code>Iterator</code> value
> */
> public Iterator iterator()
> {
> return m_proxy.iterator();
> }
>
> /**
> * Obtain the size of the list
> *
> * @return an <code>int</code> value
> */
> public int size()
> {
> return m_proxy.size();
> }
>
> /**
> * Access an object that is in the list
> *
> * @param index an <code>int</code> value
> * @return a <code>Object</code> value
> */
> public Object get( final int index )
> {
> return m_proxy.get( index );
> }
>
> /**
> * Find out the index of an object in the list
> *
> * @param object an <code>Object</code> value
> * @return an <code>int</code> value
> */
> public int indexOf( final Object object )
> {
> return m_proxy.indexOf( object );
> }
>
> /**
> * Clear the list
> */
> public void clear()
> {
> m_proxy.clear();
> m_cache = EMPTY_ARRAY;
> }
>
> /**
> * Obtain the list as an array. Subsequents calls to this method
> * will return the same array object, until a write operation is
> * performed on the list.
> *
> * @return an <code>Object[]</code> value
> */
> public Object[] toArray()
> {
> return m_cache;
> }
> }
> }
>
>
>
>
>--
>To unsubscribe, e-mail: <ma...@jakarta.apache.org>
>For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>
>
>
>
--
Stephen J. McConnell
OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>