notify-dpml AT lists.ibiblio.org
Subject: DPML Notify
List archive
r949 - in trunk/main/metro: part/api/src/main/net/dpml/part/local runtime/src/main/net/dpml/metro/runtime
- From: mcconnell at BerliOS <mcconnell AT mail.berlios.de>
- To: notify-dpml AT lists.ibiblio.org
- Subject: r949 - in trunk/main/metro: part/api/src/main/net/dpml/part/local runtime/src/main/net/dpml/metro/runtime
- Date: Mon, 23 Jan 2006 03:13:26 +0100
Author: mcconnell
Date: 2006-01-23 03:13:10 +0100 (Mon, 23 Jan 2006)
New Revision: 949
Removed:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionContext.java
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/EventProducer.java
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/LocalWeakEventProducer.java
Modified:
trunk/main/metro/part/api/src/main/net/dpml/part/local/Controller.java
trunk/main/metro/part/api/src/main/net/dpml/part/local/InitialContext.java
trunk/main/metro/part/api/src/main/net/dpml/part/local/LocalEventProducer.java
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentHandler.java
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionController.java
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultComponentModel.java
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultContextModel.java
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultProvider.java
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/UnicastEventSource.java
Log:
closing up metro disposal
Modified:
trunk/main/metro/part/api/src/main/net/dpml/part/local/Controller.java
===================================================================
--- trunk/main/metro/part/api/src/main/net/dpml/part/local/Controller.java
2006-01-23 00:56:47 UTC (rev 948)
+++ trunk/main/metro/part/api/src/main/net/dpml/part/local/Controller.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -39,7 +39,7 @@
/**
* Static default controller.
*/
- static final Controller STANDARD = PartManager.CONTROLLER;
+ static final Controller STANDARD = InitialContext.CONTROLLER;
/**
* Returns the identity of the object implementing this interface.
Modified:
trunk/main/metro/part/api/src/main/net/dpml/part/local/InitialContext.java
===================================================================
---
trunk/main/metro/part/api/src/main/net/dpml/part/local/InitialContext.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/part/api/src/main/net/dpml/part/local/InitialContext.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -46,7 +46,41 @@
// static
//----------------------------------------------------------------------------
+ private static final InitialContext CONTEXT = new InitialContext();
+
/**
+ * Create a shutdown hook that will trigger shutdown of the supplied
plugin.
+ * @param thread the application thread
+ */
+ static
+ {
+ //
+ // Create a shutdown hook to trigger clean disposal of the
+ // controller
+ //
+
+ Runtime.getRuntime().addShutdownHook(
+ new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ CONTEXT.dispose();
+ }
+ catch( Throwable e )
+ {
+ boolean ignorable = true;
+ }
+ System.runFinalization();
+ }
+ }
+ );
+ }
+
+ public static final Controller CONTROLLER = newController( CONTEXT );
+
+ /**
* Construct a controller.
* @param context the controller context
* @return the controller
@@ -167,10 +201,11 @@
*/
public void dispose()
{
- m_logger.debug( "context disposal" );
+ getInternalLogger().debug( "initiating context disposal" );
ControllerDisposalEvent event = new ControllerDisposalEvent( this );
enqueueEvent( event, false );
super.dispose();
+ getInternalLogger().debug( "disposed" );
}
//----------------------------------------------------------------------------
@@ -288,7 +323,7 @@
{
final String error =
"ControllerContextListener working dir change
notification error.";
- getLogger().error( error, e );
+ getInternalLogger().error( error, e );
}
}
}
@@ -311,7 +346,7 @@
{
final String error =
"ControllerContextListener temp dir change
notification error.";
- getLogger().error( error, e );
+ getInternalLogger().error( error, e );
}
}
}
@@ -334,7 +369,7 @@
{
final String error =
"ControllerContextListener disposal notification
error.";
- getLogger().error( error, e );
+ getInternalLogger().error( error, e );
}
}
}
Modified:
trunk/main/metro/part/api/src/main/net/dpml/part/local/LocalEventProducer.java
===================================================================
---
trunk/main/metro/part/api/src/main/net/dpml/part/local/LocalEventProducer.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/part/api/src/main/net/dpml/part/local/LocalEventProducer.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -24,10 +24,8 @@
import java.util.LinkedList;
import java.util.Map;
import java.util.WeakHashMap;
-import java.util.HashMap;
import net.dpml.transit.Logger;
-import net.dpml.transit.util.ExceptionHelper;
/**
* A abstract base class that established an event queue and handles event
dispatch
@@ -38,8 +36,18 @@
*/
abstract class LocalEventProducer
{
- private Map m_listeners = new HashMap();
+
//----------------------------------------------------------------------------
+ // state
+
//----------------------------------------------------------------------------
+
+ /**
+ * Weak hashmap of event listeners.
+ */
+ private Map m_listeners = new WeakHashMap();
+ /**
+ * Logging channel.
+ */
private Logger m_logger;
/**
@@ -47,16 +55,44 @@
*/
private final Object m_lock = new Object();
+
//----------------------------------------------------------------------------
+ // constructor
+
//----------------------------------------------------------------------------
+
+ /**
+ * Creation of a new local event producer.
+ * @param logger the assigned logging channel
+ */
LocalEventProducer( Logger logger )
{
m_logger = logger;
}
+
//----------------------------------------------------------------------------
+ // implementation
+
//----------------------------------------------------------------------------
+
+ /**
+ * Return the internal context logging channel.
+ * @return the logging channel
+ */
+ protected Logger getInternalLogger()
+ {
+ return m_logger;
+ }
+
+ /**
+ * Return the synchronization lock.
+ * @return the lock
+ */
protected Object getLock()
{
return m_lock;
}
+ /**
+ * Dispose of the event producer.
+ */
void dispose()
{
m_logger.debug( "context event channel disposal" );
@@ -160,16 +196,12 @@
EventObject event = null;
synchronized( EVENT_QUEUE )
{
- try
+ try
{
- while( m_continue && EVENT_QUEUE.isEmpty() )
+ while( EVENT_QUEUE.isEmpty() )
{
EVENT_QUEUE.wait();
}
- if ( !m_continue )
- {
- break;
- }
Object object = EVENT_QUEUE.remove( 0 );
try
{
@@ -188,7 +220,7 @@
return;
}
}
-
+
Object source = event.getSource();
if( source instanceof LocalEventProducer )
{
Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentHandler.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentHandler.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentHandler.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -143,7 +143,7 @@
final ComponentController control, final ComponentModel model )
throws RemoteException, ControlException
{
- super();
+ super( logger );
m_parent = parent;
m_classloader = classloader;
@@ -580,6 +580,7 @@
{
synchronized( getLock() )
{
+ getLogger().debug( "disposal" );
m_holder.dispose();
super.dispose();
}
@@ -669,15 +670,6 @@
}
//--------------------------------------------------------------------------
- // internal
-
//--------------------------------------------------------------------------
-
- private Logger getLogger()
- {
- return m_logger;
- }
-
-
//--------------------------------------------------------------------------
// Object
//--------------------------------------------------------------------------
Deleted:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionContext.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionContext.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionContext.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -1,331 +0,0 @@
-/*
- * Copyright (c) 2005 Stephen J. McConnell
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- *
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.dpml.metro.runtime;
-
-import java.io.File;
-import java.util.EventObject;
-import java.util.EventListener;
-
-import net.dpml.part.Disposable;
-import net.dpml.part.local.ControllerContext;
-import net.dpml.part.local.ControllerContextListener;
-import net.dpml.part.local.ControllerContextEvent;
-
-import net.dpml.transit.Logger;
-
-/**
- * The CompositionControllerContext class wraps a ContentModel and supplies
convinience
- * operations that translate ContentModel properties and events to type-safe
values used
- * in the conposition controller.
- *
- * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
- * @version @PROJECT-VERSION@
- */
-public class CompositionContext extends LocalWeakEventProducer
- implements ControllerContext, Disposable
-{
-
//----------------------------------------------------------------------------
- // state
-
//----------------------------------------------------------------------------
-
- /**
- * Working directory.
- */
- private File m_work;
-
- /**
- * Temp directory.
- */
- private File m_temp;
-
- /**
- * The assigned logging channel.
- */
- private Logger m_logger;
-
-
//----------------------------------------------------------------------------
- // constructor
-
//----------------------------------------------------------------------------
-
- /**
- * Creation of a new <tt>CompositionContext</tt>.
- * @param logger the assigned logging channel
- */
- public CompositionContext( Logger logger )
- {
- this( logger, null, null );
- }
-
- /**
- * Creation of a new <tt>CompositionContext</tt>.
- * @param logger the assigned logging channel
- * @param work the working directory
- * @param temp the temporary directory
- */
- public CompositionContext( Logger logger, File work, File temp )
- {
- super();
-
- if( null == logger )
- {
- throw new NullPointerException( "logger" );
- }
-
- m_logger = logger;
-
- if( null == work )
- {
- String path = System.getProperty( "user.dir" );
- m_work = new File( path );
- }
- else
- {
- m_work = work;
- }
-
- if( null == temp )
- {
- String path = System.getProperty( "java.io.tmpdir" );
- m_temp = new File( path );
- }
- else
- {
- m_temp = temp;
- }
- }
-
-
//----------------------------------------------------------------------------
- // Disposable
-
//----------------------------------------------------------------------------
-
- public void dispose()
- {
- }
-
-
//----------------------------------------------------------------------------
- // ControllerContext
-
//----------------------------------------------------------------------------
-
- /**
- * Return the assigned logging channel
- * @return the logging channel
- */
- public Logger getLogger()
- {
- return m_logger;
- }
-
- /**
- * Return the root working directory.
- *
- * @return directory representing the root of the working directory
hierachy
- */
- public File getWorkingDirectory()
- {
- synchronized( getLock() )
- {
- return m_work;
- }
- }
-
- /**
- * Set the root working directory.
- *
- * @param dir the root of the working directory hierachy
- */
- public void setWorkingDirectory( File dir )
- {
- synchronized( getLock() )
- {
- m_work = dir;
- }
- }
-
- /**
- * Return the root temporary directory.
- *
- * @return directory representing the root of the temporary directory
hierachy.
- */
- public File getTempDirectory()
- {
- synchronized( getLock() )
- {
- return m_temp;
- }
- }
-
- /**
- * Add the supplied controller context listener to the controller
context. A
- * controller implementation should not maintain strong references to
supplied
- * listeners.
- *
- * @param listener the controller context listener to add
- */
- public void addControllerContextListener( ControllerContextListener
listener )
- {
- addListener( listener );
- }
-
- /**
- * Remove the supplied controller context listener from the controller
context.
- *
- * @param listener the controller context listener to remove
- */
- public void removeControllerContextListener( ControllerContextListener
listener )
- {
- removeListener( listener );
- }
-
-
//----------------------------------------------------------------------------
- // impl
-
//----------------------------------------------------------------------------
-
- /**
- * Process a context related event.
- * @param event the event to process
- */
- protected void processEvent( EventObject event )
- {
- if( event instanceof WorkingDirectoryChangeEvent )
- {
- processWorkingDirectoryChangeEvent(
(WorkingDirectoryChangeEvent) event );
- }
- else if( event instanceof TempDirectoryChangeEvent )
- {
- processTempDirectoryChangeEvent( (TempDirectoryChangeEvent)
event );
- }
- else if( event instanceof ControllerDisposalEvent )
- {
- processControllerDisposalEvent( (ControllerDisposalEvent) event
);
- }
- else
- {
- super.processEvent( event );
- }
- }
-
- private void processWorkingDirectoryChangeEvent(
WorkingDirectoryChangeEvent event )
- {
- EventListener[] listeners = super.listeners();
- for( int i=0; i<listeners.length; i++ )
- {
- EventListener eventListener = listeners[i];
- if( eventListener instanceof ControllerContextListener )
- {
- ControllerContextListener listener =
(ControllerContextListener) eventListener;
- try
- {
- listener.workingDirectoryChanged( event );
- }
- catch( Throwable e )
- {
- final String error =
- "ControllerContextListener working dir change
notification error.";
- getLogger().error( error, e );
- }
- }
- }
- }
-
- private void processTempDirectoryChangeEvent( TempDirectoryChangeEvent
event )
- {
- EventListener[] listeners = super.listeners();
- for( int i=0; i<listeners.length; i++ )
- {
- EventListener eventListener = listeners[i];
- if( eventListener instanceof ControllerContextListener )
- {
- ControllerContextListener listener =
(ControllerContextListener) eventListener;
- try
- {
- listener.tempDirectoryChanged( event );
- }
- catch( Throwable e )
- {
- final String error =
- "ControllerContextListener temp dir change
notification error.";
- getLogger().error( error, e );
- }
- }
- }
- }
-
- private void processControllerDisposalEvent( ControllerDisposalEvent
event )
- {
- EventListener[] listeners = super.listeners();
- for( int i=0; i<listeners.length; i++ )
- {
- EventListener eventListener = listeners[i];
- if( eventListener instanceof ControllerContextListener )
- {
- ControllerContextListener listener =
(ControllerContextListener) eventListener;
- try
- {
- listener.controllerDisposal( event );
- }
- catch( Throwable e )
- {
- final String error =
- "ControllerContextListener disposal notification
error.";
- getLogger().error( error, e );
- }
- }
- }
- }
-
-
//----------------------------------------------------------------------------
- // static (private)
-
//----------------------------------------------------------------------------
-
- /**
- * Working directory change event impl.
- */
- private static class WorkingDirectoryChangeEvent extends
ControllerContextEvent
- {
- public WorkingDirectoryChangeEvent(
- ControllerContext source, File oldDir, File newDir )
- {
- super( source, oldDir, newDir );
- }
- }
-
- /**
- * Temp directory change event impl.
- */
- private static class TempDirectoryChangeEvent extends
ControllerContextEvent
- {
- public TempDirectoryChangeEvent(
- ControllerContext source, File oldDir, File newDir )
- {
- super( source, oldDir, newDir );
- }
- }
-
- /**
- * Disposal event.
- */
- private static class ControllerDisposalEvent extends
ControllerContextEvent
- {
- public ControllerDisposalEvent( ControllerContext source )
- {
- super( source, null, null );
- }
- }
-
-}
Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionController.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionController.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionController.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -66,6 +66,7 @@
private final ComponentController m_controller;
private final HashMap m_handlers = new HashMap(); // foreign controllers
private final Repository m_loader;
+ private final InternalControllerContextListener m_listener;
//--------------------------------------------------------------------
// mutable state
@@ -79,17 +80,6 @@
/**
* Creation of a new controller.
- * @param logger the logging chanel
- * @exception ControlException if an error occurs during controller
creation
- */
- public CompositionController( net.dpml.transit.Logger logger )
- throws ControlException
- {
- this( new CompositionContext( logger, null, null ) );
- }
-
- /**
- * Creation of a new controller.
* @param context the control context
* @exception ControlException if an error occurs during controller
creation
*/
@@ -99,10 +89,10 @@
super();
m_context = context;
- m_logger = new StandardLogger( context.getLogger() );
-
- m_context.addControllerContextListener(
- new InternalControllerContextListener( this ) );
+ Logger root = new StandardLogger( context.getLogger() );
+ m_logger = root.getChildLogger( "control" );
+ m_listener = new InternalControllerContextListener( this );
+ m_context.addControllerContextListener( m_listener );
m_loader = Transit.getInstance().getRepository();
m_logger.debug( "controller: " + CONTROLLER_URI );
m_controller = new ComponentController( m_logger, this );
@@ -357,15 +347,12 @@
void dispose()
{
- getLogger().info( "initating controller disposal" );
- m_disposed = true;
+ getLogger().debug( "initating controller disposal" );
+ m_context.removeControllerContextListener( m_listener );
+ m_EVENT_DISPATCH_THREAD.dispose();
+ getLogger().debug( "disposal complete" );
}
- boolean isDisposed()
- {
- return m_disposed;
- }
-
/**
* Static URI of this controller.
*/
@@ -428,19 +415,29 @@
*/
private static class EventDispatchThread extends Thread
{
- private final CompositionController m_controller;
private final Logger m_logger;
- EventDispatchThread( CompositionController controller, Logger logger
)
+ private boolean m_continue = true;
+
+ EventDispatchThread( Logger logger )
{
- m_controller = controller;
m_logger = logger;
m_logger.debug( "starting event dispatch thread" );
}
+ void dispose()
+ {
+ synchronized( EVENT_QUEUE )
+ {
+ m_logger.debug( "stopping event dispatch thread" );
+ m_continue = false;
+ EVENT_QUEUE.notify();
+ }
+ }
+
public void run()
{
- while( !m_controller.isDisposed() )
+ while( m_continue )
{
// Wait on EVENT_QUEUE till an event is present
EventObject event = null;
@@ -485,8 +482,7 @@
"Unexpected error while processing event."
+ "\nEvent: " + event
+ "\nSource: " + source;
- String msg = ExceptionHelper.packException( error,
e, true );
- System.err.println( msg );
+ m_logger.warn( error, e );
}
}
else
@@ -514,8 +510,8 @@
{
if( m_EVENT_DISPATCH_THREAD == null )
{
- Logger logger = getLogger();
- m_EVENT_DISPATCH_THREAD = new EventDispatchThread( this, logger
);
+ Logger logger = getLogger().getChildLogger( "event" );
+ m_EVENT_DISPATCH_THREAD = new EventDispatchThread( logger );
m_EVENT_DISPATCH_THREAD.setDaemon( true );
m_EVENT_DISPATCH_THREAD.start();
}
@@ -554,7 +550,6 @@
*/
public void controllerDisposal( ControllerContextEvent event )
{
- System.out.println( "# DISPOSAL EVENT" );
m_controller.dispose();
}
}
Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultComponentModel.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultComponentModel.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultComponentModel.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -75,7 +75,6 @@
private final HashMap m_parts = new HashMap();
private final DefaultContextModel m_context;
private final String m_path;
- private final Logger m_logger;
private String m_classname;
private ActivationPolicy m_activation;
@@ -95,10 +94,8 @@
ComponentDirective directive, String partition )
throws ControlException, RemoteException
{
- super();
+ super( new StandardLogger( partition.substring( 1 ).replace( '/',
'.' ) ) );
- m_logger = new StandardLogger( partition.substring( 1 ).replace(
'/', '.' ) );
-
m_controller = controller;
m_path = partition + directive.getName();
@@ -115,7 +112,8 @@
m_configuration = directive.getConfiguration();
ContextDirective context = directive.getContextDirective();
- m_context = new DefaultContextModel( this, m_logger, m_classloader,
m_type, context );
+ Logger logger = getLogger();
+ m_context = new DefaultContextModel( this, logger, m_classloader,
m_type, context );
final String base = m_path + PARTITION_SEPARATOR;
m_partKeys = getPartKeys( m_type );
@@ -158,7 +156,7 @@
{
final String error =
"ModelListener change notification error.";
- m_logger.error( error, e );
+ getLogger().error( error, e );
}
}
}
Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultContextModel.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultContextModel.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultContextModel.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -62,7 +62,6 @@
private final Map m_contextTable =
Collections.synchronizedMap( new HashMap() ); // (key,directive)
private final DefaultComponentModel m_parent;
- private final Logger m_logger;
//
------------------------------------------------------------------------
// mutable state
@@ -87,9 +86,8 @@
DefaultComponentModel parent, Logger logger, ClassLoader classloader,
Type type, ContextDirective directive )
throws ModelException, RemoteException
{
- super();
+ super( logger );
- m_logger = logger;
m_parent = parent;
m_directive = directive;
m_classloader = classloader;
@@ -155,7 +153,7 @@
{
final String error =
"ModelListener change notification error.";
- m_logger.error( error, e );
+ getLogger().error( error, e );
}
}
}
Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultProvider.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultProvider.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultProvider.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -69,11 +69,6 @@
*/
private final DefaultStateMachine m_machine;
- /**
- * The logging channel.
- */
- private final Logger m_logger;
-
//-------------------------------------------------------------------
// mutable state
//-------------------------------------------------------------------
@@ -111,7 +106,7 @@
DefaultProvider( ComponentHandler handler, Logger logger )
throws RemoteException, ControlException, InvocationTargetException
{
- super();
+ super( logger );
if( null == handler )
{
@@ -122,7 +117,6 @@
throw new NullPointerException( "logger" );
}
- m_logger = logger;
m_handler = handler;
State graph = handler.getStateGraph();
@@ -250,7 +244,7 @@
final String error =
"Event type not supported."
+ "\nEvent Class: " + event.getClass().getName();
- m_logger.warn( error );
+ getLogger().warn( error );
}
}
@@ -339,11 +333,6 @@
m_handler.removePropertyChangeListener( listener );
}
- private Logger getLogger()
- {
- return m_logger;
- }
-
private String createTag( Object instance )
{
String tag =
Deleted:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/EventProducer.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/EventProducer.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/EventProducer.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -1,296 +0,0 @@
-/*
- * Copyright 2005 Stephen J. McConnell.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- *
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.dpml.metro.runtime;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.rmi.NoSuchObjectException;
-import java.util.EventObject;
-import java.util.EventListener;
-import java.util.List;
-import java.util.LinkedList;
-
-import net.dpml.transit.util.ExceptionHelper;
-
-
-/**
- * A abstract base class that established an event queue and handles event
dispatch
- * operations for listeners declared in a class extending this base class.
- *
- * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
- * @version @PROJECT-VERSION@
- */
-abstract class EventProducer extends UnicastRemoteObject
-{
- /**
- * Registered event listeners.
- */
- private EventListener[] m_listeners = new EventListener[0];
-
- /**
- * Internal synchronization lock.
- */
- private final Object m_lock = new Object();
-
- private boolean m_disposed = false;
-
- protected EventProducer() throws RemoteException
- {
- super();
- }
-
- /**
- * Abstract operation to be implemented by classes extending this base
class.
- * An implementation is reposible for the posting of the event to
associated
- * listeners. Event posting will be executed under a separate thread to
the
- * thread that initiated the event post.
- *
- * @param event the event to process
- */
- protected abstract void processEvent( EventObject event );
-
- /**
- * Add a listener to the set of listeners handled by this producer.
- * @param listener the event listener
- */
- protected void addListener( EventListener listener )
- {
- if( m_disposed )
- {
- throw new IllegalStateException( "disposed" );
- }
-
- if( null == listener )
- {
- throw new NullPointerException( "listener" );
- }
-
- synchronized( m_lock )
- {
- Object[] old = m_listeners;
- m_listeners = new EventListener[ old.length + 1 ];
- System.arraycopy( old, 0, m_listeners, 0, old.length );
- m_listeners[old.length] = listener;
- }
- startEventDispatchThread();
- }
-
- /**
- * Remove a listener to the set of listeners handled by this producer.
- * @param listener the event listener
- */
- protected void removeListener( EventListener listener )
- {
- if( null == listener )
- {
- throw new NullPointerException( "listener" );
- }
-
- if( m_disposed )
- {
- throw new IllegalStateException( "disposed" );
- }
-
- synchronized( m_lock )
- {
- if( m_listeners.length == 0 )
- {
- throw new IllegalArgumentException( "Listener not
registered." );
- }
- // create the copy
- EventListener[] replacement = new EventListener[
m_listeners.length - 1 ];
- // copy listeners from 0 up to the listener being removed
- int i=0;
- while( i < replacement.length && m_listeners[i] != listener )
- {
- replacement[i] = m_listeners[i++];
- }
- // check that the listener has been located
- if( i == replacement.length && m_listeners[i] != listener )
- {
- throw new IllegalArgumentException( "Listener not
registered." );
- }
- // complete the copy operation
- while( i < replacement.length )
- {
- replacement[i] = m_listeners[++i];
- }
- // commit the copy
- m_listeners = replacement;
- }
- }
-
- protected Object getLock()
- {
- return m_lock;
- }
-
- protected boolean isDisposed()
- {
- return m_disposed;
- }
-
- protected void dispose()
- {
- if( m_disposed )
- {
- return;
- }
-
- synchronized( m_lock )
- {
- try
- {
- unexportObject( this, false );
- }
- catch( NoSuchObjectException e )
- {
- }
- m_listeners = new EventListener[0];
- m_disposed = true;
- }
- }
-
- /**
- * Queue of pending notification events. When an event for which
- * there are one or more listeners occurs, it is placed on this queue
- * and the queue is notified. A background thread waits on this queue
- * and delivers the events. This decouples event delivery from
- * the application concern, greatly simplifying locking and reducing
- * opportunity for deadlock.
- */
- private static final List EVENT_QUEUE = new LinkedList();
-
- /**
- * A single background thread ("the event notification thread") monitors
- * the event queue and delivers events that are placed on the queue.
- */
- private static class EventDispatchThread extends Thread
- {
- public void run()
- {
- while( true )
- {
- // Wait on EVENT_QUEUE till an event is present
- EventObject event = null;
- synchronized( EVENT_QUEUE )
- {
- try
- {
- while( EVENT_QUEUE.isEmpty() )
- {
- EVENT_QUEUE.wait();
- }
- Object object = EVENT_QUEUE.remove( 0 );
- try
- {
- event = (EventObject) object;
- }
- catch( ClassCastException cce )
- {
- final String error =
- "Unexpected class cast exception while
processing an event."
- + "\nEvent: " + object;
- throw new IllegalStateException( error );
- }
- }
- catch( InterruptedException e )
- {
- return;
- }
- }
-
- Object source = event.getSource();
- if( source instanceof EventProducer )
- {
- EventProducer producer = (EventProducer) source;
- try
- {
- producer.processEvent( event );
- }
- catch( Throwable e )
- {
- final String error =
- "Unexpected error while processing event."
- + "\nEvent: " + event
- + "\nSource: " + source;
- String msg = ExceptionHelper.packException( error,
e, true );
- System.err.println( msg );
- }
- }
- else
- {
- final String error =
- "Event source ["
- + source.getClass().getName()
- + "] is not an instance of " +
EventProducer.class.getName();
- throw new IllegalStateException( error );
- }
- }
- }
- }
-
- private static Thread m_EVENT_DISPATCH_THREAD = null;
-
- /**
- * This method starts the event dispatch thread the first time it
- * is called. The event dispatch thread will be started only
- * if someone registers a listener.
- */
- private static synchronized void startEventDispatchThread()
- {
- if( m_EVENT_DISPATCH_THREAD == null )
- {
- m_EVENT_DISPATCH_THREAD = new EventDispatchThread();
- m_EVENT_DISPATCH_THREAD.setDaemon( true );
- m_EVENT_DISPATCH_THREAD.start();
- }
- }
-
- /**
- * Return this node's preference/node change listeners. Even though
- * we're using a copy-on-write lists, we use synchronized accessors to
- * ensure information transmission from the writing thread to the
- * reading thread.
- */
- protected EventListener[] listeners()
- {
- synchronized( m_lock )
- {
- return m_listeners;
- }
- }
-
- /**
- * Enqueue an event for delivery to registered
- * listeners unless there are no registered
- * listeners.
- */
- protected void enqueueEvent( EventObject event )
- {
- if( m_listeners.length != 0 )
- {
- synchronized( EVENT_QUEUE )
- {
- EVENT_QUEUE.add( event );
- EVENT_QUEUE.notify();
- }
- }
- }
-}
Deleted:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/LocalWeakEventProducer.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/LocalWeakEventProducer.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/LocalWeakEventProducer.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -1,241 +0,0 @@
-/*
- * Copyright 2005 Stephen J. McConnell.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- *
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.dpml.metro.runtime;
-
-import java.util.EventObject;
-import java.util.EventListener;
-import java.util.List;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import net.dpml.transit.util.ExceptionHelper;
-
-/**
- * A abstract base class that established an event queue and handles event
dispatch
- * operations for listeners declared in a class extending this base class.
- *
- * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
- * @version @PROJECT-VERSION@
- */
-abstract class LocalWeakEventProducer
-{
- private Map m_listeners = new WeakHashMap();
-
- /**
- * Internal synchronization lock.
- */
- private final Object m_lock = new Object();
-
- protected Object getLock()
- {
- return m_lock;
- }
-
- /**
- * Abstract operation to be implemented by classes extending this base
class.
- * An implementation is reposible for the posting of the event to
associated
- * listeners. Event posting will be executed under a separate thread to
the
- * thread that initiated the event post.
- *
- * @param event the event to process
- */
- protected void processEvent( EventObject event )
- {
- final String error =
- "Event class not recognized: " + event.getClass().getName();
- throw new IllegalArgumentException( error );
- }
-
- /**
- * Add a listener to the set of listeners handled by this producer.
- * @param listener the event listener
- */
- protected void addListener( EventListener listener )
- {
- if( null == listener )
- {
- throw new NullPointerException( "listener" );
- }
- synchronized( m_lock )
- {
- m_listeners.put( listener, null );
- }
- startEventDispatchThread();
- }
-
- /**
- * Remove a listener to the set of listeners handled by this producer.
- * @param listener the event listener
- */
- protected void removeListener( EventListener listener )
- {
- if( null == listener )
- {
- throw new NullPointerException( "listener" );
- }
-
- synchronized( m_lock )
- {
- m_listeners.remove( listener );
- }
- }
-
- /**
- * Queue of pending notification events. When an event for which
- * there are one or more listeners occurs, it is placed on this queue
- * and the queue is notified. A background thread waits on this queue
- * and delivers the events. This decouples event delivery from
- * the application concern, greatly simplifying locking and reducing
- * opportunity for deadlock.
- */
- private static final List EVENT_QUEUE = new LinkedList();
-
- /**
- * A single background thread ("the event notification thread") monitors
- * the event queue and delivers events that are placed on the queue.
- */
- private static class EventDispatchThread extends Thread
- {
- public void run()
- {
- while( true )
- {
- // Wait on EVENT_QUEUE till an event is present
- EventObject event = null;
- synchronized( EVENT_QUEUE )
- {
- try
- {
- while( EVENT_QUEUE.isEmpty() )
- {
- EVENT_QUEUE.wait();
- }
- Object object = EVENT_QUEUE.remove( 0 );
- try
- {
- event = (EventObject) object;
- }
- catch( ClassCastException cce )
- {
- final String error =
- "Unexpected class cast exception while
processing an event."
- + "\nEvent: " + object;
- throw new IllegalStateException( error );
- }
- }
- catch( InterruptedException e )
- {
- return;
- }
- }
-
- Object source = event.getSource();
- if( source instanceof LocalWeakEventProducer )
- {
- LocalWeakEventProducer producer =
(LocalWeakEventProducer) source;
- try
- {
- producer.processEvent( event );
- }
- catch( Throwable e )
- {
- final String error =
- "Unexpected error while processing event."
- + "\nEvent: " + event
- + "\nSource: " + this;
- String msg = ExceptionHelper.packException( error,
e, true );
- System.err.println( msg );
- }
- }
- else
- {
- final String error =
- "Event source is not an instance of " +
LocalWeakEventProducer.class.getName();
- throw new IllegalStateException( error );
- }
- }
- }
- }
-
- private static Thread m_EVENT_DISPATCH_THREAD = null;
-
- /**
- * This method starts the event dispatch thread the first time it
- * is called. The event dispatch thread will be started only
- * if someone registers a listener.
- */
- private static synchronized void startEventDispatchThread()
- {
- if( m_EVENT_DISPATCH_THREAD == null )
- {
- m_EVENT_DISPATCH_THREAD = new EventDispatchThread();
- m_EVENT_DISPATCH_THREAD.setDaemon( true );
- m_EVENT_DISPATCH_THREAD.start();
- }
- }
-
- /**
- * Return this node's preference/node change listeners. Even though
- * we're using a copy-on-write lists, we use synchronized accessors to
- * ensure information transmission from the writing thread to the
- * reading thread.
- */
- protected EventListener[] listeners()
- {
- synchronized( m_lock )
- {
- return (EventListener[]) m_listeners.keySet().toArray( new
EventListener[0] );
- }
- }
-
- /**
- * Enqueue an event for delivery to registered
- * listeners unless there are no registered
- * listeners.
- */
- protected void enqueueEvent( EventObject event )
- {
- enqueueEvent( event, true );
- }
-
- /**
- * Enqueue an event for delivery to registered
- * listeners unless there are no registered
- * listeners.
- */
- protected void enqueueEvent( EventObject event, boolean asynchronouse )
- {
- if( m_listeners.size() != 0 )
- {
- if( asynchronouse )
- {
- synchronized( EVENT_QUEUE )
- {
- EVENT_QUEUE.add( event );
- EVENT_QUEUE.notify();
- }
- }
- else
- {
- processEvent( event );
- }
- }
- }
-}
Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/UnicastEventSource.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/UnicastEventSource.java
2006-01-23 00:56:47 UTC (rev 948)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/UnicastEventSource.java
2006-01-23 02:13:10 UTC (rev 949)
@@ -26,6 +26,8 @@
import java.util.List;
import java.util.LinkedList;
+import net.dpml.logging.Logger;
+
import net.dpml.transit.util.ExceptionHelper;
/**
@@ -47,18 +49,34 @@
*/
private final Object m_lock = new Object();
+ private final Logger m_logger;
+
private boolean m_disposed = false;
/**
* Creation of a new <tt>UnicastEventSource</tt>.
* @exception RemoteException if a remote I/O exception occurs
*/
- protected UnicastEventSource() throws RemoteException
+ protected UnicastEventSource( Logger logger ) throws RemoteException
{
super();
+ m_logger = logger;
}
+
//--------------------------------------------------------------------------
+ // internal
+
//--------------------------------------------------------------------------
+
/**
+ * Return the logging channel assigned to the event source.
+ * @return the logging channel
+ */
+ protected Logger getLogger()
+ {
+ return m_logger;
+ }
+
+ /**
* Abstract operation to be implemented by classes extending this base
class.
* An implementation is reposible for the posting of the event to
associated
* listeners. Event posting will be executed under a separate thread to
the
@@ -168,16 +186,48 @@
synchronized( m_lock )
{
+ EventListener[] listeners = listeners();
+ for( int i=0; i < listeners.length; i++ )
+ {
+ EventListener listener = listeners[i];
+ removeListener( listener );
+ }
+ m_disposed = true;
+ getLogger().debug( "disposed" );
+ }
+
+ Thread thread = new Terminator( this, m_logger );
+ thread.start();
+ }
+
+ private class Terminator extends Thread
+ {
+ private final UnicastEventSource m_source;
+ private final Logger m_logger;
+
+ Terminator( UnicastEventSource source, Logger logger )
+ {
+ m_source = source;
+ m_logger = logger;
+ }
+
+ public void run()
+ {
try
{
- unexportObject( this, false );
+ UnicastRemoteObject.unexportObject( m_source, true );
+ m_logger.debug( "terminated" );
}
catch( NoSuchObjectException e )
{
- // ignore
+ boolean ignoreThis = true; // objct has not been exported
}
- m_listeners = new EventListener[0];
- m_disposed = true;
+ catch( RemoteException e )
+ {
+ final String error =
+ "Unexpected remote exception while retracting component
handler remote reference.";
+ m_logger.warn( error, e );
+ }
}
}
- r949 - in trunk/main/metro: part/api/src/main/net/dpml/part/local runtime/src/main/net/dpml/metro/runtime, mcconnell at BerliOS, 01/22/2006
Archive powered by MHonArc 2.6.24.