Skip to Content.
Sympa Menu

notify-dpml - svn commit: r2260 - in development/main: metro metro/automation/control/src/main/net/dpml/automation/control metro/automation/control/src/main/net/dpml/automation/model metro/composition/api/src/main/net/dpml/composition/model metro/composition/builder/src/main/net/dpml/composition/builder metro/composition/control/src/main/net/dpml/composition/control metro/composition/control/src/main/net/dpml/composition/models metro/composition/impl/src/main/net/dpml/composition/model/impl metro/composition/testing/acme metro/composition/testing/acme/src/main/net/dpml/composition/testing metro/composition/testing/unit metro/composition/testing/unit/src/test/net/dpml/composition/testing metro/meta/api/src/main/net/dpml/meta/info transit/core/tools/src/main/net/dpml/transit/tools

notify-dpml AT lists.ibiblio.org

Subject: DPML Notify

List archive

Chronological Thread  
  • From: mcconnell AT dpml.net
  • To: notify-dpml AT lists.ibiblio.org
  • Subject: svn commit: r2260 - in development/main: metro metro/automation/control/src/main/net/dpml/automation/control metro/automation/control/src/main/net/dpml/automation/model metro/composition/api/src/main/net/dpml/composition/model metro/composition/builder/src/main/net/dpml/composition/builder metro/composition/control/src/main/net/dpml/composition/control metro/composition/control/src/main/net/dpml/composition/models metro/composition/impl/src/main/net/dpml/composition/model/impl metro/composition/testing/acme metro/composition/testing/acme/src/main/net/dpml/composition/testing metro/composition/testing/unit metro/composition/testing/unit/src/test/net/dpml/composition/testing metro/meta/api/src/main/net/dpml/meta/info transit/core/tools/src/main/net/dpml/transit/tools
  • Date: Sun, 10 Apr 2005 22:37:32 -0400

Author: mcconnell AT dpml.net
Date: Sun Apr 10 22:37:29 2005
New Revision: 2260

Added:

development/main/metro/automation/control/src/main/net/dpml/automation/control/EntryNotFoundException.java

development/main/metro/automation/control/src/main/net/dpml/automation/control/InvalidQueryException.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextManagerInvocationHandler.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/ValueHolder.java

development/main/metro/composition/control/src/main/net/dpml/composition/models/AbstractModel.java
- copied, changed from r2259,
development/main/metro/composition/control/src/main/net/dpml/composition/models/EntryModel.java

development/main/metro/composition/control/src/main/net/dpml/composition/models/EntryTable.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/AcmeContainer.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/BadColorException.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/BadWidget.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ColorContext.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ColorContextManager.java
Removed:

development/main/metro/composition/control/src/main/net/dpml/composition/models/EntryModel.java

development/main/metro/composition/control/src/main/net/dpml/composition/models/StandardEntryModel.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/AcmeComponent.java
Modified:

development/main/metro/automation/control/src/main/net/dpml/automation/control/Controller.java

development/main/metro/automation/control/src/main/net/dpml/automation/control/LifecycleException.java

development/main/metro/automation/control/src/main/net/dpml/automation/control/SystemManager.java

development/main/metro/automation/control/src/main/net/dpml/automation/model/Model.java

development/main/metro/composition/api/src/main/net/dpml/composition/model/ContextModel.java

development/main/metro/composition/api/src/main/net/dpml/composition/model/EntryModel.java

development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/ApplianceInvocationHandler.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionClassLoader.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextInvocationHandler.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/Holder.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/LifecycleHandler.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/LifestyleHandler.java

development/main/metro/composition/control/src/main/net/dpml/composition/control/PartsInvocationHandler.java

development/main/metro/composition/control/src/main/net/dpml/composition/models/PartsModel.java

development/main/metro/composition/control/src/main/net/dpml/composition/models/StandardComponentModel.java

development/main/metro/composition/control/src/main/net/dpml/composition/models/ValueModel.java

development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContextModel.java

development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultEntryModel.java

development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultImportModel.java

development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultValueModel.java
development/main/metro/composition/testing/acme/build.xml

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Dimension.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Gizmo.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/GizmoComponent.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Widget.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/WidgetComponent.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/WidgetValue.java
development/main/metro/composition/testing/unit/build.xml

development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/CompositeTestCase.java

development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/SimpleTestCase.java
development/main/metro/index.xml

development/main/metro/meta/api/src/main/net/dpml/meta/info/PartDescriptor.java

development/main/transit/core/tools/src/main/net/dpml/transit/tools/PluginTask.java

development/main/transit/core/tools/src/main/net/dpml/transit/tools/TransitComponentHelper.java
Log:
Improvements of the client/system contract involving simplification of the
model defintion - improvements to the controller api, lots of improvements to
the context handling scheme. Addition of context manager support and
examples of container controlled context handling.

Modified:
development/main/metro/automation/control/src/main/net/dpml/automation/control/Controller.java
==============================================================================
---
development/main/metro/automation/control/src/main/net/dpml/automation/control/Controller.java
(original)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/control/Controller.java
Sun Apr 10 22:37:29 2005
@@ -20,6 +20,7 @@

import java.net.URI;
import java.io.IOException;
+import java.util.Map.Entry;

import net.dpml.automation.part.Part;
import net.dpml.automation.model.Model;
@@ -56,25 +57,38 @@
Object getResource( Model model, URI urn );

/**
- * Return the model for a supplied part.
+ * Return a model identified by the supplied uri from the supplied model.
+ * Recognized urn schemes include 'parts' and 'context'.
+ *
+ * @param model the enclosing model
+ * @param urn the resource identifier
+ * @return the nested model or null if the model is not found
+ */
+ Entry getEntry( Model model, URI urn ) throws EntryNotFoundException;
+
+ /**
+ * Create a return a new model for a supplied part.
*
* @param partition the enclosing partition
* @param parent the parent classloader
* @param part the part datastructure
+ * @param name the name to assign to the model
* @return the model
*/
- Model getModel( ClassLoader parent, Part part )
+ Model getModel( ClassLoader parent, Part part, String name )
throws DelegationException, ModelException;

/**
- * Return the model for a supplied part.
+ * Create a return a new nested model for a supplied part within the
supplied
+ * enclosing model.
*
* @param model the enclosing model
* @param parent the parent classloader
* @param part the part datastructure
+ * @param name the name to assign to the model
* @return the model
*/
- Model getModel( Model model, ClassLoader parent, Part part )
+ Model getModel( Model model, ClassLoader parent, Part part, String name
)
throws DelegationException, ModelException;

/**
@@ -84,7 +98,17 @@
* @param model the component model
* @return the resolved instance
*/
- Object create( Model model ) throws Exception;
+ Entry create( Model model ) throws Exception;
+
+ /**
+ * Create and return a new non-proxied instance of the component
represented
+ * by the supplied model.
+ *
+ * @param model the component model
+ * @param key the instance key
+ * @return the resolved instance
+ */
+ Entry create( Model model, Object key ) throws Exception;

/**
* Create and return a new instance of the component represented
@@ -96,7 +120,7 @@
Object resolve( Model model ) throws Exception;

/**
- * Create and return a new instance of the component represented
+ * Return an identified instance of the component type represented
* by the supplied model.
*
* @param model the component model
@@ -111,11 +135,4 @@
*/
void release( Object instance );

- /**
- * Return a model identified by the supplied path within the supplied
model.
- * @param model the enclosing model
- * @param uri the nested part address
- * @return the nested model or null if the model is not found
- */
- Model getModel( Model model, URI uri );
}

Added:
development/main/metro/automation/control/src/main/net/dpml/automation/control/EntryNotFoundException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/control/EntryNotFoundException.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 Stephen J. McConnell
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dpml.automation.control;
+
+import java.net.URI;
+
+/**
+ * Exception thrown when an attempt is made to reference an unknown part.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public class EntryNotFoundException extends Exception
+{
+ private URI m_model;
+ private URI m_query;
+
+ public EntryNotFoundException( URI model, URI query )
+ {
+ super( buildMessage( model, query ) );
+ m_model = model;
+ m_query = query;
+ }
+
+ public URI getModelURI()
+ {
+ return m_model;
+ }
+
+ public URI getQuery()
+ {
+ return m_query;
+ }
+
+ private static String buildMessage( URI model, URI query )
+ {
+ final String error =
+ "Could not locate an entry within the enclosing model ["
+ + model
+ + "] relative to the query ["
+ + query
+ + "].";
+ return error;
+ }
+
+}
+

Added:
development/main/metro/automation/control/src/main/net/dpml/automation/control/InvalidQueryException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/control/InvalidQueryException.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 Stephen J. McConnell
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dpml.automation.control;
+
+import java.net.URI;
+
+/**
+ * Exception thrown in response to an attempt to register a part model
+ * under a key that is already assigned.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public class InvalidQueryException extends ControlRuntimeException
+{
+ private URI m_model;
+ private URI m_query;
+
+ public InvalidQueryException( URI model, URI query )
+ {
+ super( buildMessage( model, query ) );
+ m_model = model;
+ m_query = query;
+ }
+
+ public URI getModelURI()
+ {
+ return m_model;
+ }
+
+ public URI getQuery()
+ {
+ return m_query;
+ }
+
+ private static String buildMessage( URI model, URI query )
+ {
+ final String error =
+ "The following query ["
+ + query
+ + "] was rejected as invalid when applied to the model ["
+ + model
+ + "].";
+ return error;
+ }
+}
+

Modified:
development/main/metro/automation/control/src/main/net/dpml/automation/control/LifecycleException.java
==============================================================================
---
development/main/metro/automation/control/src/main/net/dpml/automation/control/LifecycleException.java
(original)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/control/LifecycleException.java
Sun Apr 10 22:37:29 2005
@@ -18,6 +18,9 @@

package net.dpml.automation.control;

+import net.dpml.automation.model.Model;
+
+
/**
* Exception to indicate that there was a lifecycle related error.
*
@@ -27,25 +30,21 @@
public class LifecycleException
extends Exception
{
+ private Model m_model;
+
/**
* Construct a new <code>LifecycleException</code> instance.
*
- * @param message The detail message for this exception.
+ * @param throwable the root cause of the exception
*/
- public LifecycleException( final String message )
+ public LifecycleException( final Model model, final Throwable throwable )
{
- this( message, null );
+ super( null, throwable );
}

- /**
- * Construct a new <code>LifecycleException</code> instance.
- *
- * @param message The detail message for this exception.
- * @param throwable the root cause of the exception
- */
- public LifecycleException( final String message, final Throwable
throwable )
+ public Model getModel()
{
- super( message, throwable );
+ return m_model;
}
}


Modified:
development/main/metro/automation/control/src/main/net/dpml/automation/control/SystemManager.java
==============================================================================
---
development/main/metro/automation/control/src/main/net/dpml/automation/control/SystemManager.java
(original)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/control/SystemManager.java
Sun Apr 10 22:37:29 2005
@@ -40,7 +40,7 @@
* @param uri a part uri
* @return the management view of the loaded part
*/
- Model addPart( URI uri ) throws IOException, DelegationException,
ModelException, PartNotFoundException;
+ Model addPart( URI uri, String key ) throws IOException,
DelegationException, ModelException, PartNotFoundException;

/**
* Add a model to the system scope.
@@ -62,6 +62,6 @@
/**
* Dispose of the manager.
*/
- void dispose();
+ //void dispose();

}

Modified:
development/main/metro/automation/control/src/main/net/dpml/automation/model/Model.java
==============================================================================
---
development/main/metro/automation/control/src/main/net/dpml/automation/model/Model.java
(original)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/model/Model.java
Sun Apr 10 22:37:29 2005
@@ -18,8 +18,10 @@

package net.dpml.automation.model;

+import java.util.Map.Entry;
import java.io.Serializable;
import java.net.URI;
+import java.util.Map.Entry;

import net.dpml.automation.control.Controller;

@@ -30,7 +32,7 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
*/
-public interface Model
+public interface Model extends Entry
{
/**
* Return the primary controller assigned to the model.
@@ -47,17 +49,10 @@
*/
Object getResource( URI urn );

- String getName();
-
URI getPartition();

URI getURI();

- Object create() throws Exception;
-
- Object resolve() throws Exception;
-
- Object resolve( Object key ) throws Exception;
+ //Entry create() throws Exception;

- void release( Object object );
}

Modified:
development/main/metro/composition/api/src/main/net/dpml/composition/model/ContextModel.java
==============================================================================
---
development/main/metro/composition/api/src/main/net/dpml/composition/model/ContextModel.java
(original)
+++
development/main/metro/composition/api/src/main/net/dpml/composition/model/ContextModel.java
Sun Apr 10 22:37:29 2005
@@ -19,6 +19,7 @@
package net.dpml.composition.model;

import java.util.Map;
+import java.util.Map.Entry;

import net.dpml.automation.model.Model;

@@ -51,14 +52,14 @@
*
* @return the entry models
*/
- Model[] getEntryModels();
+ Entry[] getEntryModels();

/**
* Return an entry model matching the supplied key.
*
* @return the entry model or null if tyhe key is unknown
*/
- Model getEntryModel( String key );
+ Entry getEntryModel( Object key );

/**
* Set the entry model relative to a supplied key.
@@ -66,7 +67,7 @@
* @param key the entry key
* @param model the entry model
*/
- void setEntryModel( String key, Model model );
+ void setEntryModel( Object key, Entry model );

/**
* Set the entry to a suplied value.

Modified:
development/main/metro/composition/api/src/main/net/dpml/composition/model/EntryModel.java
==============================================================================
---
development/main/metro/composition/api/src/main/net/dpml/composition/model/EntryModel.java
(original)
+++
development/main/metro/composition/api/src/main/net/dpml/composition/model/EntryModel.java
Sun Apr 10 22:37:29 2005
@@ -18,7 +18,7 @@

package net.dpml.composition.model;

-import net.dpml.automation.model.Model;
+import java.util.Map.Entry;

/**
* <p>Specification of a context enty model from which a
@@ -27,20 +27,20 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Id$
*/
-public interface EntryModel extends Model
+public interface EntryModel extends Entry
{
/**
* Return the context entry key.
*
* @return the key
*/
- String getKey();
+ //String getKey();

/**
* Return the context entry value.
*
* @return the context entry value
*/
- Object getValue() throws ModelException;
+ //Object getValue();

}

Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
==============================================================================
---
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
(original)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
Sun Apr 10 22:37:29 2005
@@ -28,6 +28,7 @@
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.Properties;
+import java.util.Map.Entry;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -497,7 +498,7 @@
validateNoExceptions( method );
validateAtMostOneParameter( method );

