Skip to Content.
Sympa Menu

notify-dpml - r970 - in trunk/main: central/src/docs/about/notepad/freight central/src/docs/metro/runtime/components central/src/docs/metro/tasks/components metro/exec/src/main/net/dpml/metro/exec metro/model/src/main/net/dpml/metro/control metro/model/src/main/net/dpml/metro/model metro/runtime metro/runtime/src/main/net/dpml/metro/runtime metro/test/src/main/net/dpml/test/app metro/test/src/main/net/dpml/test/composite metro/test/src/test/net/dpml/metro/runtime/test

notify-dpml AT lists.ibiblio.org

Subject: DPML Notify

List archive

Chronological Thread  
  • From: mcconnell at BerliOS <mcconnell AT mail.berlios.de>
  • To: notify-dpml AT lists.ibiblio.org
  • Subject: r970 - in trunk/main: central/src/docs/about/notepad/freight central/src/docs/metro/runtime/components central/src/docs/metro/tasks/components metro/exec/src/main/net/dpml/metro/exec metro/model/src/main/net/dpml/metro/control metro/model/src/main/net/dpml/metro/model metro/runtime metro/runtime/src/main/net/dpml/metro/runtime metro/test/src/main/net/dpml/test/app metro/test/src/main/net/dpml/test/composite metro/test/src/test/net/dpml/metro/runtime/test
  • Date: Tue, 24 Jan 2006 18:07:36 +0100

Author: mcconnell
Date: 2006-01-24 18:07:29 +0100 (Tue, 24 Jan 2006)
New Revision: 970

Added:

trunk/main/metro/model/src/main/net/dpml/metro/control/ComponentHandler.java

trunk/main/metro/model/src/main/net/dpml/metro/control/ComponentManager.java

trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModelManager.java

trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModelOperations.java

trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModelManager.java

trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModelOperations.java

trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultComponentHandler.java

trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/DefaultComponentHandlerTestCase.java
Removed:
trunk/main/metro/model/src/main/net/dpml/metro/control/Handler.java
trunk/main/metro/model/src/main/net/dpml/metro/control/PartsManager.java

trunk/main/metro/model/src/main/net/dpml/metro/model/MutableComponentModel.java

trunk/main/metro/model/src/main/net/dpml/metro/model/MutableContextModel.java

trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentHandler.java

trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentHandlerTestCase.java
Modified:
trunk/main/central/src/docs/about/notepad/freight/observations.xml
trunk/main/central/src/docs/metro/runtime/components/index.xml
trunk/main/central/src/docs/metro/tasks/components/categories.xml
trunk/main/metro/exec/src/main/net/dpml/metro/exec/AbstractAdapter.java
trunk/main/metro/exec/src/main/net/dpml/metro/exec/ComponentAdapter.java
trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModel.java
trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModel.java
trunk/main/metro/runtime/build.xml

trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentController.java

trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionController.java

trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ContextInvocationHandler.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/DefaultPartsManager.java

trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultProvider.java

trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/PartsInvocationHandler.java
trunk/main/metro/test/src/main/net/dpml/test/app/Demo.java
trunk/main/metro/test/src/main/net/dpml/test/composite/PartsComponent.java

trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentModelTestCase.java

trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/CompositeTestCase.java

trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ContextModelTestCase.java

trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ObserverTestCase.java

trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ProviderTestCase.java
Log:
updating of the component handler class and consumers to take advantage of
package repositioning

Modified: trunk/main/central/src/docs/about/notepad/freight/observations.xml
===================================================================
--- trunk/main/central/src/docs/about/notepad/freight/observations.xml
2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/central/src/docs/about/notepad/freight/observations.xml
2006-01-24 17:07:29 UTC (rev 970)
@@ -85,7 +85,7 @@
<li>Packaging of default part with a component (e.g.
[classname].parts) is required.</li>
<li>The &lt;type&gt; task needs to be updated to include the
part association or we could put in place a .parts serialized object
colocated with the class.</li>
<li>Parts builders need to updated to load and check for
pre-declared default part entries.</li>
- <li>The PartsManager is not currently implemented (however, it
is expected that this will follow closely the general approach used for
context management.</li>
+ <li>The ComponentManager is not currently implemented
(however, it is expected that this will follow closely the general approach
used for context management.</li>
</ol>
</li>
<li>integration between FT and classic

Modified: trunk/main/central/src/docs/metro/runtime/components/index.xml
===================================================================
--- trunk/main/central/src/docs/metro/runtime/components/index.xml
2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/central/src/docs/metro/runtime/components/index.xml
2006-01-24 17:07:29 UTC (rev 970)
@@ -27,21 +27,21 @@
<li>provider: access to runtime service providers</li>
</ul>

- <subsection name="ComponentHandler">
+ <subsection name="DefaultComponentHandler">

<p>
- The <tt>net.dpml.metro.runtime.ComponentHandler</tt> class is the
reference implementation
+ The <tt>net.dpml.metro.runtime.DefaultComponentHandler</tt> class is
the reference implementation
of the <tt>Component</tt> interface. It is created by the
<tt>CompositionController</tt>
using either an implicit or explicit remotely accessible
<tt>ComponentModel</tt> that
aggregates information about a component <tt>type</tt> and
deployment solution.
</p>

<p>
- Following the separation of model and control concerns, the
<tt>ComponentHandler</tt> has
+ Following the separation of model and control concerns, the
<tt>DefaultComponentHandler</tt> has
as associated class controller to which a majority of functional
concerns are delegated.
This internal controller deals with the establishment of the
lifestyle handler taking into
account lifestyle and collection policies declared under the
<tt>ComponentModel</tt>.
- The <tt>ComponentHandler</tt> maintains a map of objects
implementing the
+ The <tt>DefaultComponentHandler</tt> maintains a map of objects
implementing the
<tt>net.dpml.part.Instance</tt> interface. This map representes the
collection of
runtime service providers bound to the type/directive combination.
</p>

Modified: trunk/main/central/src/docs/metro/tasks/components/categories.xml
===================================================================
--- trunk/main/central/src/docs/metro/tasks/components/categories.xml
2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/central/src/docs/metro/tasks/components/categories.xml
2006-01-24 17:07:29 UTC (rev 970)
@@ -71,7 +71,7 @@
categories configuration uri to the ComponentAdapter, the adapter
does not currently support this feature. A second issue relates to
non-assignment of logging category targets within the runtime
- ComponentHandler.
+ DefaultComponentHandler.
</p>

</section>

Modified:
trunk/main/metro/exec/src/main/net/dpml/metro/exec/AbstractAdapter.java
===================================================================
--- trunk/main/metro/exec/src/main/net/dpml/metro/exec/AbstractAdapter.java
2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/metro/exec/src/main/net/dpml/metro/exec/AbstractAdapter.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -26,7 +26,7 @@
import net.dpml.part.ControlException;
import net.dpml.part.remote.Provider;
import net.dpml.part.remote.Service;
-import net.dpml.part.remote.ServiceNotFoundException;
+import net.dpml.part.ServiceNotFoundException;

import net.dpml.transit.Logger;


Modified:
trunk/main/metro/exec/src/main/net/dpml/metro/exec/ComponentAdapter.java
===================================================================
--- trunk/main/metro/exec/src/main/net/dpml/metro/exec/ComponentAdapter.java
2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/metro/exec/src/main/net/dpml/metro/exec/ComponentAdapter.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -32,18 +32,19 @@
import net.dpml.metro.info.EntryDescriptor;
import net.dpml.metro.data.ValueDirective;

+import net.dpml.part.ControlException;
+import net.dpml.part.ServiceNotFoundException;
import net.dpml.part.local.Controller;
import net.dpml.part.local.ControllerContext;
import net.dpml.part.local.InitialContext;
import net.dpml.part.remote.Component;
-import net.dpml.part.ControlException;
import net.dpml.part.remote.Provider;
import net.dpml.part.remote.Model;
import net.dpml.part.remote.Service;
-import net.dpml.part.remote.ServiceNotFoundException;
-import net.dpml.metro.model.MutableComponentModel;
-import net.dpml.metro.model.MutableContextModel;

+import net.dpml.metro.model.ComponentModel;
+import net.dpml.metro.model.ContextModel;
+
import net.dpml.configuration.Configurable;
import net.dpml.configuration.Configuration;
import net.dpml.configuration.impl.DefaultConfigurationBuilder;
@@ -154,10 +155,10 @@
throw new UnsupportedOperationException( "Parameters not
currently supported." );
}

- if( model instanceof MutableComponentModel )
+ if( model instanceof ComponentModel )
{
- MutableComponentModel componentModel = (MutableComponentModel)
model;
- MutableContextModel cm = (MutableContextModel)
componentModel.getContextModel();
+ ComponentModel componentModel = (ComponentModel) model;
+ ContextModel cm = componentModel.getContextModel();
Enumeration names = properties.propertyNames();
while( names.hasMoreElements() )
{

Copied:
trunk/main/metro/model/src/main/net/dpml/metro/control/ComponentHandler.java
(from rev 969,
trunk/main/metro/model/src/main/net/dpml/metro/control/Handler.java)
===================================================================
--- trunk/main/metro/model/src/main/net/dpml/metro/control/Handler.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/model/src/main/net/dpml/metro/control/ComponentHandler.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -0,0 +1,50 @@
+/*
+ * 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.control;
+
+import java.util.Map;
+
+import net.dpml.part.ComponentOperations;
+
+import net.dpml.metro.model.ComponentModel;
+
+/**
+ * Local interface through which a component implementation may
+ * interact with subsidary parts.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public interface ComponentHandler extends ComponentOperations
+{
+ /**
+ * Return a mutible context map.
+ *
+ * @return the context map
+ */
+ Map getContextMap();
+
+ /**
+ * Return the component model associated with the component handler.
+ * @return the component model
+ */
+ ComponentModel getComponentModel();
+
+}
+

Copied:
trunk/main/metro/model/src/main/net/dpml/metro/control/ComponentManager.java
(from rev 964,
trunk/main/metro/model/src/main/net/dpml/metro/control/PartsManager.java)
===================================================================
--- trunk/main/metro/model/src/main/net/dpml/metro/control/PartsManager.java
2006-01-24 15:16:14 UTC (rev 964)
+++
trunk/main/metro/model/src/main/net/dpml/metro/control/ComponentManager.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -0,0 +1,75 @@
+/*
+ * 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.control;
+
+import net.dpml.part.ControlException;
+import net.dpml.part.remote.Component;
+import net.dpml.part.remote.Model;
+
+import net.dpml.lang.UnknownKeyException;
+
+/**
+ * Local interface through which a component implementation may
+ * interact with subsidary parts.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public interface ComponentManager
+{
+ /**
+ * Return the array of keys used to idenetity internal parts.
+ * @return the part key array
+ */
+ String[] getKeys();
+
+ /**
+ * Return an internal component.
+ * @param key the internal component key
+ * @return the component
+ * @exception UnknownKeyException the key is not recognized
+ */
+ Component getComponent( String key ) throws UnknownKeyException;
+
+ /**
+ * Return a local component handler.
+ * @param key the internal part key
+ * @return the local component handler
+ * @exception UnknownKeyException the key is not recognized
+ */
+ ComponentHandler getComponentHandler( String key ) throws
UnknownKeyException;
+
+ /**
+ * Return the commissioned state of the part collection.
+ * @return true if commissioned else false
+ */
+ boolean isCommissioned();
+
+ /**
+ * Initiate the oprdered activation of all internal parts.
+ * @exception ControlException if an activation error occurs
+ */
+ void commission() throws ControlException;
+
+ /**
+ * Initiate deactivation of all internal parts.
+ */
+ void decommission();
+}
+

Deleted: trunk/main/metro/model/src/main/net/dpml/metro/control/Handler.java
===================================================================
--- trunk/main/metro/model/src/main/net/dpml/metro/control/Handler.java
2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/metro/model/src/main/net/dpml/metro/control/Handler.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -1,54 +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.control;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.Map;
-
-import net.dpml.part.ControlException;
-import net.dpml.part.ComponentOperations;
-import net.dpml.part.remote.Provider;
-
-/**
- * Local interface through which a component implementation may
- * interact with subsidary parts.
- *
- * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
- * @version @PROJECT-VERSION@
- */
-public interface Handler extends ComponentOperations
-{
- /**
- * Return a mutible context map.
- *
- * @return the context map
- */
- Map getContextMap();
-
- /**
- * Return a reference to a managed provider.
- * @return the service provider
- * @exception InvocationTargetException if the component instantiation
process
- * is on demand and an target invocation error occurs
- * @exception ControlException if the component could not be established
due to a controller
- * related error
- */
- //Provider getProvider() throws ControlException,
InvocationTargetException;
-}
-

Deleted:
trunk/main/metro/model/src/main/net/dpml/metro/control/PartsManager.java
===================================================================
--- trunk/main/metro/model/src/main/net/dpml/metro/control/PartsManager.java
2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/metro/model/src/main/net/dpml/metro/control/PartsManager.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -1,82 +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.control;
-
-import net.dpml.part.ControlException;
-import net.dpml.part.remote.Component;
-import net.dpml.part.remote.Model;
-
-import net.dpml.lang.UnknownKeyException;
-
-/**
- * Local interface through which a component implementation may
- * interact with subsidary parts.
- *
- * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
- * @version @PROJECT-VERSION@
- */
-public interface PartsManager
-{
- /**
- * Return the array of keys used to idenetity internal parts.
- * @return the part key array
- */
- String[] getKeys();
-
- /**
- * Return an internal component.
- * @param key the internal component key
- * @return the component
- * @exception UnknownKeyException the key is not recognized
- */
- Component getComponent( String key ) throws UnknownKeyException;
-
- /**
- * Return the component model for the supplied component.
- * @param component the component
- * @return the component model
- */
- Model getComponentModel( Component component );
-
- /**
- * Return a local component handler.
- * @param key the internal part key
- * @return the local component handler
- * @exception UnknownKeyException the key is not recognized
- */
- Handler getComponentHandler( String key ) throws UnknownKeyException;
-
- /**
- * Return the commissioned state of the part collection.
- * @return true if commissioned else false
- */
- boolean isCommissioned();
-
- /**
- * Initiate the oprdered activation of all internal parts.
- * @exception ControlException if an activation error occurs
- */
- void commission() throws ControlException;
-
- /**
- * Initiate deactivation of all internal parts.
- */
- void decommission();
-}
-

Modified:
trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModel.java
===================================================================
--- trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModel.java
2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModel.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -41,91 +41,7 @@
* @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
* @version @PROJECT-VERSION@
*/
-public interface ComponentModel extends Model, Remote
+public interface ComponentModel extends Model, ComponentModelManager
{
- /**
- * Return the component name.
- * @return the name
- * @exception RemoteException if a remote exception occurs
- */
- String getName() throws RemoteException;
-
- /**
- * Return the component implementation class name.
- *
- * @return the classname of the implementation
- * @exception RemoteException if a remote exception occurs
- */
- String getImplementationClassName() throws RemoteException;
-
- /**
- * Return the component classloader directive.
- *
- * @return the classloader directive for the component
- * @exception RemoteException if a remote exception occurs
- */
- ClassLoaderDirective getClassLoaderDirective() throws RemoteException;
-
- /**
- * Return the component lifestyle policy.
- *
- * @return the lifestyle policy value
- * @exception RemoteException if a remote exception occurs
- */
- LifestylePolicy getLifestylePolicy() throws RemoteException;
-
- /**
- * Return the current component collection policy. If null, the component
- * type collection policy will be returned.
- *
- * @return a HARD, WEAK, SOFT or SYSTEM
- * @exception RemoteException if a remote exception occurs
- */
- CollectionPolicy getCollectionPolicy() throws RemoteException;
-
- /**
- * Return the current context model.
- *
- * @return the context model
- * @exception RemoteException if a remote exception occurs
- */
- ContextModel getContextModel() throws RemoteException;
-
- /**
- * Return the set of component model keys.
- * @return the component part keys
- * @exception RemoteException if a remote exception occurs
- */
- String[] getPartKeys() throws RemoteException;
-
- /**
- * Return the component model of an internal part referenced by the
supplied key.
- * @param key the part key
- * @return the internal part component model
- * @exception UnknownKeyException if the key is unknown
- * @exception RemoteException if a remote exception occurs
- */
- ComponentModel getComponentModel( String key ) throws
UnknownKeyException, RemoteException;
-
- /**
- * Return the component configuration.
- * @return the configuration
- * @exception RemoteException if a remote exception occurs
- */
- Configuration getConfiguration() throws RemoteException;
-
- /**
- * Return the component parameters.
- * @return the parameters
- * @exception RemoteException if a remote exception occurs
- */
- Parameters getParameters() throws RemoteException;
-
- /**
- * Return the component logging categories.
- * @return the categories
- * @exception RemoteException if a remote exception occurs
- */
- CategoryDirective[] getCategoryDirectives() throws RemoteException;
}


Copied:
trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModelManager.java
(from rev 963,
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableComponentModel.java)
===================================================================
---
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableComponentModel.java
2006-01-24 15:11:47 UTC (rev 963)
+++
trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModelManager.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -0,0 +1,50 @@
+/*
+ * 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.model;
+
+import java.rmi.RemoteException;
+
+import net.dpml.metro.info.CollectionPolicy;
+
+import net.dpml.part.ActivationPolicy;
+
+/**
+ * The MutableComponentModel interface extends ComponentModel with a set of
+ * operations supporting model changes.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public interface ComponentModelManager extends ComponentModelOperations
+{
+ /**
+ * Set the component activation policy to the supplied value.
+ * @param policy the new activation policy
+ * @exception RemoteException if a remote exception occurs
+ */
+ void setActivationPolicy( ActivationPolicy policy ) throws
RemoteException;
+
+ /**
+ * Override the assigned collection policy.
+ * @param policy the collection policy value
+ * @exception RemoteException if a remote exception occurs
+ */
+ void setCollectionPolicy( CollectionPolicy policy ) throws
RemoteException;
+}
+

Added:
trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModelOperations.java
===================================================================
---
trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModelOperations.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/model/src/main/net/dpml/metro/model/ComponentModelOperations.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -0,0 +1,132 @@
+/*
+ * 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.model;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+import net.dpml.metro.info.LifestylePolicy;
+import net.dpml.metro.info.CollectionPolicy;
+import net.dpml.metro.data.ClassLoaderDirective;
+import net.dpml.metro.data.CategoryDirective;
+
+import net.dpml.part.remote.Model;
+
+import net.dpml.configuration.Configuration;
+
+import net.dpml.parameters.Parameters;
+
+import net.dpml.lang.UnknownKeyException;
+
+/**
+ * The ComponentModel interface defines the remotely accessible aspects of a
component
+ * configuration.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public interface ComponentModelOperations
+{
+ /**
+ * Return the component name.
+ * @return the name
+ * @exception RemoteException if a remote exception occurs
+ */
+ String getName() throws RemoteException;
+
+ /**
+ * Return the component implementation class name.
+ *
+ * @return the classname of the implementation
+ * @exception RemoteException if a remote exception occurs
+ */
+ String getImplementationClassName() throws RemoteException;
+
+ /**
+ * Return the component classloader directive.
+ *
+ * @return the classloader directive for the component
+ * @exception RemoteException if a remote exception occurs
+ */
+ ClassLoaderDirective getClassLoaderDirective() throws RemoteException;
+
+ /**
+ * Return the component lifestyle policy.
+ *
+ * @return the lifestyle policy value
+ * @exception RemoteException if a remote exception occurs
+ */
+ LifestylePolicy getLifestylePolicy() throws RemoteException;
+
+ /**
+ * Return the current component collection policy. If null, the component
+ * type collection policy will be returned.
+ *
+ * @return a HARD, WEAK, SOFT or SYSTEM
+ * @exception RemoteException if a remote exception occurs
+ */
+ CollectionPolicy getCollectionPolicy() throws RemoteException;
+
+ /**
+ * Return the current context model.
+ *
+ * @return the context model
+ * @exception RemoteException if a remote exception occurs
+ */
+ ContextModel getContextModel() throws RemoteException;
+
+ /**
+ * Return the set of component model keys.
+ * @return the component part keys
+ * @exception RemoteException if a remote exception occurs
+ */
+ String[] getPartKeys() throws RemoteException;
+
+ /**
+ * Return the component model of an internal part referenced by the
supplied key.
+ * @param key the part key
+ * @return the internal part component model
+ * @exception UnknownKeyException if the key is unknown
+ * @exception RemoteException if a remote exception occurs
+ */
+ ComponentModel getComponentModel( String key ) throws
UnknownKeyException, RemoteException;
+
+ /**
+ * Return the component configuration.
+ * @return the configuration
+ * @exception RemoteException if a remote exception occurs
+ */
+ Configuration getConfiguration() throws RemoteException;
+
+ /**
+ * Return the component parameters.
+ * @return the parameters
+ * @exception RemoteException if a remote exception occurs
+ */
+ Parameters getParameters() throws RemoteException;
+
+ /**
+ * Return the component logging categories.
+ * @return the categories
+ * @exception RemoteException if a remote exception occurs
+ */
+ CategoryDirective[] getCategoryDirectives() throws RemoteException;
+
+}
+

