notify-dpml AT lists.ibiblio.org
Subject: DPML Notify
List archive
svn commit: r2272 - in development/main/metro: automation/control/src/main/net/dpml/automation/control composition/builder/src/main/net/dpml/composition/builder composition/builder/src/main/net/dpml/composition/builder/datatypes composition/control/src/main/net/dpml/composition/control composition/testing/acme composition/testing/acme/src/main/net/dpml/composition/testing composition/testing/unit composition/testing/unit/src/test/net/dpml/composition/testing meta/api/src/main/net/dpml/meta/info
- From: mcconnell AT dpml.net
- To: notify-dpml AT lists.ibiblio.org
- Subject: svn commit: r2272 - in development/main/metro: automation/control/src/main/net/dpml/automation/control composition/builder/src/main/net/dpml/composition/builder composition/builder/src/main/net/dpml/composition/builder/datatypes composition/control/src/main/net/dpml/composition/control composition/testing/acme composition/testing/acme/src/main/net/dpml/composition/testing composition/testing/unit composition/testing/unit/src/test/net/dpml/composition/testing meta/api/src/main/net/dpml/meta/info
- Date: Tue, 12 Apr 2005 22:59:43 -0400
Author: mcconnell AT dpml.net
Date: Tue Apr 12 22:59:35 2005
New Revision: 2272
Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartDataType.java
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DimensionComponent.java
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DimensionValue.java
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DimensionalContext.java
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Example.java
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ExampleComponent.java
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ExampleContainer.java
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/ExampleTestCase.java
Removed:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ColorContextManager.java
Modified:
development/main/metro/automation/control/src/main/net/dpml/automation/control/Controller.java
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/ContextDataType.java
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartsDataType.java
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/ValueDataType.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/PartsInvocationHandler.java
development/main/metro/composition/testing/acme/build.xml
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/ColorContext.java
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/WidgetComponent.java
development/main/metro/composition/testing/unit/build.xml
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/SimpleTestCase.java
development/main/metro/meta/api/src/main/net/dpml/meta/info/PartDescriptor.java
Log:
Lots of updates - mainly in the acme test with the addition of demonstrates
linked to the writup. Some enhancements to the Parts patterns and some
improvements to the part builder tasks.
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
Tue Apr 12 22:59:35 2005
@@ -124,11 +124,23 @@
* by the supplied model.
*
* @param model the component model
+ * @param key the instance identifier
* @return the resolved instance
*/
Object resolve( Model model, Object key ) throws Exception;
/**
+ * Return an identified instance of the component type represented
+ * by the supplied model.
+ *
+ * @param model the component model
+ * @param key the instance identifier
+ * @param policy the proxy creation policy
+ * @return the resolved instance
+ */
+ Object resolve( Model model, Object key, boolean policy ) throws
Exception;
+
+ /**
* Return a component instance
*
* @param instance the instance to release
Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java
==============================================================================
---
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java
(original)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java
Tue Apr 12 22:59:35 2005
@@ -136,11 +136,6 @@
m_output = file;
}
- public void setUri( URI uri )
- {
- m_uri = uri;
- }
-
public void setKey( String key )
{
m_key = key;
@@ -151,7 +146,7 @@
m_name = name;
}
- public void setClass( String classname )
+ public void setType( String classname )
{
m_classname = classname;
}
@@ -487,62 +482,10 @@
private ComponentProfile buildComponentProfile( ClassLoader classloader,
ClassLoaderDirective cld )
throws IntrospectionException, IOException, ClassNotFoundException
{
+ String id = getName();
+ log( "building component: " + id );
String classname = getClassname();
- log( "building " + classname );
-
Type type = loadType( classloader, classname );
-
- String id = getName();
- if( null != m_uri )
- {
- log( "including component: " + m_uri, Project.MSG_VERBOSE );
- CompositionPartHandler handler = new CompositionPartHandler();
- try
- {
- Part part = handler.loadPart( m_uri );
- if( part instanceof ComponentProfile )
- {
- ComponentProfile profile = (ComponentProfile) part;
- return new ComponentProfile( id, profile );
- }
- else
- {
- final String error =
- "The part ["
- + part.getClass().getName()
- + "] references by the uri ["
- + m_uri
- + "] is not assignable from "
- + ComponentProfile.class.getName()
- + ".";
- throw new BuildException( error, getLocation() );
- }
- }
- catch( PartNotFoundException pnfe )
- {
- final String error =
- "Part not found ["
- + m_uri
- + "].";
- throw new BuildException( error, getLocation() );
- }
- catch( DelegationException de )
- {
- final String error =
- "Delegation error while attempting to load part ["
- + m_uri
- + "] due to: "
- + de.getMessage();
- throw new BuildException( error, de, getLocation() );
- }
- }
-
- log( "building component: " + id, Project.MSG_VERBOSE );
-
- //
- // setup classname and type
- //
-
String lifestyle = getLifestylePolicy( type );
int collection = getCollectionPolicy( type );
int activation = getActivationPolicy();
@@ -551,7 +494,6 @@
ContextDirective context = getContextDirective( classloader, type );
DependencyDirective[] dependencies = getDependencyDirectives(
classloader, type );
PartReference[] parts = getParts( classloader, type );
-
Parameters parameters = getParameters();
Configuration configuration = getConfiguration();
@@ -632,7 +574,7 @@
if( null == m_classname )
{
final String error =
- "Missing component 'class' attribute.";
+ "Missing component 'type' attribute.";
throw new BuildException( error, getLocation() );
}
return m_classname;
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
Tue Apr 12 22:59:35 2005
@@ -28,6 +28,7 @@
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.Properties;
+import java.util.Map;
import java.util.Map.Entry;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
@@ -584,27 +585,48 @@
Method method = methods[i];
if( key.equals( PartDescriptor.getPartKey( method ) ) )
{
- Operation operation = getOperation( method );
+ Operation operation = getOperation( key, method );
list.add( operation );
}
}
return (Operation[]) list.toArray( new Operation[0] );
}
- private Operation getOperation( Method method ) throws
IntrospectionException
+ private Operation getOperation( String key, Method method ) throws
IntrospectionException
{
+ //
+ // TODO: pass key on to the validation methods to improve error
reporting
+ //
+
final String name = method.getName();
final int semantic = PartDescriptor.getPartSemantic( method );
- if( semantic == PartDescriptor.GET )
+ if( semantic == PartDescriptor.SELECT )
{
validateNoExceptions( method );
- validateAtMostOneParameter( method );
Class returnType = method.getReturnType();
validateNonNullReturnType( method, returnType );
validateNonArrayReturnType( method, returnType );
String type = returnType.getName();
String postfix = PartDescriptor.getPartPostfix( method );
- return new Operation( PartDescriptor.GET, postfix, type );
+ if( PartDescriptor.ENTRY_KEY.equals( postfix ) )
+ {
+ validateEntryReturnType( method );
+ validateAtMostOneParameter( method );
+ }
+ else if( PartDescriptor.PARTS_MAP_KEY.equals( postfix ) ||
PartDescriptor.CONTEXT_MAP_KEY.equals( postfix ) )
+ {
+ validateMapReturnType( method );
+ validateAtMostOneParameter( method );
+ }
+ else if( PartDescriptor.PARTS_MANAGER_KEY.equals( postfix ) ||
PartDescriptor.CONTEXT_MANAGER_KEY.equals( postfix ) )
+ {
+ validateAtMostOneParameter( method );
+ }
+ else
+ {
+ validateSelectPattern( method );
+ }
+ return new Operation( PartDescriptor.SELECT, postfix, type );
}
else if( semantic == PartDescriptor.CREATE )
{
@@ -631,7 +653,9 @@
final String error =
"Unrecognized part accessor method signature ["
+ name
- + "]";
+ + "] for the parts key ["
+ + key
+ + "].";
throw new IllegalArgumentException( error );
}
}
@@ -766,8 +790,39 @@
}
return null;
}
+
+ private void validateMapReturnType( Method method )
+ throws IntrospectionException
+ {
+ Class returnType = method.getReturnType();
+ if( Map.class != returnType )
+ {
+ String name = method.getName();
+ final String error =
+ "The method ["
+ + name
+ + "] does not declare java.util.Map as a return type.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private void validateEntryReturnType( Method method )
+ throws IntrospectionException
+ {
+ Class returnType = method.getReturnType();
+ if( Map.Entry.class != returnType )
+ {
+ String name = method.getName();
+ final String error =
+ "The method ["
+ + name
+ + "] does not declare java.util.Map.Entry as a return type.";
+ throw new IntrospectionException( error );
+ }
+ }
- private void validateReturnTypeIsAssignable( Method method, Class type )
throws IntrospectionException
+ private void validateReturnTypeIsAssignable( Method method, Class type )
+ throws IntrospectionException
{
Class c = method.getReturnType();
if( false == type.isAssignableFrom( c ) )
@@ -784,7 +839,8 @@
}
}
- private void validateNonNullParameter( Method method, Class type )
throws IntrospectionException
+ private void validateNonNullParameter( Method method, Class type )
+ throws IntrospectionException
{
if( Void.TYPE.equals( type ) )
{
@@ -797,7 +853,8 @@
}
- private void validateNonNullReturnType( Method method, Class returnType
) throws IntrospectionException
+ private void validateNonNullReturnType( Method method, Class returnType
)
+ throws IntrospectionException
{
if( Void.TYPE.equals( returnType ) )
{
@@ -809,7 +866,8 @@
}
}
- private void validateNullReturnType( Method method, Class returnType )
throws IntrospectionException
+ private void validateNullReturnType( Method method, Class returnType )
+ throws IntrospectionException
{
if( false == Void.TYPE.equals( returnType ) )
{
@@ -821,7 +879,8 @@
}
}
- private void validateNonArrayReturnType( Method method, Class returnType
) throws IntrospectionException
+ private void validateNonArrayReturnType( Method method, Class returnType
)
+ throws IntrospectionException
{
if( null != returnType.getComponentType() )
{
@@ -833,7 +892,8 @@
}
}
- private void validateNonArrayType( Method method, Class type ) throws
IntrospectionException
+ private void validateNonArrayType( Method method, Class type )
+ throws IntrospectionException
{
if( null != type.getComponentType() )
{
@@ -845,7 +905,8 @@
}
}
- private void validateInterfaceReturnType( Method method, Class
returnType ) throws IntrospectionException
+ private void validateInterfaceReturnType( Method method, Class
returnType )
+ throws IntrospectionException
{
if( returnType.isInterface() == false )
{
@@ -859,7 +920,8 @@
}
}
- private void validateMethodName( Method method ) throws
IntrospectionException
+ private void validateMethodName( Method method )
+ throws IntrospectionException
{
if( method.getName().startsWith( "get" ) == false )
{
@@ -871,7 +933,8 @@
}
}
- private void validateNoExceptions( Method method ) throws
IntrospectionException
+ private void validateNoExceptions( Method method )
+ throws IntrospectionException
{
Class[] exceptionTypes = method.getExceptionTypes();
if( exceptionTypes.length > 0 )
@@ -884,7 +947,8 @@
}
}
- private void validateNoParameters( Method method ) throws
IntrospectionException
+ private void validateNoParameters( Method method )
+ throws IntrospectionException
{
Class[] parameterTypes = method.getParameterTypes();
if( parameterTypes.length > 0 )
@@ -897,7 +961,8 @@
}
}
- private void validateAtMostOneParameter( Method method ) throws
IntrospectionException
+ private void validateAtMostOneParameter( Method method )
+ throws IntrospectionException
{
Class[] parameterTypes = method.getParameterTypes();
if( parameterTypes.length > 1 )
@@ -910,7 +975,8 @@
}
}
- private Class validateSingleParameter( Method method ) throws
IntrospectionException
+ private Class validateSingleParameter( Method method )
+ throws IntrospectionException
{
Class[] parameterTypes = method.getParameterTypes();
if( parameterTypes.length != 1 )
@@ -925,7 +991,8 @@
}
- private void validateNonArrayParameter( Method method, Class type )
throws IntrospectionException
+ private void validateNonArrayParameter( Method method, Class type )
+ throws IntrospectionException
{
if( null != type.getComponentType() )
{
@@ -937,6 +1004,26 @@
}
}
+ private void validateSelectPattern( Method method )
+ throws IntrospectionException
+ {
+ Class[] parameterTypes = method.getParameterTypes();
+ int n = parameterTypes.length;
+ if( n == 2 )
+ {
+ Class b = parameterTypes[1];
+ if( false == Boolean.TYPE.isAssignableFrom( b ) )
+ {
+ String name = method.getName();
+ final String error =
+ "Second parameter in the select method ["
+ + name
+ + "] is not assignable to a boolean.";
+ throw new IntrospectionException( error );
+ }
+ }
+ }
+
private Class loadSubjectClass( ClassLoader classloader )
{
if( null == m_classname )
Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/ContextDataType.java
==============================================================================
---
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/ContextDataType.java
(original)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/ContextDataType.java
Tue Apr 12 22:59:35 2005
@@ -35,6 +35,7 @@
import net.dpml.meta.info.Type;
+import org.apache.tools.ant.Task;
/**
* A context directive class.
@@ -118,6 +119,10 @@
for( int i=0; i<builders.length; i++ )
{
PartReferenceBuilder builder = builders[i];
+ if( builder instanceof ComponentBuilderTask )
+ {
+ ((Task)builder).setTaskName( "component" );
+ }
PartReference reference = builder.buildPartReference(
classloader, type );
references[i] = reference;
}
Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartDataType.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartDataType.java
Tue Apr 12 22:59:35 2005
@@ -0,0 +1,179 @@
+/*
+ * 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.builder.datatypes;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import net.dpml.meta.info.Type;
+
+import net.dpml.composition.builder.PartReferenceBuilder;
+import net.dpml.composition.control.CompositionPartHandler;
+
+import net.dpml.automation.control.PartNotFoundException;
+import net.dpml.automation.control.DelegationException;
+import net.dpml.automation.part.Part;
+import net.dpml.automation.part.PartHolder;
+import net.dpml.automation.part.PartReference;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Task that handles the construction of a serialized container 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 PartDataType implements PartReferenceBuilder
+{
+ private URI m_uri;
+ private String m_key;
+
+ public void setUri( URI uri )
+ {
+ m_uri = uri;
+ }
+
+ public void setKey( String key )
+ {
+ m_key = key;
+ }
+
+ //---------------------------------------------------------------------
+ // Builder
+ //---------------------------------------------------------------------
+
+ /**
+ * Return a uri identitifying the builder.
+ *
+ * @return the builder uri
+ */
+ public URI getBuilderURI()
+ {
+ return PART_BUILDER_URI;
+ }
+
+ /**
+ * Return a urn identitifying the part handler for this builder.
+ *
+ * @return a strategy uri
+ */
+ public URI getPartHandlerURI()
+ {
+ return PART_HANDLER_URI;
+ }
+
+ //---------------------------------------------------------------------
+ // PartReferenceBuilder
+ //---------------------------------------------------------------------
+
+ /**
+ * Return the part key.
+ *
+ * @return the key
+ */
+ public String getKey()
+ {
+ if( null == m_key )
+ {
+ final String error =
+ "Missing key attribute for nested part reference.";
+ throw new BuildException( error );
+ }
+ return m_key;
+ }
+
+ /**
+ * Return the part uri.
+ *
+ * @return the uri
+ */
+ public URI getURI()
+ {
+ if( null == m_uri )
+ {
+ final String error =
+ "Missing uri attribute for nested part reference.";
+ throw new BuildException( error );
+ }
+ return m_uri;
+ }
+
+ public PartReference buildPartReference( ClassLoader classloader, Type
type )
+ {
+ String key = getKey();
+ Part part = buildPart( type, classloader );
+ return new PartReference( key, part );
+ }
+
+ private Part buildPart( Type type, ClassLoader classloader )
+ {
+ String key = getKey();
+ URI uri = getURI();
+ CompositionPartHandler handler = new CompositionPartHandler();
+ try
+ {
+ return handler.loadPart( uri );
+ }
+ catch( PartNotFoundException pnfe )
+ {
+ final String error =
+ "Unable to include the part ["
+ + key
+ + "] because part refernece ["
+ + uri
+ + "] could not be found.";
+ throw new BuildException( error );
+ }
+ catch( DelegationException de )
+ {
+ final String error =
+ "Delegation error while attempting to load part ["
+ + m_uri
+ + "] due to: "
+ + de.getMessage();
+ throw new BuildException( error, de );
+ }
+ catch( IOException ioe )
+ {
+ final String error =
+ "IO error while attempting to load part ["
+ + m_uri
+ + "] due to: "
+ + ioe.getMessage();
+ throw new BuildException( error, ioe );
+ }
+ }
+
+ private static URI PART_HANDLER_URI = setupURI( "@PART-HANDLER-URI@" );
+ private static URI PART_BUILDER_URI = setupURI( "@PART-BUILDER-URI@" );
+
+ protected static URI setupURI( String spec )
+ {
+ try
+ {
+ return new URI( spec );
+ }
+ catch( URISyntaxException ioe )
+ {
+ return null;
+ }
+ }
+}
Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartsDataType.java
==============================================================================
---
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartsDataType.java
(original)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartsDataType.java
Tue Apr 12 22:59:35 2005
@@ -26,7 +26,6 @@
import net.dpml.automation.part.Part;
import net.dpml.automation.part.PartReference;
import net.dpml.automation.builder.PartBuilder;
-//import net.dpml.automation.builder.PartReferenceBuilder;
import net.dpml.automation.builder.IntrospectionException;
import net.dpml.composition.builder.ComponentBuilderTask;
@@ -69,6 +68,13 @@
return builder;
}
+ public PartDataType createPart()
+ {
+ PartDataType builder = new PartDataType();
+ m_builders.add( builder );
+ return builder;
+ }
+
/**
* Create a new constructed value builder.
* @return a part builder
@@ -184,6 +190,10 @@
for( int i=0; i<builders.length; i++ )
{
PartReferenceBuilder builder = builders[i];
+ if( builder instanceof ComponentBuilderTask )
+ {
+ ((Task)builder).setTaskName( "component" );
+ }
parts[i] = builder.buildPartReference( classloader, type );
}
return parts;
Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/ValueDataType.java
==============================================================================
---
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/ValueDataType.java
(original)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/ValueDataType.java
Tue Apr 12 22:59:35 2005
@@ -76,7 +76,7 @@
* Create, assign and return a new nested entry constructor parameter.
* @return the new context entry param
*/
- public ValueDataType createValue()
+ public ValueDataType createParam()
{
final ValueDataType param = new ValueDataType();
m_params.add( param );
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
Tue Apr 12 22:59:35 2005
@@ -361,18 +361,29 @@
*/
public Entry create( Model model ) throws Exception
{
- if( model instanceof CompositionModel )
+ if( model instanceof ValueModel )
{
- CompositionModel standard = (CompositionModel) model;
- return getHolder( standard, null );
+ return model;
}
- else if( model instanceof ValueModel )
+ else if( model instanceof CompositionModel )
{
- return model;
+ return create( model, null );
}
else
{
- return model.getController().create( model );
+ Controller controller = model.getController();
+ if( false == controller.equals( this ) )
+ {
+ return controller.create( model );
+ }
+ else
+ {
+ final String error =
+ "Unsupported model implementation class ["
+ + model.getClass().getName()
+ + "] passed to 'create/1'.";
+ throw new UnsupportedOperationException( error );
+ }
}
}
@@ -392,7 +403,19 @@
}
else
{
- return model.getController().create( model, key );
+ Controller controller = model.getController();
+ if( false == controller.equals( this ) )
+ {
+ return controller.create( model, key );
+ }
+ else
+ {
+ final String error =
+ "Unsupported model implementation class ["
+ + model.getClass().getName()
+ + "] passed to 'create/2'.";
+ throw new UnsupportedOperationException( error );
+ }
}
}
@@ -405,22 +428,7 @@
*/
public Object resolve( Model model ) throws Exception
{
- if( model instanceof CompositionModel )
- {
- CompositionModel standard = (CompositionModel) model;
- Holder holder = getHolder( standard, null );
- InvocationHandler handler = new ApplianceInvocationHandler(
holder );
- return holder.getProxy( handler );
- }
- else if( model instanceof ValueModel )
- {
- ValueModel value = (ValueModel) model;
- return value.getValue();
- }
- else
- {
- return model.getController().resolve( model );
- }
+ return resolve( model, null, true );
}
/**
@@ -433,24 +441,53 @@
*/
public Object resolve( Model model, Object key ) throws Exception
{
+ return resolve( model, key, true );
+ }
+
+ /**
+ * Create and return a new identifiable instance of the component
represented
+ * by the supplied proxy policy.
+ *
+ * @param model the component model
+ * @param key the object key
+ * @param policy the proxy creation policy
+ * @return the resolved instance
+ */
+ public Object resolve( Model model, Object key, boolean policy ) throws
Exception
+ {
if( null == model )
{
throw new NullPointerException( "model" );
}
- if( null == key )
- {
- throw new NullPointerException( "key" );
- }
if( model instanceof CompositionModel )
{
CompositionModel componentModel = (CompositionModel) model;
Holder holder = getHolder( componentModel , key );
- InvocationHandler handler = new ApplianceInvocationHandler(
holder );
- return holder.getProxy( handler );
+ if( policy )
+ {
+ InvocationHandler handler = new ApplianceInvocationHandler(
holder );
+ return holder.getProxy( handler );
+ }
+ else
+ {
+ return holder.getValue();
+ }
}
else
{
- return model.getController().resolve( model, key );
+ Controller controller = model.getController();
+ if( false == controller.equals( this ) )
+ {
+ return controller.resolve( model, key );
+ }
+ else
+ {
+ final String error =
+ "Unsupported model implementation class ["
+ + model.getClass().getName()
+ + "] passed to 'resolve/3'.";
+ throw new UnsupportedOperationException( error );
+ }
}
}
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
Tue Apr 12 22:59:35 2005
@@ -152,44 +152,30 @@
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 )
+ final Entry provider = getComponentModel().getEntry( uri );
+
+ if( PartDescriptor.SELECT == semantic )
{
if( null == postfix )
{
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 );
- }
+ Model model = getModelFromProvider( provider, key,
"select/1" );
+ Controller controller = model.getController();
+ return controller.resolve( model, arg );
+ }
+ else if( args.length == 2 )
+ {
+ Object arg = args[0];
+ boolean policy = getBooleanValue( args[1] );
+ Model model = getModelFromProvider( provider, key,
"select/2" );
+ Controller controller = model.getController();
+ return controller.resolve( model, arg, policy );
}
else
{
@@ -200,10 +186,32 @@
throw new IllegalStateException( error );
}
}
- else if( PartDescriptor.CONTEXT_MANAGER_KEY.equals( postfix ) )
+ else if( PartDescriptor.ENTRY_KEY.equals( postfix ) )
+ {
+ if( null == args )
+ {
+ Model model = getModelFromProvider( provider, key,
"select/entry/0" );
+ return invokeCreate( key, model );
+ }
+ else if( args.length == 1 )
+ {
+ Object arg = args[0];
+ Model model = getModelFromProvider( provider, key,
"select/entry/1" );
+ return invokeCreate( key, model, arg );
+ }
+ else
+ {
+ final String error =
+ "Illegal number of parameters supplied under the
'select/entry' method ["
+ + method.getName()
+ + "].";
+ throw new IllegalStateException( error );
+ }
+ }
+ else if( PartDescriptor.CONTEXT_MANAGER_KEY.equals( postfix )
+ || PartDescriptor.CONTEXT_MAP_KEY.equals( postfix ) )
{
Class clazz = method.getReturnType();
-
if( !clazz.isInterface() )
{
final String error =
@@ -216,31 +224,43 @@
+ "] is not an interface.";
throw new IllegalStateException( error );
}
- if( provider instanceof CompositionModel )
- {
- CompositionModel standard = (CompositionModel) 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
+
+ if( false == ( provider instanceof CompositionModel ) )
{
+ //
+ // TODO: we could construct a context manager with no
+ // visible contest entries - but let's leave that till
+ // later
+ //
+
throw new UnsupportedOperationException(
method.getName() );
}
+
+ CompositionModel model = (CompositionModel) provider;
+ Controller controller = model.getController();
+ Holder holder = getHolder( model, args );
+ ClassLoader classloader = model.getClassLoader();
+ SystemContext system = getSystemContext();
+ ContextManagerInvocationHandler handler =
+ new ContextManagerInvocationHandler( system, holder );
+ return Proxy.newProxyInstance( classloader, new Class[]{
clazz }, handler );
}
- else if( PartDescriptor.PARTS_MANAGER_KEY.equals( postfix ) )
+ else if( PartDescriptor.PARTS_MANAGER_KEY.equals( postfix )
+ || PartDescriptor.PARTS_MAP_KEY.equals( postfix ) )
{
+ //
+ // TODO: write the implementation
+ //
+
throw new UnsupportedOperationException( method.getName() );
}
else
{
final String error =
- "Unrecognized postfix in the part accessor method ["
+ "Unrecognized select postfix in the part accessor method ["
+ method.getName()
+ + "] for the key ["
+ + key
+ "].";
throw new IllegalStateException( error );
}
@@ -423,4 +443,64 @@
buffer.append( "}]" );
return buffer.toString();
}
+
+ private boolean getBooleanValue( Object object ) throws
IllegalArgumentException
+ {
+ if( object instanceof Boolean )
+ {
+ Boolean value = (Boolean) object;
+ return value.booleanValue();
+ }
+ else if( object instanceof String )
+ {
+ return Boolean.getBoolean( (String) object );
+ }
+ else
+ {
+ final String error =
+ "Cannot convert supplied parameter ["
+ + object.getClass().getName()
+ + "] to a boolean value.";
+ throw new IllegalArgumentException( error );
+ }
+ }
+
+ private Model getModelFromProvider( Entry entry, String key, String
operation )
+ {
+ if( entry instanceof Model )
+ {
+ return (Model) entry;
+ }
+ else
+ {
+ final String error =
+ "The request for the application of '"
+ + operation
+ + "' 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 IllegalArgumentException( error );
+ }
+ }
+
+ private Holder getHolder( CompositionModel model, Object[] args ) throws
Exception
+ {
+ Controller controller = model.getController();
+ if( null == args )
+ {
+ return (Holder) controller.create( model );
+ }
+ else if( args.length == 0 )
+ {
+ return (Holder) controller.create( model );
+ }
+ else
+ {
+ return (Holder) controller.create( model, args[0] );
+ }
+ }
}
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 Tue Apr 12
22:59:35 2005
@@ -9,30 +9,20 @@
<!-- create the component types -->
<types xmlns="plugin:dpml/composition/dpml-composition-builder">
+ <type class="net.dpml.composition.testing.ExampleComponent"/>
+ <type class="net.dpml.composition.testing.ExampleContainer"/>
<type class="net.dpml.composition.testing.WidgetComponent"/>
<type class="net.dpml.composition.testing.SimpleWidget"/>
<type class="net.dpml.composition.testing.BadWidget"/>
<type class="net.dpml.composition.testing.GizmoComponent"/>
+ <type class="net.dpml.composition.testing.DimensionComponent"/>
<type class="net.dpml.composition.testing.AcmeContainer"/>
</types>
- <!-- simple component -->
+ <!-- creation of a component for reference by uri -->
<component xmlns="plugin:dpml/composition/dpml-composition-builder"
- name="widget" class="net.dpml.composition.testing.WidgetComponent">
- <context>
- <value key="name" value="urn:model:name"/>
- <value key="partition" value="urn:model:partition"/>
- <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>
+ type="net.dpml.composition.testing.DimensionComponent"
+ name="dimension"/>
</target>
Modified:
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/AcmeContainer.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/AcmeContainer.java
Tue Apr 12 22:59:35 2005
@@ -18,6 +18,7 @@
package net.dpml.composition.testing;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
@@ -27,7 +28,7 @@
* @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
+public class AcmeContainer implements Example
{
//------------------------------------------------------------------
// static
@@ -40,6 +41,7 @@
//------------------------------------------------------------------
private final Logger m_logger;
+ private final Context m_context;
private final Parts m_parts;
//------------------------------------------------------------------
@@ -53,13 +55,23 @@
*
* @param logger the logging channel asign by the container
*/
- public AcmeContainer( final Logger logger, Parts parts )
+ public AcmeContainer( final Logger logger, Context context, Parts parts )
{
m_logger = logger;
+ m_context = context;
m_parts = parts;
}
//------------------------------------------------------------------
+ // Example service
+ //------------------------------------------------------------------
+
+ public void doMyStuff()
+ {
+ execute();
+ }
+
+ //------------------------------------------------------------------
// implementation
//------------------------------------------------------------------
@@ -68,18 +80,29 @@
Parts parts = getParts();
//
- // get the widget's color context manager and play with some values
+ // get the gizmo's color context manager and play with some values
//
getLogger().info( "getting widget context manager" );
- ColorContextManager manager = parts.getGizmoContextManager();
- String color = manager.getColor( "purple" );
+ ColorContext.Manager manager = parts.selectGizmoContextManager();
- manager.setColor( "blue" );
- Gizmo gizmo = parts.getGizmo();
- gizmo.doGizmoStuff();
- manager.setColor( "orange" );
+ String color = manager.getColor( "purple" );
+ manager.setColor( color );
+ Gizmo gizmo = parts.selectGizmo();
gizmo.doGizmoStuff();
+
+ //
+ // get the widget's generic context manager and assign a
+ // default dimension and update the gixmo component's
+ // context manager with the assignment of white as the
+ // preferred color
+ //
+
+ int width = m_context.getWidth( 1 );
+ int height = m_context.getWidth( 5 );
+ Dimension d = new DimensionValue( width, height );
+ Map map = parts.selectWidgetContextMap();
+ map.put( "dimension", d );
manager.setColor( "white" );
gizmo.doGizmoStuff();
@@ -89,11 +112,11 @@
//
debug( "getting gizmo impl" );
- Entry entry = parts.createGizmo();
+ Entry entry = parts.selectGizmoEntry();
GizmoComponent newGizmo = (GizmoComponent) entry.getValue();
debug( "getting identified gizmo" );
- Gizmo myGizmo = parts.getGizmo( "my-gizmo" );
+ Gizmo myGizmo = parts.selectGizmo( "my-gizmo" );
debug( "cleaning up" );
parts.releaseGizmo( gizmo );
@@ -115,6 +138,10 @@
// concerns
//------------------------------------------------------------------
+ public interface Context extends DimensionalContext
+ {
+ }
+
public interface Parts
{
/**
@@ -122,7 +149,14 @@
*
* @return the widget service
*/
- Widget getWidget();
+ Widget selectWidget();
+
+ /**
+ * Return the widget's context manager.
+ *
+ * @return the widget context manager
+ */
+ Map selectWidgetContextMap();
/**
* Return an instance of gizmo using the lifestyle policy
@@ -130,14 +164,14 @@
*
* @return the gizmo service
*/
- Gizmo getGizmo();
+ Gizmo selectGizmo();
/**
* Return the gizmo context manager.
*
* @return the gizmo context manager
*/
- ColorContextManager getGizmoContextManager();
+ ColorContext.Manager selectGizmoContextManager();
/**
* Return an identified instance of gizmo.
@@ -145,7 +179,7 @@
* @param key the instance identifier
* @return the gizmo service
*/
- Gizmo getGizmo( Object key );
+ Gizmo selectGizmo( Object key );
/**
* Create and return a new annonomouse instance of gizmo as a
@@ -153,7 +187,7 @@
*
* @return the gizmo component
*/
- Entry createGizmo();
+ Entry selectGizmoEntry();
/**
* Optional release of an instance of the gizmo component.
Modified:
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/ColorContext.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ColorContext.java
Tue Apr 12 22:59:35 2005
@@ -26,5 +26,11 @@
*/
public interface ColorContext
{
- public String getColor( String defaultColor );
+ String getColor( String defaultColor );
+
+ interface Manager extends ColorContext
+ {
+ 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
Tue Apr 12 22:59:35 2005
@@ -19,63 +19,14 @@
package net.dpml.composition.testing;
/**
- * An example of a multi-parameter class used as a constructed context entry.
- * The class takes two int values as constructed arguments and proves a
service
- * of multiplying the two numbers together. The purpose of this class is
simply
- * to demonstrate how foreign classes can be easily included into a
component
- * context.
+ * The dimension interface.
*
* @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 Dimension
+public interface Dimension
{
- private int m_x;
- private int m_y;
-
- public Dimension( int x, int y )
- {
- m_x = x;
- m_y = y;
- }
-
- public int getWidth()
- {
- return m_x;
- }
-
- public int getHeight()
- {
- return m_y;
- }
-
- public int getSize()
- {
- return multiply( m_x, m_y );
- }
-
- private int multiply( int x, int y )
- {
- int result = 0;
- if( 1 == x )
- {
- return y;
- }
- else if( 1 == y )
- {
- return x;
- }
- else if( ( x % 2) == 0 )
- {
- // even number
- int m = x/2;
- int subtotal = multiply( m, y );
- return subtotal + subtotal;
- }
- else
- {
- // odd number
- return y + multiply( x-1, y );
- }
- }
+ int getWidth();
+ int getHeight();
+ int getSize();
}
Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DimensionComponent.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DimensionComponent.java
Tue Apr 12 22:59:35 2005
@@ -0,0 +1,86 @@
+/*
+ * 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;
+
+/**
+ * An example of component based implementation of a Dimension. Unlike
+ * the DimensionValue, this implementation resolves width and height
parameters
+ * form the supplied context.
+ *
+ * @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 DimensionComponent implements Dimension
+{
+ private final Context m_context;
+
+ public DimensionComponent( Context context )
+ {
+ m_context = context;
+ }
+
+ public int getWidth()
+ {
+ return m_context.getWidth( 1024 );
+ }
+
+ public int getHeight()
+ {
+ return m_context.getHeight( 512 );
+ }
+
+ public int getSize()
+ {
+ synchronized( m_context )
+ {
+ int x = getWidth();
+ int y = getHeight();
+ return multiply( x, y );
+ }
+ }
+
+ private int multiply( int x, int y )
+ {
+ int result = 0;
+ if( 1 == x )
+ {
+ return y;
+ }
+ else if( 1 == y )
+ {
+ return x;
+ }
+ else if( ( x % 2) == 0 )
+ {
+ // even number
+ int m = x/2;
+ int subtotal = multiply( m, y );
+ return subtotal + subtotal;
+ }
+ else
+ {
+ // odd number
+ return y + multiply( x-1, y );
+ }
+ }
+
+ public interface Context extends DimensionalContext
+ {
+ }
+}
Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DimensionValue.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DimensionValue.java
Tue Apr 12 22:59:35 2005
@@ -0,0 +1,81 @@
+/*
+ * 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;
+
+/**
+ * An example of a multi-parameter class used as a constructed context entry.
+ * The class takes two int values as constructed arguments and proves a
service
+ * of multiplying the two numbers together. The purpose of this class is
simply
+ * to demonstrate how foreign classes can be easily included into a
component
+ * context.
+ *
+ * @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 DimensionValue implements Dimension
+{
+ private int m_x;
+ private int m_y;
+
+ public DimensionValue( int x, int y )
+ {
+ m_x = x;
+ m_y = y;
+ }
+
+ public int getWidth()
+ {
+ return m_x;
+ }
+
+ public int getHeight()
+ {
+ return m_y;
+ }
+
+ public int getSize()
+ {
+ return multiply( m_x, m_y );
+ }
+
+ private int multiply( int x, int y )
+ {
+ int result = 0;
+ if( 1 == x )
+ {
+ return y;
+ }
+ else if( 1 == y )
+ {
+ return x;
+ }
+ else if( ( x % 2) == 0 )
+ {
+ // even number
+ int m = x/2;
+ int subtotal = multiply( m, y );
+ return subtotal + subtotal;
+ }
+ else
+ {
+ // odd number
+ return y + multiply( x-1, y );
+ }
+ }
+}
Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DimensionalContext.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DimensionalContext.java
Tue Apr 12 22:59:35 2005
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+/**
+ * An example of a standard context interface.
+ *
+ * @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 DimensionalContext
+{
+ int getHeight( int h );
+ int getWidth( int w );
+
+ interface Manager extends DimensionalContext
+ {
+ void setWidth( int width );
+ void setHeight( int height );
+ }
+}
Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Example.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/Example.java
Tue Apr 12 22:59:35 2005
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+/**
+ * An example service interface.
+ *
+ * @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 Example
+{
+ void doMyStuff();
+}
Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ExampleComponent.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ExampleComponent.java
Tue Apr 12 22:59:35 2005
@@ -0,0 +1,88 @@
+/*
+ * 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.net.URI;
+import java.util.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 ExampleComponent implements Example
+{
+ //------------------------------------------------------------------
+ // state
+ //------------------------------------------------------------------
+
+ /**
+ * The logging channel.
+ */
+ private final Logger m_logger;
+
+ /**
+ * The assigned context instance.
+ */
+ private final Context m_context;
+
+ //------------------------------------------------------------------
+ // constructor
+ //------------------------------------------------------------------
+
+ /**
+ * Creation of a new ExampleComponent.
+ *
+ * @param logger the logging channel asigned by the container
+ * @param context the assign component context
+ */
+ public ExampleComponent( final Logger logger, final Context context )
+ {
+ m_context = context;
+ m_logger = logger;
+ }
+
+ //------------------------------------------------------------------
+ // Service interface
+ //------------------------------------------------------------------
+
+ /**
+ * Implementation of the Example service interface.
+ */
+ public void doMyStuff()
+ {
+ Dimension defaultValue = new DimensionValue( 10, 20 );
+ Dimension dimension = m_context.getDimension( defaultValue );
+ int size = dimension.getSize();
+
+ m_logger.info(
+ "Creating a widget with a area of " + size );
+ }
+
+ //------------------------------------------------------------------
+ // concerns
+ //------------------------------------------------------------------
+
+ public interface Context
+ {
+ Dimension getDimension( Dimension d );
+ }
+}
Added:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ExampleContainer.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/ExampleContainer.java
Tue Apr 12 22:59:35 2005
@@ -0,0 +1,111 @@
+/*
+ * 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.util.Map;
+import java.util.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 ExampleContainer implements Example
+{
+ //------------------------------------------------------------------
+ // state
+ //------------------------------------------------------------------
+
+ /**
+ * The logging channel.
+ */
+ private final Logger m_logger;
+
+ /**
+ * The assigned context instance.
+ */
+ private final Context m_context;
+
+ /**
+ * The assigned context instance.
+ */
+ private final Parts m_parts;
+
+ //------------------------------------------------------------------
+ // constructor
+ //------------------------------------------------------------------
+
+ /**
+ * Creation of a new ExampleComponent.
+ *
+ * @param logger the logging channel asigned by the container
+ * @param context the assign component context
+ */
+ public ExampleContainer( final Logger logger, final Context context,
final Parts parts )
+ {
+ m_logger = logger;
+ m_context = context;
+ m_parts = parts;
+ }
+
+ //------------------------------------------------------------------
+ // Service interface
+ //------------------------------------------------------------------
+
+ /**
+ * Implementation of the Example service interface.
+ */
+ public void doMyStuff()
+ {
+ //
+ // retrive and configure the 'dimension' parts' context using
+ // width and height values in our context
+ //
+
+ int width = m_context.getWidth( 9 );
+ int height = m_context.getHeight( 7 );
+ DimensionalContext.Manager manager =
+ m_parts.selectDimensionContextManager();
+ manager.setHeight( height );
+ manager.setWidth( width );
+
+ //Map map = m_parts.selectDimensionContextMap();
+ //map.put( "height", new Integer( height ) );
+ //map.put( "width", new Integer( width ) );
+
+ Dimension dimension = m_parts.selectDimension();
+ int size = dimension.getSize();
+ m_logger.info(
+ "Creating a widget with a area of " + size );
+ }
+
+ //------------------------------------------------------------------
+ // concerns
+ //------------------------------------------------------------------
+
+ public interface Context extends DimensionalContext{}
+
+ public interface Parts
+ {
+ DimensionalContext.Manager selectDimensionContextManager();
+ Map selectDimensionContextMap();
+ Dimension selectDimension();
+ }
+}
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
Tue Apr 12 22:59:35 2005
@@ -142,7 +142,7 @@
*/
public void doWidgetStuff( final String color )
{
- Dimension d = new Dimension( 10, 20 );
+ Dimension d = new DimensionValue( 10, 20 );
int width = m_context.getDimension( d ).getWidth();
int height = m_context.getDimension( d ).getHeight();
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 Tue Apr 12
22:59:35 2005
@@ -8,6 +8,63 @@
<target name="build" depends="standard.build">
<!--
+ Example component.
+ -->
+ <component dest="target/test/acme-example-one.part"
+ xmlns="plugin:dpml/composition/dpml-composition-builder"
+ type="net.dpml.composition.testing.ExampleComponent"
+ name="demo">
+ <context>
+ <value key="dimension"
class="net.dpml.composition.testing.DimensionValue">
+ <param class="int" value="2"/>
+ <param class="int" value="5"/>
+ </value>
+ </context>
+ </component>
+
+ <!--
+ Example component using a nested dimension component.
+ -->
+ <component dest="target/test/acme-example-two.part"
+ xmlns="plugin:dpml/composition/dpml-composition-builder"
+ type="net.dpml.composition.testing.ExampleComponent"
+ name="demo">
+ <context>
+ <component key="dimension"
type="net.dpml.composition.testing.DimensionComponent">
+ <context>
+ <value key="width" value="12"/>
+ <value key="height" value="100"/>
+ </context>
+ </component>
+ </context>
+ </component>
+
+ <!--
+ Example component using an internal part.
+ -->
+ <component dest="target/test/acme-example-three.part"
+ xmlns="plugin:dpml/composition/dpml-composition-builder"
+ type="net.dpml.composition.testing.ExampleContainer"
+ name="demo">
+ <parts>
+ <component name="dimension"
type="net.dpml.composition.testing.DimensionComponent"/>
+ </parts>
+ </component>
+
+ <!--
+ Example component using a part by reference.
+ -->
+ <x:property key="dpml-composition-testing-acme" feature="uri"
type="part" name="acme.uri"/>
+ <component dest="target/test/acme-example-four.part"
+ xmlns="plugin:dpml/composition/dpml-composition-builder"
+ type="net.dpml.composition.testing.ExampleContainer"
+ name="demo">
+ <parts>
+ <part key="dimension" uri="${acme.uri}"/>
+ </parts>
+ </component>
+
+ <!--
Simple component example.
This is a simple component with no dependencies. It is used
primarily to validate context entry construction. It includes
@@ -19,20 +76,46 @@
-->
<component dest="target/test/acme-simple.part"
xmlns="plugin:dpml/composition/dpml-composition-builder"
- class="net.dpml.composition.testing.WidgetComponent"
+ type="net.dpml.composition.testing.WidgetComponent"
name="widget">
<context>
<value key="name" value="urn:model:name"/>
<value key="partition" value="urn:model:partition"/>
<value key="uri" value="urn:model:uri"/>
<value key="workingDirectory">
- <value class="java.io.File" value="urn:system:work.dir"/>
- <value value="acme/workspace"/>
+ <param class="java.io.File" value="urn:system:work.dir"/>
+ <param value="acme/workspace"/>
+ </value>
+ <value key="dimension"
class="net.dpml.composition.testing.DimensionValue">
+ <param class="int" value="12"/>
+ <param class="int" value="100"/>
</value>
- <value key="dimension"
class="net.dpml.composition.testing.Dimension">
- <value class="int" value="12"/>
- <value class="int" value="100"/>
+ </context>
+ </component>
+
+ <!--
+ Simple component example.
+ In this example we substitute the creation of a simple value type
+ with a component.
+ -->
+ <component dest="target/test/acme-widget.part"
+ xmlns="plugin:dpml/composition/dpml-composition-builder"
+ type="net.dpml.composition.testing.WidgetComponent"
+ name="widget">
+ <context>
+ <value key="name" value="urn:model:name"/>
+ <value key="partition" value="urn:model:partition"/>
+ <value key="uri" value="urn:model:uri"/>
+ <value key="workingDirectory">
+ <param class="java.io.File" value="urn:system:work.dir"/>
+ <param value="acme/workspace"/>
</value>
+ <component key="dimension"
type="net.dpml.composition.testing.DimensionComponent">
+ <context>
+ <value key="width" value="12"/>
+ <value key="height" value="100"/>
+ </context>
+ </component>
</context>
</component>
@@ -56,21 +139,21 @@
-->
<component dest="target/test/acme-container.part"
xmlns="plugin:dpml/composition/dpml-composition-builder"
- class="net.dpml.composition.testing.AcmeContainer"
+ type="net.dpml.composition.testing.AcmeContainer"
name="acme">
<parts>
- <component name="widget"
class="net.dpml.composition.testing.WidgetComponent">
+ <component name="widget"
type="net.dpml.composition.testing.WidgetComponent">
<context>
<value key="workingDirectory">
- <value class="java.io.File" value="urn:system:work.dir"/>
- <value value="acme/workspace"/>
+ <param class="java.io.File" value="urn:system:work.dir"/>
+ <param value="acme/workspace"/>
</value>
<value key="name" value="urn:model:name"/>
<value key="partition" value="urn:model:partition"/>
<value key="uri" value="urn:model:uri"/>
</context>
</component>
- <component name="gizmo"
class="net.dpml.composition.testing.GizmoComponent">
+ <component name="gizmo"
type="net.dpml.composition.testing.GizmoComponent">
<context>
<value key="color" value="red"/>
<reference key="widget" uri="parts:widget"/>
@@ -87,11 +170,11 @@
-->
<component dest="target/test/acme-test-container.part"
xmlns="plugin:dpml/composition/dpml-composition-builder"
- class="net.dpml.composition.testing.AcmeContainer"
+ type="net.dpml.composition.testing.AcmeContainer"
name="acme">
<parts>
- <component name="widget"
class="net.dpml.composition.testing.SimpleWidget"/>
- <component name="gizmo"
class="net.dpml.composition.testing.GizmoComponent">
+ <component name="widget"
type="net.dpml.composition.testing.SimpleWidget"/>
+ <component name="gizmo"
type="net.dpml.composition.testing.GizmoComponent">
<context>
<value key="color" value="red"/>
<reference key="widget" uri="parts:widget"/>
@@ -105,11 +188,11 @@
-->
<component dest="target/test/acme-bad-widget.part"
xmlns="plugin:dpml/composition/dpml-composition-builder"
- class="net.dpml.composition.testing.AcmeContainer"
+ type="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">
+ <component name="widget"
type="net.dpml.composition.testing.BadWidget"/>
+ <component name="gizmo"
type="net.dpml.composition.testing.GizmoComponent">
<context>
<value key="color" value="red"/>
<reference key="widget" uri="parts:widget"/>
Added:
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/ExampleTestCase.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/testing/ExampleTestCase.java
Tue Apr 12 22:59:35 2005
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2004 Stephen J. McConnell.
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * 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.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;
+
+/**
+ * Test a simple component case.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: AbstractDescriptorTestCase.java 1556 2005-01-22 12:43:42Z
niclas $
+ */
+public class ExampleTestCase extends TestCase
+{
+ /**
+ * Test the construction of the example component and the invocation of
+ * an operation on the example service interface.
+ */
+ public void testExampleUsingValue() throws Exception
+ {
+ CompositionHelper helper = new CompositionHelper();
+ URI uri = helper.toURI( "acme-example-one.part" );
+ Model model = helper.getCompositionManager().addPart( uri, "example"
);
+ Example example = (Example) model.getValue();
+ example.doMyStuff();
+ }
+
+ /**
+ * Test the construction of the example component using a
+ * component declared inside the context of the target
+ * component.
+ */
+ public void testExampleUsingComponent() throws Exception
+ {
+ CompositionHelper helper = new CompositionHelper();
+ URI uri = helper.toURI( "acme-example-two.part" );
+ Model model = helper.getCompositionManager().addPart( uri, "example"
);
+ Example example = (Example) model.getValue();
+ example.doMyStuff();
+ }
+
+ /**
+ * Test the construction of the example component using a
+ * component declared as a part of an enclosing component.
+ */
+ public void testExampleUsingContainer() throws Exception
+ {
+ CompositionHelper helper = new CompositionHelper();
+ URI uri = helper.toURI( "acme-example-three.part" );
+ Model model = helper.getCompositionManager().addPart( uri, "example"
);
+ Example example = (Example) model.getValue();
+ example.doMyStuff();
+ }
+
+ /**
+ * Test the construction of the example component using a
+ * component declared as a part of an enclosing component using
+ * a part reference.
+ */
+ public void testExampleUsingPartReference() throws Exception
+ {
+ CompositionHelper helper = new CompositionHelper();
+ URI uri = helper.toURI( "acme-example-four.part" );
+ Model model = helper.getCompositionManager().addPart( uri, "example"
);
+ Example example = (Example) model.getValue();
+ example.doMyStuff();
+ }
+}
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
Tue Apr 12 22:59:35 2005
@@ -54,6 +54,20 @@
}
/**
+ * Test the construction of the widget component using the
+ * DimensionComponent as the Dimension provider.
+ */
+ public void testDimensionInWidget() throws Exception
+ {
+ CompositionHelper helper = new CompositionHelper();
+ URI uri = helper.toURI( "acme-widget.part" );
+ Model model = helper.getCompositionManager().addPart( uri, "widget"
);
+ Widget widget = (Widget) model.getValue();
+ widget.doWidgetStuff( "magenta" );
+ model.getController().release( widget );
+ }
+
+ /**
* Test the isolation of the widget.
*/
public void testServiceIsolation() throws Exception
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
Tue Apr 12 22:59:35 2005
@@ -55,16 +55,21 @@
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 SELECT = 1;
+ public static final int CREATE = 2;
+ public static final int RELEASE = -1;
public static final String GET_KEY = "get";
+ public static final String SELECT_KEY = "select";
public static final String CREATE_KEY = "create";
public static final String RELEASE_KEY = "release";
+ public static final String CONTEXT_MAP_KEY = "ContextMap";
public static final String CONTEXT_MANAGER_KEY = "ContextManager";
public static final String PARTS_MANAGER_KEY = "PartsManager";
+ public static final String PARTS_MAP_KEY = "PartsMap";
+ public static final String ENTRY_KEY = "Entry";
public static String toString( int semantic )
{
@@ -72,6 +77,10 @@
{
return "create";
}
+ else if( SELECT == semantic )
+ {
+ return "select";
+ }
else if( GET == semantic )
{
return "get";
@@ -93,10 +102,22 @@
{
return CONTEXT_MANAGER_KEY;
}
+ else if( name.endsWith( CONTEXT_MAP_KEY ) )
+ {
+ return CONTEXT_MAP_KEY;
+ }
else if( name.endsWith( PARTS_MANAGER_KEY ) )
{
return PARTS_MANAGER_KEY;
}
+ else if( name.endsWith( PARTS_MAP_KEY ) )
+ {
+ return PARTS_MAP_KEY;
+ }
+ else if( name.endsWith( ENTRY_KEY ) )
+ {
+ return ENTRY_KEY;
+ }
else
{
return null;
@@ -106,7 +127,11 @@
public static int getPartSemantic( Method method )
{
String name = method.getName();
- if( name.startsWith( GET_KEY ) )
+ if( name.startsWith( SELECT_KEY ) )
+ {
+ return SELECT;
+ }
+ else if( name.startsWith( GET_KEY ) )
{
return GET;
}
@@ -137,27 +162,52 @@
public static String getPartKey( Method method, int semantic )
{
String name = method.getName();
- if( GET == semantic )
+ if( SELECT == semantic )
{
- if( name.endsWith( CONTEXT_MANAGER_KEY ) )
+ if( name.endsWith( ENTRY_KEY ) )
+ {
+ int n = ENTRY_KEY.length();
+ int j = name.length() - n;
+ String substring = name.substring( 0, j );
+ return formatKey( substring, 6 );
+ }
+ else 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 );
+ return formatKey( substring, 6 );
+ }
+ else if( name.endsWith( CONTEXT_MAP_KEY ) )
+ {
+ int n = CONTEXT_MAP_KEY.length();
+ int j = name.length() - n;
+ String substring = name.substring( 0, j );
+ return formatKey( substring, 6 );
}
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 );
+ return formatKey( substring, 6 );
+ }
+ else if( name.endsWith( PARTS_MAP_KEY ) )
+ {
+ int n = PARTS_MAP_KEY.length();
+ int j = name.length() - n;
+ String substring = name.substring( 0, j );
+ return formatKey( substring, 6 );
}
else
{
- return formatKey( name, 3 );
+ return formatKey( name, 6 );
}
}
+ else if( GET == semantic )
+ {
+ return formatKey( name, 3 );
+ }
else if( CREATE == semantic )
{
return formatKey( name, 6 );
- svn commit: r2272 - in development/main/metro: automation/control/src/main/net/dpml/automation/control composition/builder/src/main/net/dpml/composition/builder composition/builder/src/main/net/dpml/composition/builder/datatypes composition/control/src/main/net/dpml/composition/control composition/testing/acme composition/testing/acme/src/main/net/dpml/composition/testing composition/testing/unit composition/testing/unit/src/test/net/dpml/composition/testing meta/api/src/main/net/dpml/meta/info, mcconnell, 04/12/2005
Archive powered by MHonArc 2.6.24.