- String key = getPartKey( method, "get" );
+ String key = PartDescriptor.getPartKey( method, PartDescriptor.GET );
String type = returnType.getName();
return new DependencyDescriptor( key, type );
}
@@ -554,7 +555,7 @@
for( int i=0; i<methods.length; i++ )
{
Method method = methods[i];
- String key = getPartKey( method );
+ String key = PartDescriptor.getPartKey( method );
if( false == list.contains( key ) )
{
list.add( key );
@@ -581,7 +582,7 @@
for( int i=0; i<methods.length; i++ )
{
Method method = methods[i];
- if( key.equals( getPartKey( method ) ) )
+ if( key.equals( PartDescriptor.getPartKey( method ) ) )
{
Operation operation = getOperation( method );
list.add( operation );
@@ -593,7 +594,8 @@
private Operation getOperation( Method method ) throws
IntrospectionException
{
final String name = method.getName();
- if( name.startsWith( PartDescriptor.GET_KEY ) )
+ final int semantic = PartDescriptor.getPartSemantic( method );
+ if( semantic == PartDescriptor.GET )
{
validateNoExceptions( method );
validateAtMostOneParameter( method );
@@ -601,18 +603,19 @@
validateNonNullReturnType( method, returnType );
validateNonArrayReturnType( method, returnType );
String type = returnType.getName();
- return new Operation( PartDescriptor.GET, type );
+ String postfix = PartDescriptor.getPartPostfix( method );
+ return new Operation( PartDescriptor.GET, postfix, type );
}
- else if( name.startsWith( PartDescriptor.CREATE_KEY ) )
+ else if( semantic == PartDescriptor.CREATE )
{
- validateNoParameters( method );
+ validateNoExceptions( method );
+ validateAtMostOneParameter( method );
Class returnType = method.getReturnType();
- validateNonNullReturnType( method, returnType );
- validateNonArrayReturnType( method, returnType );
+ validateReturnTypeIsAssignable( method, Entry.class );
String type = returnType.getName();
return new Operation( PartDescriptor.CREATE, type );
}
- else if( name.startsWith( PartDescriptor.RELEASE_KEY ) )
+ else if( semantic == PartDescriptor.RELEASE )
{
validateNoExceptions( method );
Class param = validateSingleParameter( method );
@@ -633,121 +636,6 @@
}
}

- private String getPartKey( Method method )
- {
- String name = method.getName();
- if( name.startsWith( PartDescriptor.GET_KEY ) )
- {
- return getPartKey( method, PartDescriptor.GET );
- }
- else if( name.startsWith( PartDescriptor.CREATE_KEY ) )
- {
- return getPartKey( method, PartDescriptor.CREATE );
- }
- else if( name.startsWith( PartDescriptor.RELEASE_KEY ) )
- {
- return getPartKey( method, PartDescriptor.RELEASE );
- }
- else
- {
- final String error =
- "Unrecognized part accessor method signature ["
- + name
- + "]";
- throw new IllegalArgumentException( error );
- }
- }
-
- private String getPartKey( Method method, int semantic )
- {
- String name = method.getName();
- if( PartDescriptor.GET == semantic )
- {
- return formatKey( name, 3 );
- }
- else if( PartDescriptor.CREATE == semantic )
- {
- return formatKey( name, 6 );
- }
- else if( PartDescriptor.RELEASE == semantic )
- {
- return formatKey( name, 7 );
- }
- else
- {
- final String error =
- "Unrecognized part accessor method signature ["
- + name
- + "]";
- throw new IllegalArgumentException( error );
- }
- }
-
- /**
- * Creation of a new part descriptor using a supplied method and a part
builder.
- * The method is the method used by the component implementation to get
the part
- * runtime instance. The part builder establishes the deployment
solution for the
- * part implementation.
- */
- /*
- private PartDescriptor createPartDescriptor( Method method )
- throws IntrospectionException
- {
- String name = method.getName();
- validateNoExceptions( method );
- if( name.startsWith( PartDescriptor.GET_KEY ) )
- {
- validateAtMostOneParameter( method );
- Class returnType = method.getReturnType();
- validateNonNullReturnType( method, returnType );
- validateNonArrayReturnType( method, returnType );
- String key = getPartKey( method, "get" );
- String type = returnType.getName();
- return new PartDescriptor( key, type, PartDescriptor.GET );
- }
- else if( name.startsWith( PartDescriptor.CREATE_KEY ) )
- {
- validateNoParameters( method );
- Class returnType = method.getReturnType();
- validateNonNullReturnType( method, returnType );
- validateNonArrayReturnType( method, returnType );
- String key = getPartKey( method, "create" );
- String type = returnType.getName();
- return new PartDescriptor( key, type, PartDescriptor.CREATE );
- }
- else if( name.startsWith( PartDescriptor.RELEASE_KEY ) )
- {
- if( method.getParameterTypes().length == 1 )
- {
- Class[] params = method.getParameterTypes();
- Class param = params [0];
- Class returnType = method.getReturnType();
- validateNullReturnType( method, returnType );
- validateNonArrayType( method, param );
- String key = getPartKey( method, "create" );
- String type = param.getName();
- return new PartDescriptor( key, type, PartDescriptor.RELEASE
);
- }
- else
- {
- final String error =
- "The parts release method ["
- + name
- + "] does not declare a recognized pattern - no release
parameter was found.";
- throw new IntrospectionException( error );
- }
- }
- else
- {
- final String error =
- "Part method ["
- + name
- + "] does not match the recognized 'get', 'create' or
'release' patterns.";
- throw new IntrospectionException( error );
- }
- }
- */
-
private ContextDescriptor createContextDescriptor( Class subject )
throws IntrospectionException
{
Class[] classes = subject.getClasses();
@@ -804,7 +692,7 @@
validateMethodName( method );
validateNoExceptions( method );

- String key = getPartKey( method, "get" );
+ String key = PartDescriptor.getPartKey( method, PartDescriptor.GET );

Class returnType = method.getReturnType();
if( method.getParameterTypes().length == 0 )
@@ -848,13 +736,6 @@
}
}

- private String getPartKey( Method method, String prefix )
- {
- String name = method.getName();
- int offset = prefix.length();
- return formatKey( name, offset );
- }
-
private String formatKey( String key, int offset )
{
String k = key.substring( offset );
@@ -885,6 +766,23 @@
}
return null;
}
+
+ private void validateReturnTypeIsAssignable( Method method, Class type )
throws IntrospectionException
+ {
+ Class c = method.getReturnType();
+ if( false == type.isAssignableFrom( c ) )
+ {
+ final String error =
+ "Method ["
+ + method.getName()
+ + "] declares a return type ["
+ + c.getName()
+ + "] that is not assignable from the class ["
+ + type.getName()
+ + "].";
+ throw new IntrospectionException( error );
+ }
+ }

private void validateNonNullParameter( Method method, Class type )
throws IntrospectionException
{

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ApplianceInvocationHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/ApplianceInvocationHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ApplianceInvocationHandler.java
Sun Apr 10 22:37:29 2005
@@ -63,7 +63,7 @@
{
assertNotNull( holder, "holder" );
m_holder = holder;
- m_instance = m_holder.getInstance();
+ m_instance = holder.getValue();
}

//-------------------------------------------------------------------
@@ -94,7 +94,7 @@
}
catch( Throwable e )
{
- throw handleInvocationThrowable( e );
+ throw handleInvocationThrowable( method, e );
}
}

@@ -126,11 +126,14 @@
// utilities
//-------------------------------------------------------------------

- private Throwable handleInvocationThrowable( Throwable e )
+ private Throwable handleInvocationThrowable( Method method, Throwable e )
{
+ final String name = method.getName();
final String error =
"Delegation error raised in ["
- + m_holder
+ + getURI()
+ + "] while attempting to invoke the operation ["
+ + name
+ "].";

while( true )

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionClassLoader.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionClassLoader.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionClassLoader.java
Sun Apr 10 22:37:29 2005
@@ -151,11 +151,11 @@
String spec = uri.toString();
return new URL( null, spec, new
net.dpml.transit.artifact.Handler() );
}
- else if( "link".equals( uri.getScheme() ) )
- {
- String spec = uri.toString();
- return new URL( null, spec, new
net.dpml.transit.link.Handler() );
- }
+ //else if( "link".equals( uri.getScheme() ) )
+ //{
+ // String spec = uri.toString();
+ // return new URL( null, spec, new
net.dpml.transit.link.Handler() );
+ //}
else
{
return uri.toURL();

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
Sun Apr 10 22:37:29 2005
@@ -29,8 +29,10 @@
import java.util.WeakHashMap;
import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.Map.Entry;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;

import net.dpml.automation.part.Part;

@@ -44,6 +46,7 @@
import net.dpml.automation.control.LifecycleException;
import net.dpml.automation.control.UnsupportedPartTypeException;
import net.dpml.automation.control.PartNotFoundException;
+import net.dpml.automation.control.EntryNotFoundException;
import net.dpml.automation.control.ControlException;
import net.dpml.automation.model.ModelException;
import net.dpml.automation.model.Model;
@@ -158,7 +161,7 @@
{
if( "name".equals( key ) )
{
- return model.getName();
+ return model.getKey();
}
else if( "partition".equals( key ) )
{
@@ -192,72 +195,173 @@
return m_partition.toString();
}

+ public Entry getEntry( Model model, URI uri ) throws
EntryNotFoundException
+ {
+ if( model instanceof StandardComponentModel )
+ {
+ StandardComponentModel standard = (StandardComponentModel) model;
+ return standard.getEntry( uri );
+ }
+ else
+ {
+ Controller controller = model.getController();
+ if( this.equals( controller ) )
+ {
+ URI ref = getURI();
+ throw new EntryNotFoundException( ref, uri );
+ }
+ else
+ {
+ return controller.getEntry( model, uri );
+ }
+ }
+ }
+
/**
* Return the model for a supplied part.
*
- * @param partition the enclosing partition
* @param parent the parent classloader
* @param part the part datastructure
+ * @param key the key to assign to the model
* @return the model
*/
- public Model getModel( ClassLoader parent, Part part ) throws
DelegationException, ModelException
+ public Model getModel( ClassLoader parent, Part part, String key )
throws DelegationException, ModelException
{
- return getModel( null, parent, part );
+ return getModel( null, parent, part, key );
}

/**
* Return the model for a supplied part.
*
* @param model the enclosing model
- * @param partition the enclosing partition
- * @param parent the parent classloader
+ * @param classloader the parent classloader
* @param part the part datastructure
+ * @param key the key to assign to the model
* @return the model
*/
- public Model getModel( Model model, ClassLoader parent, Part part )
throws DelegationException, ModelException
+ public Model getModel( Model model, ClassLoader classloader, Part part,
String key ) throws DelegationException, ModelException
{
if( part instanceof ComponentProfile )
{
- ComponentProfile profile = (ComponentProfile) part;
- return getComponentModel( model, parent, profile );
+ final ComponentProfile profile = (ComponentProfile) part;
+ getMonitor().debug( "creating nested model using " + profile );
+ URI partition = getPartition( model );
+ ClassLoader parent = getClassLoader( partition, classloader,
profile );
+ if( null == model )
+ {
+ return new StandardComponentModel( this, partition, parent,
profile, key );
+ }
+ else
+ {
+ return new StandardComponentModel( this, model, partition,
parent, profile, key );
+ }
}
else if( part instanceof ValueDirective )
{
- ValueDirective value = (ValueDirective) part;
- return getValueModel( model, parent, value );
+ final ValueDirective directive = (ValueDirective) part;
+ return new ValueModel( key, this, classloader, directive, model
);
}
else
{
- URI uri = part.getPartHandlerURI();
+ final URI uri = part.getPartHandlerURI();
if( getURI().equals( uri ) )
{
throw new UnsupportedPartTypeException(
part.getClass().getName() );
}
else
{
- return getForeignModel( model, parent, part, uri );
+ try
+ {
+ PartHandler handler = loadPartHandler( uri );
+ Controller controller = handler.getController();
+ if( null == model )
+ {
+ return controller.getModel( classloader, part, key );
+ }
+ else
+ {
+ return controller.getModel( model, classloader,
part, key );
+ }
+ }
+ catch( HandlerNotFoundException e )
+ {
+ if( null == model )
+ {
+ final String error =
+ "Cannot create model ["
+ + key
+ + "] because the part handler ["
+ + uri
+ + "] was not found.";
+ throw new DelegationException( uri, error, e );
+ }
+ else
+ {
+ final String error =
+ "Cannot create model ["
+ + key
+ + "] in the model ["
+ + model.getURI()
+ + "] because the part handler ["
+ + uri
+ + "] was not found.";
+ throw new DelegationException( uri, error, e );
+ }
+ }
+ catch( ModelException e )
+ {
+ if( null == model )
+ {
+ final String error =
+ "Cannot create model ["
+ + key
+ + "] due to an external model related error raised
by ["
+ + uri
+ + "].";
+ throw new DelegationException( uri, error, e );
+ }
+ else
+ {
+ final String error =
+ "Cannot create model ["
+ + key
+ + "] in the model ["
+ + model.getURI()
+ + "] due to an external model related error raised
by ["
+ + uri
+ + "].";
+ throw new DelegationException( uri, error, e );
+ }
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected error raised by delegate while requesting
part model.";
+ throw new DelegationException( uri, error, e );
+ }
}
}
}

/**
- * Create and return a new non-proxied instance of the component
represented
- * by the supplied model.
+ * Create and return an instance entry.
*
* @param model the component model
* @return the resolved instance
*/
- public Object create( Model model ) throws Exception
+ public Entry create( Model model ) throws Exception
{
if( model instanceof StandardComponentModel )
{
- StandardComponentModel componentModel = (StandardComponentModel)
model;
- return m_factory.incarnate( componentModel );
+ StandardComponentModel standard = (StandardComponentModel) model;
+ return getHolder( standard, null );
}
else if( model instanceof ValueModel )
{
ValueModel value = (ValueModel) model;
- return value.getValue();
+ URI uri = value.getURI();
+ Object v = value.getValue();
+ return new ValueHolder( uri, v );
}
else
{
@@ -266,6 +370,26 @@
}

/**
+ * Create and return an instance entry using a supplied instance
identifier.
+ *
+ * @param model the component model
+ * @param key the instance identifier
+ * @return the resolved instance
+ */
+ public Entry create( Model model, Object key ) throws Exception
+ {
+ if( model instanceof StandardComponentModel )
+ {
+ StandardComponentModel standard = (StandardComponentModel) model;
+ return getHolder( standard, key );
+ }
+ else
+ {
+ return model.getController().create( model, key );
+ }
+ }
+
+ /**
* Create and return a new instance of the component represented
* by the supplied model using the assigned lifestyle policy.
*
@@ -276,8 +400,8 @@
{
if( model instanceof StandardComponentModel )
{
- StandardComponentModel componentModel = (StandardComponentModel)
model;
- Holder holder = getHolder( componentModel , null );
+ StandardComponentModel standard = (StandardComponentModel) model;
+ Holder holder = getHolder( standard, null );
return holder.newProxy();
}
else if( model instanceof ValueModel )
@@ -344,23 +468,6 @@
}
}

- public Model getModel( Model model, URI uri )
- {
- if( model instanceof StandardComponentModel )
- {
- StandardComponentModel m = (StandardComponentModel) model;
- return m.getModel( uri );
- }
- else if( model instanceof ValueModel )
- {
- return null;
- }
- else
- {
- return model.getController().getModel( model, uri );
- }
- }
-
//--------------------------------------------------------------------
// CompositionController
//--------------------------------------------------------------------
@@ -391,32 +498,6 @@
return m_monitor;
}

- /**
- * Return the model for a supplied part.
- *
- * @param model the enclosing model
- * @param partition the enclosing partition
- * @param parent the parent classloader
- * @param profile the part profile
- * @return the model
- */
- public StandardComponentModel getComponentModel(
- Model model, ClassLoader parent, ComponentProfile profile )
- throws DelegationException, ModelException
- {
- getMonitor().debug( "creating nested model using " + profile );
- URI partition = getPartition( model );
- ClassLoader classloader = getClassLoader( partition, parent, profile
);
- if( null == model )
- {
- return new StandardComponentModel( this, partition, classloader,
profile );
- }
- else
- {
- return new StandardComponentModel( this, model, partition,
classloader, profile );
- }
- }
-
private URI getPartition( Model model )
{
if( null == model )
@@ -429,28 +510,11 @@
}
}

- /**
- * Return the model for a supplied part.
- *
- * @param model the enclosing model
- * @param partition the enclosing partition
- * @param parent the parent classloader
- * @param profile the part profile
- * @return the model
- */
- private ValueModel getValueModel(
- Model model, ClassLoader parent, ValueDirective directive )
- throws DelegationException, ModelException
- {
- String key = directive.getKey();
- return new ValueModel( key, this, parent, directive, model );
- }
-
//--------------------------------------------------------------------
// private
//--------------------------------------------------------------------

- private Holder getHolder( StandardComponentModel model, Object key )
throws LifecycleException
+ private Holder getHolder( StandardComponentModel model, Object key )
throws LifecycleException, InvocationTargetException
{
if( null == key )
{
@@ -462,49 +526,6 @@
}
}

- /**
- * Return a management view of a part.
- *
- * @param model the enclosing model
- * @param partition the assigned partition
- * @param classloader the parent classloader
- * @param part the part backing the moel to be created
- * @param uri the part controller uri
- * @return the part model
- */
- private Model getForeignModel(
- Model parent, ClassLoader classloader, Part part, URI uri )
- throws DelegationException
- {
- try
- {
- PartHandler handler = loadPartHandler( uri );
- Controller controller = handler.getController();
- if( null == parent )
- {
- return controller.getModel( classloader, part );
- }
- else
- {
- return controller.getModel( parent, classloader, part );
- }
- }
- catch( HandlerNotFoundException e )
- {
- final String error =
- "Requested part handler ["
- + uri
- + "] not found.";
- throw new DelegationException( uri, error, e );
- }
- catch( Throwable e )
- {
- final String error =
- "Unexpected error raised by delegate while requesting part
model.";
- throw new DelegationException( uri, error, e );
- }
- }
-
private ClassLoader getClassLoader( URI partition, ClassLoader parent,
ComponentProfile profile )
{
final String name = profile.getName();

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java
Sun Apr 10 22:37:29 2005
@@ -92,11 +92,14 @@
* @param uri a uri identifying the part to add
* @return the model of the part
*/
- public Model addPart( URI uri )
+ public Model addPart( URI uri, String key )
throws IOException, DelegationException, ModelException,
PartNotFoundException
{
Part part = loadPart( uri );
- return installPart( part );
+ ClassLoader classloader = getClassLoader();
+ Model model = getModel( classloader, part, key );
+ m_models.add( model );
+ return model;
}

/**
@@ -133,21 +136,6 @@
}

/**
- * Install a part to the collection of parts managed by this manager.
- *
- * @param name the name identifying the part within the collection
- * @param part the part to add
- */
- private Model installPart( Part part )
- throws DelegationException, ModelException
- {
- ClassLoader classloader = getClassLoader();
- Model model = getModel( classloader, part );
- m_models.add( model );
- return model;
- }
-
- /**
* Return an array of managed parts.
* @return the parts array
*/
@@ -210,7 +198,6 @@
// static utilities
//--------------------------------------------------------------------

-
private static URI createPartition( SystemContext system )
{
URI uri = system.getDomain();

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextInvocationHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextInvocationHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextInvocationHandler.java
Sun Apr 10 22:37:29 2005
@@ -25,22 +25,22 @@
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Map;
+import java.util.Map.Entry;

import net.dpml.automation.control.Controller;
import net.dpml.automation.control.LifecycleException;
import net.dpml.automation.control.ControlRuntimeException;
+import net.dpml.automation.control.EntryNotFoundException;
import net.dpml.automation.model.ModelException;
import net.dpml.automation.model.Model;

import net.dpml.composition.models.StandardComponentModel;
import net.dpml.composition.models.ValueModel;
-import net.dpml.composition.models.StandardEntryModel;
import net.dpml.composition.data.ContextDirective;
import net.dpml.composition.data.ImportDirective;
import net.dpml.composition.data.ValueDirective;

import net.dpml.meta.info.Type;
-//import net.dpml.meta.info.EntryDescriptor;

import net.dpml.system.SystemContext;

@@ -51,7 +51,7 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Id: ApplianceInvocationHandler.java 2106 2005-03-21 18:46:10Z
mcconnell AT dpml.net $
*/
-public final class ContextInvocationHandler
+public class ContextInvocationHandler
implements InvocationHandler
{
//-------------------------------------------------------------------
@@ -66,17 +66,7 @@
/**
* The component model.
*/
- private final StandardComponentModel m_model;
-
- /**
- * The component type.
- */
- private final Type m_type;
-
- /**
- * The instance uri (possibly null)
- */
- private final URI m_uri;
+ private final Holder m_holder;

//-------------------------------------------------------------------
// constructor
@@ -88,19 +78,22 @@
* @param system the system context
* @param model the component model
*/
- public ContextInvocationHandler( SystemContext system,
StandardComponentModel model, URI uri )
+ public ContextInvocationHandler( SystemContext system, Holder holder )
throws LifecycleException, ModelException
{
m_system = system;
- m_model = model;
- m_uri = uri;
- m_type = model.getType();
+ m_holder = holder;
}

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

+ StandardComponentModel getComponentModel()
+ {
+ return m_holder.getModel();
+ }
+
/**
* Invoke the specified method on underlying object.
* This is called by the proxy object.
@@ -116,52 +109,17 @@
public Object invoke( final Object proxy, final Method method, final
Object[] args )
throws Throwable, NullPointerException
{
- if( proxy == null )
- throw new NullPointerException( "proxy" );
- if( method == null )
- throw new NullPointerException( "method" );
-
Class source = method.getDeclaringClass();
- if( Object.class == method.getDeclaringClass() )
+ if( Object.class == source )
{
return method.invoke( this, args );
}
-
- String name = method.getName();
- String key = getKeyFromMethod( method );
- URI uri = CompositionController.createURI( "context", key );
- final Model provider = m_model.getModel( uri );
- return getInstance( key, provider, args );
- }
-
- private Object getInstance( String key, Model provider, final Object[]
args )
- {
- if( null == key )
- {
- throw new NullPointerException( "key" );
- }
- if( null != provider )
- {
- try
- {
- return provider.resolve();
- }
- catch( Throwable e )
- {
- final String error =
- "Unexpected runtime error while attempting to resolve the
context value for the key ["
- + key
- + "] using the provider ["
- + provider
- + "] for the component type ["
- + m_type.getInfo().getClassname()
- + "].";
- throw new ControlRuntimeException( error, e );
- }
- }
else
{
- return returnClientSuppliedDefaultArgument( key, args );
+ String name = method.getName();
+ String key = getKeyFromMethod( method );
+ Holder.ContextMap map = getHolder().getContextMap();
+ return map.getValue( key, args );
}
}

@@ -193,20 +151,9 @@
return first + remainder;
}

- private Object returnClientSuppliedDefaultArgument( String key, Object[]
args )
+ Holder getHolder()
{
- if( args.length < 1 )
- {
- final String error =
- "Insuffient arguments to resolve a default value for the key ["
- + key
- + "] within the component type ["
- + m_type.getInfo().getName()
- + "].";
- throw new IllegalArgumentException( error );
- }
- Object arg = args[0];
- return arg;
+ return m_holder;
}

//-------------------------------------------------------------------

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextManagerInvocationHandler.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextManagerInvocationHandler.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2004 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.composition.control;
+
+import java.net.URI;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.lang.reflect.Method;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import net.dpml.automation.control.Controller;
+import net.dpml.automation.control.LifecycleException;
+import net.dpml.automation.control.ControlRuntimeException;
+import net.dpml.automation.control.EntryNotFoundException;
+import net.dpml.automation.model.ModelException;
+import net.dpml.automation.model.Model;
+
+import net.dpml.composition.models.StandardComponentModel;
+import net.dpml.composition.models.ValueModel;
+import net.dpml.composition.models.EntryTable;
+import net.dpml.composition.data.ContextDirective;
+import net.dpml.composition.data.ImportDirective;
+import net.dpml.composition.data.ValueDirective;
+
+import net.dpml.meta.info.Type;
+
+import net.dpml.system.SystemContext;
+
+/**
+ * This makes a dynamic proxy for an object. The object can be represented
+ * by one, some or all of it's interfaces.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: ApplianceInvocationHandler.java 2106 2005-03-21 18:46:10Z
mcconnell AT dpml.net $
+ */
+public final class ContextManagerInvocationHandler extends
ContextInvocationHandler
+{
+ //-------------------------------------------------------------------
+ // constructor
+ //-------------------------------------------------------------------
+
+ /**
+ * Create a context invocation handler.
+ *
+ * @param system the system context
+ * @param model the component model
+ */
+ public ContextManagerInvocationHandler(
+ SystemContext system, Holder holder )
+ throws LifecycleException, ModelException
+ {
+ super( system, holder );
+ }
+
+ //-------------------------------------------------------------------
+ // implementation
+ //-------------------------------------------------------------------
+
+ /**
+ * Invoke the specified method on underlying object.
+ * This is called by the proxy object.
+ *
+ * @param proxy the proxy object
+ * @param method the method invoked on proxy object
+ * @param args the arguments supplied to method
+ * @return the return value of method
+ * @throws Throwable if an error occurs
+ * @exception NullPointerException if any one of the proxy or method
arguments
+ * is null, or if the object instance has been destroyed
earlier.
+ */
+ public Object invoke( final Object proxy, final Method method, final
Object[] args )
+ throws Throwable, NullPointerException
+ {
+ String name = method.getName();
+ Class source = method.getDeclaringClass();
+ if( Object.class == method.getDeclaringClass() )
+ {
+ return method.invoke( this, args );
+ }
+ else if( Map.class == source )
+ {
+ Map map = getHolder().getContextMap();
+ return method.invoke( map, args );
+ }
+ else if( name.startsWith( "set" ) )
+ {
+ String s = name.substring( 3 );
+ String first = s.substring( 0, 1 ).toLowerCase();
+ String remainder = s.substring( 1 );
+ String key = first + remainder;
+ if( args.length < 1 )
+ {
+ final String error =
+ "Set method must have at least one parameter.";
+ throw new IllegalStateException( error );
+ }
+ Object value = args[0];
+ getHolder().getContextMap().put( key, value );
+ return null;
+ }
+ else
+ {
+ return super.invoke( proxy, method, args );
+ }
+ }
+}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/Holder.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/Holder.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/Holder.java
Sun Apr 10 22:37:29 2005
@@ -20,13 +20,19 @@

import java.net.URI;
import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.WeakHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Hashtable;

import net.dpml.automation.control.Monitor;
import net.dpml.automation.control.LifecycleException;
+import net.dpml.automation.control.ControlRuntimeException;
import net.dpml.automation.control.Monitor;

+import net.dpml.composition.models.EntryTable;
import net.dpml.composition.models.StandardComponentModel;

/**
@@ -38,20 +44,23 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Id: LifestyleManager.java 259 2004-10-30 07:24:40Z mcconnell $
*/
-public class Holder
+public class Holder implements Entry
{
- private final WeakHashMap m_proxies = new WeakHashMap();
+ private final Map m_proxies = new WeakHashMap();

private final Object m_key;
private final Monitor m_monitor;
private final StandardComponentModel m_model;
private final URI m_uri;
private final LifecycleHandler m_factory;
+ private final ContextMap m_context;
+ private final Object m_instance;

private boolean m_disposed = false;
- private Object m_instance;

- public Holder( Monitor monitor, LifecycleHandler factory,
StandardComponentModel model, Object key )
+ public Holder(
+ Monitor monitor, LifecycleHandler factory, StandardComponentModel
model, Object key )
+ throws LifecycleException, InvocationTargetException
{
m_monitor = monitor;
m_factory = factory;
@@ -68,7 +77,7 @@

//
// Create a uri identifying the instance. If the instance key is
LifestyleHandler.SELF then
- // we use the model's uri, otherwise the key bacomes a fragment part
of the uri using the model
+ // we use the model's uri, otherwise the key is assigned as the
fragment part of the uri using the model
// uri as the base.
//

@@ -82,22 +91,9 @@
String fragment = getFragment( getKey() );
m_uri = CompositionController.createInstanceURI( base, fragment
);
}
- }

- private String getFragment( Object key )
- {
- if( key instanceof String )
- {
- return (String) key;
- }
- else if( key instanceof Integer )
- {
- return key.toString();
- }
- else
- {
- return "" + System.identityHashCode( key );
- }
+ m_context = new ContextMap( model );
+ m_instance = factory.incarnate( this );
}

public Object getKey()
@@ -129,20 +125,19 @@
}
}

- public Object getInstance() throws Exception
+ public Object setValue( Object value )
{
- synchronized( m_proxies )
- {
- if( m_disposed )
- {
- throw new IllegalStateException( "disposed" );
- }
- if( null == m_instance )
- {
- m_instance = m_factory.incarnate( this );
- }
- return m_instance;
- }
+ throw new UnsupportedOperationException( "setValue/1" );
+ }
+
+ public Object getValue()
+ {
+ return m_instance;
+ }
+
+ public ContextMap getContextMap()
+ {
+ return m_context;
}

public void release( Object proxy )
@@ -180,11 +175,7 @@
}
m_proxies.clear();
m_model.remove( this );
- if( null != m_instance )
- {
- m_factory.etherialize( m_instance );
- m_instance = null;
- }
+ m_factory.etherialize( m_instance );
}
}

@@ -197,4 +188,49 @@
{
dispose();
}
+
+ private String getFragment( Object key )
+ {
+ if( key instanceof String )
+ {
+ return (String) key;
+ }
+ else if( key instanceof Integer )
+ {
+ return key.toString();
+ }
+ else
+ {
+ return "" + System.identityHashCode( key );
+ }
+ }
+
+ public static class ContextMap extends Hashtable
+ {
+ private StandardComponentModel m_model;
+
+ public ContextMap( StandardComponentModel model )
+ {
+ m_model = model;
+ }
+
+ public Object getValue( String key, Object[] args )
+ {
+ Object value = get( key );
+ if( null != value )
+ {
+ return value;
+ }
+ else
+ {
+ EntryTable table = getModel().getContextTable();
+ return table.getValue( key, args );
+ }
+ }
+
+ private StandardComponentModel getModel()
+ {
+ return m_model;
+ }
+ }
}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifecycleHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifecycleHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifecycleHandler.java
Sun Apr 10 22:37:29 2005
@@ -21,10 +21,12 @@
import java.net.URI;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import net.dpml.automation.control.LifecycleException;
+import net.dpml.automation.control.LifecycleRuntimeException;
import net.dpml.automation.control.Monitor;

import net.dpml.composition.models.StandardComponentModel;
@@ -46,6 +48,26 @@
*/
public class LifecycleHandler
{
+ public static Class getInnerClass( Class subject, String postfix )
+ {
+ Class[] classes = subject.getClasses();
+ return locateClass( postfix, classes );
+ }
+
+ public static Class locateClass( String postfix, Class[] classes )
+ {
+ for( int i=0; i<classes.length; i++ )
+ {
+ Class inner = classes[i];
+ String name = inner.getName();
+ if( name.endsWith( postfix ) )
+ {
+ return inner;
+ }
+ }
+ return null;
+ }
+
private final Monitor m_monitor;
private final SystemContext m_system;

@@ -61,7 +83,7 @@
*
* @return a new component instance
*/
- public Object incarnate( Holder holder ) throws LifecycleException
+ public Object incarnate( Holder holder ) throws LifecycleException,
InvocationTargetException
{
if( getMonitor().isDebugEnabled() )
{
@@ -73,36 +95,7 @@
}
StandardComponentModel model = holder.getModel();
URI uri = holder.getURI();
- return execute( model, uri );
- }
-
- /**
- * Execute the incarnation sequence and return a new
- * component instance.
- *
- * @return a new component instance
- */
- public Object incarnate( StandardComponentModel model ) throws
LifecycleException
- {
- if( getMonitor().isDebugEnabled() )
- {
- final String message =
- "Incarnating ["
- + model.getURI()
- + "].";
- getMonitor().debug( message );
- }
- return execute( model, null );
- }

- /**
- * Execute the incarnation sequence and return a new
- * component instance.
- *
- * @return a new component instance
- */
- private Object execute( StandardComponentModel model, URI id ) throws
LifecycleException
- {
Class subject = model.getDeploymentClass();
ClassLoader classloader = subject.getClassLoader();
Constructor constructor = getConstructor( subject );
@@ -120,21 +113,21 @@
}
else if( ( null != parts ) && parts.isAssignableFrom( c ) )
{
- args[i] = newPartsInvocationHandler( model, parts );
+ args[i] = newPartsInvocationHandler( holder, parts );
}
else if( ( null != context ) && context.isAssignableFrom( c ) )
{
- args[i] = newContextInvocationHandler( model, context, id );
+ args[i] = newContextInvocationHandler( holder, context );
}
else
{
final String error =
- "The componet class ["
+ "The component class ["
+ subject.getName()
+ "] decares an unsupported constructor parameter type ["
+ c.getName()
+ "].";
- throw new LifecycleException( error );
+ throw new LifecycleRuntimeException( error );
}
}

@@ -145,11 +138,7 @@
catch( Throwable e )
{
Class clazz = constructor.getDeclaringClass();
- final String error =
- "Internal error while attempting to instantiate the component
class ["
- + clazz.getName()
- + "].";
- throw new LifecycleException( error, e );
+ throw new LifecycleException( model, e );
}
}

@@ -191,7 +180,7 @@
}
}