Modified:
trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModel.java
===================================================================
--- trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModel.java
2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModel.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -33,7 +33,7 @@
* @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
* @version @PROJECT-VERSION@
*/
-public interface ContextModel extends Remote
+public interface ContextModel extends Remote, ContextModelManager
{
/**
* Return the set of context entries descriptors.

Copied:
trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModelManager.java
(from rev 963,
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableContextModel.java)
===================================================================
---
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableContextModel.java
2006-01-24 15:11:47 UTC (rev 963)
+++
trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModelManager.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -0,0 +1,59 @@
+/*
+ * 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.model;
+
+import java.rmi.RemoteException;
+
+import net.dpml.metro.info.PartReference;
+import net.dpml.part.Directive;
+
+import net.dpml.lang.UnknownKeyException;
+
+
+/**
+ * The MutableContextModel interface extends ContextModel with operations
supporting
+ * context entry value mutation.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public interface ContextModelManager extends ContextModelOperations
+{
+ /**
+ * Set a context entry directive value.
+ * @param key the context entry key
+ * @param directive the context entry directive
+ * @exception UnknownKeyException if the key is unknown
+ * @exception RemoteException if a remote exception occurs
+ */
+ void setEntryDirective( String key, Directive directive ) throws
UnknownKeyException, RemoteException;
+
+ /**
+ * Apply an array of tagged directive as an atomic operation.
Application of
+ * directives to the context model is atomic such that changes are
applied under a
+ * 'all-or-nothing' policy.
+ *
+ * @param directives an array of part references
+ * @exception UnknownKeyException if a key within the array does not
match a key within
+ * the context model.
+ * @exception RemoteException if a remote exception occurs
+ */
+ void setEntryDirectives( PartReference[] directives ) throws
UnknownKeyException, RemoteException;
+
+}

Added:
trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModelOperations.java
===================================================================
---
trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModelOperations.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/model/src/main/net/dpml/metro/model/ContextModelOperations.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -0,0 +1,71 @@
+/*
+ * 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.model;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+import net.dpml.metro.info.EntryDescriptor;
+import net.dpml.part.Directive;
+
+import net.dpml.lang.UnknownKeyException;
+
+
+/**
+ * The ContextModelOperations interface defines the common local and
remotely accessible component context.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public interface ContextModelOperations
+{
+ /**
+ * Return the set of context entries descriptors.
+ *
+ * @return context entry descriptor array
+ * @exception RemoteException if a remote exception occurs
+ */
+ EntryDescriptor[] getEntryDescriptors() throws RemoteException;
+
+ /**
+ * Return a of context entry descriptor.
+ *
+ * @param key the entry key
+ * @return the entry descriptor
+ * @exception UnknownKeyException if the key is unknown
+ * @exception RemoteException if a remote exception occurs
+ */
+ EntryDescriptor getEntryDescriptor( String key ) throws
UnknownKeyException, RemoteException;
+
+ /**
+ * Return the current directive assigned to a context entry.
+ * @param key the context entry key
+ * @return the directive
+ * @exception UnknownKeyException if the key is unknown
+ * @exception RemoteException if a remote exception occurs
+ */
+ Directive getEntryDirective( String key ) throws UnknownKeyException,
RemoteException;
+
+ /**
+ * Validate the model.
+ * @exception ValidationException if one or more issues exist within the
model
+ * @exception RemoteException if a remote exception occurs
+ */
+ void validate() throws ValidationException, RemoteException;
+}

Deleted:
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableComponentModel.java
===================================================================
---
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableComponentModel.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableComponentModel.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -1,50 +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.model;
-
-import java.rmi.RemoteException;
-
-import net.dpml.metro.info.CollectionPolicy;
-
-import net.dpml.part.ActivationPolicy;
-
-/**
- * The MutableComponentModel interface extends ComponentModel with a set of
- * operations supporting model changes.
- *
- * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
- * @version @PROJECT-VERSION@
- */
-public interface MutableComponentModel extends ComponentModel
-{
- /**
- * Set the component activation policy to the supplied value.
- * @param policy the new activation policy
- * @exception RemoteException if a remote exception occurs
- */
- void setActivationPolicy( ActivationPolicy policy ) throws
RemoteException;
-
- /**
- * Override the assigned collection policy.
- * @param policy the collection policy value
- * @exception RemoteException if a remote exception occurs
- */
- void setCollectionPolicy( CollectionPolicy policy ) throws
RemoteException;
-}
-

Deleted:
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableContextModel.java
===================================================================
---
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableContextModel.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/model/src/main/net/dpml/metro/model/MutableContextModel.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -1,59 +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.model;
-
-import java.rmi.RemoteException;
-
-import net.dpml.metro.info.PartReference;
-import net.dpml.part.Directive;
-
-import net.dpml.lang.UnknownKeyException;
-
-
-/**
- * The MutableContextModel interface extends ContextModel with operations
supporting
- * context entry value mutation.
- *
- * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
- * @version @PROJECT-VERSION@
- */
-public interface MutableContextModel extends ContextModel
-{
- /**
- * Set a context entry directive value.
- * @param key the context entry key
- * @param directive the context entry directive
- * @exception UnknownKeyException if the key is unknown
- * @exception RemoteException if a remote exception occurs
- */
- void setEntryDirective( String key, Directive directive ) throws
UnknownKeyException, RemoteException;
-
- /**
- * Apply an array of tagged directive as an atomic operation.
Application of
- * directives to the context model is atomic such that changes are
applied under a
- * 'all-or-nothing' policy.
- *
- * @param directives an array of part references
- * @exception UnknownKeyException if a key within the array does not
match a key within
- * the context model.
- * @exception RemoteException if a remote exception occurs
- */
- void setEntryDirectives( PartReference[] directives ) throws
UnknownKeyException, RemoteException;
-
-}

