notify-dpml AT lists.ibiblio.org
Subject: DPML Notify
List archive
svn commit: r2209 - in development/main/metro: automation/control/src/main/net/dpml/automation/model composition/control/src/main/net/dpml/composition/control composition/control/src/main/net/dpml/composition/models composition/testing/acme/src/main/net/dpml/composition/testing
- From: mcconnell AT dpml.net
- To: notify-dpml AT lists.ibiblio.org
- Subject: svn commit: r2209 - in development/main/metro: automation/control/src/main/net/dpml/automation/model composition/control/src/main/net/dpml/composition/control composition/control/src/main/net/dpml/composition/models composition/testing/acme/src/main/net/dpml/composition/testing
- Date: Tue, 05 Apr 2005 09:31:26 -0400
Author: mcconnell AT dpml.net
Date: Tue Apr 5 09:31:19 2005
New Revision: 2209
Added:
development/main/metro/automation/control/src/main/net/dpml/automation/model/PartClassNotFoundException.java
development/main/metro/automation/control/src/main/net/dpml/automation/model/ServiceClassNotFoundException.java
development/main/metro/automation/control/src/main/net/dpml/automation/model/TypeClassNotFoundException.java
development/main/metro/composition/control/src/main/net/dpml/composition/models/DuplicateKeyException.java
development/main/metro/composition/control/src/main/net/dpml/composition/models/InvalidModelException.java
development/main/metro/composition/control/src/main/net/dpml/composition/models/MissingDependencyDirectiveException.java
development/main/metro/composition/control/src/main/net/dpml/composition/models/MissingPartException.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/UnresolvableDependencyException.java
Modified:
development/main/metro/automation/control/src/main/net/dpml/automation/model/ModelRuntimeException.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/models/StandardComponentModel.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/DefaultGizmo.java
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultWidget.java
Log:
Separate parts into a nested model (keeping the primary model simpler and
easier to follow).
Modified:
development/main/metro/automation/control/src/main/net/dpml/automation/model/ModelRuntimeException.java
==============================================================================
---
development/main/metro/automation/control/src/main/net/dpml/automation/model/ModelRuntimeException.java
(original)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/model/ModelRuntimeException.java
Tue Apr 5 09:31:19 2005
@@ -26,10 +26,14 @@
*/
public class ModelRuntimeException extends RuntimeException
{
+ public ModelRuntimeException( String message )
+ {
+ super( message );
+ }
+
public ModelRuntimeException( String message, Throwable cause )
{
super( message, cause );
}
-
}
Added:
development/main/metro/automation/control/src/main/net/dpml/automation/model/PartClassNotFoundException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/model/PartClassNotFoundException.java
Tue Apr 5 09:31:19 2005
@@ -0,0 +1,43 @@
+/*
+ * 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.model;
+
+/**
+ * Exception thrown when an attempt is made to locate a class declared
+ * by a parts accessor and the class cannot be found.
+ *
+ * @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 PartClassNotFoundException extends ModelRuntimeException
+{
+ private String m_classname;
+
+ public PartClassNotFoundException( String classname )
+ {
+ super( classname );
+ m_classname = classname;
+ }
+
+ public String getClassname()
+ {
+ return m_classname;
+ }
+}
+
Added:
development/main/metro/automation/control/src/main/net/dpml/automation/model/ServiceClassNotFoundException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/model/ServiceClassNotFoundException.java
Tue Apr 5 09:31:19 2005
@@ -0,0 +1,61 @@
+/*
+ * 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.model;
+
+/**
+ * Unexpected runtime exception indicating an internal model error.
+ *
+ * @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 ServiceClassNotFoundException extends ModelRuntimeException
+{
+ private String m_serviceClassname;
+ private String m_componentClassname;
+
+ public ServiceClassNotFoundException( String componentClassname, String
serviceClassname )
+ {
+ super( buildMessage( componentClassname, serviceClassname ) );
+ m_serviceClassname = serviceClassname;
+ m_componentClassname = componentClassname;
+ }
+
+ public String getComponentClassname()
+ {
+ return m_componentClassname;
+ }
+
+ public String getServiceClassname()
+ {
+ return m_serviceClassname;
+ }
+
+ private static String buildMessage( String componentClassname, String
serviceClassname )
+ {
+ String error =
+ "Service class ["
+ + serviceClassname
+ + "] declared by the component type ["
+ + componentClassname
+ + "] was not found.";
+ return error;
+ }
+
+}
+
Added:
development/main/metro/automation/control/src/main/net/dpml/automation/model/TypeClassNotFoundException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/automation/model/TypeClassNotFoundException.java
Tue Apr 5 09:31:19 2005
@@ -0,0 +1,42 @@
+/*
+ * 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.model;
+
+/**
+ * Unexpected runtime exception indicating an internal model error.
+ *
+ * @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 TypeClassNotFoundException extends ModelRuntimeException
+{
+ private String m_classname;
+
+ public TypeClassNotFoundException( String classname )
+ {
+ super( classname );
+ m_classname = classname;
+ }
+
+ public String getClassname()
+ {
+ return m_classname;
+ }
+}
+
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
Tue Apr 5 09:31:19 2005
@@ -69,6 +69,16 @@
return m_key;
}
+ public StandardComponentModel getModel()
+ {
+ return m_model;
+ }
+
+ public Object getQualifiedName()
+ {
+ return getModel().getQualifiedName() + "#" + getKey().toString();
+ }
+
public Object newProxy() throws Exception
{
synchronized( m_proxies )
@@ -93,7 +103,7 @@
}
if( null == m_instance )
{
- m_instance = m_factory.incarnate( m_model );
+ m_instance = m_factory.incarnate( this );
}
return m_instance;
}
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
Tue Apr 5 09:31:19 2005
@@ -55,7 +55,27 @@
}
/**
- * Execute the incarnation sequence and return a new annonomous
+ * Execute the incarnation sequence and return a new
+ * component instance.
+ *
+ * @return a new component instance
+ */
+ public Object incarnate( Holder holder ) throws LifecycleException
+ {
+ if( getMonitor().isDebugEnabled() )
+ {
+ final String message =
+ "Incarnating ["
+ + holder.getQualifiedName()
+ + "].";
+ getMonitor().debug( message );
+ }
+ StandardComponentModel model = holder.getModel();
+ return execute( model );
+ }
+
+ /**
+ * Execute the incarnation sequence and return a new
* component instance.
*
* @return a new component instance
@@ -65,12 +85,22 @@
if( getMonitor().isDebugEnabled() )
{
final String message =
- "Initiating incarnation using the model ["
+ "Incarnating ["
+ model.getQualifiedName()
+ "].";
getMonitor().debug( message );
}
+ return execute( model );
+ }
+ /**
+ * Execute the incarnation sequence and return a new
+ * component instance.
+ *
+ * @return a new component instance
+ */
+ private Object execute( StandardComponentModel model ) throws
LifecycleException
+ {
Class subject = model.getDeploymentClass();
ClassLoader classloader = subject.getClassLoader();
Constructor constructor = getConstructor( subject );
Added:
development/main/metro/composition/control/src/main/net/dpml/composition/models/DuplicateKeyException.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/DuplicateKeyException.java
Tue Apr 5 09:31:19 2005
@@ -0,0 +1,47 @@
+/*
+ * 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 net.dpml.automation.model.ModelException;
+
+import net.dpml.composition.data.DependencyDirective;
+
+/**
+ * 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 DuplicateKeyException extends ModelException
+{
+ private String m_key;
+
+ public DuplicateKeyException( String key )
+ {
+ super( key );
+ m_key = key;
+ }
+
+ public String getKey()
+ {
+ return m_key;
+ }
+}
+
Added:
development/main/metro/composition/control/src/main/net/dpml/composition/models/InvalidModelException.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/InvalidModelException.java
Tue Apr 5 09:31:19 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.composition.models;
+
+import net.dpml.automation.model.ModelRuntimeException;
+
+/**
+ * Unexpected runtime exception indicating an internal model error.
+ *
+ * @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 InvalidModelException extends ModelRuntimeException
+{
+ private Throwable[] m_issues;
+
+ public InvalidModelException( StandardComponentModel model, Throwable[]
issues )
+ {
+ super( buildMessage( model, issues ) );
+ m_issues = issues;
+ }
+
+ public Throwable[] getIssues()
+ {
+ return m_issues;
+ }
+
+ private static String buildMessage( StandardComponentModel model,
Throwable[] issues )
+ {
+ final String name = model.getQualifiedName();
+ final String error =
+ "The component model ["
+ + name
+ + "] contains "
+ + issues.length
+ + " unresolved ";
+ if( issues.length == 1 )
+ {
+ return error + "issue.";
+ }
+ else
+ {
+ return error + "issues.";
+ }
+ }
+}
+
Added:
development/main/metro/composition/control/src/main/net/dpml/composition/models/MissingDependencyDirectiveException.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/MissingDependencyDirectiveException.java
Tue Apr 5 09:31:19 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.composition.models;
+
+import net.dpml.automation.model.ModelException;
+
+/**
+ * Unexpected runtime exception indicating an internal model error.
+ *
+ * @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 MissingDependencyDirectiveException extends ModelException
+{
+ private StandardComponentModel m_model;
+ private String m_key;
+
+ public MissingDependencyDirectiveException( StandardComponentModel
model, String key )
+ {
+ super( buildMessage( model, key ) );
+ m_model = model;
+ m_key = key;
+ }
+
+ public String getKey()
+ {
+ return m_key;
+ }
+
+ public StandardComponentModel getModel()
+ {
+ return m_model;
+ }
+
+ private static String buildMessage( StandardComponentModel model, String
key )
+ {
+ final String name = model.getQualifiedName();
+ final String error =
+ "The component model ["
+ + name
+ + "] does not delcare a dependency directive for the required
dependency ["
+ + key
+ + "].";
+ return error;
+ }
+}
+
Added:
development/main/metro/composition/control/src/main/net/dpml/composition/models/MissingPartException.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/MissingPartException.java
Tue Apr 5 09:31:19 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.composition.models;
+
+import net.dpml.automation.model.ModelException;
+
+/**
+ * Unexpected runtime exception indicating an internal model error.
+ *
+ * @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 MissingPartException extends ModelException
+{
+ private StandardComponentModel m_model;
+ private String m_key;
+
+ public MissingPartException( StandardComponentModel model, String key )
+ {
+ super( buildMessage( model, key ) );
+ m_model = model;
+ m_key = key;
+ }
+
+ public String getKey()
+ {
+ return m_key;
+ }
+
+ public StandardComponentModel getModel()
+ {
+ return m_model;
+ }
+
+ private static String buildMessage( StandardComponentModel model, String
key )
+ {
+ final String name = model.getQualifiedName();
+ final String error =
+ "The component model ["
+ + name
+ + "] does not contain a part for the key ["
+ + key
+ + "].";
+ return error;
+ }
+}
+
Added:
development/main/metro/composition/control/src/main/net/dpml/composition/models/PartsModel.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/PartsModel.java
Tue Apr 5 09:31:19 2005
@@ -0,0 +1,227 @@
+/*
+ * 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.Hashtable;
+import java.util.WeakHashMap;
+import java.util.List;
+import java.util.LinkedList;
+
+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.Controller;
+import net.dpml.automation.control.DelegationException;
+import net.dpml.automation.part.Part;
+
+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 PartsModel implements Serializable
+{
+ private final ClassLoader m_classloader;
+ private final String m_partition;
+ private final CompositionController m_controller;
+ private final StandardComponentModel m_parent;
+
+ private final Map m_parts = new Hashtable();
+ private final List m_errors = new LinkedList();
+
+ /**
+ * Creation of a model representing the parts within a component.
+ *
+ * @param controller the model controller
+ * @param parent the enclosing parent model
+ * @param partition a name defining the partition within which the parts
are enclosed
+ * @param classloader the classloader established as the parent for the
parts
+ * @param profile the component profile from which initial default values
are established
+ */
+ public PartsModel(
+ CompositionController controller, StandardComponentModel parent,
String partition, ClassLoader classloader )
+ throws DelegationException, ModelException
+ {
+ m_controller = controller;
+ m_partition = partition;
+ m_classloader = classloader;
+ m_parent = parent;
+ }
+
+ public Model getModel( String key )
+ {
+ if( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
+ return (Model) m_parts.get( key );
+ }
+
+ public void addModel( String key, Part part ) throws
DelegationException, ModelException
+ {
+ if( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
+ if( null == part )
+ {
+ throw new NullPointerException( "part" );
+ }
+ addPartToCollection( key, part, true );
+ }
+
+ public void validate() throws InvalidModelException
+ {
+ if( m_errors.isEmpty() )
+ {
+ return;
+ }
+ else
+ {
+ StandardComponentModel model = getParentModel();
+ Throwable[] issues = getIssues();
+ throw new InvalidModelException( model, issues );
+ }
+ }
+
+ private Throwable[] getIssues()
+ {
+ if( m_errors.isEmpty() )
+ {
+ return new Throwable[0];
+ }
+ else
+ {
+ return (Throwable[]) m_errors.toArray( new Throwable[ 0 ] );
+ }
+ }
+
+ void addPartToCollection( String key, Part part, boolean validate )
throws DelegationException, ModelException
+ {
+ Model model = loadModelFromPart( part );
+ String k = getKey( key, model );
+ if( m_parts.containsKey( k ) )
+ {
+ throw new DuplicateKeyException( k );
+ }
+ m_parts.put( k, model );
+ if( validate )
+ {
+ build();
+ }
+ }
+
+ private String getKey( String key, Model model )
+ {
+ if( null == key )
+ {
+ return model.getName();
+ }
+ else
+ {
+ return key;
+ }
+ }
+
+ private Model loadModelFromPart( Part part ) throws DelegationException,
ModelException, DuplicateKeyException
+ {
+ StandardComponentModel parent = getParentModel();
+ String partition = getPartition();
+ ClassLoader classloader = getClassLoader();
+ return getController().getModel( parent, partition, classloader,
part );
+ }
+
+ private void build()
+ {
+ StandardComponentModel parent = getParentModel();
+ synchronized( m_errors )
+ {
+ m_errors.clear();
+ PartDescriptor[] descriptors =
m_parent.getType().getPartDescriptors();
+ for( int i=0; i<descriptors.length; i++ )
+ {
+ PartDescriptor descriptor = descriptors[i];
+ String key = descriptor.getKey();
+ Model model = (Model) m_parts.get( key );
+ if( null == model )
+ {
+ Exception e = new MissingPartException( parent, key );
+ m_errors.add( e );
+ }
+ else
+ {
+ //String returnType = descriptor.getType();
+ //Class returnClass = loadReturnClass( returnType );
+ //model.getController().....
+ }
+ }
+ }
+ }
+
+ private Class loadReturnClass( ClassLoader classloader, String classname
)
+ {
+ try
+ {
+ return classloader.loadClass( classname );
+ }
+ catch( ClassNotFoundException cnfe )
+ {
+ throw new PartClassNotFoundException( classname );
+ }
+ }
+
+
+ private StandardComponentModel getParentModel()
+ {
+ return m_parent;
+ }
+
+ private String getPartition()
+ {
+ return m_partition;
+ }
+
+ private ClassLoader getClassLoader()
+ {
+ return m_classloader;
+ }
+
+ private CompositionController getController()
+ {
+ return m_controller;
+ }
+}
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
Tue Apr 5 09:31:19 2005
@@ -22,10 +22,14 @@
import java.util.Map;
import java.util.Hashtable;
import java.util.WeakHashMap;
+import java.util.List;
+import java.util.LinkedList;
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.control.Controller;
import net.dpml.automation.control.DelegationException;
import net.dpml.automation.part.Part;
@@ -54,17 +58,27 @@
private final ClassLoader m_classloader;
private final String m_partition;
private final CompositionController m_controller;
+ private final PartsModel m_parts;
private final Class m_class;
private final Type m_type;
private final Class[] m_interfaces;
- private final String m_name;
- private final String m_lifestyle;
private transient Map m_holders = new WeakHashMap();
- private final Hashtable m_providers = new Hashtable();
- private final Hashtable m_parts = new Hashtable();
+ private final Map m_providers = new Hashtable();
+ private final List m_errors = new LinkedList();
+ private String m_name;
+ private String m_lifestyle;
+
+ /**
+ * Creation of a new root component model.
+ *
+ * @param controller the model controller
+ * @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
+ */
public StandardComponentModel(
CompositionController controller, String partition, ClassLoader
classloader, ComponentProfile profile )
throws DelegationException, ModelException
@@ -72,6 +86,22 @@
this( controller, null, partition, classloader, profile );
}
+ /**
+ * Creation of a new nested component model.
+ *
+ * TODO: Update so that the constructor simply established the initial
state
+ * (including validity) in such a way that we can progromatically update
the
+ * state. As such only a small subset of operations in the constructor
will
+ * result in a runtime exception (e.g. component class not found, etc.).
this
+ * will require the creation of som sub-models such as DependenciesModel,
+ * ContextModel, PartsModel, etc. - each representing a management
concern.
+ *
+ * @param controller the model controller
+ * @param parent the enclosing parent model
+ * @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
+ */
public StandardComponentModel(
CompositionController controller, Model parent, String partition,
ClassLoader classloader, ComponentProfile profile )
throws DelegationException, ModelException
@@ -84,12 +114,13 @@
m_class = loadComponentClass( classloader, profile );
m_type = controller.loadType( m_class );
m_name = profile.getName();
- m_lifestyle = profile.getLifestylePolicy();
//
- // construct an array of the interface classes that the component
+ // Construct an array of the interface classes that the component
// exposes as public services - these will be used when constructing
- // a proxy to component instances created from this model
+ // a proxy to component instances created from this model. If an
+ // error occurs while attempting to load a service class - a runtime
+ // exception will be thrown.
//
ServiceDescriptor[] services = m_type.getServices();
@@ -102,25 +133,35 @@
m_interfaces = interfaces;
//
+ // set the preferred lifestyle policy
+ //
+
+ m_lifestyle = profile.getLifestylePolicy();
+
+ //
// Get the set of parts within this part and add them as nested
models
// within this model. There is an issue here concerning selection of
// our classloader as the parent for the parts - in effect we need a
- // classname that identifies a class in the component's api loader.
+ // classname that identifies a class in the component's api loader
+ // (or alternatively - we pass the classloader chain into the
constructor)
//
String newPartition = getQualifiedName() + "/";
+ m_parts = new PartsModel( controller, this, newPartition,
classloader );
Part[] parts = profile.getParts();
for( int i=0; i<parts.length; i++ )
{
Part part = parts[i];
- Model model = getController().getModel( this, newPartition,
m_classloader, part );
- m_parts.put( model.getName(), model );
+ m_parts.addPartToCollection( null, part, false );
}
//
- // Any dependencies declared by the component part must be resolvable
- // by the enclosing model's controller (if available). We use the
supplied
- // parent model
+ // If this component model has been asserted as a root model then it
cannot
+ // have any non-optional dependencies. If the model is nested within
another
+ // model then we can attempt to resolve dependencies using the
supplied enclosing
+ // model and dependency directves declared in this model's profile.
If a
+ // dependency directive is not available and the dependency is
required
+ // (non-optional) then flag the model as unresolved.
//
DependencyDescriptor[] dependencies = m_type.getDependencies();
@@ -128,17 +169,6 @@
{
DependencyDescriptor dependency = dependencies[i];
boolean required = dependency.isRequired();
- String key = dependency.getKey();
- DependencyDirective directive = profile.getDependencyDirective(
key );
-
- if( ( null == directive ) && required )
- {
- final String error =
- "Missing required dependency directive for the key ["
- + key
- + "].";
- throw new ModelException( error );
- }
if( null == parent )
{
@@ -148,46 +178,71 @@
"The top-level component ["
+ getQualifiedName()
+ "] is declaring a required service dependency which
logically cannot be resolved.";
- throw new ModelException( error );
+ throw new ModelRuntimeException( error );
+ }
+ else
+ {
+ // ignore it as its optional and unresolvable
}
}
else
{
- Controller manager = parent.getController();
- String path = directive.getSource();
- Model model = manager.getProvider( parent, path );
- if( null == model )
+ String key = dependency.getKey();
+ DependencyDirective directive =
profile.getDependencyDirective( key );
+ if( null == directive )
{
- final String error =
- "Unable to locate a service provider for the key ["
- + key
- + "] in the component model ["
- + getQualifiedName()
- + "] using the source path ["
- + path
- + "].";
- throw new ModelException( error );
+ if( required )
+ {
+ Exception e = new
MissingDependencyDirectiveException( this, key );
+ m_errors.add( e );
+ }
}
else
{
- m_providers.put( key, model );
+ Controller manager = parent.getController();
+ String path = directive.getSource();
+ Model model = manager.getProvider( parent, path );
+ if( null == model )
+ {
+ final Exception e = new
UnresolvableDependencyException( this, directive );
+ m_errors.add( e );
+ }
+ else
+ {
+ m_providers.put( key, model );
+ }
}
}
}
}
+ public Throwable[] getIssues()
+ {
+ if( m_errors.isEmpty() )
+ {
+ return new Throwable[0];
+ }
+ else
+ {
+ return (Throwable[]) m_errors.toArray( new Throwable[ 0 ] );
+ }
+ }
+
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 );
}
@@ -204,11 +259,10 @@
public Model getPart( String spec )
{
//
- // the following is rather limited - in particular we are
+ // the following is too limited - in particular we are
// not handling paths in the form aaa/bbb/ccc
//
-
- return (Model) m_parts.get( spec );
+ return m_parts.getModel( spec );
}
public ClassLoader getClassLoader()
@@ -231,6 +285,18 @@
return m_name;
}
+ public void setName( String name )
+ {
+ if( null == name )
+ {
+ throw new NullPointerException( "name" );
+ }
+ if( false == name.equals( getName() ) )
+ {
+ m_name = name;
+ }
+ }
+
public String getPartition()
{
return m_partition;
@@ -312,11 +378,7 @@
}
catch( ClassNotFoundException cnfe )
{
- final String error =
- "Component implementation class ["
- + classname
- + "] not found.";
- throw new ModelRuntimeException( error, cnfe );
+ throw new TypeClassNotFoundException( classname );
}
}
@@ -329,12 +391,21 @@
}
catch( ClassNotFoundException cnfe )
{
- final String error =
- "Service interface class ["
- + classname
- + "] not found.";
- throw new ModelRuntimeException( error, cnfe );
+ String type = m_class.getName();
+ throw new ServiceClassNotFoundException( type, classname );
}
}
+ private void validate()
+ {
+ if( m_errors.isEmpty() )
+ {
+ return;
+ }
+ else
+ {
+ Throwable[] issues = getIssues();
+ throw new InvalidModelException( this, issues );
+ }
+ }
}
Added:
development/main/metro/composition/control/src/main/net/dpml/composition/models/UnresolvableDependencyException.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/UnresolvableDependencyException.java
Tue Apr 5 09:31:19 2005
@@ -0,0 +1,69 @@
+/*
+ * 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 net.dpml.automation.model.ModelException;
+
+import net.dpml.composition.data.DependencyDirective;
+
+/**
+ * Unexpected runtime exception indicating an internal model error.
+ *
+ * @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 UnresolvableDependencyException extends ModelException
+{
+ private StandardComponentModel m_model;
+ private DependencyDirective m_directive;
+
+ public UnresolvableDependencyException( StandardComponentModel model,
DependencyDirective directive )
+ {
+ super( buildMessage( model, directive ) );
+ m_model = model;
+ m_directive = directive;
+ }
+
+ public DependencyDirective getDirective()
+ {
+ return m_directive;
+ }
+
+ public StandardComponentModel getModel()
+ {
+ return m_model;
+ }
+
+ private static String buildMessage( StandardComponentModel model,
DependencyDirective directive )
+ {
+ final String name = model.getQualifiedName();
+ final String key = directive.getKey();
+ final String source = directive.getSource();
+ final String error =
+ "The source provider address ["
+ + source
+ + "] declared by the component model ["
+ + name
+ + "] under the dependency key ["
+ + key
+ + "] was not found.";
+ return error;
+ }
+}
+
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 5 09:31:19 2005
@@ -56,25 +56,25 @@
public AcmeContainer( final Logger logger, Parts parts )
{
m_logger = logger;
- logger.info( "getting widget" );
+ logger.debug( "getting widget" );
Widget widget = parts.getWidget();
- logger.info( "getting gizmo" );
+ logger.debug( "getting gizmo" );
Gizmo gizmo = parts.getGizmo();
- logger.info( "getting gizmo impl" );
+ logger.debug( "getting gizmo impl" );
DefaultGizmo newGizmo = parts.createGizmo();
- logger.info( "getting identified gizmo" );
+ logger.debug( "getting identified gizmo" );
Gizmo myGizmo = parts.getGizmo( "my-gizmo" );
- logger.info( "releasing stuff" );
+ logger.debug( "releasing stuff" );
parts.releaseGizmo( gizmo );
parts.releaseGizmo( myGizmo );
parts.releaseGizmo( newGizmo );
parts.releaseWidget( widget );
- logger.info( "done" );
+ logger.debug( "done" );
}
//------------------------------------------------------------------
@@ -83,7 +83,7 @@
public void dispose()
{
- m_logger.info( "disposal" );
+ m_logger.debug( "disposal" );
}
public boolean equals( Object other )
Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultGizmo.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultGizmo.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultGizmo.java
Tue Apr 5 09:31:19 2005
@@ -63,7 +63,7 @@
m_logger = logger;
Widget widget = dependencies.getWidget();
widget.doWidgetTypeStuff();
- logger.info( "ready");
+ logger.debug( "ready");
}
//------------------------------------------------------------------
@@ -72,7 +72,7 @@
public void dispose()
{
- m_logger.info( "disposal" );
+ m_logger.debug( "disposal" );
}
//------------------------------------------------------------------
Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultWidget.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultWidget.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultWidget.java
Tue Apr 5 09:31:19 2005
@@ -80,7 +80,7 @@
String partition = m_context.getPartition();
File work = m_context.getWorkingDirectory();
- m_logger.info( "widget created" );
+ m_logger.debug( "widget created" );
}
//------------------------------------------------------------------
@@ -110,7 +110,7 @@
*/
public void dispose()
{
- m_logger.info( "disposal" );
+ m_logger.debug( "disposal" );
}
/**
@@ -137,7 +137,7 @@
int width = m_context.getWidth();
int height = m_context.getHeight( 5024 );
- m_logger.info(
+ m_logger.debug(
name
+ " established with a width of "
+ width
- svn commit: r2209 - in development/main/metro: automation/control/src/main/net/dpml/automation/model composition/control/src/main/net/dpml/composition/control composition/control/src/main/net/dpml/composition/models composition/testing/acme/src/main/net/dpml/composition/testing, mcconnell, 04/04/2005
Archive powered by MHonArc 2.6.24.