- private Constructor getConstructor( Class subject ) throws
LifecycleException
+ private Constructor getConstructor( Class subject ) throws
LifecycleRuntimeException
{
Constructor[] constructors = subject.getConstructors();
if( constructors.length < 1 )
@@ -200,7 +189,7 @@
"The component class ["
+ subject.getName()
+ "] does not declare a public constructor.";
- throw new LifecycleException( error );
+ throw new LifecycleRuntimeException( error );
}
else if( constructors.length > 1 )
{
@@ -208,7 +197,7 @@
"The component class ["
+ subject.getName()
+ "] declares more than one public constructor.";
- throw new LifecycleException( error );
+ throw new LifecycleRuntimeException( error );
}
else
{
@@ -216,55 +205,35 @@
}
}

- private Class getInnerClass( Class subject, String postfix )
- {
- Class[] classes = subject.getClasses();
- return locateClass( postfix, classes );
- }
-
- private Class locateClass( String postfix, Class[] classes )
- {
- for( int i=0; i<classes.length; i++ )
- {
- Class inner = classes[i];
- String name = inner.getName();
- if( name.endsWith( postfix ) )
- {
- return inner;
- }
- }
- return null;
- }
-
- private Object newContextInvocationHandler( StandardComponentModel
model, Class clazz, URI uri ) throws LifecycleException
+ private Object newContextInvocationHandler( Holder holder, Class clazz )
throws LifecycleRuntimeException
{
try
{
- InvocationHandler handler = new ContextInvocationHandler(
m_system, model, uri );
- ClassLoader classloader =
model.getDeploymentClass().getClassLoader();
+ InvocationHandler handler = new ContextInvocationHandler(
m_system, holder );
+ ClassLoader classloader =
holder.getModel().getDeploymentClass().getClassLoader();
return Proxy.newProxyInstance( classloader, new Class[]{ clazz
}, handler );
}
catch( Throwable e )
{
final String error =
"Unexpected error while attempting to construct the context
invocation handler.";
- throw new LifecycleException( error, e );
+ throw new LifecycleRuntimeException( error, e );
}
}