Modified: trunk/main/metro/runtime/build.xml
===================================================================
--- trunk/main/metro/runtime/build.xml 2006-01-24 15:48:40 UTC (rev 969)
+++ trunk/main/metro/runtime/build.xml 2006-01-24 17:07:29 UTC (rev 970)
@@ -32,9 +32,9 @@
<rmic base="${project.target.classes.main.dir}"
classpathref="project.compile.path">
<include name="**/DefaultComponentModel.class"/>
<include name="**/DefaultContextModel.class"/>
- <include name="**/ComponentHandler.class"/>
+ <include name="**/DefaultComponentHandler.class"/>
<include name="**/DefaultProvider.class"/>
- <include name="**/ComponentHandler.class"/>
+ <include name="**/DefaultComponentHandler.class"/>
<include name="**/CompositionHandler.class"/>
<include name="**/ValueHandler.class"/>
</rmic>

Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentController.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentController.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentController.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -48,7 +48,7 @@
import net.dpml.part.Directive;
import net.dpml.part.ControlException;
import net.dpml.part.Version;
-import net.dpml.metro.control.PartsManager;
+import net.dpml.metro.control.ComponentManager;
import net.dpml.part.remote.Component;
import net.dpml.part.remote.Model;
import net.dpml.part.ServiceNotFoundException;
@@ -105,11 +105,11 @@
* @param flag if true the component model is responsible for model
lifecycle
* @return the runtime handler
*/
- public ComponentHandler createComponentHandler(
+ public DefaultComponentHandler createDefaultComponentHandler(
ComponentModel model, boolean flag ) throws ControlException
{
ClassLoader anchor = Thread.currentThread().getContextClassLoader();
- return createComponentHandler( anchor, model, flag );
+ return createDefaultComponentHandler( anchor, model, flag );
}

public ClassLoader createClassLoader(
@@ -169,10 +169,10 @@
* @param context the managed context
* @return the runtime handler
*/
- ComponentHandler createComponentHandler(
+ DefaultComponentHandler createDefaultComponentHandler(
ClassLoader anchor, ComponentModel context, boolean flag ) throws
ControlException
{
- return createComponentHandler( null, anchor, context, flag );
+ return createDefaultComponentHandler( null, anchor, context, flag );
}

/**
@@ -182,7 +182,7 @@
* @param context the managed context
* @return the runtime handler
*/
- ComponentHandler createComponentHandler(
+ DefaultComponentHandler createDefaultComponentHandler(
Component parent, ClassLoader anchor, ComponentModel context, boolean
flag )
throws ControlException
{
@@ -193,7 +193,7 @@
Logger logger = new StandardLogger( path.substring( 1 ).replace(
'/', '.' ) );
final ClassLoaderDirective directive =
context.getClassLoaderDirective();
ClassLoader classloader = createClassLoader( anchor, directive,
name );
- return new ComponentHandler( parent, classloader, logger, this,
context, flag );
+ return new DefaultComponentHandler( parent, classloader, logger,
this, context, flag );
}
catch( RemoteException e )
{
@@ -205,7 +205,7 @@

Object createInstance( DefaultProvider provider ) throws
ControlException, InvocationTargetException
{
- ComponentHandler handler = provider.getComponentHandler();
+ DefaultComponentHandler handler =
provider.getDefaultComponentHandler();
Class subject = handler.getImplementationClass();
Constructor constructor = getConstructor( subject );
Class parts = getPartsClass( subject );
@@ -328,12 +328,12 @@
}
}

- File getWorkDirectory( ComponentHandler handler )
+ File getWorkDirectory( DefaultComponentHandler handler )
{
return m_controller.getControllerContext().getWorkingDirectory();
}

- File getTempDirectory( ComponentHandler handler )
+ File getTempDirectory( DefaultComponentHandler handler )
{
return m_controller.getControllerContext().getTempDirectory();
}
@@ -346,7 +346,7 @@
* @exception ControlException if an error occurs while attempting to
load a
* declared service class
*/
- DefaultService[] loadServices( ComponentHandler handler ) throws
ControlException
+ DefaultService[] loadServices( DefaultComponentHandler handler ) throws
ControlException
{
Type type = handler.getType();
ClassLoader classloader = handler.getClassLoader();
@@ -465,7 +465,7 @@
Class clazz = getInnerClass( subject, "$Parts" );
if( null == clazz )
{
- return PartsManager.class;
+ return ComponentManager.class;
}
else
{
@@ -493,7 +493,7 @@
return null;
}

- private Object createParametersArgument( ComponentHandler handler )
throws ControlException
+ private Object createParametersArgument( DefaultComponentHandler handler
) throws ControlException
{
try
{
@@ -511,7 +511,7 @@
}
}

- private Object createConfigurationArgument( ComponentHandler handler )
throws ControlException
+ private Object createConfigurationArgument( DefaultComponentHandler
handler ) throws ControlException
{
try
{
@@ -546,10 +546,10 @@
}
}

- private Object createPartsInvocationHandler( ComponentHandler handler,
Class clazz )
+ private Object createPartsInvocationHandler( DefaultComponentHandler
handler, Class clazz )
throws ControlException
{
- DefaultPartsManager manager = handler.getPartsManager();
+ DefaultComponentManager manager = handler.getComponentManager();
try
{
InvocationHandler invocationHandler = new
PartsInvocationHandler( manager );
@@ -564,13 +564,13 @@
}
}

- String getPathForLogger( ComponentHandler handler )
+ String getPathForLogger( DefaultComponentHandler handler )
{
String path = handler.getPath();
return path.substring( 1 ).replace( '/', '.' );
}

- Object getContextValue( ComponentHandler handler, String key ) throws
ControlException
+ Object getContextValue( DefaultComponentHandler handler, String key )
throws ControlException
{
try
{
@@ -706,7 +706,7 @@
}
}

- private Object executeLookup( ComponentHandler handler, DefaultService
service )
+ private Object executeLookup( DefaultComponentHandler handler,
DefaultService service )
throws Exception
{
Component parent = handler.getParentHandler();
@@ -770,7 +770,7 @@
}

private DefaultService loadService(
- ComponentHandler handler, ServiceDescriptor service ) throws
ControlException
+ DefaultComponentHandler handler, ServiceDescriptor service ) throws
ControlException
{
ClassLoader classloader = handler.getClassLoader();
final String classname = service.getClassname();

Deleted:
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-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ComponentHandler.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -1,1042 +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.io.File;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URI;
-import java.rmi.RemoteException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.EventObject;
-import java.util.Map;
-import java.util.Hashtable;
-import java.util.WeakHashMap;
-import java.util.logging.Level;
-
-import net.dpml.metro.info.Type;
-import net.dpml.metro.info.LifestylePolicy;
-import net.dpml.metro.info.CollectionPolicy;
-import net.dpml.metro.info.Priority;
-import net.dpml.metro.data.CategoryDirective;
-import net.dpml.metro.model.ComponentModel;
-import net.dpml.metro.control.Handler;
-
-import net.dpml.logging.Logger;
-
-import net.dpml.part.ActivationPolicy;
-import net.dpml.part.Disposable;
-import net.dpml.part.ControlException;
-import net.dpml.part.Version;
-import net.dpml.part.ServiceNotFoundException;
-import net.dpml.part.remote.Component;
-import net.dpml.part.remote.Provider;
-import net.dpml.part.remote.Service;
-import net.dpml.part.remote.ModelEvent;
-import net.dpml.part.remote.ModelListener;
-
-import net.dpml.lang.UnknownKeyException;
-
-import net.dpml.state.State;
-
-/**
- * <p>Runtime handler for a component. The component handler maintains an
internal
- * map of all instances derived from the component model based on the
LifestylePolicy
- * declared by the model. If the lifestyle policy is <tt>SINGLETON</tt>
- * a single instance is shared between all concurrent requests. If the
policy is
- * <tt>TRANSIENT</tt> (the default) a new instance is created per request.
- * If the policy is <tt>THREAD</tt> and single instance is created per
- * thread. In all cases, the lifetime of a supplied instance is a function
of the collection
- * policy declared by the component model. For <tt>SINGLETON</tt> models
the collection
- * policies of <tt>HARD</tt>, <tt>SOFT</tt> and <tt>WEAK</tt> are rigorously
respected.
- * Components employing a <tt>THREAD</tt> lifestle policy are will be
referenced under a
- * weak reference to a thread local valiable containing a <tt>HARD</tt>,
<tt>SOFT</tt> or
- * <tt>WEAK</tt> reference to the component instance. For transient
lifestyles, the
- * implementation employs a WeakHashMap irrespective of the declared
collection policy in
- * order to avoid potential memory leaks arrising from non-disposal of
consumed instances.
- * If a component model declares an activation policy of <tt>STARTUP</tt> a
new
- * {@link Provider} will be deloyed on activation of the handler otherwise
the component
- * will be deloyed on <tt>DEMAND</tt> in response to a service request.</p>
- *
- * <p><image src="doc-files/composition-handler-uml.png" border="0"/></p>
- *
- * <p>A component handler is created using a part handler and component
model. The
- * following example demonstrates the creation of a component model using a
part-based
- * deployment template which in-turn is supplied as an argument when
creating a new
- * component handler. Separation of context and handler creation enables
the creation
- * and management of a component model in a separate JVM from the runtime
handler and
- * centralization of shared context information across multiple handlers.</p>
- * <pre>
- Controller controller = Controller.STANDARD; // system controller
- Directive part = controller.loadDirective( uri );
- Context context = controller.createContext( part ); // management info
- Component handler = controller.createComponent( context ); // runtime
controller
- handler.activate();
- Provider instance = handler.getProvider(); // instance controller
- Object value = instance.getValue( true ); // service instance
- * </pre>
- *
- * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
- * @version @PROJECT-VERSION@
- * @see LifestylePolicy
- * @see CollectionPolicy
- * @see ActivationPolicy
- * @see ComponentModel
- * @see Provider
- */
-public class ComponentHandler extends UnicastEventSource implements
Component, Handler, Disposable, ModelListener
-{
-
//--------------------------------------------------------------------------
- // immutable state
-
//--------------------------------------------------------------------------
-
- private final Logger m_logger;
- private final ComponentController m_controller;
- private final ComponentModel m_model;
- private final State m_graph;
- private final ClassLoader m_classloader;
- private final Class m_class;
- private final Type m_type;
- private final DefaultService[] m_services;
- private final String m_path;
- private final URI m_uri;
- private final Holder m_holder;
- private final Component m_parent;
- private final PropertyChangeSupport m_support;
-
- private final Map m_map = new Hashtable(); // symbolic value map
- private final Map m_cache = new Hashtable(); // context entry/value cache
-
- private final DefaultPartsManager m_parts;
- private final boolean m_flag;
-
-
//--------------------------------------------------------------------------
- // mutable state
-
//--------------------------------------------------------------------------
-
- private boolean m_active = false;
-
-
//--------------------------------------------------------------------------
- // constructor
-
//--------------------------------------------------------------------------
-
- ComponentHandler(
- final Component parent, final ClassLoader classloader, final Logger
logger,
- final ComponentController control, final ComponentModel model, boolean
flag )
- throws RemoteException, ControlException
- {
- super( logger );
-
- m_parent = parent;
- m_classloader = classloader;
- m_logger = logger;
- m_controller = control;
- m_model = model;
- m_path = model.getContextPath();
- m_flag = flag;
-
- m_support = new PropertyChangeSupport( this );
- model.addModelListener( this );
-
- String classname = model.getImplementationClassName();
- try
- {
- m_class = control.loadComponentClass( classloader, classname );
- }
- catch( ControlException e )
- {
- final String error =
- "Unable to load component class: "
- + classname;
- throw new ControllerException( error, e );
- }
-
- try
- {
- m_type = control.loadType( m_class );
- }
- catch( ControlException e )
- {
- final String error =
- "Unable to load component type: "
- + classname;
- throw new ControllerException( error, e );
- }
-
- m_graph = m_type.getStateGraph();
-
- try
- {
- m_services = control.loadServices( this );
- }
- catch( ControlException e )
- {
- final String error =
- "Unable to load a service class declared in component type: "
- + classname;
- throw new ControllerException( error, e );
- }
-
- try
- {
- m_uri = new URI( "component:" + m_path );
- }
- catch( Throwable e )
- {
- final String error =
- "Internal error while attempting to construct the component
uri using the path ["
- + m_path + "]";
- throw new ControllerException( error, e );
- }
-
- String name = model.getName();
- File work = control.getWorkDirectory( this );
- File temp = control.getTempDirectory( this );
- m_map.put( "name", name );
- m_map.put( "path", m_path );
- m_map.put( "work", work.toString() );
- m_map.put( "temp", temp.toString() );
- m_map.put( "uri", m_uri.toASCIIString() );
-
- LifestylePolicy lifestyle = model.getLifestylePolicy();
- if( lifestyle.equals( LifestylePolicy.SINGLETON ) )
- {
- m_holder = new SingletonHolder();
- }
- else if( lifestyle.equals( LifestylePolicy.TRANSIENT ) )
- {
- m_holder = new TransientHolder();
- }
- else if( lifestyle.equals( LifestylePolicy.THREAD ) )
- {
- m_holder = new ThreadHolder();
- }
- else
- {
- final String error =
- "Unsuppported lifestyle policy: " + lifestyle;
- throw new UnsupportedOperationException( error );
- }
-
- // At this point the component handler is fully established with
respect to
- // its own logic as a simple component. Before completing
initialization we
- // need to establish all of the component parts that are children of
this
- // component.
-
- m_parts = new DefaultPartsManager( control, this, logger );
-
- getLogger().debug( "component controller [" + this + "] established"
);
- }
-
-
//--------------------------------------------------------------------------
- // ModelListener
-
//--------------------------------------------------------------------------
-
- /**
- * Notification from the component model of a change to the model.
- * @param event the model change event
- */
- public void modelChanged( ModelEvent event )
- {
- String feature = event.getFeature();
- Object oldValue = event.getOldValue();
- Object newValue = event.getNewValue();
- m_support.firePropertyChange( feature, oldValue, newValue );
- }
-
-
//--------------------------------------------------------------------------
- // Handler
-
//--------------------------------------------------------------------------
-
- /**
- * Return a mutable context map.
- *
- * @return the context map
- */
- public Map getContextMap()
- {
- return m_cache;
- }
-
- /**
- * Return an <tt>Provider</tt> holder. The value returned will be a
function
- * of the lifestyle policy implemented by the component.
- *
- * @return the <tt>Provider</tt>
- * @exception InvocationTargetException if the request triggers the
construction
- * of a new provider instance and the provider raises an error during
creation
- * or activation
- * @exception ControlException if a control related error occurs
- */
- public Provider getProvider() throws InvocationTargetException,
ControlException
- {
- activate();
- return m_holder.getProvider();
- }
-
-
//--------------------------------------------------------------------------
- // Component
-
//--------------------------------------------------------------------------
-
- /**
- * Return a mutible context map.
- *
- * @return the context map
- */
- public Map getSymbolMap()
- {
- return m_map;
- }
-
- /**
- * Return a handler capable of supporting the requested service.
- * @param service the service definition
- * @return a component matching the serivce definiton
- * @exception ServiceNotFoundException if no component found
- * @exception RemoteException if a remote exception occurs
- */
- public Component lookup( Service service ) throws
ServiceNotFoundException, RemoteException
- {
- if( getLogger().isDebugEnabled() )
- {
- getLogger().debug(
- "lookup in ["
- + this
- + "] for ["
- + service.getServiceClass().getName()
- + "]." );
- }
-
- Component[] components = m_parts.getComponents();
- //Component[] components = (Component[])
m_handlers.values().toArray( new Component[0] );
- for( int i=0; i<components.length; i++ )
- {
- Component component = components[i];
- if( component.isaCandidate( service ) )
- {
- return component;
- }
- }
- if( m_parent != null )
- {
- return m_parent.lookup( service );
- }
- else
- {
- String classname = service.getServiceClass().getName();
- throw new ServiceNotFoundException(
CompositionController.CONTROLLER_URI, classname );
- }
- }
-
- /**
- * Return the number of instances currently under management. If the
component
- * is a singleton the value returned will be between zero and 1
(depending on the
- * activated status of the handler. If the component is transient, the
instance
- * count will reflect the number of instances currently referenced.
- *
- * @return the instance count.
- */
- public int size()
- {
- return m_holder.getProviderCount();
- }
-
- /**
- * Returns the active status of the handler.
- * @return TRUE if the handler has been activated otherwise FALSE
- */
- public boolean isActive()
- {
- return m_active;
- }
-
- /**
- * Activate the component handler. If the component declares an activate
on
- * startup policy then a new instance will be created and activated.
- *
- * @exception ControlException if an activation error occurs
- * @exception InvocationTargetException if the client component raises an
error
- */
- public synchronized void activate() throws ControlException,
InvocationTargetException
- {
- if( isActive() )
- {
- return;
- }
-
- // setup and subsidiary logging channels declared by the component
type
-
- try
- {
- String path = m_controller.getPathForLogger( this );
- CategoryDirective[] categories = m_model.getCategoryDirectives();
- for( int i=0; i<categories.length; i++ )
- {
- CategoryDirective category = categories[i];
- String spec = path + "." + category.getName();
- java.util.logging.Logger log =
java.util.logging.Logger.getLogger( spec );
- Priority priority = category.getPriority();
- if( null != priority )
- {
- if( Priority.ERROR.equals( priority ) )
- {
- log.setLevel( Level.SEVERE );
- }
- else if( Priority.WARN.equals( priority ) )
- {
- log.setLevel( Level.WARNING );
- }
- else if( Priority.INFO.equals( priority ) )
- {
- log.setLevel( Level.INFO );
- }
- else if( Priority.DEBUG.equals( priority ) )
- {
- log.setLevel( Level.FINE );
- }
- }
-
- // TODO: set category target
-
- }
- }
- catch( RemoteException e )
- {
- final String error =
- "Remote exception raised while attempting to access component
logging categories.";
- throw new ControllerException( error, e );
- }
-
- try
- {
- if( m_model.getActivationPolicy().equals(
ActivationPolicy.STARTUP ) )
- {
- getLogger().debug( "activating" );
- m_holder.getProvider();
- }
-
- m_parts.commission();
- m_active = true;
- }
- catch( RemoteException e )
- {
- getLogger().warn( "activation failed due to a remote exception",
e );
- deactivate();
- final String error =
- "Remote exception raised while attempting to access component
activation policy.";
- throw new ControllerException( error, e );
- }
- catch( ControlException e )
- {
- getLogger().warn( "activation failed due to a control
exception", e );
- deactivate();
- throw e;
- }
- catch( InvocationTargetException e )
- {
- getLogger().warn( "activation failed due to a client initated
invocation exception", e );
- deactivate();
- throw e;
- }
- catch( Throwable e )
- {
- getLogger().warn( "activation failed due to a unexpected
exception", e );
- deactivate();
- }
- finally
- {
- if( !m_active )
- {
- getLogger().warn( "activation failed" );
- deactivate();
- }
- }
- }
-
- /**
- * Deactivate the component.
- */
- public synchronized void deactivate()
- {
- if( !isActive() )
- {
- return;
- }
-
- getLogger().debug( "deactivating" );
-
- //
- // dispose of all of the instances managed by this component
- //
-
- m_holder.dispose();
-
- //
- // deactivate all of the subsidiary components
- //
-
- m_parts.decommission();
-
- m_active = false;
- }
-
- /**
- * Return the array of services provider by the handler.
- * @return the service array
- */
- public Service[] getServices()
- {
- return m_services;
- }
-
- /**
- * Return true if this handler is a candidate for the supplied service
definition.
- * @param service the service definition
- * @return true if this is a candidate
- * @exception RemoteException if a remote exception occurs
- */
- public boolean isaCandidate( Service service ) throws RemoteException
- {
- Class clazz = service.getServiceClass();
- Version version = service.getVersion();
- DefaultService[] services = m_services;
- for( int i=0; i<services.length; i++ )
- {
- DefaultService s = services[i];
- Version v = s.getVersion();
- Class c = s.getServiceClass();
- if( v.complies( version ) && clazz.isAssignableFrom( c ) )
- {
- return true;
- }
- }
- return false;
- }
-
-
//--------------------------------------------------------------------------
- // EventProducer
-
//--------------------------------------------------------------------------
-
- /**
- * Process the supplied event.
- * @param event the event object
- */
- protected void processEvent( EventObject event )
- {
- // TODO
- }
-
-
//--------------------------------------------------------------------------
- // ComponentHandler
-
//--------------------------------------------------------------------------
-
- DefaultPartsManager getPartsManager()
- {
- return m_parts;
- }
-
- /**
- * Add a property change listener. This method is used by a provider
- * to register a component implement property change listener. The
component
- * handler is responsible for the propergation of context change events
- * to the registered listeners.
- * @param listener the propery change listener
- */
- void addPropertyChangeListener( PropertyChangeListener listener )
- {
- m_support.addPropertyChangeListener( listener );
- }
-
- /**
- * Remove a property change listener.
- * @param listener the propery change listener
- */
- void removePropertyChangeListener( PropertyChangeListener listener )
- {
- m_support.removePropertyChangeListener( listener );
- }
-
- /**
- * Dispose of the component handler.
- */
- public void dispose()
- {
- synchronized( getLock() )
- {
- getLogger().debug( "disposal" );
- m_holder.dispose();
- if( m_flag )
- {
- if( m_model instanceof Disposable )
- {
- Disposable disposable = (Disposable) m_model;
- disposable.dispose();
- }
- }
- super.dispose();
- }
- }
-
- /**
- * Return a subsidiary component.
- * @param key the subsidiary component key
- * @return the subsidiary component
- * @exception UnknownKeyException if the key does not match
- * any of the internal components managed by this component
- */
- Component getPartHandler( String key ) throws UnknownKeyException
- {
- Handler handler = m_parts.getComponentHandler( key );
- if( handler instanceof Component )
- {
- return (Component) handler;
- }
- else
- {
- final String error =
- "Component handler ["
- + handler.getClass().getName()
- + "] does not implement the component interface.";
- throw new ControllerRuntimeException( error );
- }
- }
-
- Object getContextValue( String key ) throws ControlException
- {
- return m_controller.getContextValue( this, key );
- }
-
- State getStateGraph()
- {
- return m_graph;
- }
-
- Class getImplementationClass()
- {
- return m_class;
- }
-
- ClassLoader getClassLoader()
- {
- return m_classloader;
- }
-
- Component getParentHandler()
- {
- return m_parent;
- }
-
- /**
- * Returns the component type.
- * @return the type descriptor
- */
- Type getType()
- {
- return m_type;
- }
-
- String getPath()
- {
- return m_path;
- }
-
- ComponentModel getComponentModel()
- {
- return m_model;
- }
-
- Object createNewObject( DefaultProvider provider ) throws
ControlException, InvocationTargetException
- {
- return m_controller.createInstance( provider );
- }
-
- Class[] getServiceClassArray()
- {
- Class[] classes = new Class[ m_services.length ];
- for( int i=0; i<classes.length; i++ )
- {
- classes[i] = m_services[i].getServiceClass();
- }
- return classes;
- }
-
-
//--------------------------------------------------------------------------
- // Object
-
//--------------------------------------------------------------------------
-
- /**
- * Return a string representation of this component.
- * @return the string value
- */
- public String toString()
- {
- try
- {
- return "component:" + m_path + " (" +
m_model.getImplementationClassName() + ")";
- }
- catch( RemoteException e )
- {
- return "component:" + getClass().getName();
- }
- }
-
-
//--------------------------------------------------------------------------
- // utilities
-
//--------------------------------------------------------------------------
-
- /**
- * Apply best efforts to construct a fully validated activated instance
holder.
- * @return the instance holder
- * @exception ControlException if the construction of the instance was
not successfull
- * @exception InvocationTargetException if a error was raised by the
external implementation
- */
- private DefaultProvider createDefaultProvider()
- throws InvocationTargetException, ControlException
- {
- try
- {
- return new DefaultProvider( this, getLogger() );
- }
- catch( RemoteException e )
- {
- final String error =
- "Unable to create instance holder due to a remote exception.";
- throw new ControllerException( error, e );
- }
- }
-
- /**
- * Abstract holder class that serves as the base class for holders dealing
- * with variouse lifestyle policies.
- */
- private abstract class Holder
- {
- private boolean m_disposed = false;
-
- /**
- * Return an <tt>I(nstance</tt> taking into account the component
- * lifestyle policy.
- * @return the <tt>Provider</tt> manager
- * @exception ControlException of a controller error occurs
- * @exception InvocationTargetException if a client implementation
error occurs
- */
- abstract DefaultProvider getProvider() throws ControlException,
InvocationTargetException;
-
- /**
- * Return the number of instances handled by the holder.
- * @return the instance count
- */
- abstract int getProviderCount();
-
- /**
- * Dispose of the holder and all managed instances.
- */
- void dispose()
- {
- if( isDisposed() )
- {
- return;
- }
- else
- {
- m_disposed = true;
- }
- }
-
- /**
- * Return the disposed state of the holder.
- */
- boolean isDisposed()
- {
- return m_disposed;
- }
- }
-
- /**
- * Singleton holder class. The singleton holder mains a single
- * <tt>Provider</tt> of a component relative to the component model
- * identity within the scope of the controller. References to the
- * singleton instance will be shared across mutliple threads.
- */
- private class SingletonHolder extends Holder
- {
- private Reference m_reference;
-
- /**
- * Creation of a new singleton holder.
- */
- SingletonHolder()
- {
- m_reference = createReference( null );
- }
-
- DefaultProvider getProvider() throws ControlException,
InvocationTargetException
- {
- if( m_reference == null )
- {
- throw new IllegalStateException( "disposed" );
- }
-
- DefaultProvider instance = (DefaultProvider) m_reference.get();
- if( null == instance )
- {
- instance = createDefaultProvider();
- m_reference = createReference( instance );
- return instance;
- }
- else
- {
- return instance;
- }
- }
-
- void dispose()
- {
- if( !isDisposed() )
- {
- DefaultProvider instance = (DefaultProvider)
m_reference.get();
- if( instance != null )
- {
- instance.dispose();
- }
- m_reference.clear();
- super.dispose();
- }
- }
-
- int getProviderCount()
- {
- if( null != m_reference.get() )
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- }
-
- /**
- * Transient holder class. The transient holder provides support for
- * the transient lifestyle ensuing the creation of a new <tt>Provider</tt>
- * per request.
- */
- private class TransientHolder extends Holder
- {
- private WeakHashMap m_instances = new WeakHashMap(); // transients
-
- DefaultProvider getProvider() throws ControlException,
InvocationTargetException
- {
- DefaultProvider instance = createDefaultProvider();
- m_instances.put( instance, null );
- return instance;
- }
-
- void dispose()
- {
- if( !isDisposed() )
- {
- DefaultProvider[] instances = getAllProviders();
- for( int i=0; i<instances.length; i++ )
- {
- DefaultProvider instance = instances[i];
- m_instances.remove( instance );
- instance.dispose();
- }
- super.dispose();
- }
- }
-
- int getProviderCount()
- {
- return m_instances.size();
- }
-
- private DefaultProvider[] getAllProviders()
- {
- return (DefaultProvider[]) m_instances.keySet().toArray( new
DefaultProvider[0] );
- }
- }
-
- /**
- * The ThreadHolder class provides support for the per-thread lifestyle
- * policy within which new <tt>Provider</tt> creation is based on a single
- * <tt>Provider</tt> per thread.
- */
- private class ThreadHolder extends Holder
- {
- private ThreadLocalHolder m_threadLocalHolder = new
ThreadLocalHolder();
-
- DefaultProvider getProvider() throws ControlException,
InvocationTargetException
- {
- return (DefaultProvider) m_threadLocalHolder.get();
- }
-
- void dispose()
- {
- if( !isDisposed() )
- {
- m_threadLocalHolder.dispose();
- super.dispose();
- }
- }
-
- int getProviderCount()
- {
- return m_threadLocalHolder.getProviderCount();
- }
-
- private DefaultProvider[] getAllProviders()
- {
- return m_threadLocalHolder.getAllProviders();
- }
- }
-
- /**
- * Internal thread local holder for the per-thread lifestyle holder.
- */
- private class ThreadLocalHolder extends ThreadLocal
- {
- private WeakHashMap m_instances = new WeakHashMap(); // per thread
instances
-
- protected Object initialValue()
- {
- try
- {
- DefaultProvider instance = createDefaultProvider();
- m_instances.put( instance, null );
- return instance;
- }
- catch( Exception e )
- {
- final String error =
- "Per-thread lifestyle policy handler encountered an error
while attempting to establish instance.";
- throw new ControllerRuntimeException( error, e );
- }
- }
-
- int getProviderCount()
- {
- return m_instances.size();
- }
-
- DefaultProvider[] getAllProviders()
- {
- return (DefaultProvider[]) m_instances.keySet().toArray( new
DefaultProvider[0] );
- }
-
- void dispose()
- {
- DefaultProvider[] instances = getAllProviders();
- for( int i=0; i<instances.length; i++ )
- {
- DefaultProvider instance = instances[i];
- instance.dispose();
- m_instances.remove( instance );
- }
- }
- }
-
- /**
- * Constructs a reference that reflects the component cololection policy.
- * @param object the initial reference value
- * @return the reference
- */
- private Reference createReference( Object object )
- {
- //
- // if this is a top-level component then set the collection policy
- // to hard otherwise we'll loose the instance because nothing is
- // referencing it directly
- //
-
- try
- {
- CollectionPolicy policy = m_model.getCollectionPolicy();
-
- //
- // if an explicit collection policy is defined then apply it now
- // otherwise use SOFT collection as the SYSTEM default
- //
-
- if( policy.equals( CollectionPolicy.SYSTEM ) )
- {
- if( null == m_parent )
- {
- return new HardReference( object );
- }
- else
- {
- return new SoftReference( object );
- }
- }
- else if( policy.equals( CollectionPolicy.SOFT ) )
- {
- return new SoftReference( object );
- }
- else if( policy.equals( CollectionPolicy.WEAK ) )
- {
- return new WeakReference( object );
- }
- else
- {
- return new HardReference( object );
- }
- }
- catch( RemoteException e )
- {
- final String error =
- "Reference object creating failure due to a remote exception.";
- throw new ControllerRuntimeException( error, e );
- }
- }
-
- /**
- * A reference class that implements hard reference semantics.
- */
- private static class HardReference extends SoftReference
- {
- private Object m_referent;
-
- /**
- * Creation of a new hard reference.
- * @param referent the referenced object
- */
- public HardReference( Object referent )
- {
- super( referent );
- m_referent = referent;
- }
-
- /**
- * Return the referent.
- * @return the referent object
- */
- public Object get()
- {
- return m_referent;
- }
- }
-}

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-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/CompositionController.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -211,7 +211,7 @@
if( model instanceof ComponentModel )
{
ComponentModel componentModel = (ComponentModel) model;
- return m_controller.createComponentHandler( componentModel, flag
);
+ return m_controller.createDefaultComponentHandler(
componentModel, flag );
}
else
{

Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ContextInvocationHandler.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ContextInvocationHandler.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/ContextInvocationHandler.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -46,7 +46,7 @@
/**
* The component.
*/
- private final ComponentHandler m_handler;
+ private final DefaultComponentHandler m_handler;

//-------------------------------------------------------------------
// constructor
@@ -60,14 +60,14 @@
ContextInvocationHandler( DefaultProvider provider )
{
m_provider = provider;
- m_handler = provider.getComponentHandler();
+ m_handler = provider.getDefaultComponentHandler();
}

//-------------------------------------------------------------------
// implementation
//-------------------------------------------------------------------

- private ComponentHandler getComponentHandler()
+ private DefaultComponentHandler getDefaultComponentHandler()
{
return m_handler;
}
@@ -91,7 +91,7 @@
}
else
{
- ComponentHandler handler = getComponentHandler();
+ DefaultComponentHandler handler = getDefaultComponentHandler();
String name = method.getName();
if( name.startsWith( "get" ) )
{

Copied:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultComponentHandler.java
(from rev 969,
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-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultComponentHandler.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -0,0 +1,1046 @@
+/*
+ * 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.io.File;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.rmi.RemoteException;
+import java.rmi.NoSuchObjectException;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.EventObject;
+import java.util.Map;
+import java.util.Hashtable;
+import java.util.WeakHashMap;
+import java.util.logging.Level;
+
+import net.dpml.metro.info.Type;
+import net.dpml.metro.info.LifestylePolicy;
+import net.dpml.metro.info.CollectionPolicy;
+import net.dpml.metro.info.Priority;
+import net.dpml.metro.data.CategoryDirective;
+import net.dpml.metro.model.ComponentModel;
+import net.dpml.metro.control.ComponentHandler;
+
+import net.dpml.logging.Logger;
+
+import net.dpml.part.ActivationPolicy;
+import net.dpml.part.Disposable;
+import net.dpml.part.ControlException;
+import net.dpml.part.Version;
+import net.dpml.part.ServiceNotFoundException;
+import net.dpml.part.remote.Component;
+import net.dpml.part.remote.Provider;
+import net.dpml.part.remote.Service;
+import net.dpml.part.remote.ModelEvent;
+import net.dpml.part.remote.ModelListener;
+
+import net.dpml.lang.UnknownKeyException;
+
+import net.dpml.state.State;
+
+/**
+ * <p>Runtime handler for a component. The component handler maintains an
internal
+ * map of all instances derived from the component model based on the
LifestylePolicy
+ * declared by the model. If the lifestyle policy is <tt>SINGLETON</tt>
+ * a single instance is shared between all concurrent requests. If the
policy is
+ * <tt>TRANSIENT</tt> (the default) a new instance is created per request.
+ * If the policy is <tt>THREAD</tt> and single instance is created per
+ * thread. In all cases, the lifetime of a supplied instance is a function
of the collection
+ * policy declared by the component model. For <tt>SINGLETON</tt> models
the collection
+ * policies of <tt>HARD</tt>, <tt>SOFT</tt> and <tt>WEAK</tt> are rigorously
respected.
+ * Components employing a <tt>THREAD</tt> lifestle policy are will be
referenced under a
+ * weak reference to a thread local valiable containing a <tt>HARD</tt>,
<tt>SOFT</tt> or
+ * <tt>WEAK</tt> reference to the component instance. For transient
lifestyles, the
+ * implementation employs a WeakHashMap irrespective of the declared
collection policy in
+ * order to avoid potential memory leaks arrising from non-disposal of
consumed instances.
+ * If a component model declares an activation policy of <tt>STARTUP</tt> a
new
+ * {@link Provider} will be deloyed on activation of the handler otherwise
the component
+ * will be deloyed on <tt>DEMAND</tt> in response to a service request.</p>
+ *
+ * <p><image src="doc-files/composition-handler-uml.png" border="0"/></p>
+ *
+ * <p>A component handler is created using a part handler and component
model. The
+ * following example demonstrates the creation of a component model using a
part-based
+ * deployment template which in-turn is supplied as an argument when
creating a new
+ * component handler. Separation of context and handler creation enables
the creation
+ * and management of a component model in a separate JVM from the runtime
handler and
+ * centralization of shared context information across multiple handlers.</p>
+ * <pre>
+ Controller controller = Controller.STANDARD; // system controller
+ Directive part = controller.loadDirective( uri );
+ Context context = controller.createContext( part ); // management info
+ Component handler = controller.createComponent( context ); // runtime
controller
+ handler.activate();
+ Provider instance = handler.getProvider(); // instance controller
+ Object value = instance.getValue( true ); // service instance
+ * </pre>
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ * @see LifestylePolicy
+ * @see CollectionPolicy
+ * @see ActivationPolicy
+ * @see ComponentModel
+ * @see Provider
+ */
+public class DefaultComponentHandler extends UnicastEventSource implements
Component, ComponentHandler, Disposable, ModelListener
+{
+
//--------------------------------------------------------------------------
+ // immutable state
+
//--------------------------------------------------------------------------
+
+ private final Logger m_logger;
+ private final ComponentController m_controller;
+ private final ComponentModel m_model;
+ private final State m_graph;
+ private final ClassLoader m_classloader;
+ private final Class m_class;
+ private final Type m_type;
+ private final DefaultService[] m_services;
+ private final String m_path;
+ private final URI m_uri;
+ private final Holder m_holder;
+ private final Component m_parent;
+ private final PropertyChangeSupport m_support;
+
+ private final Map m_map = new Hashtable(); // symbolic value map
+ private final Map m_cache = new Hashtable(); // context entry/value cache
+
+ private final DefaultComponentManager m_parts;
+ private final boolean m_flag;
+
+
//--------------------------------------------------------------------------
+ // mutable state
+
//--------------------------------------------------------------------------
+
+ private boolean m_active = false;
+
+
//--------------------------------------------------------------------------
+ // constructor
+
//--------------------------------------------------------------------------
+
+ DefaultComponentHandler(
+ final Component parent, final ClassLoader classloader, final Logger
logger,
+ final ComponentController control, final ComponentModel model, boolean
flag )
+ throws RemoteException, ControlException
+ {
+ super( logger );
+
+ m_parent = parent;
+ m_classloader = classloader;
+ m_logger = logger;
+ m_controller = control;
+ m_model = model;
+ m_path = model.getContextPath();
+ m_flag = flag;
+
+ m_support = new PropertyChangeSupport( this );
+ model.addModelListener( this );
+
+ String classname = model.getImplementationClassName();
+ try
+ {
+ m_class = control.loadComponentClass( classloader, classname );
+ }
+ catch( ControlException e )
+ {
+ final String error =
+ "Unable to load component class: "
+ + classname;
+ throw new ControllerException( error, e );
+ }
+
+ try
+ {
+ m_type = control.loadType( m_class );
+ }
+ catch( ControlException e )
+ {
+ final String error =
+ "Unable to load component type: "
+ + classname;
+ throw new ControllerException( error, e );
+ }
+
+ m_graph = m_type.getStateGraph();
+
+ try
+ {
+ m_services = control.loadServices( this );
+ }
+ catch( ControlException e )
+ {
+ final String error =
+ "Unable to load a service class declared in component type: "
+ + classname;
+ throw new ControllerException( error, e );
+ }
+
+ try
+ {
+ m_uri = new URI( "component:" + m_path );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Internal error while attempting to construct the component
uri using the path ["
+ + m_path + "]";
+ throw new ControllerException( error, e );
+ }
+
+ String name = model.getName();
+ File work = control.getWorkDirectory( this );
+ File temp = control.getTempDirectory( this );
+ m_map.put( "name", name );
+ m_map.put( "path", m_path );
+ m_map.put( "work", work.toString() );
+ m_map.put( "temp", temp.toString() );
+ m_map.put( "uri", m_uri.toASCIIString() );
+
+ LifestylePolicy lifestyle = model.getLifestylePolicy();
+ if( lifestyle.equals( LifestylePolicy.SINGLETON ) )
+ {
+ m_holder = new SingletonHolder();
+ }
+ else if( lifestyle.equals( LifestylePolicy.TRANSIENT ) )
+ {
+ m_holder = new TransientHolder();
+ }
+ else if( lifestyle.equals( LifestylePolicy.THREAD ) )
+ {
+ m_holder = new ThreadHolder();
+ }
+ else
+ {
+ final String error =
+ "Unsuppported lifestyle policy: " + lifestyle;
+ throw new UnsupportedOperationException( error );
+ }
+
+ // At this point the component handler is fully established with
respect to
+ // its own logic as a simple component. Before completing
initialization we
+ // need to establish all of the component parts that are children of
this
+ // component.
+
+ m_parts = new DefaultComponentManager( control, this, logger );
+
+ getLogger().debug( "component controller [" + this + "] established"
);
+ }
+
+
//--------------------------------------------------------------------------
+ // ModelListener
+
//--------------------------------------------------------------------------
+
+ /**
+ * Notification from the component model of a change to the model.
+ * @param event the model change event
+ */
+ public void modelChanged( ModelEvent event )
+ {
+ String feature = event.getFeature();
+ Object oldValue = event.getOldValue();
+ Object newValue = event.getNewValue();
+ m_support.firePropertyChange( feature, oldValue, newValue );
+ }
+
+
//--------------------------------------------------------------------------
+ // ComponentHandler
+
//--------------------------------------------------------------------------
+
+ /**
+ * Return a mutable context map.
+ *
+ * @return the context map
+ */
+ public Map getContextMap()
+ {
+ return m_cache;
+ }
+
+ /**
+ * Return an <tt>Provider</tt> holder. The value returned will be a
function
+ * of the lifestyle policy implemented by the component.
+ *
+ * @return the <tt>Provider</tt>
+ * @exception InvocationTargetException if the request triggers the
construction
+ * of a new provider instance and the provider raises an error during
creation
+ * or activation
+ * @exception ControlException if a control related error occurs
+ */
+ public Provider getProvider() throws InvocationTargetException,
ControlException
+ {
+ activate();
+ return m_holder.getProvider();
+ }
+
+ /**
+ * Return the component model assiged to the handler.
+ * @return the component model
+ */
+ public ComponentModel getComponentModel()
+ {
+ return m_model;
+ }
+
+
//--------------------------------------------------------------------------
+ // Component
+
//--------------------------------------------------------------------------
+
+ /**
+ * Return a mutible context map.
+ *
+ * @return the context map
+ */
+ public Map getSymbolMap()
+ {
+ return m_map;
+ }
+
+ /**
+ * Return a handler capable of supporting the requested service.
+ * @param service the service definition
+ * @return a component matching the serivce definiton
+ * @exception ServiceNotFoundException if no component found
+ * @exception RemoteException if a remote exception occurs
+ */
+ public Component lookup( Service service ) throws
ServiceNotFoundException, RemoteException
+ {
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug(
+ "lookup in ["
+ + this
+ + "] for ["
+ + service.getServiceClass().getName()
+ + "]." );
+ }
+
+ Component[] components = m_parts.getComponents();
+ for( int i=0; i<components.length; i++ )
+ {
+ Component component = components[i];
+ if( component.isaCandidate( service ) )
+ {
+ return component;
+ }
+ }
+ if( m_parent != null )
+ {
+ return m_parent.lookup( service );
+ }
+ else
+ {
+ String classname = service.getServiceClass().getName();
+ throw new ServiceNotFoundException(
CompositionController.CONTROLLER_URI, classname );
+ }
+ }
+
+ /**
+ * Return the number of instances currently under management. If the
component
+ * is a singleton the value returned will be between zero and 1
(depending on the
+ * activated status of the handler. If the component is transient, the
instance
+ * count will reflect the number of instances currently referenced.
+ *
+ * @return the instance count.
+ */
+ public int size()
+ {
+ return m_holder.getProviderCount();
+ }
+
+ /**
+ * Returns the active status of the handler.
+ * @return TRUE if the handler has been activated otherwise FALSE
+ */
+ public boolean isActive()
+ {
+ return m_active;
+ }
+
+ /**
+ * Activate the component handler. If the component declares an activate
on
+ * startup policy then a new instance will be created and activated.
+ *
+ * @exception ControlException if an activation error occurs
+ * @exception InvocationTargetException if the client component raises an
error
+ */
+ public synchronized void activate() throws ControlException,
InvocationTargetException
+ {
+ if( isActive() )
+ {
+ return;
+ }
+
+ // setup and subsidiary logging channels declared by the component
type
+
+ try
+ {
+ String path = m_controller.getPathForLogger( this );
+ CategoryDirective[] categories = m_model.getCategoryDirectives();
+ for( int i=0; i<categories.length; i++ )
+ {
+ CategoryDirective category = categories[i];
+ String spec = path + "." + category.getName();
+ java.util.logging.Logger log =
java.util.logging.Logger.getLogger( spec );
+ Priority priority = category.getPriority();
+ if( null != priority )
+ {
+ if( Priority.ERROR.equals( priority ) )
+ {
+ log.setLevel( Level.SEVERE );
+ }
+ else if( Priority.WARN.equals( priority ) )
+ {
+ log.setLevel( Level.WARNING );
+ }
+ else if( Priority.INFO.equals( priority ) )
+ {
+ log.setLevel( Level.INFO );
+ }
+ else if( Priority.DEBUG.equals( priority ) )
+ {
+ log.setLevel( Level.FINE );
+ }
+ }
+
+ // TODO: set category target
+
+ }
+ }
+ catch( RemoteException e )
+ {
+ final String error =
+ "Remote exception raised while attempting to access component
logging categories.";
+ throw new ControllerException( error, e );
+ }
+
+ try
+ {
+ if( m_model.getActivationPolicy().equals(
ActivationPolicy.STARTUP ) )
+ {
+ getLogger().debug( "activating" );
+ m_holder.getProvider();
+ }
+
+ m_parts.commission();
+ m_active = true;
+ }
+ catch( RemoteException e )
+ {
+ getLogger().warn( "activation failed due to a remote exception",
e );
+ deactivate();
+ final String error =
+ "Remote exception raised while attempting to access component
activation policy.";
+ throw new ControllerException( error, e );
+ }
+ catch( ControlException e )
+ {
+ getLogger().warn( "activation failed due to a control
exception", e );
+ deactivate();
+ throw e;
+ }
+ catch( InvocationTargetException e )
+ {
+ getLogger().warn( "activation failed due to a client initated
invocation exception", e );
+ deactivate();
+ throw e;
+ }
+ catch( Throwable e )
+ {
+ getLogger().warn( "activation failed due to a unexpected
exception", e );
+ deactivate();
+ }
+ finally
+ {
+ if( !m_active )
+ {
+ getLogger().warn( "activation failed" );
+ deactivate();
+ }
+ }
+ }
+
+ /**
+ * Deactivate the component.
+ */
+ public synchronized void deactivate()
+ {
+ if( !isActive() )
+ {
+ return;
+ }
+
+ getLogger().debug( "deactivating" );
+
+ //
+ // dispose of all of the instances managed by this component
+ //
+
+ m_holder.dispose();
+
+ //
+ // deactivate all of the subsidiary components
+ //
+
+ m_parts.decommission();
+
+ m_active = false;
+ }
+
+ /**
+ * Return the array of services provider by the handler.
+ * @return the service array
+ */
+ public Service[] getServices()
+ {
+ return m_services;
+ }
+
+ /**
+ * Return true if this handler is a candidate for the supplied service
definition.
+ * @param service the service definition
+ * @return true if this is a candidate
+ * @exception RemoteException if a remote exception occurs
+ */
+ public boolean isaCandidate( Service service ) throws RemoteException
+ {
+ Class clazz = service.getServiceClass();
+ Version version = service.getVersion();
+ DefaultService[] services = m_services;
+ for( int i=0; i<services.length; i++ )
+ {
+ DefaultService s = services[i];
+ Version v = s.getVersion();
+ Class c = s.getServiceClass();
+ if( v.complies( version ) && clazz.isAssignableFrom( c ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
//--------------------------------------------------------------------------
+ // EventProducer
+
//--------------------------------------------------------------------------
+
+ /**
+ * Process the supplied event.
+ * @param event the event object
+ */
+ protected void processEvent( EventObject event )
+ {
+ // TODO
+ }
+
+
//--------------------------------------------------------------------------
+ // DefaultComponentHandler
+
//--------------------------------------------------------------------------
+
+ DefaultComponentManager getComponentManager()
+ {
+ return m_parts;
+ }
+
+ /**
+ * Add a property change listener. This method is used by a provider
+ * to register a component implement property change listener. The
component
+ * handler is responsible for the propergation of context change events
+ * to the registered listeners.
+ * @param listener the propery change listener
+ */
+ void addPropertyChangeListener( PropertyChangeListener listener )
+ {
+ m_support.addPropertyChangeListener( listener );
+ }
+
+ /**
+ * Remove a property change listener.
+ * @param listener the propery change listener
+ */
+ void removePropertyChangeListener( PropertyChangeListener listener )
+ {
+ m_support.removePropertyChangeListener( listener );
+ }
+
+ /**
+ * Dispose of the component handler.
+ */
+ public void dispose()
+ {
+ synchronized( getLock() )
+ {
+ getLogger().debug( "disposal" );
+ m_holder.dispose();
+ if( m_flag )
+ {
+ if( m_model instanceof Disposable )
+ {
+ Disposable disposable = (Disposable) m_model;
+ disposable.dispose();
+ }
+ }
+ super.dispose();
+ }
+ }
+
+ /**
+ * Return a subsidiary component.
+ * @param key the subsidiary component key
+ * @return the subsidiary component
+ * @exception UnknownKeyException if the key does not match
+ * any of the internal components managed by this component
+ */
+ Component getPartHandler( String key ) throws UnknownKeyException
+ {
+ ComponentHandler handler = m_parts.getComponentHandler( key );
+ if( handler instanceof Component )
+ {
+ return (Component) handler;
+ }
+ else
+ {
+ final String error =
+ "Internal error. Component handler ["
+ + handler
+ + "] is not an instance of "
+ + Component.class.getName();
+ throw new ControllerRuntimeException( error );
+ }
+ }
+
+ Object getContextValue( String key ) throws ControlException
+ {
+ return m_controller.getContextValue( this, key );
+ }
+
+ State getStateGraph()
+ {
+ return m_graph;
+ }
+
+ Class getImplementationClass()
+ {
+ return m_class;
+ }
+
+ ClassLoader getClassLoader()
+ {
+ return m_classloader;
+ }
+
+ Component getParentHandler()
+ {
+ return m_parent;
+ }
+
+ /**
+ * Returns the component type.
+ * @return the type descriptor
+ */
+ Type getType()
+ {
+ return m_type;
+ }
+
+ String getPath()
+ {
+ return m_path;
+ }
+
+ Object createNewObject( DefaultProvider provider ) throws
ControlException, InvocationTargetException
+ {
+ return m_controller.createInstance( provider );
+ }
+
+ Class[] getServiceClassArray()
+ {
+ Class[] classes = new Class[ m_services.length ];
+ for( int i=0; i<classes.length; i++ )
+ {
+ classes[i] = m_services[i].getServiceClass();
+ }
+ return classes;
+ }
+
+
//--------------------------------------------------------------------------
+ // Object
+
//--------------------------------------------------------------------------
+
+ /**
+ * Return a string representation of this component.
+ * @return the string value
+ */
+ public String toString()
+ {
+ try
+ {
+ return "component:" + m_path + " (" +
m_model.getImplementationClassName() + ")";
+ }
+ catch( RemoteException e )
+ {
+ return "component:" + getClass().getName();
+ }
+ }
+
+
//--------------------------------------------------------------------------
+ // utilities
+
//--------------------------------------------------------------------------
+
+ /**
+ * Apply best efforts to construct a fully validated activated instance
holder.
+ * @return the instance holder
+ * @exception ControlException if the construction of the instance was
not successfull
+ * @exception InvocationTargetException if a error was raised by the
external implementation
+ */
+ private DefaultProvider createDefaultProvider()
+ throws InvocationTargetException, ControlException
+ {
+ try
+ {
+ return new DefaultProvider( this, getLogger() );
+ }
+ catch( RemoteException e )
+ {
+ final String error =
+ "Unable to create instance holder due to a remote exception.";
+ throw new ControllerException( error, e );
+ }
+ }
+
+ /**
+ * Abstract holder class that serves as the base class for holders dealing
+ * with variouse lifestyle policies.
+ */
+ private abstract class Holder
+ {
+ private boolean m_disposed = false;
+
+ /**
+ * Return an <tt>I(nstance</tt> taking into account the component
+ * lifestyle policy.
+ * @return the <tt>Provider</tt> manager
+ * @exception ControlException of a controller error occurs
+ * @exception InvocationTargetException if a client implementation
error occurs
+ */
+ abstract DefaultProvider getProvider() throws ControlException,
InvocationTargetException;
+
+ /**
+ * Return the number of instances handled by the holder.
+ * @return the instance count
+ */
+ abstract int getProviderCount();
+
+ /**
+ * Dispose of the holder and all managed instances.
+ */
+ void dispose()
+ {
+ if( isDisposed() )
+ {
+ return;
+ }
+ else
+ {
+ m_disposed = true;
+ }
+ }
+
+ /**
+ * Return the disposed state of the holder.
+ */
+ boolean isDisposed()
+ {
+ return m_disposed;
+ }
+ }
+
+ /**
+ * Singleton holder class. The singleton holder mains a single
+ * <tt>Provider</tt> of a component relative to the component model
+ * identity within the scope of the controller. References to the
+ * singleton instance will be shared across mutliple threads.
+ */
+ private class SingletonHolder extends Holder
+ {
+ private Reference m_reference;
+
+ /**
+ * Creation of a new singleton holder.
+ */
+ SingletonHolder()
+ {
+ m_reference = createReference( null );
+ }
+
+ DefaultProvider getProvider() throws ControlException,
InvocationTargetException
+ {
+ if( m_reference == null )
+ {
+ throw new IllegalStateException( "disposed" );
+ }
+
+ DefaultProvider instance = (DefaultProvider) m_reference.get();
+ if( null == instance )
+ {
+ instance = createDefaultProvider();
+ m_reference = createReference( instance );
+ return instance;
+ }
+ else
+ {
+ return instance;
+ }
+ }
+
+ void dispose()
+ {
+ if( !isDisposed() )
+ {
+ DefaultProvider instance = (DefaultProvider)
m_reference.get();
+ if( instance != null )
+ {
+ instance.dispose();
+ }
+ m_reference.clear();
+ super.dispose();
+ }
+ }
+
+ int getProviderCount()
+ {
+ if( null != m_reference.get() )
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+
+ /**
+ * Transient holder class. The transient holder provides support for
+ * the transient lifestyle ensuing the creation of a new <tt>Provider</tt>
+ * per request.
+ */
+ private class TransientHolder extends Holder
+ {
+ private WeakHashMap m_instances = new WeakHashMap(); // transients
+
+ DefaultProvider getProvider() throws ControlException,
InvocationTargetException
+ {
+ DefaultProvider instance = createDefaultProvider();
+ m_instances.put( instance, null );
+ return instance;
+ }
+
+ void dispose()
+ {
+ if( !isDisposed() )
+ {
+ DefaultProvider[] instances = getAllProviders();
+ for( int i=0; i<instances.length; i++ )
+ {
+ DefaultProvider instance = instances[i];
+ m_instances.remove( instance );
+ instance.dispose();
+ }
+ super.dispose();
+ }
+ }
+
+ int getProviderCount()
+ {
+ return m_instances.size();
+ }
+
+ private DefaultProvider[] getAllProviders()
+ {
+ return (DefaultProvider[]) m_instances.keySet().toArray( new
DefaultProvider[0] );
+ }
+ }
+
+ /**
+ * The ThreadHolder class provides support for the per-thread lifestyle
+ * policy within which new <tt>Provider</tt> creation is based on a single
+ * <tt>Provider</tt> per thread.
+ */
+ private class ThreadHolder extends Holder
+ {
+ private ThreadLocalHolder m_threadLocalHolder = new
ThreadLocalHolder();
+
+ DefaultProvider getProvider() throws ControlException,
InvocationTargetException
+ {
+ return (DefaultProvider) m_threadLocalHolder.get();
+ }
+
+ void dispose()
+ {
+ if( !isDisposed() )
+ {
+ m_threadLocalHolder.dispose();
+ super.dispose();
+ }
+ }
+
+ int getProviderCount()
+ {
+ return m_threadLocalHolder.getProviderCount();
+ }
+
+ private DefaultProvider[] getAllProviders()
+ {
+ return m_threadLocalHolder.getAllProviders();
+ }
+ }
+
+ /**
+ * Internal thread local holder for the per-thread lifestyle holder.
+ */
+ private class ThreadLocalHolder extends ThreadLocal
+ {
+ private WeakHashMap m_instances = new WeakHashMap(); // per thread
instances
+
+ protected Object initialValue()
+ {
+ try
+ {
+ DefaultProvider instance = createDefaultProvider();
+ m_instances.put( instance, null );
+ return instance;
+ }
+ catch( Exception e )
+ {
+ final String error =
+ "Per-thread lifestyle policy handler encountered an error
while attempting to establish instance.";
+ throw new ControllerRuntimeException( error, e );
+ }
+ }
+
+ int getProviderCount()
+ {
+ return m_instances.size();
+ }
+
+ DefaultProvider[] getAllProviders()
+ {
+ return (DefaultProvider[]) m_instances.keySet().toArray( new
DefaultProvider[0] );
+ }
+
+ void dispose()
+ {
+ DefaultProvider[] instances = getAllProviders();
+ for( int i=0; i<instances.length; i++ )
+ {
+ DefaultProvider instance = instances[i];
+ instance.dispose();
+ m_instances.remove( instance );
+ }
+ }
+ }
+
+ /**
+ * Constructs a reference that reflects the component cololection policy.
+ * @param object the initial reference value
+ * @return the reference
+ */
+ private Reference createReference( Object object )
+ {
+ //
+ // if this is a top-level component then set the collection policy
+ // to hard otherwise we'll loose the instance because nothing is
+ // referencing it directly
+ //
+
+ try
+ {
+ CollectionPolicy policy = m_model.getCollectionPolicy();
+
+ //
+ // if an explicit collection policy is defined then apply it now
+ // otherwise use SOFT collection as the SYSTEM default
+ //
+
+ if( policy.equals( CollectionPolicy.SYSTEM ) )
+ {
+ if( null == m_parent )
+ {
+ return new HardReference( object );
+ }
+ else
+ {
+ return new SoftReference( object );
+ }
+ }
+ else if( policy.equals( CollectionPolicy.SOFT ) )
+ {
+ return new SoftReference( object );
+ }
+ else if( policy.equals( CollectionPolicy.WEAK ) )
+ {
+ return new WeakReference( object );
+ }
+ else
+ {
+ return new HardReference( object );
+ }
+ }
+ catch( RemoteException e )
+ {
+ final String error =
+ "Reference object creating failure due to a remote exception.";
+ throw new ControllerRuntimeException( error, e );
+ }
+ }
+
+ /**
+ * A reference class that implements hard reference semantics.
+ */
+ private static class HardReference extends SoftReference
+ {
+ private Object m_referent;
+
+ /**
+ * Creation of a new hard reference.
+ * @param referent the referenced object
+ */
+ public HardReference( Object referent )
+ {
+ super( referent );
+ m_referent = referent;
+ }
+
+ /**
+ * Return the referent.
+ * @return the referent object
+ */
+ public Object get()
+ {
+ return m_referent;
+ }
+ }
+}

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-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultComponentModel.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -33,7 +33,6 @@
import net.dpml.metro.info.Type;
import net.dpml.metro.info.PartReference;
import net.dpml.metro.model.ComponentModel;
-import net.dpml.metro.model.MutableComponentModel;
import net.dpml.metro.model.ContextModel;

import net.dpml.part.Directive;
@@ -60,7 +59,7 @@
* @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
* @version @PROJECT-VERSION@
*/
-class DefaultComponentModel extends UnicastEventSource implements
MutableComponentModel, Configurable
+class DefaultComponentModel extends UnicastEventSource implements
ComponentModel, Configurable
{
//
------------------------------------------------------------------------
// state

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-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultContextModel.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -31,7 +31,7 @@
import net.dpml.metro.info.PartReference;
import net.dpml.metro.info.Type;

-import net.dpml.metro.model.MutableContextModel;
+import net.dpml.metro.model.ContextModel;
import net.dpml.metro.model.ValidationException;
import net.dpml.metro.model.ValidationException.Issue;

@@ -50,7 +50,7 @@
* @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
* @version @PROJECT-VERSION@
*/
-class DefaultContextModel extends UnicastEventSource implements
MutableContextModel
+class DefaultContextModel extends UnicastEventSource implements ContextModel
{
//
------------------------------------------------------------------------
// immutable state

Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultPartsManager.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultPartsManager.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultPartsManager.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -30,8 +30,8 @@
import net.dpml.part.ControlException;
import net.dpml.part.remote.Component;
import net.dpml.part.remote.Model;
-import net.dpml.metro.control.PartsManager;
-import net.dpml.metro.control.Handler;
+import net.dpml.metro.control.ComponentManager;
+import net.dpml.metro.control.ComponentHandler;

import net.dpml.lang.UnknownKeyException;

@@ -41,7 +41,7 @@
* @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
* @version @PROJECT-VERSION@
*/
-class DefaultPartsManager implements PartsManager
+class DefaultComponentManager implements ComponentManager
{
//-------------------------------------------------------------------
// state
@@ -50,7 +50,7 @@
/**
* The component handler.
*/
- private final ComponentHandler m_handler;
+ private final DefaultComponentHandler m_handler;

/**
* The logging channel.
@@ -74,7 +74,7 @@
* @param handler the component handler
* @param logger the logging channel
*/
- DefaultPartsManager( ComponentController control, ComponentHandler
handler, Logger logger )
+ DefaultComponentManager( ComponentController control,
DefaultComponentHandler handler, Logger logger )
throws ControlException, RemoteException
{
m_handler = handler;
@@ -89,7 +89,7 @@
try
{
ComponentModel m = model.getComponentModel( key );
- Component h = control.createComponentHandler( handler,
classloader, m, true );
+ Component h = control.createDefaultComponentHandler(
handler, classloader, m, true );
m_handlers.put( key, h );
}
catch( UnknownKeyException e )
@@ -121,7 +121,7 @@
}

//-------------------------------------------------------------------
- // PartsManager
+ // ComponentManager
//-------------------------------------------------------------------

/**
@@ -157,9 +157,9 @@
*/
public Model getComponentModel( Component component )
{
- if( component instanceof ComponentHandler )
+ if( component instanceof DefaultComponentHandler )
{
- ComponentHandler handler = (ComponentHandler) component;
+ DefaultComponentHandler handler = (DefaultComponentHandler)
component;
return handler.getComponentModel();
}
else
@@ -167,7 +167,7 @@
final String error =
"Component ["
+ component
- + "] is not castable to
net.dpml.metro.runtime.ComponentHandler.";
+ + "] is not castable to
net.dpml.metro.runtime.DefaultComponentHandler.";
throw new IllegalArgumentException( error );
}
}
@@ -177,11 +177,11 @@
* @param key the internal component key
* @return the local component handler
*/
- public synchronized Handler getComponentHandler( String key ) throws
UnknownKeyException
+ public synchronized ComponentHandler getComponentHandler( String key )
throws UnknownKeyException
{
if( m_handlers.containsKey( key ) )
{
- return (Handler) m_handlers.get( key );
+ return (ComponentHandler) m_handlers.get( key );
}
else
{

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-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/DefaultProvider.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -62,7 +62,7 @@
/**
* The component handler.
*/
- private final ComponentHandler m_handler;
+ private final DefaultComponentHandler m_handler;

/**
* The state machine that tracks the instance state.
@@ -103,7 +103,7 @@
* @param handler the component handler
* @param logger the logging channel
*/
- DefaultProvider( ComponentHandler handler, Logger logger )
+ DefaultProvider( DefaultComponentHandler handler, Logger logger )
throws RemoteException, ControlException, InvocationTargetException
{
super( logger );
@@ -316,7 +316,7 @@
}
}

- ComponentHandler getComponentHandler()
+ DefaultComponentHandler getDefaultComponentHandler()
{
return m_handler;
}

Modified:
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/PartsInvocationHandler.java
===================================================================
---
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/PartsInvocationHandler.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/runtime/src/main/net/dpml/metro/runtime/PartsInvocationHandler.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -22,9 +22,9 @@
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

-import net.dpml.metro.control.Handler;
+import net.dpml.metro.control.ComponentHandler;
import net.dpml.part.remote.Component;
-import net.dpml.metro.control.PartsManager;
+import net.dpml.metro.control.ComponentManager;

/**
* Invoication handler for the Context inner class. The invocation handler
is
@@ -43,7 +43,7 @@
/**
* The component.
*/
- private final DefaultPartsManager m_manager;
+ private final DefaultComponentManager m_manager;

//-------------------------------------------------------------------
// constructor
@@ -54,7 +54,7 @@
*
* @param handler the component handler
*/
- PartsInvocationHandler( DefaultPartsManager manager )
+ PartsInvocationHandler( DefaultComponentManager manager )
{
m_manager = manager;
}
@@ -80,7 +80,7 @@
{
return method.invoke( this, args );
}
- else if( PartsManager.class == source )
+ else if( ComponentManager.class == source )
{
return method.invoke( m_manager, args );
}
@@ -89,7 +89,7 @@
String postfix = getPartPostfix( method );
String key = getPartKey( method, semantic );

- Handler handler = m_manager.getComponentHandler( key );
+ ComponentHandler handler = m_manager.getComponentHandler( key );

if( GET == semantic )
{

Modified: trunk/main/metro/test/src/main/net/dpml/test/app/Demo.java
===================================================================
--- trunk/main/metro/test/src/main/net/dpml/test/app/Demo.java 2006-01-24
15:48:40 UTC (rev 969)
+++ trunk/main/metro/test/src/main/net/dpml/test/app/Demo.java 2006-01-24
17:07:29 UTC (rev 970)
@@ -20,8 +20,8 @@

import net.dpml.logging.Logger;

-import net.dpml.metro.control.PartsManager;
-import net.dpml.metro.control.Handler;
+import net.dpml.metro.control.ComponentManager;
+import net.dpml.metro.control.ComponentHandler;

/**
* The demo class is used to aggregate a collection of components and
@@ -32,7 +32,7 @@
*/
public class Demo
{
- private final PartsManager m_parts;
+ private final ComponentManager m_parts;
private final Logger m_logger;

/**
@@ -40,7 +40,7 @@
* @param logger a logging channel
* @param parts the internal parts
*/
- public Demo( Logger logger, PartsManager parts )
+ public Demo( Logger logger, ComponentManager parts )
{
m_logger = logger;
m_parts = parts;
@@ -62,13 +62,13 @@

DefaultServer getServer() throws Exception
{
- Handler handler = m_parts.getComponentHandler( "server" );
+ ComponentHandler handler = m_parts.getComponentHandler( "server" );
return (DefaultServer) handler.getProvider().getValue( false );
}

DefaultListener getListener() throws Exception
{
- Handler handler = m_parts.getComponentHandler( "listener" );
+ ComponentHandler handler = m_parts.getComponentHandler( "listener" );
return (DefaultListener) handler.getProvider().getValue( false );
}
}

Modified:
trunk/main/metro/test/src/main/net/dpml/test/composite/PartsComponent.java
===================================================================
---
trunk/main/metro/test/src/main/net/dpml/test/composite/PartsComponent.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/test/src/main/net/dpml/test/composite/PartsComponent.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -25,8 +25,8 @@

import net.dpml.test.ColorManager;

-import net.dpml.metro.control.PartsManager;
-import net.dpml.metro.control.Handler;
+import net.dpml.metro.control.ComponentManager;
+import net.dpml.metro.control.ComponentHandler;

import net.dpml.lang.UnknownKeyException;

@@ -74,7 +74,7 @@
/**
* The assigned part manager.
*/
- private final PartsManager m_parts;
+ private final ComponentManager m_parts;

//------------------------------------------------------------------
// constructor
@@ -88,7 +88,7 @@
* @exception UnknownKeyException if the implementation uses a bad
reference
*/
public PartsComponent(
- final Logger logger, final Context context, final PartsManager parts )
+ final Logger logger, final Context context, final ComponentManager
parts )
throws UnknownKeyException
{
logger.debug( "instantiation" );
@@ -97,7 +97,7 @@
m_logger = logger;
m_parts = parts;

- Handler handler = parts.getComponentHandler( "child" );
+ ComponentHandler handler = parts.getComponentHandler( "child" );
Map map = handler.getContextMap();
map.put( "color", context.getColor() );
}
@@ -126,7 +126,7 @@
*/
public ChildComponent getChild() throws Exception
{
- Handler handler = m_parts.getComponentHandler( "child" );
+ ComponentHandler handler = m_parts.getComponentHandler( "child" );
return (ChildComponent) handler.getProvider().getValue( false );
}


Deleted:
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentHandlerTestCase.java
===================================================================
---
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentHandlerTestCase.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentHandlerTestCase.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -1,99 +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.test;
-
-import java.io.File;
-import java.net.URI;
-
-import junit.framework.TestCase;
-
-import net.dpml.part.local.Controller;
-import net.dpml.part.remote.Component;
-import net.dpml.part.remote.Provider;
-
-
-/**
- * Contains a series of tests applied to the component component.
- *
- * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
- * @version @PROJECT-VERSION@
- */
-public class ComponentHandlerTestCase extends TestCase
-{
- private static final Controller CONTROLLER = Controller.STANDARD;
-
- private URI m_uri;
-
- /**
- * Testcase setup during which the part defintion 'example.part'
- * is established as a file uri.
- * @exception Exception if an unexpected error occurs
- */
- public void setUp() throws Exception
- {
- final String path = "example.part";
- final File test = new File( System.getProperty( "project.test.dir" )
);
- m_uri = new File( test, path ).toURI();
- }
-
- /**
- * Test that the component initial state is inactive.
- * @exception Exception if an unexpected error occurs
- */
- public void testHandlerInitialState() throws Exception
- {
- Component component = CONTROLLER.createComponent( m_uri );
- assertNotNull( "component", component );
- assertFalse( "initial-active-state", component.isActive() );
- }
-
- /**
- * Test that the component exposes itself as active following activation
- * and inactive following deactivation.
- * @exception Exception if an unexpected error occurs
- */
- public void testActivationDeactivationCycle() throws Exception
- {
- Component component = CONTROLLER.createComponent( m_uri );
- component.activate();
- assertTrue( "is-active", component.isActive() );
- component.deactivate();
- assertFalse( "is-active-following-deactivation",
component.isActive() );
- }
-
- /**
- * Test self activation on access.
- * @exception Exception if an unexpected error occurs
- */
- public void testProviderAquisitionInInactiveState() throws Exception
- {
- Component component = CONTROLLER.createComponent( m_uri );
- Provider instance = (Provider) component.getProvider();
- assertTrue( "is-active-post-instantiation", component.isActive() );
- }
-
- static
- {
- System.setProperty(
- "java.util.logging.config.class",
- System.getProperty(
- "java.util.logging.config.class",
- "net.dpml.transit.util.ConfigurationHandler" ) );
- }
-}

Modified:
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentModelTestCase.java
===================================================================
---
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentModelTestCase.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentModelTestCase.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -28,7 +28,6 @@
import net.dpml.metro.info.LifestylePolicy;
import net.dpml.metro.info.CollectionPolicy;
import net.dpml.metro.model.ComponentModel;
-import net.dpml.metro.model.MutableComponentModel;

import net.dpml.lang.UnknownKeyException;

@@ -43,7 +42,7 @@
{
private static final Controller CONTROLLER = Controller.STANDARD;

- private MutableComponentModel m_model;
+ private ComponentModel m_model;

/**
* Testcase setup during which the part defintion 'example.part'
@@ -55,7 +54,7 @@
final String path = "example.part";
final File test = new File( System.getProperty( "project.test.dir" )
);
final URI uri = new File( test, path ).toURI();
- m_model = (MutableComponentModel) CONTROLLER.createModel( uri );
+ m_model = (ComponentModel) CONTROLLER.createModel( uri );
}

/**

Modified:
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/CompositeTestCase.java
===================================================================
---
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/CompositeTestCase.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/CompositeTestCase.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -27,7 +27,7 @@
import net.dpml.part.local.Controller;
import net.dpml.part.remote.Component;
import net.dpml.part.remote.Provider;
-import net.dpml.metro.control.Handler;
+import net.dpml.metro.control.ComponentHandler;

import net.dpml.test.composite.ChildComponent;
import net.dpml.test.composite.CompositeComponent;
@@ -80,7 +80,7 @@
public void testOverloadedComposite() throws Exception
{
Component component = CONTROLLER.createComponent( m_uri );
- Handler manager = (Handler) component;
+ ComponentHandler manager = (ComponentHandler) component;
manager.getContextMap().put( "color", Color.YELLOW );
Provider instance = component.getProvider();
CompositeComponent parent = (CompositeComponent) instance.getValue(
false );

Modified:
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ContextModelTestCase.java
===================================================================
---
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ContextModelTestCase.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ContextModelTestCase.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -29,7 +29,6 @@
import net.dpml.metro.info.EntryDescriptor;
import net.dpml.metro.model.ComponentModel;
import net.dpml.metro.model.ContextModel;
-import net.dpml.metro.model.MutableContextModel;
import net.dpml.metro.model.ValidationException;
import net.dpml.metro.model.ValidationException.Issue;

@@ -61,7 +60,7 @@
*/
public void testContextModel() throws Exception
{
- MutableContextModel context = (MutableContextModel)
m_model.getContextModel();
+ ContextModel context = m_model.getContextModel();
assertNotNull( "context", context );
EntryDescriptor[] entries = context.getEntryDescriptors();
assertEquals( "entries", 1, entries.length );
@@ -93,7 +92,7 @@
*/
public void testValidationWithCause() throws Exception
{
- MutableContextModel context = (MutableContextModel)
m_model.getContextModel();
+ ContextModel context = m_model.getContextModel();
context.setEntryDirective( "color", null );
try
{

Copied:
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/DefaultComponentHandlerTestCase.java
(from rev 953,
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentHandlerTestCase.java)
===================================================================
---
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ComponentHandlerTestCase.java
2006-01-23 04:08:06 UTC (rev 953)
+++
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/DefaultComponentHandlerTestCase.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -0,0 +1,99 @@
+/*
+ * 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.test;
+
+import java.io.File;
+import java.net.URI;
+
+import junit.framework.TestCase;
+
+import net.dpml.part.local.Controller;
+import net.dpml.part.remote.Component;
+import net.dpml.part.remote.Provider;
+
+
+/**
+ * Contains a series of tests applied to the component component.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public class DefaultComponentHandlerTestCase extends TestCase
+{
+ private static final Controller CONTROLLER = Controller.STANDARD;
+
+ private URI m_uri;
+
+ /**
+ * Testcase setup during which the part defintion 'example.part'
+ * is established as a file uri.
+ * @exception Exception if an unexpected error occurs
+ */
+ public void setUp() throws Exception
+ {
+ final String path = "example.part";
+ final File test = new File( System.getProperty( "project.test.dir" )
);
+ m_uri = new File( test, path ).toURI();
+ }
+
+ /**
+ * Test that the component initial state is inactive.
+ * @exception Exception if an unexpected error occurs
+ */
+ public void testHandlerInitialState() throws Exception
+ {
+ Component component = CONTROLLER.createComponent( m_uri );
+ assertNotNull( "component", component );
+ assertFalse( "initial-active-state", component.isActive() );
+ }
+
+ /**
+ * Test that the component exposes itself as active following activation
+ * and inactive following deactivation.
+ * @exception Exception if an unexpected error occurs
+ */
+ public void testActivationDeactivationCycle() throws Exception
+ {
+ Component component = CONTROLLER.createComponent( m_uri );
+ component.activate();
+ assertTrue( "is-active", component.isActive() );
+ component.deactivate();
+ assertFalse( "is-active-following-deactivation",
component.isActive() );
+ }
+
+ /**
+ * Test self activation on access.
+ * @exception Exception if an unexpected error occurs
+ */
+ public void testProviderAquisitionInInactiveState() throws Exception
+ {
+ Component component = CONTROLLER.createComponent( m_uri );
+ Provider instance = (Provider) component.getProvider();
+ assertTrue( "is-active-post-instantiation", component.isActive() );
+ }
+
+ static
+ {
+ System.setProperty(
+ "java.util.logging.config.class",
+ System.getProperty(
+ "java.util.logging.config.class",
+ "net.dpml.transit.util.ConfigurationHandler" ) );
+ }
+}

Modified:
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ObserverTestCase.java
===================================================================
---
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ObserverTestCase.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ObserverTestCase.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -29,7 +29,7 @@
import net.dpml.part.remote.Provider;
import net.dpml.metro.data.ValueDirective;
import net.dpml.metro.model.ComponentModel;
-import net.dpml.metro.model.MutableContextModel;
+import net.dpml.metro.model.ContextModel;

/**
* Test aspects of the component model implementation.
@@ -58,7 +58,7 @@
*/
public void testContextModel() throws Exception
{
- MutableContextModel context = (MutableContextModel)
m_model.getContextModel();
+ ContextModel context = (ContextModel) m_model.getContextModel();
Component component = Controller.STANDARD.createComponent( m_model );
Provider provider = component.getProvider();
Object instance = provider.getValue( false );

Modified:
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ProviderTestCase.java
===================================================================
---
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ProviderTestCase.java
2006-01-24 15:48:40 UTC (rev 969)
+++
trunk/main/metro/test/src/test/net/dpml/metro/runtime/test/ProviderTestCase.java
2006-01-24 17:07:29 UTC (rev 970)
@@ -35,7 +35,7 @@
import net.dpml.state.impl.DefaultStateListener;
import net.dpml.metro.data.ValueDirective;
import net.dpml.metro.model.ComponentModel;
-import net.dpml.metro.model.MutableContextModel;
+import net.dpml.metro.model.ContextModel;

import net.dpml.test.ColorManager;
import net.dpml.test.ExampleComponent;
@@ -236,7 +236,7 @@
Color color = manager.getColor();
assertEquals( "initial-color", Color.RED, color );
ValueDirective newDirective = new ValueDirective(
Color.class.getName(), "BLUE", (String) null );
- MutableContextModel context = (MutableContextModel)
model.getContextModel();
+ ContextModel context = (ContextModel) model.getContextModel();
context.setEntryDirective( "color", newDirective );
color = manager.getColor();
assertEquals( "mutated-color", Color.BLUE, color );




  • r970 - in trunk/main: central/src/docs/about/notepad/freight central/src/docs/metro/runtime/components central/src/docs/metro/tasks/components metro/exec/src/main/net/dpml/metro/exec metro/model/src/main/net/dpml/metro/control metro/model/src/main/net/dpml/metro/model metro/runtime metro/runtime/src/main/net/dpml/metro/runtime metro/test/src/main/net/dpml/test/app metro/test/src/main/net/dpml/test/composite metro/test/src/test/net/dpml/metro/runtime/test, mcconnell at BerliOS, 01/24/2006

Archive powered by MHonArc 2.6.24.

Top of Page