- private Object newPartsInvocationHandler( StandardComponentModel model,
Class clazz ) throws LifecycleException
+ private Object newPartsInvocationHandler( Holder holder, Class clazz )
throws LifecycleException
{
try
{
- InvocationHandler handler = new PartsInvocationHandler( model );
- ClassLoader classloader =
model.getDeploymentClass().getClassLoader();
+ InvocationHandler handler = new PartsInvocationHandler(
m_system, holder );
+ ClassLoader classloader =
holder.getModel().getDeploymentClass().getClassLoader();
return Proxy.newProxyInstance( classloader, new Class[]{ clazz
}, handler );
}
catch( Throwable e )
{
final String error =
"Unexpected error while attempting to construct the parts
invocation handler.";
- throw new LifecycleException( error, e );
+ throw new LifecycleRuntimeException( error, e );
}
}


Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifestyleHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifestyleHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifestyleHandler.java
Sun Apr 10 22:37:29 2005
@@ -18,6 +18,8 @@

package net.dpml.composition.control;

+import java.lang.reflect.InvocationTargetException;
+
import net.dpml.automation.control.LifecycleException;
import net.dpml.automation.control.Monitor;

@@ -51,7 +53,7 @@
* @param model the model from which new or existing instances will be
resolved
* @return the key to the resolved instance
*/
- public Holder aquire( StandardComponentModel model ) throws
LifecycleException
+ public Holder aquire( StandardComponentModel model ) throws
LifecycleException, InvocationTargetException
{
final String lifestyle = model.getLifestylePolicy();
if( getMonitor().isDebugEnabled() )
@@ -113,7 +115,7 @@
* @param model the model from which new or existing instances will be
resolved
* @return the key to the resolved instance
*/
- public Holder aquire( StandardComponentModel model, Object key ) throws
LifecycleException
+ public Holder aquire( StandardComponentModel model, Object key ) throws
LifecycleException, InvocationTargetException
{
Holder holder = model.get( key );
if( null == holder )

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/PartsInvocationHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/PartsInvocationHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/PartsInvocationHandler.java
Sun Apr 10 22:37:29 2005
@@ -18,6 +18,7 @@

package net.dpml.composition.control;

+import java.net.URI;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
@@ -25,15 +26,19 @@
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Map;
+import java.util.Map.Entry;

import net.dpml.meta.info.Type;
import net.dpml.meta.info.PartDescriptor;

import net.dpml.automation.control.Controller;
+import net.dpml.automation.control.DelegationException;
import net.dpml.automation.model.Model;

import net.dpml.composition.models.StandardComponentModel;

+import net.dpml.system.SystemContext;
+
/**
* The parts invocation handler maps client request for 'get', 'create' and
* 'release' relative to keys identified by the method name. Method name
@@ -57,14 +62,14 @@
//-------------------------------------------------------------------

/**
- * The component type.
+ * The component model.
*/
- private final Type m_type;
+ private final Holder m_holder;

/**
- * The component type.
+ * The system context.
*/
- private final StandardComponentModel m_model;
+ private final SystemContext m_system;

//-------------------------------------------------------------------
// constructor
@@ -75,11 +80,11 @@
*
* @param model the component model
*/
- public PartsInvocationHandler( StandardComponentModel model )
+ public PartsInvocationHandler( SystemContext system, Holder holder )
throws NullPointerException
{
- m_model = model;
- m_type = model.getType();
+ m_holder = holder;
+ m_system = system;
}

//-------------------------------------------------------------------
@@ -101,45 +106,139 @@
public Object invoke( final Object proxy, final Method method, final
Object[] args )
throws Throwable, NullPointerException
{
+ try
+ {
+ return execute( proxy, method, args );
+ }
+ catch( InvocationTargetException e )
+ {
+ throw e.getTargetException();
+ }
+ }
+
+ StandardComponentModel getComponentModel()
+ {
+ return m_holder.getModel();
+ }
+
+ SystemContext getSystemContext()
+ {
+ return m_system;
+ }
+
+ /**
+ * Invoke the specified method on underlying object.
+ * This is called by the proxy object.
+ *
+ * @param proxy the proxy object
+ * @param method the method invoked on proxy object
+ * @param args the arguments supplied to method
+ * @return the return value of method
+ * @throws Throwable if an error occurs
+ * @exception NullPointerException if any one of the proxy or method
arguments
+ * is null, or if the object instance has been destroyed
earlier.
+ */
+ private Object execute( final Object proxy, final Method method, final
Object[] args )
+ throws Throwable, NullPointerException
+ {
Class source = method.getDeclaringClass();
if( Object.class == method.getDeclaringClass() )
{
return method.invoke( this, args );
}

- int semantic = getSemantic( method );
- String key = getKey( method, semantic );
- Model m = m_model.getPart( key );
- if( null == m )
- {
- final String error =
- "Unable to locate a part using the key ["
- + key
- + "] withing the component ["
- + m_model.getURI()
- + "].";
- throw new IllegalStateException( error );
- }
-
- Controller controller = m.getController();
+ int semantic = PartDescriptor.getPartSemantic( method );
+ String postfix = PartDescriptor.getPartPostfix( method );
+ String key = PartDescriptor.getPartKey( method, semantic );
+ URI uri = CompositionController.createURI( "parts", key );
+ final Entry provider = getComponentModel().getEntry( uri );
if( PartDescriptor.GET == semantic )
{
- if( null == args )
+ if( null == postfix )
{
- return controller.resolve( m );
+ if( null == args )
+ {
+ //
+ // return the default value from the assigned provider
+ //
+
+ return provider.getValue();
+ }
+ else if( args.length == 1 )
+ {
+ //
+ // return an identifiable value from the assigned
provider
+ //
+
+ Object arg = args[0];
+ if( provider instanceof Model )
+ {
+ Model model = (Model) provider;
+ Controller controller = model.getController();
+ return controller.resolve( model, arg );
+ }
+ else
+ {
+ final String error =
+ "The request for the application of 'resolve/1'
for the key ["
+ + key
+ + "] in the component ["
+ + getComponentModel().getURI()
+ + "] could not be applied as the entry referenced
by the key is not an instance of "
+ + Model.class.getName()
+ + ".";
+ throw new IllegalStateException( error );
+ }
+ }
+ else
+ {
+ final String error =
+ "Illegal number of parameters in ["
+ + method.getName()
+ + "].";
+ throw new IllegalStateException( error );
+ }
}
- else if( args.length == 0 )
+ else if( PartDescriptor.CONTEXT_MANAGER_KEY.equals( postfix ) )
{
- return controller.resolve( m );
+ Class clazz = method.getReturnType();
+
+ if( !clazz.isInterface() )
+ {
+ final String error =
+ "The request for the context manager for the key ["
+ + key
+ + "] in the component ["
+ + getComponentModel().getURI()
+ + "] could not be completed as the requested return
type ["
+ + clazz.getName()
+ + "] is not an interface.";
+ throw new IllegalStateException( error );
+ }
+ if( provider instanceof StandardComponentModel )
+ {
+ StandardComponentModel standard =
(StandardComponentModel) provider;
+ Controller controller = standard.getController();
+ Holder holder = (Holder) controller.create( standard );
+ SystemContext system = getSystemContext();
+ ClassLoader classloader = standard.getClassLoader();
+ ContextManagerInvocationHandler handler =
+ new ContextManagerInvocationHandler( system, holder );
+ return Proxy.newProxyInstance( classloader, new Class[]{
clazz }, handler );
+ }
+ else
+ {
+ throw new UnsupportedOperationException(
method.getName() );
+ }
}
- else if( args.length == 1 )
+ else if( PartDescriptor.PARTS_MANAGER_KEY.equals( postfix ) )
{
- return controller.resolve( m, args[0] );
+ throw new UnsupportedOperationException( method.getName() );
}
else
{
final String error =
- "Illegal number of parameters supplied under the 'resolve'
method ["
+ "Unrecognized postfix in the part accessor method ["
+ method.getName()
+ "].";
throw new IllegalStateException( error );
@@ -147,14 +246,80 @@
}
else if( PartDescriptor.CREATE == semantic )
{
- return controller.create( m );
+ if( null == args )
+ {
+ if( provider instanceof Model )
+ {
+ Model model = (Model) provider;
+ return invokeCreate( key, model );
+ }
+ else
+ {
+ final String error =
+ "The request for the application of 'create/0' for the
key ["
+ + key
+ + "] in the component ["
+ + getComponentModel().getURI()
+ + "] could not be applied as the entry referenced by
the key is not an instance of "
+ + Model.class.getName()
+ + ".";
+ throw new IllegalStateException( error );
+ }
+ }
+ else if( args.length == 1 )
+ {
+ Object arg = args[0];
+ if( provider instanceof Model )
+ {
+ Model model = (Model) provider;
+ return invokeCreate( key, model, arg );
+ }
+ else
+ {
+ final String error =
+ "The request for the application of 'create/1' for the
key ["
+ + key
+ + "] in the component ["
+ + getComponentModel().getURI()
+ + "] could not be applied as the entry refereced by
the key is not an instance of "
+ + Model.class.getName()
+ + ".";
+ throw new IllegalStateException( error );
+ }
+ }
+ else
+ {
+ final String error =
+ "Illegal number of parameters supplied under the 'create'
method ["
+ + method.getName()
+ + "].";
+ throw new IllegalStateException( error );
+ }
}
else if( PartDescriptor.RELEASE == semantic )
{
if( args.length == 1 )
{
- controller.release( args[0] );
- return null;
+ Object arg = args[0];
+ if( provider instanceof Model )
+ {
+ Model model = (Model) provider;
+ Controller controller = model.getController();
+ controller.release( arg );
+ return null;
+ }
+ else
+ {
+ final String error =
+ "The request for the application of 'release/1' for
the instance ["
+ + arg
+ + "] in the component ["
+ + getComponentModel().getURI()
+ + "] could not be applied as the entry referenced by
the key is not an instance of "
+ + Model.class.getName()
+ + ".";
+ throw new IllegalStateException( error );
+ }
}
else
{
@@ -175,77 +340,66 @@
}
}

- //-------------------------------------------------------------------
- // implementation
- //-------------------------------------------------------------------
-
- private int getSemantic( Method method )
+ private Entry invokeCreate( String key, Model provider ) throws
DelegationException
{
- String name = method.getName();
- if( name.startsWith( PartDescriptor.GET_KEY ) )
+ Controller controller = provider.getController();
+ try
{
- return PartDescriptor.GET;
+ return controller.create( provider );
}
- else if( name.startsWith( PartDescriptor.CREATE_KEY ) )
+ catch( Throwable e )
{
- return PartDescriptor.CREATE;
- }
- else if( name.startsWith( PartDescriptor.RELEASE_KEY ) )
- {
- return PartDescriptor.RELEASE;
- }
- else
- {
- final String error =
- "Unrecognized part accessor method signature ["
- + name
- + "]";
- throw new IllegalArgumentException( error );
+ final DelegationException exception =
+ createDelegationException( key, provider, "create/0", e );
+ throw exception;
}
}

- private String getKey( Method method, int semantic )
+ private Entry invokeCreate( String key, Model provider, Object arg )
throws DelegationException
{
- String name = method.getName();
- if( PartDescriptor.GET == semantic )
+ Controller controller = provider.getController();
+ try
{
- return formatKey( name, 3 );
+ return controller.create( provider, arg );
}
- else if( PartDescriptor.CREATE == semantic )
- {
- return formatKey( name, 6 );
- }
- else if( PartDescriptor.RELEASE == semantic )
+ catch( Throwable e )
{
- return formatKey( name, 7 );
- }
- else
- {
- final String error =
- "Unrecognized part accessor method signature ["
- + name
- + "]";
- throw new IllegalArgumentException( error );
+ final DelegationException exception =
+ createDelegationException( key, provider, "create/1", e );
+ throw exception;
}
}

- private String formatKey( String method, int offset )
- {
- String string = method.substring( offset );
- return formatKey( string );
- }
-
- private String formatKey( String key )
+ private DelegationException createDelegationException( String key, Model
provider, String function, Throwable e )
{
- if( key.length() < 1 )
+ URI uri = provider.getURI();
+ final String error =
+ "The request for the invocation of "
+ + function
+ + " for the key ["
+ + key
+ + "] in the component ["
+ + getComponentModel().getURI()
+ + "] could not be completed as the provider ["
+ + uri
+ + "] raised an exception.";
+
+ if( e instanceof InvocationTargetException )
+ {
+ InvocationTargetException target = (InvocationTargetException) e;
+ final Throwable cause = target.getTargetException();
+ return new DelegationException( uri, error, cause );
+ }
+ else
{
- throw new IllegalArgumentException( "key" );
+ return new DelegationException( uri, error, e );
}
- String first = key.substring( 0, 1 ).toLowerCase();
- String remainder = key.substring( 1 );
- return first + remainder;
}

+ //-------------------------------------------------------------------
+ // implementation
+ //-------------------------------------------------------------------
+
private void assertNotNull( Object object, String key )
throws NullPointerException
{
@@ -259,7 +413,7 @@
{
StringBuffer buffer = new StringBuffer();
buffer.append( "[parts {" );
- PartDescriptor[] entries = m_type.getPartDescriptors();
+ PartDescriptor[] entries =
getComponentModel().getType().getPartDescriptors();
for( int i=0; i<entries.length; i++ )
{
PartDescriptor p = entries[i];

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ValueHolder.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ValueHolder.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2004 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.composition.control;
+
+import java.net.URI;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.util.WeakHashMap;
+import java.util.Map.Entry;
+
+import net.dpml.automation.control.Monitor;
+import net.dpml.automation.control.LifecycleException;
+import net.dpml.automation.control.ControlRuntimeException;
+import net.dpml.automation.control.Monitor;
+
+import net.dpml.composition.models.StandardComponentModel;
+
+/**
+ * A lifestyle handler provides support for the aquisition and release
+ * of component instances. An implementation is responsible for the
+ * handling of new instance creation based on lifestyle policy declared
+ * in a component model.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: LifestyleManager.java 259 2004-10-30 07:24:40Z mcconnell $
+ */
+public class ValueHolder implements Entry
+{
+ private final Object m_key;
+ private Object m_value;
+
+ public ValueHolder( Object key, Object value )
+ {
+ m_key = key;
+ m_value = value;
+ }
+
+ public Object getKey()
+ {
+ return m_key;
+ }
+
+ public Object getValue()
+ {
+ return m_value;
+ }
+
+ public Object setValue( Object value )
+ {
+ Object current = m_value;
+ m_value = value;
+ return current;
+ }
+}

Copied:
development/main/metro/composition/control/src/main/net/dpml/composition/models/AbstractModel.java
(from r2259,
development/main/metro/composition/control/src/main/net/dpml/composition/models/EntryModel.java)
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/models/EntryModel.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/AbstractModel.java
Sun Apr 10 22:37:29 2005
@@ -19,11 +19,14 @@
package net.dpml.composition.models;

import java.net.URI;
+import java.util.Map.Entry;

import net.dpml.automation.model.Model;
import net.dpml.automation.model.ModelException;
import net.dpml.automation.control.Controller;

+import net.dpml.composition.control.CompositionController;
+
import net.dpml.meta.info.EntryDescriptor;

/**
@@ -32,13 +35,14 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Id: DefaultEntryModel.java 1518 2005-01-17 17:13:05Z niclas $
*/
-public abstract class EntryModel implements Model
+public abstract class AbstractModel implements Model
{
//--------------------------------------------------------------
// state
//--------------------------------------------------------------

- private Controller m_controller;
+ private CompositionController m_controller;
+ private String m_key;

//--------------------------------------------------------------
// constructor
@@ -50,14 +54,19 @@
* @param descriptor the context entry descriptor
* @exception NullPointerException is the descriptor argument is null.
*/
- public EntryModel( Controller controller )
+ public AbstractModel( CompositionController controller, String key )
throws NullPointerException
{
if( controller == null )
{
throw new NullPointerException( "controller" );
}
+ if( key == null )
+ {
+ throw new NullPointerException( "key" );
+ }
m_controller = controller;
+ m_key = key;
}

//--------------------------------------------------------------
@@ -65,60 +74,59 @@
//--------------------------------------------------------------

/**
- * Return a resource relative to the supplied urn.
- *
- * @param urn the uniform resource identifier
- * @return the resource
- * @exception IllegalStateException if the supplied urn is not valid
+ * Return the primary controller assigned to the model.
+ * @return the primary controller
*/
- public Object getResource( URI urn )
- {
- return m_controller.getResource( this, urn );
- }
-
- public Object create() throws Exception
- {
- return getValue();
- }
-
- public Object resolve() throws Exception
+ public Controller getController()
{
- return getValue();
+ return getCompositionController();
}

- public Object resolve( Object key ) throws Exception
+ public CompositionController getCompositionController()
{
- throw new UnsupportedOperationException( "resolve/1" );
+ return m_controller;
}

- public void release( Object object )
+ /**
+ * Return a resource relative to the supplied urn.
+ *
+ * @param urn the uniform resource identifier
+ * @return the resource
+ * @exception IllegalStateException if the supplied urn is not valid
+ */
+ public Object getResource( URI urn )
{
+ return getController().getResource( this, urn );
}

- public Controller getController()
+ public Object getKey()
{
- return m_controller;
+ return m_key;
}

- public abstract String getName();
-
public abstract URI getPartition();

public abstract URI getURI();

- public Model getModel( URI uri )
- {
- return null;
- }
-
//--------------------------------------------------------------
- // EntryModel
+ // Entry
//--------------------------------------------------------------

/**
- * Return the context entry value.
+ * Return the entry value.
*
- * @return the context entry value
+ * @return the entry value
*/
- public abstract Object getValue() throws ModelException;
+ public abstract Object getValue();
+
+ /**
+ * Set the value.
+ *
+ * @param value the new value
+ * @return the old value
+ */
+ public Object setValue( Object value )
+ {
+ throw new UnsupportedOperationException( "setValue/1" );
+ }
}

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/models/EntryTable.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/EntryTable.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2005 Stephen J. McConnell
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dpml.composition.models;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Hashtable;
+import java.util.WeakHashMap;
+import java.util.List;
+import java.util.LinkedList;
+import java.net.URI;
+
+import net.dpml.automation.model.Model;
+import net.dpml.automation.model.ModelException;
+import net.dpml.automation.model.ModelRuntimeException;
+import net.dpml.automation.model.ServiceClassNotFoundException;
+import net.dpml.automation.model.TypeClassNotFoundException;
+import net.dpml.automation.model.PartClassNotFoundException;
+import net.dpml.automation.control.EntryNotFoundException;
+import net.dpml.automation.control.Controller;
+import net.dpml.automation.control.DelegationException;
+import net.dpml.automation.part.Part;
+
+import net.dpml.composition.data.ReferenceDirective;
+import net.dpml.composition.data.ComponentProfile;
+import net.dpml.composition.data.ContextDirective;
+import net.dpml.composition.data.DependencyDirective;
+import net.dpml.composition.control.CompositionClassLoader;
+import net.dpml.composition.control.CompositionController;
+import net.dpml.composition.control.Holder;
+
+import net.dpml.meta.info.Type;
+import net.dpml.meta.info.ServiceDescriptor;
+import net.dpml.meta.info.DependencyDescriptor;
+import net.dpml.meta.info.PartDescriptor;
+
+/**
+ * The parts model is a model of the set of parts maintained by a parent
model.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public class EntryTable
+{
+ private final Map m_entries = new Hashtable();
+ private final StandardComponentModel m_model;
+ private final Model m_parent;
+
+ /**
+ * Creation of a new entry table.
+ *
+ * @param model the model
+ * @param parent the enclosing parent model
+ * @param partition the enclosing component uri
+ * @param classloader the classloader established as the parent for the
parts
+ * @param profile the component profile from which initial default values
are established
+ */
+ public EntryTable(
+ StandardComponentModel model, Model parent )
+ throws DelegationException, ModelException
+ {
+ m_model = model;
+ m_parent = parent;
+ }
+
+ public Entry getEntry( String key )
+ {
+ if( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
+ return (Entry) m_entries.get( key );
+ }
+
+ public void addEntry( String key, Part part ) throws
DelegationException, ModelException
+ {
+ if( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
+ if( null == part )
+ {
+ throw new NullPointerException( "part" );
+ }
+ if( m_entries.containsKey( key ) )
+ {
+ throw new DuplicateKeyException( key );
+ }
+
+ Model parent = getParentModel();
+ if( part instanceof ReferenceDirective )
+ {
+ ReferenceDirective ref = (ReferenceDirective) part;
+ URI uri = ref.getURI();
+ if( null == m_parent )
+ {
+ final String error =
+ "The entry ["
+ + key
+ + "] in the component ["
+ + getComponentModel().getURI()
+ + "] is requesting a reference to a part ["
+ + uri
+ + "] which cannot be resolved as the component has no
enclosing parent.";
+ throw new ModelException( error );
+ }
+ else
+ {
+ try
+ {
+ Entry model =
getComponentModel().getController().getEntry( parent, uri );
+ addEntry( key, model );
+ }
+ catch( EntryNotFoundException e )
+ {
+ final String error =
+ "Could not add part under the key ["
+ + key
+ + "] because ["
+ + uri
+ + "] was not found.";
+ throw new ModelException( error, e );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Could not add part under the key ["
+ + key
+ + "] in the model ["
+ + getComponentModel().getURI()
+ + "] due to an unexpected error when invoking the
query ["
+ + uri
+ + "].";
+ throw new ModelException( error, e );
+ }
+ }
+ }
+ else
+ {
+ ClassLoader classloader = getComponentModel().getClassLoader();
+ Model model = getComponentModel();
+ Controller controller = model.getController();
+ Entry entry = controller.getModel( model, classloader, part, key
);
+ addEntry( key, entry );
+ }
+ }
+
+ public void addEntry( String key, Entry entry ) throws
DelegationException, ModelException
+ {
+ if( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
+ if( null == entry )
+ {
+ throw new NullPointerException( "entry" );
+ }
+ if( m_entries.containsKey( key ) )
+ {
+ throw new DuplicateKeyException( key );
+ }
+ setEntry( key, entry );
+ }
+
+ public void setEntry( String key, Entry value )
+ {
+ if( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
+ synchronized( m_entries )
+ {
+ m_entries.put( key, value );
+ }
+ }
+
+ public Object getValue( String key, Object[] args )
+ {
+ Entry entry = getEntry( key );
+ if( null == entry )
+ {
+ return getDefaultValue( args );
+ }
+ else
+ {
+ Object value = entry.getValue();
+ if( null == value )
+ {
+ return getDefaultValue( args );
+ }
+ else
+ {
+ return value;
+ }
+ }
+ }
+
+ private Object getDefaultValue( Object[] args )
+ {
+ if( null == args )
+ {
+ return null;
+ }
+ else if( args.length < 1 )
+ {
+ return null;
+ }
+ else
+ {
+ return args[0];
+ }
+ }
+
+ private StandardComponentModel getComponentModel()
+ {
+ return m_model;
+ }
+
+ private Model getParentModel()
+ {
+ return m_parent;
+ }
+}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/models/PartsModel.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/models/PartsModel.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/PartsModel.java
Sun Apr 10 22:37:29 2005
@@ -20,6 +20,7 @@

import java.io.Serializable;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Hashtable;
import java.util.WeakHashMap;
import java.util.List;
@@ -32,6 +33,7 @@
import net.dpml.automation.model.ServiceClassNotFoundException;
import net.dpml.automation.model.TypeClassNotFoundException;
import net.dpml.automation.model.PartClassNotFoundException;
+import net.dpml.automation.control.EntryNotFoundException;
import net.dpml.automation.control.Controller;
import net.dpml.automation.control.DelegationException;
import net.dpml.automation.part.Part;
@@ -83,16 +85,16 @@
m_parent = parent;
}

- public Model getModel( String key )
+ public Entry getEntry( String key )
{
if( null == key )
{
throw new NullPointerException( "key" );
}
- return (Model) m_parts.get( key );
+ return (Entry) m_parts.get( key );
}

- public void addModel( String key, Part part ) throws
DelegationException, ModelException
+ public void addEntry( String key, Part part ) throws
DelegationException, ModelException
{
if( null == key )
{
@@ -133,11 +135,14 @@

void addPartToCollection( String key, Part part, boolean validate )
throws DelegationException, ModelException
{
- Model model = loadModelFromPart( part );
if( m_parts.containsKey( key ) )
{
throw new DuplicateKeyException( key );
}
+ StandardComponentModel parent = getParentModel();
+ URI partition = getPartition();
+ ClassLoader classloader = getClassLoader();
+ Entry model = getController().getModel( parent, classloader, part,
key );
m_parts.put( key, model );
if( validate )
{
@@ -145,14 +150,6 @@
}
}

- private Model loadModelFromPart( Part part ) throws DelegationException,
ModelException, DuplicateKeyException
- {
- StandardComponentModel parent = getParentModel();
- URI partition = getPartition();
- ClassLoader classloader = getClassLoader();
- return getController().getModel( parent, classloader, part );
- }
-
private void build()
{
StandardComponentModel parent = getParentModel();
@@ -164,7 +161,7 @@
{
PartDescriptor descriptor = descriptors[i];
String key = descriptor.getKey();
- Model model = (Model) m_parts.get( key );
+ Entry model = (Entry) m_parts.get( key );
if( null == model )
{
Exception e = new MissingPartException( parent, key );

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/models/StandardComponentModel.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/models/StandardComponentModel.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/StandardComponentModel.java
Sun Apr 10 22:37:29 2005
@@ -25,6 +25,7 @@
import java.util.WeakHashMap;
import java.util.List;
import java.util.LinkedList;
+import java.util.Map.Entry;

import net.dpml.automation.model.Model;
import net.dpml.automation.model.ModelException;
@@ -34,6 +35,8 @@
import net.dpml.automation.control.Controller;
import net.dpml.automation.control.DelegationException;
import net.dpml.automation.control.PartNotFoundException;
+import net.dpml.automation.control.EntryNotFoundException;
+import net.dpml.automation.control.InvalidQueryException;
import net.dpml.automation.part.Part;
import net.dpml.automation.part.PartReference;

@@ -58,25 +61,23 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
*/
-public class StandardComponentModel implements Model, Serializable
+public class StandardComponentModel extends AbstractModel implements Model,
Serializable
{
private final ComponentProfile m_profile;
private final ClassLoader m_classloader;
private final URI m_partition;
- private final CompositionController m_controller;
private final PartsModel m_parts;
+ private final EntryTable m_context;
+ private final List m_errors = new LinkedList();

private final Class m_class;
private final Type m_type;
private final Class[] m_interfaces;

- private transient Map m_holders = new WeakHashMap();
- private final Map m_providers = new Hashtable();
- private final List m_errors = new LinkedList();
+ private final Map m_holders = new WeakHashMap();

- private String m_name;
- private String m_lifestyle;
- private URI m_uri;
+ private final String m_lifestyle;
+ private final URI m_uri;

/**
* Creation of a new root component model.
@@ -85,12 +86,13 @@
* @param partition a name defining the partition that this model exists
within
* @param classloader the classloader established for this model
* @param profile the component profile from which initial default values
are established
+ * @param name the name of the model
*/
public StandardComponentModel(
- CompositionController controller, URI partition, ClassLoader
classloader, ComponentProfile profile )
+ CompositionController controller, URI partition, ClassLoader
classloader, ComponentProfile profile, String name )
throws DelegationException, ModelException
{
- this( controller, null, partition, classloader, profile );
+ this( controller, null, partition, classloader, profile, name );
}

/**
@@ -108,23 +110,23 @@
* @param partition a name defineing the partition that this model exists
within
* @param classloader the classloader established for this model
* @param profile the component profile from which initial default values
are established
+ * @param name the name of the model
*/
public StandardComponentModel(
- CompositionController controller, Model parent, URI partition,
ClassLoader classloader, ComponentProfile profile )
+ CompositionController controller, Model parent, URI partition,
ClassLoader classloader,
+ ComponentProfile profile, String name )
throws DelegationException, ModelException
{
- m_controller = controller;
+ super( controller, name );
+
m_partition = partition;
m_classloader = classloader;
m_profile = profile;

+ m_uri = CompositionController.createURI( partition, name );
m_class = loadComponentClass( classloader, profile );
m_type = controller.loadType( m_class );

- String name = profile.getName();
- m_name = name;
- m_uri = CompositionController.createURI( partition, name );
-
//
// Construct an array of the interface classes that the component
// exposes as public services - these will be used when constructing
@@ -156,7 +158,8 @@
// (or alternatively - we pass the classloader chain into the
constructor)
//

- m_parts = new PartsModel( controller, this, getURI(), classloader );
+ URI uri = getURI();
+ m_parts = new PartsModel( controller, this, uri, classloader );
PartReference[] parts = profile.getParts();
for( int i=0; i<parts.length; i++ )
{
@@ -167,9 +170,14 @@
}

//
- // build the context model
+ // Build the context model. The initial population of the context
+ // model is establised by reading in the set of PartReference
instances
+ // contained within the ContextDirective. Each part reference is
located
+ // using a context entry key. The part reference also holds the
part
+ // that will be used to construct a context entry model.
//

+ m_context = new EntryTable( this, parent );
ContextDirective context = profile.getContextDirective();
EntryDescriptor[] entries = m_type.getContext().getEntries();
for( int i=0; i<entries.length; i++ )
@@ -193,8 +201,7 @@
else
{
Part part = reference.getPart();
- Model m = loadModel( key, part, controller, classloader,
parent );
- m_providers.put( key, m );
+ getContextTable().addEntry( key, part );
}
}

@@ -230,77 +237,25 @@
else
{
Part part = reference.getPart();
- Model m = loadModel( key, part, controller, classloader,
parent );
- m_providers.put( key, m );
+ getContextTable().addEntry( key, part );
}
}
}

- /**
- * Return a resource relative to the supplied urn.
- *
- * @param urn the uniform resource identifier
- * @return the resource
- * @exception IllegalStateException if the supplied urn is not valid
- */
- public Object getResource( URI urn )
- {
- return m_controller.getResource( this, urn );
- }
-
- /**
- * <p>Load a part that is referenced by a PartReference. The part
reference contains a
- * uri that identifies the part to include in this model. Recognized uri
schemes include
- * the following:</p>
- * <ol>
- * <li>context:[key] - a reference to a context entry in the enclosing
model</p>
- * <li>parts:[key] - a reference to a parts entry in the enclosing
model</p>
- * </ol>
- *
- * @param reference the part reference
- * @param controller the controller handling this part type
- * @param classloader the assigned classloader
- * @param parent the parent model
- */
- private Model loadModel( String key, Part part, Controller controller,
ClassLoader classloader, Model parent )
- throws DelegationException, ModelException
+ public Object getValue()
{
- if( part instanceof ValueDirective )
- {
- ValueDirective directive = (ValueDirective) part;
- return new ValueModel( key, controller, classloader, directive,
this );
- }
- else if( part instanceof ReferenceDirective )
- {
- ReferenceDirective ref = (ReferenceDirective) part;
- URI uri = ref.getURI();
- if( null == parent )
- {
- final String error =
- "The component ["
- + this
- + "] is requesting the resolution of a dependency ["
- + uri.toString()
- + "] which cannot be resolved as this component has no
enclosing parent.";
- throw new ModelException( error );
- }
- Model m = controller.getModel( parent, uri );
- if( null != m )
- {
- return m;
- }
- else
- {
- URI enclosing = parent.getURI();
- Exception cause = new PartNotFoundException( enclosing, uri
);
- String message = cause.getMessage();
- throw new ModelException( message, cause );
- }
- }
- else
- {
- return controller.getModel( this, classloader, part );
- }
+ try
+ {
+ return getController().resolve( this );
+ }
+ catch( Exception e )
+ {
+ final String error =
+ "Unable to establish value due in ["
+ + this
+ + "].";
+ throw new ModelRuntimeException( error, e );
+ }
}

public Throwable[] getIssues()
@@ -315,63 +270,16 @@
}
}

- public Object create() throws Exception
- {
- validate();
- return getController().create( this );
- }
-
- public Object resolve() throws Exception
- {
- validate();
- return getController().resolve( this );
- }
-
- public Object resolve( Object key ) throws Exception
- {
- validate();
- return getController().resolve( this, key );
- }
-
- public void release( Object object )
- {
- getController().release( object );
- }
-
public String getLifestylePolicy()
{
return m_lifestyle;
}

- public Model getPart( String spec )
- {
- //
- // the following is too limited - in particular we are
- // not handling paths in the form aaa/bbb/ccc
- //
- return m_parts.getModel( spec );
- }
-
public ClassLoader getClassLoader()
{
return m_classloader;
}

- public Controller getController()
- {
- return getCompositionController();
- }
-
- public CompositionController getCompositionController()
- {
- return m_controller;
- }
-
- public String getName()
- {
- return m_name;
- }
-
public URI getPartition()
{
return m_partition;
@@ -397,32 +305,43 @@
return m_interfaces;
}

- public ContextDirective getContextDirective()
- {
- return m_profile.getContextDirective();
- }
-
- public Model getModel( URI uri )
+ public Entry getEntry( URI uri ) throws EntryNotFoundException,
InvalidQueryException
{
+ Entry model = null;
final String scheme = uri.getScheme();
final String path = uri.getSchemeSpecificPart();
if( "parts".equals( scheme ) )
{
- return getPart( path );
+ model = getPartsModel().getEntry( path );
}
else if( "context".equals( scheme ) )
{
- return getProvider( path );
+ model = getContextTable().getEntry( path );
+ }
+ else
+ {
+ URI ref = getURI();
+ throw new InvalidQueryException( ref, uri );
+ }
+ if( null == model )
+ {
+ URI ref = getURI();
+ throw new EntryNotFoundException( ref, uri );
}
else
{
- return null;
+ return model;
}
}

- private Model getProvider( String key )
+ public EntryTable getContextTable()
+ {
+ return m_context;
+ }
+
+ public PartsModel getPartsModel()
{
- return (Model) m_providers.get( key );
+ return m_parts;
}

public void put( Holder holder )

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/models/ValueModel.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/models/ValueModel.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/ValueModel.java
Sun Apr 10 22:37:29 2005
@@ -25,6 +25,7 @@
import net.dpml.automation.control.Controller;
import net.dpml.automation.model.Model;
import net.dpml.automation.model.ModelException;
+import net.dpml.automation.model.ModelRuntimeException;

import net.dpml.composition.data.ValueDirective;
import net.dpml.composition.data.ValueDirective.Value;
@@ -38,13 +39,12 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Id: DefaultConstructorModel.java 1518 2005-01-17 17:13:05Z
niclas $
*/
-public class ValueModel extends EntryModel
+public class ValueModel extends AbstractModel
{
//--------------------------------------------------------------
// state
//--------------------------------------------------------------

- private final String m_name;
private final URI m_uri;
private final ValueDirective m_directive;
private final ClassLoader m_classloader;
@@ -64,10 +64,10 @@
* @exception NullArgumentException if either the directive argument or
the
* context argument is null.
*/
- public ValueModel( String name, Controller controller, ClassLoader
classloader, ValueDirective directive, Model model )
+ public ValueModel( String name, CompositionController controller,
ClassLoader classloader, ValueDirective directive, Model model )
throws ModelException, NullPointerException
{
- super( controller );
+ super( controller, name );
if( directive == null )
{
throw new NullPointerException( "directive" );
@@ -76,11 +76,6 @@
{
throw new NullPointerException( "model" );
}
- if( null == name )
- {
- throw new NullPointerException( "name" );
- }
- m_name = name;
m_directive = directive;
m_classloader = classloader;
m_model = model;
@@ -91,11 +86,6 @@
//validate();
}

- public String getName()
- {
- return m_name;
- }
-
public URI getPartition()
{
return m_model.getURI();
@@ -200,14 +190,12 @@
* @return the context entry value
*/
public Object getValue()
- throws ModelException
{
if( m_value != null )
{
return m_value;
}

- String target = m_name;
try
{
String argument = m_directive.getLocalValue();
@@ -223,19 +211,17 @@
//{
// m_value = object;
//}
-
return object;
-
}
catch( Throwable e )
{
final String error =
"Cannot establish a constructed value in the model ["
+ getURI()
- + "] withing the value type ["
- + getURI()
+ + "] withing the value ["
+ + getKey()
+ "].";
- throw new ModelException( error, e );
+ throw new ModelRuntimeException( error, e );
}
}


Modified:
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContextModel.java
==============================================================================
---
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContextModel.java
(original)
+++
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContextModel.java
Sun Apr 10 22:37:29 2005
@@ -20,10 +20,10 @@

import java.util.Hashtable;
import java.util.Map;
+import java.util.Map.Entry;

import net.dpml.automation.part.Part;
import net.dpml.automation.part.PartReference;
-import net.dpml.automation.model.Model;

import net.dpml.composition.data.ValueDirective;
import net.dpml.composition.data.ContextDirective;
@@ -237,9 +237,9 @@
*
* @return the entry models
*/
- public Model[] getEntryModels()
+ public Entry[] getEntryModels()
{
- return (Model[]) m_map.values().toArray( new Model[0] );
+ return (Entry[]) m_map.values().toArray( new Entry[0] );
}

/**
@@ -247,9 +247,9 @@
*
* @return the entry model or null if tyhe key is unknown
*/
- public Model getEntryModel( String key )
+ public Entry getEntryModel( Object key )
{
- return (Model) m_map.get( key );
+ return (Entry) m_map.get( key );
}

/**
@@ -258,7 +258,7 @@
* @param key the entry key
* @param model the entry model
*/
- public void setEntryModel( String key, Model model )
+ public void setEntryModel( Object key, Entry model )
{
m_map.put( key, model );
}
@@ -269,7 +269,7 @@
* @param key the entry key
* @param value the entry value
*/
- public void setEntry( String key, Object value )
+ public void setEntry( Object key, Object value )
{
throw new UnsupportedOperationException( "setEntry" );
// EntryDescriptor descriptor = m_descriptor.getEntry( key );

Modified:
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultEntryModel.java
==============================================================================
---
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultEntryModel.java
(original)
+++
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultEntryModel.java
Sun Apr 10 22:37:29 2005
@@ -19,8 +19,7 @@
package net.dpml.composition.model.impl;

import java.net.URI;
-
-import net.dpml.automation.control.Controller;
+import java.util.Map.Entry;

import net.dpml.composition.model.EntryModel;
import net.dpml.composition.model.ModelException;
@@ -64,54 +63,6 @@
}

//==============================================================
- // Model
- //==============================================================
-
- public Object create() throws Exception
- {
- return getValue();
- }
-
- public Object resolve() throws Exception
- {
- return getValue();
- }
-
- public Object resolve( Object key ) throws Exception
- {
- throw new UnsupportedOperationException( "resolve/1" );
- }
-
- public void release( Object instance )
- {
- }
-
- public Controller getController()
- {
- throw new UnsupportedOperationException( "getController/0" );
- }
-
- public URI getPartition()
- {
- throw new UnsupportedOperationException( "getQualifiedName/0" );
- }
-
- public URI getURI()
- {
- throw new UnsupportedOperationException( "getURI/0" );
- }
-
- public String getName()
- {
- throw new UnsupportedOperationException( "getName/0" );
- }
-
- public Object getResource( URI urn )
- {
- throw new UnsupportedOperationException( "getResource/0" );
- }
-
- //==============================================================
// EntryModel
//==============================================================

@@ -120,7 +71,7 @@
*
* @return the key
*/
- public String getKey()
+ public Object getKey()
{
return m_descriptor.getKey();
}
@@ -130,6 +81,16 @@
*
* @return the context entry value
*/
- public abstract Object getValue() throws ModelException;
+ public abstract Object getValue();

+ /**
+ * Set the entry value.
+ *
+ * @param the new value
+ * @return the old value
+ */
+ public Object setValue( Object value )
+ {
+ throw new UnsupportedOperationException( "setvalue/1" );
+ }
}

Modified:
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultImportModel.java
==============================================================================
---
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultImportModel.java
(original)
+++
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultImportModel.java
Sun Apr 10 22:37:29 2005
@@ -115,7 +115,7 @@
*
* @return the context entry value
*/
- public Object getValue() throws ModelException
+ public Object getValue()
{
if( m_value != null ) return m_value;
return getStandardEntry( m_key );

Modified:
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultValueModel.java
==============================================================================
---
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultValueModel.java
(original)
+++
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultValueModel.java
Sun Apr 10 22:37:29 2005
@@ -27,6 +27,7 @@

import net.dpml.composition.model.EntryModel;
import net.dpml.composition.model.ModelException;
+import net.dpml.composition.model.ModelRuntimeException;

import net.dpml.composition.provider.ComponentContext;

@@ -209,7 +210,6 @@
* @return the context entry value
*/
public Object getValue()
- throws ModelException
{
if( m_value != null )
{
@@ -232,7 +232,7 @@
final String error =
"Cannot establish a constructed context entry for the key " +
target
+ " due to a runtime failure.";
- throw new ModelException( error, e );
+ throw new ModelRuntimeException( error, e );
}

if( !m_descriptor.isVolatile() )

Modified: development/main/metro/composition/testing/acme/build.xml
==============================================================================
--- development/main/metro/composition/testing/acme/build.xml (original)
+++ development/main/metro/composition/testing/acme/build.xml Sun Apr 10
22:37:29 2005
@@ -11,26 +11,24 @@
<types xmlns="plugin:dpml/composition/dpml-composition-builder">
<type class="net.dpml.composition.testing.WidgetComponent"/>
<type class="net.dpml.composition.testing.GizmoComponent"/>
- <type class="net.dpml.composition.testing.AcmeComponent"/>
+ <type class="net.dpml.composition.testing.BadWidget"/>
+ <type class="net.dpml.composition.testing.AcmeContainer"/>
</types>

<!-- simple component -->
<component xmlns="plugin:dpml/composition/dpml-composition-builder"
name="widget" class="net.dpml.composition.testing.WidgetComponent">
<context>
- <value key="foo" value="bar"/>
- <value key="width" value="12"/>
- <value key="height" value="100"/>
<value key="name" value="urn:model:name"/>
<value key="partition" value="urn:model:partition"/>
- <value key="componentURI" value="urn:model:uri"/>
+ <value key="uri" value="urn:model:uri"/>
<value key="workingDirectory">
<value class="java.io.File" value="urn:system:work.dir"/>
<value value="acme/workspace"/>
</value>
<value key="dimension"
class="net.dpml.composition.testing.Dimension">
- <value class="int" value="35"/>
- <value class="int" value="21"/>
+ <value class="int" value="12"/>
+ <value class="int" value="100"/>
</value>
</context>
</component>

Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/AcmeContainer.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/AcmeContainer.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2004 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.composition.testing;
+
+import java.io.File;
+import java.util.Map.Entry;
+
+import net.dpml.logging.Logger;
+
+/**
+ * A simple class composed of two parts (widget and gizmo).
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: CompositionTestCase.java 1393 2005-01-06 10:27:10Z niclas $
+ */
+public class AcmeContainer
+{
+ //------------------------------------------------------------------
+ // static
+ //------------------------------------------------------------------
+
+ public static final boolean TYPE_THREADSAFE_CAPABLE = true;
+
+ //------------------------------------------------------------------
+ // state
+ //------------------------------------------------------------------
+
+ private final Logger m_logger;
+ private final Parts m_parts;
+
+ //------------------------------------------------------------------
+ // constructor
+ //------------------------------------------------------------------
+
+ /**
+ * Creation of a composite component. This implementation demonstrates
+ * access to parts within itself and invocation of service and non-service
+ * operations on its parts.
+ *
+ * @param logger the logging channel asign by the container
+ */
+ public AcmeContainer( final Logger logger, Parts parts )
+ {
+ m_logger = logger;
+ m_parts = parts;
+ }
+
+ //------------------------------------------------------------------
+ // implementation
+ //------------------------------------------------------------------
+
+ public void execute()
+ {
+ Parts parts = getParts();
+
+ //
+ // get the widget's color context manager and play with some values
+ //
+
+ getLogger().debug( "getting widget context manager" );
+ ColorContextManager manager = parts.getGizmoContextManager();
+ String color = manager.getColor( "purple" );
+ getLogger().debug( "initial color: " + color );
+ manager.setColor( "blue" );
+ getLogger().debug( "getting gizmo" );
+ Gizmo gizmo = parts.getGizmo();
+ gizmo.doGizmoStuff();
+ manager.setColor( "orange" );
+ gizmo.doGizmoStuff();
+ manager.setColor( "white" );
+ gizmo.doGizmoStuff();
+
+ //
+ // play around with some of the other operations we declared on
+ // our parts interface
+ //
+
+ getLogger().debug( "getting gizmo impl" );
+ Entry entry = parts.createGizmo();
+ GizmoComponent newGizmo = (GizmoComponent) entry.getValue();
+
+ getLogger().debug( "getting identified gizmo" );
+ Gizmo myGizmo = parts.getGizmo( "my-gizmo" );
+
+ getLogger().debug( "releasing stuff" );
+ parts.releaseGizmo( gizmo );
+ parts.releaseGizmo( myGizmo );
+ parts.releaseGizmo( newGizmo );
+ getLogger().debug( "done" );
+ }
+
+ private Logger getLogger()
+ {
+ return m_logger;
+ }
+
+ private Parts getParts()
+ {
+ return m_parts;
+ }
+
+ //------------------------------------------------------------------
+ // concerns
+ //------------------------------------------------------------------
+
+ public interface Parts
+ {
+ /**
+ * Return an instance of widget (referenced by gizmo).
+ *
+ * @return the widget service
+ */
+ Widget getWidget();
+
+ /**
+ * Return an instance of gizmo using the lifestyle policy
+ * declared by the gizmo component.
+ *
+ * @return the gizmo service
+ */
+ Gizmo getGizmo();
+
+ /**
+ * Return the gizmo context manager.
+ *
+ * @return the gizmo context manager
+ */
+ ColorContextManager getGizmoContextManager();
+
+ /**
+ * Return an identified instance of gizmo.
+ *
+ * @param key the instance identifier
+ * @return the gizmo service
+ */
+ Gizmo getGizmo( Object key );
+
+ /**
+ * Create and return a new annonomouse instance of gizmo as a
+ * non-proxied component.
+ *
+ * @return the gizmo component
+ */
+ Entry createGizmo();
+
+ /**
+ * Optional release of an instance of the gizmo component.
+ *
+ * @param the gizmo to release
+ */
+ void releaseGizmo( Gizmo gizmo );
+
+ }
+}

Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/BadColorException.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/BadColorException.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2004 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.composition.testing;
+
+import net.dpml.logging.Logger;
+
+/**
+ * An exception that is thrown by the BadWidget
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: CompositionTestCase.java 1393 2005-01-06 10:27:10Z niclas $
+ */
+public class BadColorException extends RuntimeException
+{
+ public BadColorException( String message )
+ {
+ super( message );
+ }
+}

Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/BadWidget.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/BadWidget.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2004 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.composition.testing;
+
+import net.dpml.logging.Logger;
+
+/**
+ * Component implementation that demonstrates the use of a context
inner-class.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: CompositionTestCase.java 1393 2005-01-06 10:27:10Z niclas $
+ */
+public class BadWidget implements Widget
+{
+ // static
+ //------------------------------------------------------------------
+
+ /**
+ * Declaration to the container that this component is thread-safe.
+ */
+ public static final boolean TYPE_THREADSAFE_CAPABLE = true;
+
+ //------------------------------------------------------------------
+ // state
+ //------------------------------------------------------------------
+
+ /**
+ * The logging channel.
+ */
+ private final Logger m_logger;
+
+ //------------------------------------------------------------------
+ // constructor
+ //------------------------------------------------------------------
+
+ /**
+ * Creation of a bad widget component.
+ *
+ * @param logger the logging channel asigned by the container
+ */
+ public BadWidget( final Logger logger )
+ {
+ m_logger = logger;
+ }
+
+ //------------------------------------------------------------------
+ // Widget
+ //------------------------------------------------------------------
+
+ /**
+ * Implementation of the widget service contract.
+ */
+ public void doWidgetStuff( String color )
+ {
+ if( false == "pink".equals( color ) )
+ {
+ throw new BadColorException( "I'm nasty!" );
+ }
+ else
+ {
+ getLogger().info( "Creating a pink widget." );
+ }
+ }
+
+ //------------------------------------------------------------------
+ // internal
+ //------------------------------------------------------------------
+
+ private Logger getLogger()
+ {
+ return m_logger;
+ }
+}

Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ColorContext.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ColorContext.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,30 @@
+/*
+ * 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.composition.testing;
+
+/**
+ * An example of a ACME standard context definition.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: CompositionTestCase.java 1393 2005-01-06 10:27:10Z niclas $
+ */
+public interface ColorContext
+{
+ public String getColor( String defaultColor );
+}

Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ColorContextManager.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ColorContextManager.java
Sun Apr 10 22:37:29 2005
@@ -0,0 +1,30 @@
+/*
+ * 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.composition.testing;
+
+/**
+ * An example of a ACME standard context definition.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: CompositionTestCase.java 1393 2005-01-06 10:27:10Z niclas $
+ */
+public interface ColorContextManager extends ColorContext
+{
+ public void setColor( String color );
+}

Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Dimension.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Dimension.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Dimension.java
Sun Apr 10 22:37:29 2005
@@ -39,12 +39,12 @@
m_y = y;
}

- public int getX()
+ public int getWidth()
{
return m_x;
}

- public int getY()
+ public int getHeight()
{
return m_y;
}

Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Gizmo.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Gizmo.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Gizmo.java
Sun Apr 10 22:37:29 2005
@@ -25,4 +25,5 @@
*/
public interface Gizmo
{
+ void doGizmoStuff();
}

Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/GizmoComponent.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/GizmoComponent.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/GizmoComponent.java
Sun Apr 10 22:37:29 2005
@@ -45,6 +45,11 @@
*/
private final Logger m_logger;

+ /**
+ * The assigned context.
+ */
+ private final Context m_context;
+
//------------------------------------------------------------------
// constructor
//------------------------------------------------------------------
@@ -61,9 +66,18 @@
public GizmoComponent( Logger logger, Context context )
{
m_logger = logger;
- Widget widget = context.getWidget();
- widget.doWidgetTypeStuff();
- logger.debug( "ready");
+ m_context = context;
+ }
+
+ //------------------------------------------------------------------
+ // Gixmo
+ //------------------------------------------------------------------
+
+ public void doGizmoStuff()
+ {
+ Widget widget = m_context.getWidget();
+ String color = m_context.getColor( "red" );
+ widget.doWidgetStuff( color );
}

//------------------------------------------------------------------
@@ -79,7 +93,7 @@
// concerns
//------------------------------------------------------------------

- public interface Context
+ public interface Context extends ColorContext
{
Widget getWidget();
}

Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Widget.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Widget.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Widget.java
Sun Apr 10 22:37:29 2005
@@ -25,5 +25,5 @@
*/
public interface Widget
{
- void doWidgetTypeStuff();
+ void doWidgetStuff( String color );
}

Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/WidgetComponent.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/WidgetComponent.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/WidgetComponent.java
Sun Apr 10 22:37:29 2005
@@ -78,7 +78,7 @@
m_logger = logger;

m_name = context.getName();
- URI uri = context.getComponentURI();
+ URI uri = context.getUri();
File work = context.getWorkingDirectory();
URI partition = context.getPartition();

@@ -90,7 +90,7 @@
+ "] with a working dir ["
+ work
+ "].";
- m_logger.debug( message );
+ logger.debug( message );
}

//------------------------------------------------------------------
@@ -120,7 +120,7 @@
*/
public void dispose()
{
- m_logger.debug( "disposal" );
+ getLogger().debug( "disposal" );
}

/**
@@ -141,39 +141,39 @@
/**
* Implementation of the widget service contract.
*/
- public void doWidgetTypeStuff()
+ public void doWidgetStuff( final String color )
{
- String name = getName();
- int width = m_context.getWidth();
- int height = m_context.getHeight( 5024 );
-
- m_logger.debug(
- name
- + " established with a width of "
+ Dimension d = new Dimension( 10, 20 );
+ int width = m_context.getDimension( d ).getWidth();
+ int height = m_context.getDimension( d ).getHeight();
+
+ getLogger().info(
+ "Creating "
+ + color
+ + " widget with a width of "
+ width
+ " and a height of "
+ height );
+ }
+
+ //------------------------------------------------------------------
+ // internal
+ //------------------------------------------------------------------

- Dimension dimension = m_context.getDimension( null );
- if( null != dimension )
- {
- int size = dimension.getSize();
- m_logger.debug( "size: " + size );
- }
+ private Logger getLogger()
+ {
+ return m_logger;
}

//------------------------------------------------------------------
// concerns
//------------------------------------------------------------------

- public interface Context
+ public interface Context extends ColorContext
{
- URI getPartition();
- URI getComponentURI();
String getName();
- String getFoo();
- int getWidth();
- int getHeight( int defaultHeight );
+ URI getPartition();
+ URI getUri();
File getWorkingDirectory();
Dimension getDimension( Dimension d );
}

Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/WidgetValue.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/WidgetValue.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/WidgetValue.java
Sun Apr 10 22:37:29 2005
@@ -18,6 +18,8 @@

package net.dpml.composition.testing;

+import java.util.logging.Logger;
+
/**
* Component implementation that demonstrates the use of a context
inner-class.
*
@@ -33,9 +35,10 @@
/**
* Implementation of the widget service contract.
*/
- public void doWidgetTypeStuff()
+ public void doWidgetStuff( String color )
{
- // not much I can do
+ Logger logger = Logger.getAnonymousLogger();
+ logger.info( "Creating a " + color + " widget." );
}

}

Modified: development/main/metro/composition/testing/unit/build.xml
==============================================================================
--- development/main/metro/composition/testing/unit/build.xml (original)
+++ development/main/metro/composition/testing/unit/build.xml Sun Apr 10
22:37:29 2005
@@ -22,24 +22,20 @@
class="net.dpml.composition.testing.WidgetComponent"
name="widget">
<context>
- <value key="foo" value="bar"/>
- <value key="width" value="12"/>
- <value key="height" value="100"/>
- <value key="dimension"
class="net.dpml.composition.testing.Dimension">
- <value class="int" value="35"/>
- <value class="int" value="21"/>
- </value>
<value key="name" value="urn:model:name"/>
<value key="partition" value="urn:model:partition"/>
- <value key="componentURI" value="urn:model:uri"/>
+ <value key="uri" value="urn:model:uri"/>
<value key="workingDirectory">
<value class="java.io.File" value="urn:system:work.dir"/>
<value value="acme/workspace"/>
</value>
+ <value key="dimension"
class="net.dpml.composition.testing.Dimension">
+ <value class="int" value="12"/>
+ <value class="int" value="100"/>
+ </value>
</context>
</component>

-
<!--
Composite component example.
This is a example of a composite component (the AcmeContainer class)
@@ -60,25 +56,23 @@
-->
<component dest="target/test/acme-container.part"
xmlns="plugin:dpml/composition/dpml-composition-builder"
- class="net.dpml.composition.testing.AcmeComponent"
+ class="net.dpml.composition.testing.AcmeContainer"
name="acme">
<parts>
<component name="widget"
class="net.dpml.composition.testing.WidgetComponent">
<context>
- <value key="foo" value="bar"/>
- <value key="width" value="12"/>
- <value key="height" value="100"/>
<value key="workingDirectory">
<value class="java.io.File" value="urn:system:work.dir"/>
<value value="acme/workspace"/>
</value>
<value key="name" value="urn:model:name"/>
<value key="partition" value="urn:model:partition"/>
- <value key="componentURI" value="urn:model:uri"/>
+ <value key="uri" value="urn:model:uri"/>
</context>
</component>
<component name="gizmo"
class="net.dpml.composition.testing.GizmoComponent">
<context>
+ <value key="color" value="red"/>
<reference key="widget" uri="parts:widget"/>
</context>
</component>
@@ -95,12 +89,31 @@
-->
<component dest="target/test/acme-test-container.part"
xmlns="plugin:dpml/composition/dpml-composition-builder"
- class="net.dpml.composition.testing.AcmeComponent"
+ class="net.dpml.composition.testing.AcmeContainer"
name="acme">
<parts>
<value key="widget"
class="net.dpml.composition.testing.WidgetValue"/>
<component name="gizmo"
class="net.dpml.composition.testing.GizmoComponent">
<context>
+ <value key="color" value="red"/>
+ <reference key="widget" uri="parts:widget"/>
+ </context>
+ </component>
+ </parts>
+ </component>
+
+ <!--
+ Example using the BadWidget
+ -->
+ <component dest="target/test/acme-bad-widget.part"
+ xmlns="plugin:dpml/composition/dpml-composition-builder"
+ class="net.dpml.composition.testing.AcmeContainer"
+ name="acme">
+ <parts>
+ <component name="widget"
class="net.dpml.composition.testing.BadWidget"/>
+ <component name="gizmo"
class="net.dpml.composition.testing.GizmoComponent">
+ <context>
+ <value key="color" value="red"/>
<reference key="widget" uri="parts:widget"/>
</context>
</component>

Modified:
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/CompositeTestCase.java
==============================================================================
---
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/CompositeTestCase.java
(original)
+++
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/CompositeTestCase.java
Sun Apr 10 22:37:29 2005
@@ -21,10 +21,12 @@

import java.net.URI;
import java.util.Hashtable;
+import java.util.Map.Entry;

import junit.framework.TestCase;

import net.dpml.automation.model.Model;
+import net.dpml.automation.control.Controller;
import net.dpml.composition.unit.CompositionHelper;

/**
@@ -35,13 +37,12 @@
*/
public class CompositeTestCase extends TestCase
{
-
/**
* Test the construction of a component that contains two child components
* widget and gizmo where both are components and gizmo declares a
dependency
* on widget.
*/
- public void testAcmeContainer() throws Exception
+ public void testAcmeContainerUsingComponent() throws Exception
{
execute( "acme-container.part" );
}
@@ -50,18 +51,55 @@
* Test the construction of a component that contains two child components
* (widget and gizmo) where the widget is a value object.
*/
- public void testTestContainer() throws Exception
+ public void testAcmeContainerUsingvalue() throws Exception
{
execute( "acme-test-container.part" );
}

+ /**
+ * Test the construction of a component that contains two child components
+ * widget and gizmo where both are components and gizmo declares a
dependency
+ * on widget.
+ */
+ public void testBadWidget() throws Exception
+ {
+ CompositionHelper helper = new CompositionHelper();
+ URI uri = helper.toURI( "acme-bad-widget.part" );
+ Model model = helper.getCompositionManager().addPart( uri, "acme" );
+ Controller controller = model.getController();
+ Entry entry = controller.create( model );
+ AcmeContainer container = (AcmeContainer) entry.getValue();
+ try
+ {
+ container.execute();
+ }
+ catch( BadColorException e )
+ {
+ // success
+ }
+ finally
+ {
+ controller.release( container );
+ helper.dispose();
+ }
+ }
+
private void execute( String path ) throws Exception
{
CompositionHelper helper = new CompositionHelper();
URI uri = helper.toURI( path );
- Model model = helper.getCompositionManager().addPart( uri );
- Object object = model.resolve();
- model.release( object );
- helper.dispose();
+ Model model = helper.getCompositionManager().addPart( uri, "acme" );
+ Controller controller = model.getController();
+ Entry entry = controller.create( model );
+ AcmeContainer container = (AcmeContainer) entry.getValue();
+ try
+ {
+ container.execute();
+ }
+ finally
+ {
+ controller.release( container );
+ helper.dispose();
+ }
}
}

Modified:
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/SimpleTestCase.java
==============================================================================
---
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/SimpleTestCase.java
(original)
+++
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/SimpleTestCase.java
Sun Apr 10 22:37:29 2005
@@ -21,10 +21,12 @@

import java.net.URI;
import java.util.Hashtable;
+import java.util.Map.Entry;

import junit.framework.TestCase;

import net.dpml.automation.model.Model;
+import net.dpml.automation.control.Controller;
import net.dpml.composition.unit.CompositionHelper;

/**
@@ -41,51 +43,58 @@
* Test the construction of the widget component and the invocation of
* an operation on the widget service interface.
*/
- public void testResolve() throws Exception
+ public void testGetValue() throws Exception
{
CompositionHelper helper = new CompositionHelper();
URI uri = helper.toURI( PATH );
- Model model = helper.getCompositionManager().addPart( uri );
- Widget widget = (Widget) model.resolve();
- widget.doWidgetTypeStuff();
- model.release( widget );
+ Model model = helper.getCompositionManager().addPart( uri, "widget"
);
+ Widget widget = (Widget) model.getValue();
+ widget.doWidgetStuff( "green" );
+ model.getController().release( widget );
}

/**
* Test the isolation of the widget.
*/
- public void testResolveToImplementation() throws Exception
+ public void testServiceIsolation() throws Exception
{
CompositionHelper helper = new CompositionHelper();
URI uri = helper.toURI( PATH );
- Model model = helper.getCompositionManager().addPart( uri );
+ Model model = helper.getCompositionManager().addPart( uri, "widget"
);
+ Object object = model.getValue();
try
{
- WidgetComponent widget = (WidgetComponent) model.resolve();
+ WidgetComponent widget = (WidgetComponent) object;
fail( "Casting to implementation class!" );
}
catch( ClassCastException e )
{
// success
}
+ finally
+ {
+ model.getController().release( object );
+ }
}

/**
* Test the construction of the widget implementation and invocation
* of a non-service public method on the implementation class.
*/
- public void testCreate() throws Exception
+ public void testEntryCreation() throws Exception
{
CompositionHelper helper = new CompositionHelper();
URI uri = helper.toURI( PATH );
- Model model = helper.getCompositionManager().addPart( uri );
- WidgetComponent widget = (WidgetComponent) model.create();
+ Model model = helper.getCompositionManager().addPart( uri, "widget"
);
+ Controller controller = model.getController();
+ Entry entry = controller.create( model );
+ WidgetComponent widget = (WidgetComponent) entry.getValue();
String name = widget.getName();
assertEquals( "name", "widget", name );
String newName = "freight";
widget.setName( newName );
assertEquals( "name", newName, widget.getName() );
- model.release( widget );
+ controller.release( widget );
}

/**
@@ -95,25 +104,26 @@
* check that the instances are the same (which is dependent on the
* implementation providing a rational equals implementation).
*/
- public void testResolveIdentifiable() throws Exception
+ public void testIdentifiableCreation() throws Exception
{
CompositionHelper helper = new CompositionHelper();
URI uri = helper.toURI( PATH );
- Model model = helper.getCompositionManager().addPart( uri );
- Widget w1 = (Widget) model.resolve( "acme-widget-one" );
- Widget w2 = (Widget) model.resolve( "acme-widget-two" );
+ Model model = helper.getCompositionManager().addPart( uri, "widget"
);
+ Controller controller = model.getController();
+ Widget w1 = (Widget) controller.resolve( model, "acme-widget-one" );
+ Widget w2 = (Widget) controller.resolve( model, "acme-widget-two" );
if( w1.equals( w2 ) )
{
fail( "Widget w1 and w2 are not unique!" );
}
- Widget w3 = (Widget) model.resolve( "acme-widget-one" );
+ Widget w3 = (Widget) controller.resolve( model, "acme-widget-one" );
if( !w1.equals( w3 ) )
{
System.out.println( "" + System.identityHashCode( w1 ) );
System.out.println( "" + System.identityHashCode( w3 ) );
fail( "Widget w1 and w3 are not the same!" );
}
- model.release( w1 );
- model.release( w2 );
+ controller.release( w1 );
+ controller.release( w2 );
}
}

Modified: development/main/metro/index.xml
==============================================================================
--- development/main/metro/index.xml (original)
+++ development/main/metro/index.xml Sun Apr 10 22:37:29 2005
@@ -526,6 +526,7 @@
<dependencies>
<include key="dpml-composition-testing-acme"/>
<include key="dpml-composition-unit" runtime="false"/>
+ <include key="dpml-util-exception" runtime="false"/>
</dependencies>
<plugins>
<include key="dpml-composition-builder"/>

Modified:
development/main/metro/meta/api/src/main/net/dpml/meta/info/PartDescriptor.java
==============================================================================
---
development/main/metro/meta/api/src/main/net/dpml/meta/info/PartDescriptor.java
(original)
+++
development/main/metro/meta/api/src/main/net/dpml/meta/info/PartDescriptor.java
Sun Apr 10 22:37:29 2005
@@ -20,6 +20,7 @@
package net.dpml.meta.info;

import java.io.Serializable;
+import java.lang.reflect.Method;

/**
* A part descriptor identifies a key, access semantics and return type
@@ -54,14 +55,17 @@
public final class PartDescriptor
implements Serializable
{
+ public static final int RELEASE = -1;
public static final int GET = 0;
public static final int CREATE = 1;
- public static final int RELEASE = -1;

public static final String GET_KEY = "get";
public static final String CREATE_KEY = "create";
public static final String RELEASE_KEY = "release";

+ public static final String CONTEXT_MANAGER_KEY = "ContextManager";
+ public static final String PARTS_MANAGER_KEY = "PartsManager";
+
public static String toString( int semantic )
{
if( CREATE == semantic )
@@ -82,6 +86,96 @@
}
}

+ public static String getPartPostfix( Method method )
+ {
+ String name = method.getName();
+ if( name.endsWith( CONTEXT_MANAGER_KEY ) )
+ {
+ return CONTEXT_MANAGER_KEY;
+ }
+ else if( name.endsWith( PARTS_MANAGER_KEY ) )
+ {
+ return PARTS_MANAGER_KEY;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public static int getPartSemantic( Method method )
+ {
+ String name = method.getName();
+ if( name.startsWith( GET_KEY ) )
+ {
+ return GET;
+ }
+ else if( name.startsWith( CREATE_KEY ) )
+ {
+ return CREATE;
+ }
+ else if( name.startsWith( RELEASE_KEY ) )
+ {
+ return RELEASE;
+ }
+ else
+ {
+ final String error =
+ "Unrecognized part accessor method signature ["
+ + name
+ + "]";
+ throw new IllegalArgumentException( error );
+ }
+ }
+
+ public static String getPartKey( Method method )
+ {
+ int semantic = getPartSemantic( method );
+ return getPartKey( method, semantic );
+ }
+
+ public static String getPartKey( Method method, int semantic )
+ {
+ String name = method.getName();
+ if( GET == semantic )
+ {
+ if( name.endsWith( CONTEXT_MANAGER_KEY ) )
+ {
+ int n = CONTEXT_MANAGER_KEY.length();
+ int j = name.length() - n;
+ String substring = name.substring( 0, j );
+ return formatKey( substring, 3 );
+ }
+ else if( name.endsWith( PARTS_MANAGER_KEY ) )
+ {
+ int n = PARTS_MANAGER_KEY.length();
+ int j = name.length() - n;
+ String substring = name.substring( 0, j );
+ return formatKey( substring, 3 );
+ }
+ else
+ {
+ return formatKey( name, 3 );
+ }
+ }
+ else if( CREATE == semantic )
+ {
+ return formatKey( name, 6 );
+ }
+ else if( RELEASE == semantic )
+ {
+ return formatKey( name, 7 );
+ }
+ else
+ {
+ final String error =
+ "Unrecognized part accessor method signature ["
+ + name
+ + "]";
+ throw new IllegalArgumentException( error );
+ }
+ }
+
/**
* The key.
*/
@@ -135,6 +229,33 @@
return m_operations;
}

+ public Operation getOperation( int semantic, String postfix )
+ {
+ Operation[] operations = getOperations();
+ for( int i=0; i<operations.length; i++ )
+ {
+ Operation operation = operations[i];
+ if( semantic == operation.getSemantic() )
+ {
+ if( null == postfix )
+ {
+ if( null == operation.getPostfix() )
+ {
+ return operation;
+ }
+ }
+ else
+ {
+ if( postfix.equals( operation.getPostfix() ) )
+ {
+ return operation;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
/**
* Compare this object with another for equality.
* @param other the object to compare this object with
@@ -197,11 +318,22 @@
{
private final String m_type;
private int m_semantic;
+ private String m_postfix;

public Operation( int semantic, String type )
{
+ this( semantic, null, type );
+ }
+
+ public Operation( int semantic, String postfix, String type )
+ {
+ if( null == type )
+ {
+ throw new NullPointerException( "type" );
+ }
m_type = type;
m_semantic = semantic;
+ m_postfix = postfix;
}

public String getType()
@@ -214,9 +346,18 @@
return m_semantic;
}

+ public String getPostfix()
+ {
+ return m_postfix;
+ }
+
public boolean equals( Object other )
{
- if( false == ( other instanceof Operation ) )
+ if( null == other )
+ {
+ return false;
+ }
+ else if( false == ( other instanceof Operation ) )
{
return false;
}
@@ -227,9 +368,20 @@
{
return false;
}
+ else if( false == ( m_semantic == a.getSemantic() ) )
+ {
+ return false;
+ }
else
{
- return ( m_semantic == a.getSemantic() );
+ if( null == m_postfix )
+ {
+ return ( null == a.getPostfix() );
+ }
+ else
+ {
+ return m_postfix.equals( a.getPostfix() );
+ }
}
}
}
@@ -238,7 +390,28 @@
{
int hash = m_semantic;
hash ^= m_type.hashCode();
+ if( null != m_postfix )
+ {
+ hash ^= m_postfix.hashCode();
+ }
return hash;
}
}
+
+ private static String formatKey( String method, int offset )
+ {
+ String string = method.substring( offset );
+ return formatKey( string );
+ }
+
+ private static String formatKey( String key )
+ {
+ if( key.length() < 1 )
+ {
+ throw new IllegalArgumentException( "key" );
+ }
+ String first = key.substring( 0, 1 ).toLowerCase();
+ String remainder = key.substring( 1 );
+ return first + remainder;
+ }
}

Modified:
development/main/transit/core/tools/src/main/net/dpml/transit/tools/PluginTask.java
==============================================================================
---
development/main/transit/core/tools/src/main/net/dpml/transit/tools/PluginTask.java
(original)
+++
development/main/transit/core/tools/src/main/net/dpml/transit/tools/PluginTask.java
Sun Apr 10 22:37:29 2005
@@ -293,13 +293,8 @@
throw new BuildException( error, getLocation() );
}

- long t0 = System.currentTimeMillis();
InputStream input = classloader.getResourceAsStream( resource );
- long t1 = System.currentTimeMillis() - t0;
- if( t1 > 0 ) log( "elapsed: " + t1 ); // ## debugging
-
Element root = ElementHelper.getRootElement( input );
-
Element[] tasks = ElementHelper.getChildren( root, "taskdef" );
for( int i=0; i < tasks.length; i++ )
{

Modified:
development/main/transit/core/tools/src/main/net/dpml/transit/tools/TransitComponentHelper.java
==============================================================================
---
development/main/transit/core/tools/src/main/net/dpml/transit/tools/TransitComponentHelper.java
(original)
+++
development/main/transit/core/tools/src/main/net/dpml/transit/tools/TransitComponentHelper.java
Sun Apr 10 22:37:29 2005
@@ -326,10 +326,7 @@
else
{
String resource = descriptor.getResource();
- long t0 = System.currentTimeMillis();
InputStream input = classloader.getResourceAsStream(
resource );
- long t1 = System.currentTimeMillis() - t0;
- if( t1 > 0 ) m_project.log( "elapsed: " + t1 ); // ##
debugging
Element root = ElementHelper.getRootElement( input );
Element[] tasks = ElementHelper.getChildren( root, "taskdef"
);




  • svn commit: r2260 - in development/main: metro metro/automation/control/src/main/net/dpml/automation/control metro/automation/control/src/main/net/dpml/automation/model metro/composition/api/src/main/net/dpml/composition/model metro/composition/builder/src/main/net/dpml/composition/builder metro/composition/control/src/main/net/dpml/composition/control metro/composition/control/src/main/net/dpml/composition/models metro/composition/impl/src/main/net/dpml/composition/model/impl metro/composition/testing/acme metro/composition/testing/acme/src/main/net/dpml/composition/testing metro/composition/testing/unit metro/composition/testing/unit/src/test/net/dpml/composition/testing metro/meta/api/src/main/net/dpml/meta/info transit/core/tools/src/main/net/dpml/transit/tools, mcconnell, 04/10/2005

Archive powered by MHonArc 2.6.24.

Top of Page