Skip to Content.
Sympa Menu

notify-dpml - svn commit: r2122 - in development/main/metro: . automation automation/builder automation/builder/src automation/builder/src/main automation/builder/src/main/net automation/builder/src/main/net/dpml automation/builder/src/main/net/dpml/builder automation/control automation/control/src automation/control/src/main automation/control/src/main/net automation/control/src/main/net/dpml automation/control/src/main/net/dpml/control automation/part automation/part/src automation/part/src/main automation/part/src/main/net automation/part/src/main/net/dpml automation/part/src/main/net/dpml/part composition/api composition/api/src/main/net/dpml/composition/data composition/builder composition/builder/src composition/builder/src/main composition/builder/src/main/net composition/builder/src/main/net/dpml composition/builder/src/main/net/dpml/composition composition/builder/src/main/net/dpml/composition/builder composition/control composition/control/src composition/control/src/main composition/control/src/main/net composition/control/src/main/net/dpml composition/control/src/main/net/dpml/composition composition/control/src/main/net/dpml/composition/control composition/impl/src/main/net/dpml/composition/model/impl composition/testing composition/testing/src composition/testing/src/main composition/testing/src/main/net composition/testing/src/main/net/dpml composition/testing/src/main/net/dpml/composition composition/testing/src/main/net/dpml/composition/testing meta/api/src/main/net/dpml/meta/info meta/api/src/test/net/dpml/meta/info/test meta/impl/src/main/net/dpml/meta/info/builder/impl meta/spi/src/main/net/dpml/meta/info/builder meta/tools/src/main/net/dpml/meta/info/tags

notify-dpml AT lists.ibiblio.org

Subject: DPML Notify

List archive

Chronological Thread  
  • From: mcconnell AT dpml.net
  • To: notify-dpml AT lists.ibiblio.org
  • Subject: svn commit: r2122 - in development/main/metro: . automation automation/builder automation/builder/src automation/builder/src/main automation/builder/src/main/net automation/builder/src/main/net/dpml automation/builder/src/main/net/dpml/builder automation/control automation/control/src automation/control/src/main automation/control/src/main/net automation/control/src/main/net/dpml automation/control/src/main/net/dpml/control automation/part automation/part/src automation/part/src/main automation/part/src/main/net automation/part/src/main/net/dpml automation/part/src/main/net/dpml/part composition/api composition/api/src/main/net/dpml/composition/data composition/builder composition/builder/src composition/builder/src/main composition/builder/src/main/net composition/builder/src/main/net/dpml composition/builder/src/main/net/dpml/composition composition/builder/src/main/net/dpml/composition/builder composition/control composition/control/src composition/control/src/main composition/control/src/main/net composition/control/src/main/net/dpml composition/control/src/main/net/dpml/composition composition/control/src/main/net/dpml/composition/control composition/impl/src/main/net/dpml/composition/model/impl composition/testing composition/testing/src composition/testing/src/main composition/testing/src/main/net composition/testing/src/main/net/dpml composition/testing/src/main/net/dpml/composition composition/testing/src/main/net/dpml/composition/testing meta/api/src/main/net/dpml/meta/info meta/api/src/test/net/dpml/meta/info/test meta/impl/src/main/net/dpml/meta/info/builder/impl meta/spi/src/main/net/dpml/meta/info/builder meta/tools/src/main/net/dpml/meta/info/tags
  • Date: Wed, 23 Mar 2005 19:08:48 -0500

Author: mcconnell AT dpml.net
Date: Wed Mar 23 19:08:48 2005
New Revision: 2122

Added:
development/main/metro/automation/
development/main/metro/automation/build.xml
development/main/metro/automation/builder/
development/main/metro/automation/builder/build.xml
development/main/metro/automation/builder/src/
development/main/metro/automation/builder/src/main/
development/main/metro/automation/builder/src/main/net/
development/main/metro/automation/builder/src/main/net/dpml/
development/main/metro/automation/builder/src/main/net/dpml/builder/

development/main/metro/automation/builder/src/main/net/dpml/builder/Builder.java

development/main/metro/automation/builder/src/main/net/dpml/builder/BuilderRuntimeException.java

development/main/metro/automation/builder/src/main/net/dpml/builder/ControlBuilder.java

development/main/metro/automation/builder/src/main/net/dpml/builder/IntrospectionException.java

development/main/metro/automation/builder/src/main/net/dpml/builder/PartBuilder.java
development/main/metro/automation/control/
development/main/metro/automation/control/build.xml
development/main/metro/automation/control/src/
development/main/metro/automation/control/src/main/
development/main/metro/automation/control/src/main/net/
development/main/metro/automation/control/src/main/net/dpml/
development/main/metro/automation/control/src/main/net/dpml/control/

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

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

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

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

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

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

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

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

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

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

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

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

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

development/main/metro/automation/control/src/main/net/dpml/control/UnsupportedPartTypeException.java
development/main/metro/automation/part/
development/main/metro/automation/part/build.xml
development/main/metro/automation/part/src/
development/main/metro/automation/part/src/main/
development/main/metro/automation/part/src/main/net/
development/main/metro/automation/part/src/main/net/dpml/
development/main/metro/automation/part/src/main/net/dpml/part/

development/main/metro/automation/part/src/main/net/dpml/part/BadStrategyException.java
development/main/metro/automation/part/src/main/net/dpml/part/Part.java

development/main/metro/automation/part/src/main/net/dpml/part/PartHolder.java
development/main/metro/composition/builder/
development/main/metro/composition/builder/build.xml
development/main/metro/composition/builder/src/
development/main/metro/composition/builder/src/main/
development/main/metro/composition/builder/src/main/net/
development/main/metro/composition/builder/src/main/net/dpml/
development/main/metro/composition/builder/src/main/net/dpml/composition/

development/main/metro/composition/builder/src/main/net/dpml/composition/builder/

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

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

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

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

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

development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilder.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/TypeNotFoundException.java

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

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

development/main/metro/composition/builder/src/main/net/dpml/composition/builder/antlib.xml
development/main/metro/composition/control/
development/main/metro/composition/control/build.xml
development/main/metro/composition/control/src/
development/main/metro/composition/control/src/main/
development/main/metro/composition/control/src/main/net/
development/main/metro/composition/control/src/main/net/dpml/
development/main/metro/composition/control/src/main/net/dpml/composition/

development/main/metro/composition/control/src/main/net/dpml/composition/control/

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

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

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

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

development/main/metro/composition/control/src/main/net/dpml/composition/control/ModelPerspective.java
development/main/metro/composition/testing/
development/main/metro/composition/testing/build.xml
development/main/metro/composition/testing/src/
development/main/metro/composition/testing/src/main/
development/main/metro/composition/testing/src/main/net/
development/main/metro/composition/testing/src/main/net/dpml/
development/main/metro/composition/testing/src/main/net/dpml/composition/

development/main/metro/composition/testing/src/main/net/dpml/composition/testing/

development/main/metro/composition/testing/src/main/net/dpml/composition/testing/DefaultGizmo.java

development/main/metro/composition/testing/src/main/net/dpml/composition/testing/DefaultWidget.java

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

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

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

development/main/metro/meta/api/src/main/net/dpml/meta/info/PartDescriptor.java
Modified:
development/main/metro/composition/api/build.xml

development/main/metro/composition/api/src/main/net/dpml/composition/data/ComponentProfile.java

development/main/metro/composition/api/src/main/net/dpml/composition/data/ContainmentProfile.java

development/main/metro/composition/api/src/main/net/dpml/composition/data/DeploymentProfile.java

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

development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/Scanner.java
development/main/metro/index.xml
development/main/metro/meta/api/src/main/net/dpml/meta/info/Type.java

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

development/main/metro/meta/impl/src/main/net/dpml/meta/info/builder/impl/TypeBuilder.java

development/main/metro/meta/impl/src/main/net/dpml/meta/info/builder/impl/XMLTypeCreator.java

development/main/metro/meta/spi/src/main/net/dpml/meta/info/builder/TypeFactory.java

development/main/metro/meta/tools/src/main/net/dpml/meta/info/tags/TypeTag.java
Log:


Added: development/main/metro/automation/build.xml
==============================================================================
--- (empty file)
+++ development/main/metro/automation/build.xml Wed Mar 23 19:08:48 2005
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="dpml-automation" default="default" basedir="."
+ xmlns:transit="antlib:net.dpml.transit">
+
+ <transit:import uri="artifact:template:dpml/magic/reactor"/>
+
+</project>
+

Added: development/main/metro/automation/builder/build.xml
==============================================================================
--- (empty file)
+++ development/main/metro/automation/builder/build.xml Wed Mar 23 19:08:48
2005
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="dpml-automation-builder" default="install" basedir="."
+ xmlns:transit="antlib:net.dpml.transit">
+
+ <transit:import uri="artifact:template:dpml/magic/standard"/>
+
+</project>

Added:
development/main/metro/automation/builder/src/main/net/dpml/builder/Builder.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/builder/src/main/net/dpml/builder/Builder.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,38 @@
+/*
+ * 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.builder;
+
+import java.net.URI;
+
+/**
+ * The contract for builders that create component 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 interface Builder
+{
+ /**
+ * Return a uri identitifying the builder.
+ *
+ * @return the builder uri
+ */
+ URI getBuilderURI();
+
+}

Added:
development/main/metro/automation/builder/src/main/net/dpml/builder/BuilderRuntimeException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/builder/src/main/net/dpml/builder/BuilderRuntimeException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,33 @@
+/*
+ * 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.builder;
+
+/**
+ * An exception throws if an internal error occurs during builder execution.
+ *
+ * @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 BuilderRuntimeException extends RuntimeException
+{
+ public BuilderRuntimeException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+}

Added:
development/main/metro/automation/builder/src/main/net/dpml/builder/ControlBuilder.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/builder/src/main/net/dpml/builder/ControlBuilder.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,45 @@
+/*
+ * 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.builder;
+
+import java.net.URI;
+
+import net.dpml.control.Control;
+
+/**
+ * The contract for builders that creates a control descriptor.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public interface ControlBuilder extends Builder
+{
+ /**
+ * Return a urn identitifying the control handler for this builder.
+ *
+ * @return a uri identifing the type handler.
+ */
+ URI getControlHandlerURI();
+
+ /**
+ * Build a control descriptor.
+ * @return the serializable control descriptor.
+ */
+ Control buildControl();
+}

Added:
development/main/metro/automation/builder/src/main/net/dpml/builder/IntrospectionException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/builder/src/main/net/dpml/builder/IntrospectionException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,33 @@
+/*
+ * 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.builder;
+
+/**
+ * An exception throws if an error occurs while introspecting a method.
+ *
+ * @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 IntrospectionException extends Exception
+{
+ public IntrospectionException( String message )
+ {
+ super( message );
+ }
+}

Added:
development/main/metro/automation/builder/src/main/net/dpml/builder/PartBuilder.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/builder/src/main/net/dpml/builder/PartBuilder.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,57 @@
+/*
+ * 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.builder;
+
+import java.net.URI;
+import java.io.IOException;
+
+import net.dpml.part.Part;
+import net.dpml.part.BadStrategyException;
+
+/**
+ * The contract for builders that create component 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 interface PartBuilder extends Builder
+{
+ /**
+ * Return a urn identitifying the part handler for this builder.
+ *
+ * @return a strategy uri
+ */
+ URI getPartHandlerURI();
+
+ /**
+ * Return the key identifying the part that this builder is building.
+ */
+ String getKey();
+
+ /**
+ * Build the part.
+ * @param classloader the classloader to use if type creation is required
+ * @return the serializable part
+ * @exception Exception if a construction error occurs
+ */
+ Part buildPart( ClassLoader classloader )
+ throws IntrospectionException, IOException, ClassNotFoundException,
+ BadStrategyException;
+
+}

Added: development/main/metro/automation/control/build.xml
==============================================================================
--- (empty file)
+++ development/main/metro/automation/control/build.xml Wed Mar 23 19:08:48
2005
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="dpml-automation-control" default="install" basedir="."
+ xmlns:transit="antlib:net.dpml.transit">
+
+ <transit:import uri="artifact:template:dpml/magic/standard"/>
+
+</project>

Added:
development/main/metro/automation/control/src/main/net/dpml/control/Control.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/Control.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,45 @@
+/*
+ * 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.control;
+
+import java.net.URI;
+
+import net.dpml.part.Part;
+
+/**
+ * Common interface implemented by controls.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public interface Control
+{
+ /**
+ * Return the uri identifying this controller.
+ * @return the controller uri
+ */
+ URI getURI();
+
+ /**
+ * Return a human readable short name of the controller.
+ * @return the controller name
+ */
+ String getName();
+
+}

Added:
development/main/metro/automation/control/src/main/net/dpml/control/ControlRuntimeException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/ControlRuntimeException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,35 @@
+/*
+ * 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.control;
+
+/**
+ * Unexpected runtime exception indicating an internal home 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 ControlRuntimeException extends RuntimeException
+{
+ public ControlRuntimeException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+}
+

Added:
development/main/metro/automation/control/src/main/net/dpml/control/Controller.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/Controller.java
Wed Mar 23 19:08:48 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.control;
+
+import java.net.URI;
+import java.io.IOException;
+
+import net.dpml.part.Part;
+
+/**
+ * The Controller interface defines the a contract for a object that is
capable of
+ * operation management of a set of arbitary models together with part
handling for
+ * a particular part strategy.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public interface Controller extends Control
+{
+ /**
+ * Return a management view of a part.
+ * @param part the part to present
+ * @return the management view
+ */
+ Model getModel( Part part ) throws DelegationException;
+
+}

Added:
development/main/metro/automation/control/src/main/net/dpml/control/DelegationException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/DelegationException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,45 @@
+/*
+ * 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.control;
+
+import java.net.URI;
+
+/**
+ * Exception thrown when an attempt is made to reference an unknown handler.
+ *
+ * @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 DelegationException extends Exception
+{
+ private URI m_target;
+
+ public DelegationException( URI target, String message, Throwable cause )
+ {
+ super( message, cause );
+ m_target = target;
+ }
+
+ public URI getDelegationTarget()
+ {
+ return m_target;
+ }
+
+}
+

Added:
development/main/metro/automation/control/src/main/net/dpml/control/DuplicateNameException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/DuplicateNameException.java
Wed Mar 23 19:08:48 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.control;
+
+/**
+ * Exception thrown when an attempt is made to reference an unknown handler.
+ *
+ * @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 DuplicateNameException extends Exception
+{
+ private String m_name;
+
+ public DuplicateNameException( String name )
+ {
+ super( name );
+ m_name = name;
+ }
+
+ public String getName()
+ {
+ return m_name;
+ }
+
+}
+

Added:
development/main/metro/automation/control/src/main/net/dpml/control/HandlerNotFoundException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/HandlerNotFoundException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,50 @@
+/*
+ * 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.control;
+
+import java.net.URI;
+
+/**
+ * Exception thrown when an attempt is made to reference an unknown handler.
+ *
+ * @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 HandlerNotFoundException extends Exception
+{
+ private URI m_uri;
+
+ public HandlerNotFoundException( URI uri )
+ {
+ this( uri, null );
+ }
+
+ public HandlerNotFoundException( URI uri, Throwable cause )
+ {
+ super( uri.toString(), cause );
+ m_uri = uri;
+ }
+
+ public URI getURI()
+ {
+ return m_uri;
+ }
+
+}
+

Added:
development/main/metro/automation/control/src/main/net/dpml/control/Model.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/Model.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,36 @@
+/*
+ * 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.control;
+
+import java.io.Serializable;
+
+/**
+ * The Model interface defines a common view of a component part. Operations
+ * delcared on this interface concern the managment of the model state.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public interface Model
+{
+ String getName();
+
+ void setName( String name );
+
+}

Added:
development/main/metro/automation/control/src/main/net/dpml/control/Monitor.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/Monitor.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,67 @@
+/*
+ * 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.control;
+
+/**
+ * Monitor supplied to a startable controller.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public interface Monitor
+{
+ /**
+ * Log the supplied debug level message.
+ * @param mesage the message to log
+ */
+ void debug( String message );
+
+ /**
+ * Log the supplied info level message.
+ * @param mesage the message to log
+ */
+ void info( String message );
+
+ /**
+ * Log the supplied info level message.
+ * @param mesage the message to log
+ */
+ void warn( String message );
+
+ /**
+ * Log the supplied error level message.
+ * @param mesage the message to log
+ * @param throwable the exception
+ */
+ void error( String message, Throwable throwable );
+
+ /**
+ * Log the monitor of a normal termination.
+ * @param status TRUE if the monitor completed all scheduled activities
+ * without interruption
+ */
+ void notifyCompletion( boolean status );
+
+ /**
+ * Log the monitor of a runtime failure.
+ * @param throwable the failure cause
+ */
+ void notifyFailure( Throwable throwable );
+
+}

Added:
development/main/metro/automation/control/src/main/net/dpml/control/NoSuchControlException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/NoSuchControlException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,33 @@
+/*
+ * 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.control;
+
+/**
+ * An exception thrown in responde to a request for an unknown control.
+ *
+ * @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 NoSuchControlException extends Exception
+{
+ public NoSuchControlException( String name )
+ {
+ super( name );
+ }
+}

Added:
development/main/metro/automation/control/src/main/net/dpml/control/PartHandler.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/PartHandler.java
Wed Mar 23 19:08:48 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.control;
+
+import java.io.IOException;
+import java.net.URI;
+
+import net.dpml.part.Part;
+
+/**
+ * Definition of a part handler.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public interface PartHandler
+{
+ /**
+ * Returns the uri of the handler.
+ * @return the handler uri
+ */
+ URI getURI();
+
+ /**
+ * Load the model controller.
+ * @return the controller
+ */
+ Controller getController();
+
+ /**
+ * Load a part handler giiven a handler uri.
+ * @return the part handler
+ */
+ PartHandler loadPartHandler( URI uri )
+ throws HandlerNotFoundException, IOException, DelegationException;
+
+ /**
+ * Load a part from serialized form. The uri is assumed to be a uri that
+ * can be transformed to a URL from which an input stream to a PartHolder
+ * can be established.
+ *
+ * @return the part estracted from the part handler referenced by the uri
+ */
+ public Part loadPart( URI uri )
+ throws DelegationException, PartNotFoundException, IOException;
+
+ /**
+ * Load a part from a serialized object byte array.
+ * @param bytes the byte array
+ * @return the part
+ */
+ Part loadPart( byte[] bytes ) throws IOException;
+}

Added:
development/main/metro/automation/control/src/main/net/dpml/control/PartHandlerRuntimeException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/PartHandlerRuntimeException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,35 @@
+/*
+ * 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.control;
+
+/**
+ * Unexpected runtime exception indicating an internal part handler 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 PartHandlerRuntimeException extends RuntimeException
+{
+ public PartHandlerRuntimeException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+}
+

Added:
development/main/metro/automation/control/src/main/net/dpml/control/PartNotFoundException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/PartNotFoundException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,50 @@
+/*
+ * 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.control;
+
+import java.net.URI;
+
+/**
+ * Exception thrown when an attempt is made to reference an unknown part.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public class PartNotFoundException extends Exception
+{
+ private URI m_uri;
+
+ public PartNotFoundException( URI uri )
+ {
+ this( uri, null );
+ }
+
+ public PartNotFoundException( URI uri, Exception cause )
+ {
+ super( uri.toString(), cause );
+ m_uri = uri;
+ }
+
+ public URI getURI()
+ {
+ return m_uri;
+ }
+
+}
+

Added:
development/main/metro/automation/control/src/main/net/dpml/control/SystemManager.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/SystemManager.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,67 @@
+/*
+ * 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.control;
+
+import java.net.URI;
+import java.io.IOException;
+
+import net.dpml.part.Part;
+
+/**
+ * The SystemManager interface defines the a contract for a object that is
capable of
+ * operational management of a set of arbitary models within the scope of a
single
+ * jvm.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public interface SystemManager
+{
+ /**
+ * Add a part designated by a supplied uri to the system scope.
+ * @param uri a part uri
+ * @return the management view of the loaded part
+ */
+ Model addPart( URI uri ) throws IOException, DelegationException,
PartNotFoundException;
+
+ /**
+ * Add a model to the system scope.
+ * @param model the model to add to the controller
+ */
+ void addModel( Model model );
+
+ /**
+ * Return a management view of a part.
+ * @param part the part to present
+ * @return the management view
+ */
+ Model getModel( Part part ) throws DelegationException;
+
+ /**
+ * Start the system.
+ * @exception if a startup failure occurs
+ */
+ void start() throws Exception;
+
+ /**
+ * Stop the system.
+ */
+ void stop();
+
+}

Added:
development/main/metro/automation/control/src/main/net/dpml/control/UnsupportedPartTypeException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/control/src/main/net/dpml/control/UnsupportedPartTypeException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,53 @@
+/*
+ * 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.control;
+
+import java.net.URI;
+
+import net.dpml.part.Part;
+
+/**
+ * Exception thrown when an strategy handler attempts to handle an
+ * incompatible type.
+ *
+ * @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 UnsupportedPartTypeException extends Exception
+{
+ private String m_type;
+
+ public UnsupportedPartTypeException( Part part )
+ {
+ this( part.getClass().getName() );
+ }
+
+ public UnsupportedPartTypeException( String classname )
+ {
+ super( classname );
+ m_type = classname;
+ }
+
+ public String getPartTypeClassname()
+ {
+ return m_type;
+ }
+
+}
+

Added: development/main/metro/automation/part/build.xml
==============================================================================
--- (empty file)
+++ development/main/metro/automation/part/build.xml Wed Mar 23 19:08:48
2005
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="dpml-automation-part" default="install" basedir="."
+ xmlns:transit="antlib:net.dpml.transit">
+
+ <transit:import uri="artifact:template:dpml/magic/standard"/>
+
+</project>

Added:
development/main/metro/automation/part/src/main/net/dpml/part/BadStrategyException.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/part/src/main/net/dpml/part/BadStrategyException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,52 @@
+/*
+ * 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.part;
+
+import java.net.URI;
+
+/**
+ * Exception thrown when an strategy handler attempts to handle an
+ * incompatible type.
+ *
+ * @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 BadStrategyException extends Exception
+{
+ private URI m_handler;
+ private URI m_requested;
+
+ public BadStrategyException( URI handler, URI requested )
+ {
+ super( requested.toString() );
+ m_handler = handler;
+ m_requested = requested ;
+ }
+
+ public URI getHandlerURI()
+ {
+ return m_handler;
+ }
+
+ public URI getRequestedURI()
+ {
+ return m_requested;
+ }
+}
+

Added: development/main/metro/automation/part/src/main/net/dpml/part/Part.java
==============================================================================
--- (empty file)
+++ development/main/metro/automation/part/src/main/net/dpml/part/Part.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,40 @@
+/*
+ * 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.part;
+
+import java.io.Serializable;
+import java.net.URI;
+
+/**
+ * The common interface implemented by all parts.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
+ */
+public interface Part extends Serializable
+{
+ static final String ARTIFACT_TYPE = "part";
+
+ /**
+ * Return the part handler uri.
+ * @return the uri of the part handler
+ */
+ URI getPartHandlerURI();
+
+}

Added:
development/main/metro/automation/part/src/main/net/dpml/part/PartHolder.java
==============================================================================
--- (empty file)
+++
development/main/metro/automation/part/src/main/net/dpml/part/PartHolder.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,98 @@
+/*
+ * 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.part;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Properties;
+import java.io.Serializable;
+
+/**
+ *
+ *
+ * @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 PartHolder implements Serializable
+{
+ private final URI m_handler;
+ private final byte[] m_part;
+
+ public PartHolder( URI handler, byte[] part )
+ {
+ m_handler = handler;
+ m_part = part;
+ }
+
+ public URI getPartHandlerURI()
+ {
+ return m_handler;
+ }
+
+ public byte[] getByteArray()
+ {
+ return m_part;
+ }
+
+ public int hashCode()
+ {
+ int hash = super.hashCode();
+ hash ^= m_handler.hashCode();
+ for( int i=0; i<m_part.length; i++ )
+ {
+ hash ^= new Byte( m_part[i] ).hashCode();
+ }
+ return hash;
+ }
+
+ public boolean equals( Object other )
+ {
+ if( null == other )
+ {
+ return false;
+ }
+ else if( other instanceof PartHolder )
+ {
+ PartHolder holder = (PartHolder) other;
+ if( getPartHandlerURI().equals( holder.getPartHandlerURI() ) ==
false )
+ {
+ return false;
+ }
+ else if( Arrays.equals( getByteArray(), holder.getByteArray() )
== false )
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public String toString()
+ {
+ return "[part-holder handler:" + m_handler + " size:" +
m_part.length + "]";
+ }
+
+}
+

Modified: development/main/metro/composition/api/build.xml
==============================================================================
--- development/main/metro/composition/api/build.xml (original)
+++ development/main/metro/composition/api/build.xml Wed Mar 23 19:08:48
2005
@@ -5,4 +5,11 @@

<transit:import uri="artifact:template:dpml/magic/standard"/>

+ <target name="init" depends="standard.init">
+ <x:property key="dpml-composition-impl" feature="uri" type="plugin"
name="control.plugin"/>
+ <x:property key="dpml-composition-builder" feature="uri" type="plugin"
name="builder.plugin"/>
+ <filter token="PART-BUILDER-URI" value="${builder.plugin}"/>
+ <filter token="PART-HANDLER-URI" value="${control.plugin}"/>
+ </target>
+
</project>

Modified:
development/main/metro/composition/api/src/main/net/dpml/composition/data/ComponentProfile.java
==============================================================================
---
development/main/metro/composition/api/src/main/net/dpml/composition/data/ComponentProfile.java
(original)
+++
development/main/metro/composition/api/src/main/net/dpml/composition/data/ComponentProfile.java
Wed Mar 23 19:08:48 2005
@@ -18,6 +18,8 @@

package net.dpml.composition.data;

+import net.dpml.part.Part;
+
import net.dpml.configuration.Configuration;
import net.dpml.parameters.Parameters;
import net.dpml.meta.info.InfoDescriptor;

Modified:
development/main/metro/composition/api/src/main/net/dpml/composition/data/ContainmentProfile.java
==============================================================================
---
development/main/metro/composition/api/src/main/net/dpml/composition/data/ContainmentProfile.java
(original)
+++
development/main/metro/composition/api/src/main/net/dpml/composition/data/ContainmentProfile.java
Wed Mar 23 19:08:48 2005
@@ -20,6 +20,8 @@

import java.util.ArrayList;

+import net.dpml.part.Part;
+
import net.dpml.meta.info.ServiceDescriptor;

import net.dpml.logging.data.CategoriesDirective;
@@ -307,4 +309,5 @@
}
return hash;
}
+
}

Modified:
development/main/metro/composition/api/src/main/net/dpml/composition/data/DeploymentProfile.java
==============================================================================
---
development/main/metro/composition/api/src/main/net/dpml/composition/data/DeploymentProfile.java
(original)
+++
development/main/metro/composition/api/src/main/net/dpml/composition/data/DeploymentProfile.java
Wed Mar 23 19:08:48 2005
@@ -20,6 +20,10 @@

import java.io.Serializable;
import java.lang.Comparable;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import net.dpml.part.Part;

import net.dpml.logging.data.CategoriesDirective;

@@ -29,7 +33,7 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Id$
*/
-public abstract class DeploymentProfile implements Serializable, Comparable
+public abstract class DeploymentProfile implements Serializable, Comparable,
Part
{

//--------------------------------------------------------------------------
// static
@@ -123,6 +127,19 @@
}


//--------------------------------------------------------------------------
+ // Part
+
//--------------------------------------------------------------------------
+
+ /**
+ * Return the part handler uri.
+ * @return the uri of the part handler
+ */
+ public URI getPartHandlerURI()
+ {
+ return PART_HANDLER_URI;
+ }
+
+
//--------------------------------------------------------------------------
// implementation

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

@@ -237,4 +254,19 @@
hash ^= m_categories.hashCode();
return hash;
}
+
+ 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;
+ }
+ }
}

Added: development/main/metro/composition/builder/build.xml
==============================================================================
--- (empty file)
+++ development/main/metro/composition/builder/build.xml Wed Mar 23
19:08:48 2005
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="dpml-composition-builder" default="install" basedir="."
+ xmlns:transit="antlib:net.dpml.transit"
xmlns:x="plugin:dpml/magic/dpml-magic-core" >
+
+ <transit:import uri="artifact:template:dpml/magic/standard"/>
+
+ <target name="init" depends="standard.init">
+ <x:property key="dpml-composition-impl" feature="uri" type="plugin"
name="control.plugin"/>
+ <x:property feature="uri" type="plugin" name="builder.plugin"/>
+ <filter token="PART-BUILDER-URI" value="${builder.plugin}"/>
+ <filter token="TYPE-BUILDER-URI" value="${builder.plugin}"/>
+ <filter token="PART-HANDLER-URI" value="${control.plugin}"/>
+ <filter token="TYPE-HANDLER-URI" value="${control.plugin}"/>
+ </target>
+
+ <target name="package" depends="standard.package">
+ <x:export>
+ <antlib resource="net/dpml/composition/builder/antlib.xml"
+ urn="plugin:dpml/composition/dpml-composition-builder"/>
+ </x:export>
+ </target>
+
+</project>

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,1118 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.Serializable;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.rmi.MarshalledObject;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Properties;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import net.dpml.meta.info.Type;
+
+import net.dpml.logging.data.CategoryDirective;
+import net.dpml.logging.data.CategoriesDirective;
+
+import net.dpml.composition.data.EntryDirective;
+import net.dpml.composition.data.DeploymentProfile;
+import net.dpml.composition.data.ConstructorDirective;
+import net.dpml.composition.data.ContextDirective;
+import net.dpml.composition.data.DependencyDirective;
+import net.dpml.composition.data.Parameter;
+import net.dpml.composition.data.ComponentProfile;
+import net.dpml.composition.data.Mode;
+
+import net.dpml.part.Part;
+import net.dpml.part.PartHolder;
+
+import net.dpml.builder.PartBuilder;
+import net.dpml.builder.IntrospectionException;
+
+import net.dpml.configuration.Configuration;
+import net.dpml.configuration.impl.DefaultConfiguration;
+
+import net.dpml.meta.info.InfoDescriptor;
+
+import net.dpml.parameters.Parameters;
+import net.dpml.parameters.impl.DefaultParameters;
+
+import net.dpml.magic.tasks.ProjectTask;
+import net.dpml.magic.model.Policy;
+import net.dpml.magic.model.Definition;
+import net.dpml.magic.model.Resource;
+import net.dpml.magic.model.ResourceRef;
+import net.dpml.magic.project.Context;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DynamicElementNS;
+import org.apache.tools.ant.DynamicConfiguratorNS;
+
+/**
+ * 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 ComponentBuilderTask extends ProjectTask implements PartBuilder
+{
+ private String m_key;
+ private String m_name;
+ private String m_classname;
+ private String m_lifestyle;
+ private String m_collection;
+ private boolean m_activation = true;
+ private CategoriesDataType m_categories;
+ private ContextDataType m_context;
+ private ParametersDataType m_parameters;
+ private ConfigurationDataType m_configuration;
+ private DependenciesDataType m_dependencies;
+ private PartsDataType m_parts;
+
+ public void setKey( String key )
+ {
+ m_key = key;
+ }
+
+ public void setName( String name )
+ {
+ m_name = name;
+ }
+
+ public void setClass( String classname )
+ {
+ m_classname = classname;
+ }
+
+ public void setLifestyle( String policy )
+ {
+ m_lifestyle = policy;
+ }
+
+ public void setCollection( String policy )
+ {
+ m_collection = policy;
+ }
+
+ public void setActivation( boolean policy )
+ {
+ m_activation = policy;
+ }
+
+ public CategoriesDataType createCategories()
+ {
+ if( m_categories == null )
+ {
+ m_categories = new CategoriesDataType();
+ return m_categories;
+ }
+ else
+ {
+ final String error =
+ "Illegal attempt to create a duplicate categories
declaration.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+
+ public PartsDataType createParts()
+ {
+ if( m_parts == null )
+ {
+ m_parts = new PartsDataType( this );
+ return m_parts;
+ }
+ else
+ {
+ final String error =
+ "Illegal attempt to create a duplicate parts element.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+
+ public ContextDataType createContext()
+ {
+ if( null == m_context )
+ {
+ m_context = new ContextDataType();
+ return m_context;
+ }
+ else
+ {
+ final String error =
+ "Illegal attempt to create a duplicate context declaration.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+
+ /**
+ * Add a parameters instance to the component.
+ * @return the parameters datatype
+ */
+ public ParametersDataType createParameters()
+ {
+ if( null == m_parameters )
+ {
+ Project project = getProject();
+ m_parameters = new ParametersDataType( project );
+ return m_parameters;
+ }
+ else
+ {
+ final String error =
+ "Illegal attempt to create a duplicate parameters
declaration.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+
+ /**
+ * Add a parameters instance to the component.
+ * @return the parameters datatype
+ */
+ public ConfigurationDataType createConfiguration()
+ {
+ if( null == m_configuration )
+ {
+ Project project = getProject();
+ m_configuration = new ConfigurationDataType( project );
+ return m_configuration;
+ }
+ else
+ {
+ final String error =
+ "Illegal attempt to create a duplicate configuration.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+
+ /**
+ * Add a dependencies directive to this component.
+ * @return the depednencies directive
+ */
+ public DependenciesDataType createDependencies()
+ {
+ if( null == m_dependencies )
+ {
+ m_dependencies = new DependenciesDataType();
+ return m_dependencies;
+ }
+ else
+ {
+ final String error =
+ "Illegal attempt to create a duplicate dependencies set.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+
+ public void execute()
+ {
+ Project project = getProject();
+ Path path = getDefinition().getPath( project, Policy.RUNTIME );
+ File classes = getContext().getClassesDirectory();
+ path.createPathElement().setLocation( classes );
+ ClassLoader classloader = new AntClassLoader( project, path );
+ ComponentProfile profile = buildComponentProfile( classloader );
+
+ File file = getOutputFile();
+ try
+ {
+ URI uri = getDefinition().getArtifactURI( Part.ARTIFACT_TYPE );
+ log( "saving part to: " + uri );
+ URI handler = getPartHandlerURI();
+ byte[] bytes = SerializableObjectHelper.writeToByteArray(
profile );
+ PartHolder holder = new PartHolder( handler, bytes );
+ SerializableObjectHelper.write( holder, file );
+ }
+ catch( IOException ioe )
+ {
+ final String error =
+ "Internal error while attempting to write component part to
file ["
+ + file
+ + "]";
+ throw new BuildException( error, ioe, getLocation() );
+ }
+ }
+
+ private File getOutputFile()
+ {
+ File dir = getContext().getDeliverablesDirectory( Part.ARTIFACT_TYPE
);
+ String filename = getDefinition().getFilename( Part.ARTIFACT_TYPE );
+ File file = new File( dir, filename );
+ File parent = file.getParentFile();
+ if( !parent.exists() )
+ {
+ parent.mkdirs();
+ }
+ return file;
+ }
+
+
+ //---------------------------------------------------------------------
+ // Builder
+ //---------------------------------------------------------------------
+
+ /**
+ * Return a uri identitifying the builder.
+ *
+ * @return the builder uri
+ */
+ public URI getBuilderURI()
+ {
+ return PART_BUILDER_URI;
+ }
+
+ //---------------------------------------------------------------------
+ // PartBuilder
+ //---------------------------------------------------------------------
+
+ public Part buildPart( ClassLoader classloader )
+ {
+ return buildComponentProfile( classloader );
+ }
+
+ /**
+ * Return the key identifying the part that this builder is building.
+ */
+ public String getKey()
+ {
+ return m_key;
+ }
+
+ /**
+ * Return a urn identitifying the part handler for this builder.
+ *
+ * @return a strategy uri
+ */
+ public URI getPartHandlerURI()
+ {
+ return PART_HANDLER_URI;
+ }
+
+ //---------------------------------------------------------------------
+ // impl
+ //---------------------------------------------------------------------
+
+
+ private ComponentProfile buildComponentProfile( ClassLoader classloader )
+ {
+ log( "building component: " + getName() );
+
+ //
+ // setup clasname and type
+ //
+
+ String name = getName();
+ String classname = getClassname();
+ String lifestyle = getLifestylePolicy(); // need to update
ComponentProfile to handle this
+ int collection = getCollectionPolicy();
+ int activation = getActivationPolicy();
+ Mode mode = Mode.EXPLICIT;
+ CategoriesDirective categories = getCategoriesDirective();
+ ContextDirective context = getContextDirective();
+ DependencyDirective[] dependencies = getDependencyDirectives();
+ Parameters parameters = getParameters();
+ Configuration configuration = getConfiguration();
+
+ //
+ // return the component profile
+ //
+
+ return new ComponentProfile( name, activation, collection,
classname, categories, context, dependencies, parameters, configuration, mode
);
+
+ }
+
+ protected String getName()
+ {
+ if( null == m_name )
+ {
+ final String error =
+ "Missing component 'name' attribute.";
+ throw new BuildException( error, getLocation() );
+ }
+ return m_name;
+ }
+
+ protected String getClassname()
+ {
+ if( null == m_classname )
+ {
+ final String error =
+ "Missing component 'class' attribute.";
+ throw new BuildException( error, getLocation() );
+ }
+ return m_classname;
+ }
+
+ public String getLifestylePolicy()
+ {
+ if( null == m_lifestyle )
+ {
+ return InfoDescriptor.TRANSIENT;
+ }
+ else
+ {
+ String spec = m_lifestyle.toLowerCase();
+ if( "request".equals( spec ) )
+ {
+ return InfoDescriptor.TRANSIENT;
+ }
+ else if( "thread".equals( spec ) )
+ {
+ return InfoDescriptor.THREAD;
+ }
+ else if( "singleton".equals( spec ) )
+ {
+ return InfoDescriptor.SINGLETON;
+ }
+ else
+ {
+ final String error =
+ "Lifestyle policy ["
+ + spec
+ + "] not regignized. Valid policies include 'request',
'thread' and 'singleton'.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+ }
+
+ public int getCollectionPolicy()
+ {
+ if( null == m_collection )
+ {
+ return InfoDescriptor.UNDEFINED;
+ }
+ else
+ {
+ String spec = m_collection.toLowerCase();
+ if( "hard".equals( spec ) )
+ {
+ return InfoDescriptor.HARD;
+ }
+ else if( "soft".equals( spec ) )
+ {
+ return InfoDescriptor.SOFT;
+ }
+ else if( "weak".equals( spec ) )
+ {
+ return InfoDescriptor.WEAK;
+ }
+ else
+ {
+ final String error =
+ "Collection policy ["
+ + spec
+ + "] not recognized. Valid policies include 'hard', 'soft'
and 'weak'.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+ }
+
+ public int getActivationPolicy()
+ {
+ if( m_activation )
+ {
+ return DeploymentProfile.ENABLED;
+ }
+ else
+ {
+ return DeploymentProfile.DISABLED;
+ }
+ }
+
+ private ContextDirective getContextDirective()
+ {
+ if( null == m_context )
+ {
+ return new ContextDirective();
+ }
+ else
+ {
+ return m_context.getContextDirective();
+ }
+ }
+
+ private DependencyDirective[] getDependencyDirectives()
+ {
+ if( null == m_dependencies )
+ {
+ return new DependencyDirective[0];
+ }
+ else
+ {
+ return m_dependencies.getDependencyDirectives();
+ }
+ }
+
+ private CategoriesDirective getCategoriesDirective()
+ {
+ if( null == m_categories )
+ {
+ return new CategoriesDirective();
+ }
+ else
+ {
+ return m_categories.getCategoriesDirective();
+ }
+ }
+
+ private Parameters getParameters()
+ {
+ if( null == m_parameters )
+ {
+ return DefaultParameters.EMPTY_PARAMETERS;
+ }
+ else
+ {
+ return m_parameters.getParameters();
+ }
+ }
+
+ private Configuration getConfiguration()
+ {
+ if( null == m_configuration )
+ {
+ return null;
+ }
+ else
+ {
+ return m_configuration.getConfiguration();
+ }
+ }
+
+ //
+ // Logging category handlers.
+ //
+
+ public static class CategoriesDataType
+ {
+ private List m_list = new LinkedList();
+
+ public CategoryDataType createCategory()
+ {
+ CategoryDataType category = new CategoryDataType();
+ m_list.add( category );
+ return category;
+ }
+
+ CategoriesDirective getCategoriesDirective()
+ {
+
+ CategoryDataType[] types = (CategoryDataType[])
m_list.toArray( new CategoryDataType[0] );
+ CategoryDirective[] directives = new CategoryDirective[
types.length ];
+ for( int i=0; i<types.length; i++ )
+ {
+ CategoryDataType type = types[i];
+ CategoryDirective directive = type.getCategoryDirective();
+ }
+ return new CategoriesDirective( directives );
+ }
+
+ public class CategoryDataType
+ {
+ private String m_name;
+ private String m_priority;
+ private String m_target;
+
+ public void setName( String name )
+ {
+ m_name = name;
+ }
+
+ public void setPriority( String priority )
+ {
+ m_priority = priority;
+ }
+
+ public void setTarget( String target )
+ {
+ m_target = target;
+ }
+
+ public CategoryDirective getCategoryDirective()
+ {
+ return new CategoryDirective( m_name, m_priority, m_target
);
+ }
+ }
+ }
+
+ //
+ // context handler
+ //
+
+ /**
+ * A context directive class.
+ */
+ public static class ContextDataType
+ {
+ private String m_class;
+ private List m_entries = new ArrayList();
+
+ /**
+ * Declare a custom context implementation classname.
+ * @param classname the classname of an optional context
implementation class
+ */
+ public void setClass( final String classname )
+ {
+ m_class = classname ;
+ }
+
+ /**
+ * Return the optional context implementation classname.
+ * @return the classname
+ */
+ public String getClassname()
+ {
+ return m_class;
+ }
+
+ /**
+ * Create, add and return a new entry directive to the context.
+ * @return a new context entry directive
+ */
+ public Entry createEntry()
+ {
+ final Entry entry = new Entry();
+ m_entries.add( entry );
+ return entry;
+ }
+
+ /**
+ * Return all of the context entries within the context directive.
+ * @return the set of context entries
+ */
+ public Entry[] getEntries()
+ {
+ return (Entry[]) m_entries.toArray( new Entry[0] );
+ }
+
+ protected ContextDirective getContextDirective()
+ {
+ Entry[] entries = getEntries();
+ EntryDirective[] entryDirectives = new EntryDirective[
entries.length ];
+ for( int i=0; i<entries.length; i++ )
+ {
+ Entry entry = entries[i];
+ entryDirectives[i] = entry.getEntryDirective();
+ }
+ String classname = getClassname();
+ return new ContextDirective( classname, entryDirectives );
+ }
+ }
+
+ /**
+ * Defintion of a context entry directive.
+ */
+ public static class Entry extends Param
+ {
+ private String m_key;
+
+ /**
+ * Set the context enty key that this directive qualifies.
+ * @param key the context entry key
+ */
+ public void setKey( final String key )
+ {
+ m_key = key ;
+ }
+
+ /**
+ * Return the context entry key.
+ * @return the entry key
+ */
+ public String getKey()
+ {
+ return m_key;
+ }
+
+ public EntryDirective getEntryDirective()
+ {
+ String key = getKey();
+ String classname = getClassname();
+ String value = getValue();
+ if( null != value )
+ {
+ return new ConstructorDirective( key, classname, value );
+ }
+ else
+ {
+ Param[] params = getParams();
+ Parameter[] parameters = new Parameter[ params.length ];
+ for( int i=0; i<parameters.length; i++ )
+ {
+ Param p = params[i];
+ parameters[i] = p.getParameter();
+ }
+ return new ConstructorDirective( key, classname, parameters
);
+ }
+ }
+ }
+
+ /**
+ * Defintion of a context entry parameter directive.
+ */
+ public static class Param
+ {
+ private String m_classname;
+ private String m_value;
+ private List m_params = new ArrayList();
+
+ /**
+ * Set the context entry classname.
+ * @param classname the context entry classname
+ */
+ public void setClass( final String classname )
+ {
+ m_classname = classname;
+ }
+
+ /**
+ * Return the context entry parameter classname.
+ * @return the classname
+ */
+ public String getClassname()
+ {
+ return m_classname;
+ }
+
+ /**
+ * Set the value of the context entry parameter.
+ * @param value the param value
+ */
+ public void setValue( final String value )
+ {
+ m_value = value;
+ }
+
+ /**
+ * Return the value of the context entry param.
+ * @return the value
+ */
+ public String getValue()
+ {
+ return m_value;
+ }
+
+ /**
+ * Create, assign and return a new nested entry constructor parameter.
+ * @return the new context entry param
+ */
+ public Param createParam()
+ {
+ final Param param = new Param();
+ m_params.add( param );
+ return param;
+ }
+
+ /**
+ * Return the set of nested param directives.
+ * @return the params
+ */
+ public Param[] getParams()
+ {
+ return (Param[]) m_params.toArray( new Param[0] );
+ }
+
+ public Parameter getParameter()
+ {
+ String classname = getClassname();
+ String value = getValue();
+ if( null != value )
+ {
+ return new Parameter( classname, value );
+ }
+ else
+ {
+ Param[] params = getParams();
+ Parameter[] parameters = new Parameter[ params.length ];
+ for( int i=0; i<parameters.length; i++ )
+ {
+ Param p = params[i];
+ parameters[i] = p.getParameter();
+ }
+ return new Parameter( classname, parameters );
+ }
+ }
+ }
+
+ //
+ // Dependecies data type
+ //
+
+ public static class DependenciesDataType
+ {
+ private List m_dependencies = new ArrayList();
+
+ /**
+ * Create, assiciate and return a new dependency within this set of
dependencies.
+ * @return the new dependnecy directive
+ */
+ public DependencyDataType createDependency()
+ {
+ final DependencyDataType dep = new DependencyDataType ();
+ m_dependencies.add( dep );
+ return dep;
+ }
+
+ /**
+ * Return the set of dependency directives within this dependencies
directive.
+ * @return the dependency directives
+ */
+ public DependencyDataType[] getDependencies()
+ {
+ return (DependencyDataType[]) m_dependencies.toArray( new
DependencyDataType[0] );
+ }
+
+ protected DependencyDirective[] getDependencyDirectives()
+ {
+ DependencyDataType[] deps = getDependencies();
+ DependencyDirective[] dependencies = new DependencyDirective[
deps.length ];
+ for( int i=0; i<dependencies.length; i++ )
+ {
+ DependencyDataType dep = deps[i];
+ dependencies[i] = dep.getDependencyDirective();
+ }
+ return dependencies;
+ }
+ }
+
+ /**
+ * A dependency directive.
+ */
+ public static class DependencyDataType
+ {
+ private String m_source;
+
+ private String m_key;
+
+ /**
+ * Set the key that this depedency directive qualifies.
+ * @param key the dependency key
+ */
+ public void setKey( final String key )
+ {
+ m_key = key;
+ }
+
+ /**
+ * Get the dependency directive key.
+ */
+ public String getKey()
+ {
+ return m_key;
+ }
+
+ /**
+ * Set the address of the source component to fulofill the dependency.
+ * @param source the source component address
+ */
+ public void setSource( final String source )
+ {
+ m_source = source;
+ }
+
+ /**
+ * Return the address of the source component to use to fulfill this
dependency.
+ * @return the source component address
+ */
+ public String getSource()
+ {
+ return m_source;
+ }
+
+ protected DependencyDirective getDependencyDirective()
+ {
+ String key = getKey();
+ String source = getSource();
+ return new DependencyDirective( key, source );
+ }
+ }
+
+ /**
+ * A parameters directive declares a set of n parameters.
+ */
+ public static class ParametersDataType
+ {
+ private final List m_parameters = new ArrayList();
+ private final Project m_project;
+
+ public ParametersDataType( Project project )
+ {
+ m_project = project;
+ }
+
+ /**
+ * Create, allocate and return a new parameter with this set of
parameters.
+ * @return a new parameter directive
+ */
+ public ParameterDataType createParameter()
+ {
+ final ParameterDataType parameter = new ParameterDataType(
m_project );
+ m_parameters.add( parameter );
+ return parameter;
+ }
+
+ /**
+ * Return the set of parameter directives declarared within this
parameters directives.
+ * @return the set of parameter directives
+ */
+ public ParameterDataType[] getParameterDataTypes()
+ {
+ return (ParameterDataType[]) m_parameters.toArray( new
ParameterDataType[0] );
+ }
+
+ protected Parameters getParameters()
+ {
+ DefaultParameters parameters = new DefaultParameters();
+ ParameterDataType[] params = getParameterDataTypes();
+ for( int i=0; i<params.length; i++ )
+ {
+ ParameterDataType p = params[i];
+ String name = p.getName();
+ String value = p.getValue();
+ parameters.setParameter( name, value );
+ }
+ return parameters;
+ }
+ }
+
+ /**
+ * A parameter directive.
+ */
+ public static class ParameterDataType
+ {
+ private final Project m_project;
+
+ private String m_name;
+ private String m_value;
+
+ public ParameterDataType( Project project )
+ {
+ m_project = project;
+ }
+
+ /**
+ * Set the parameter name.
+ * @param name the parameter name
+ */
+ public void setName( final String name )
+ {
+ m_name = name;
+ }
+
+ /**
+ * Set the value assigned to the named parameter.
+ * @param value the parameter value
+ */
+ public void setValue( final String value )
+ {
+ m_value = m_project.replaceProperties( value );
+ }
+
+ /**
+ * Return the parameter name.
+ * @return the parameter name
+ */
+ public String getName()
+ {
+ return m_name;
+ }
+
+ /**
+ * Return the value assigned to the parameter.
+ * @return the parameter value
+ */
+ public String getValue()
+ {
+ return m_value;
+ }
+ }
+
+ //
+ // Configuration data type
+ //
+
+ /**
+ * A configuration directive.
+ */
+ public static class ConfigurationDataType implements
DynamicConfiguratorNS
+ {
+ private final Project m_project;
+
+ private String m_value;
+ private Map m_attributes = new Hashtable();
+ private List m_children = new LinkedList();
+ private String m_name;
+
+ /**
+ * Creation of a root configuration directive.
+ */
+ public ConfigurationDataType( Project project )
+ {
+ this( project, "configuration" );
+ }
+
+ /**
+ * Creation of a named configuration element.
+ * @param name the element name
+ */
+ public ConfigurationDataType( Project project, String name )
+ {
+ m_name = name;
+ m_project = project;
+ }
+
+ /**
+ * Add nested text.
+ * @param value the test value
+ */
+ public void addText(String value )
+ {
+ String s = value.trim();
+ if( s.length() > 0 )
+ {
+ String parsedValue = m_project.replaceProperties( s );
+ m_value = parsedValue;
+ }
+ }
+
+ /**
+ * Set a named attribute to the given value
+ *
+ * @param uri The namespace uri for this attribute, "" is
+ * used if there is no namespace uri.
+ * @param localName The localname of this attribute.
+ * @param qName The qualified name for this attribute
+ * @param value The value of this attribute.
+ * @throws BuildException when any error occurs
+ */
+ public void setDynamicAttribute(
+ String uri, String localName, String qName, String value)
+ throws BuildException
+ {
+ String parsedValue = m_project.replaceProperties( value );
+ m_attributes.put( qName, parsedValue );
+ }
+
+ /**
+ * Create an element with the given name
+ *
+ * @param qName the element nbame
+ * @throws BuildException when any error occurs
+ * @return the element created
+ */
+ public Object createDynamicElement(
+ String uri, String localName, String qName) throws BuildException
+ {
+ ConfigurationDataType conf = new ConfigurationDataType(
m_project, qName );
+ m_children.add( conf );
+ return conf;
+ }
+
+ /**
+ * Return the name of the configuration element.
+ * @return the node name
+ */
+ public String getName()
+ {
+ return m_name;
+ }
+
+ /**
+ * Return a value associated with the element.
+ * @return the assigned value
+ */
+ public String getValue()
+ {
+ return m_value;
+ }
+
+ /**
+ * Return the map of the assigned attributes.
+ * @return the attribute name value map
+ */
+ public Map getAttributes()
+ {
+ return m_attributes;
+ }
+
+ /**
+ * Return he set of nest child configuration directives.
+ * @return the configuration directives within this directive
+ */
+ public ConfigurationDataType[] getChildren()
+ {
+ return (ConfigurationDataType[]) m_children.toArray( new
ConfigurationDataType[m_children.size()] );
+ }
+
+ protected Configuration getConfiguration()
+ {
+ String name = getName();
+ DefaultConfiguration config = new DefaultConfiguration( name );
+ config.setValue( getValue() );
+ Map attributes = getAttributes();
+ String[] keys = (String[]) attributes.keySet().toArray( new
String[0] );
+ for( int i=0; i<keys.length; i++ )
+ {
+ String key = keys[i];
+ String value = (String) attributes.get( key );
+ config.setAttribute( key, value );
+ }
+ ConfigurationDataType[] nodes = getChildren();
+ Configuration[] children = new Configuration[ nodes.length ];
+ for( int i=0; i<nodes.length; i++ )
+ {
+ ConfigurationDataType data = nodes[i];
+ Configuration conf = data.getConfiguration();
+ config.addChild( conf );
+ }
+ return config;
+ }
+ }
+
+ 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;
+ }
+ }
+}

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ConstructionException.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ConstructionException.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2005 Stephen J. McConnell
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dpml.composition.builder;
+
+import java.net.URI;
+
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.BuildException;
+
+/**
+ * A construction exception indicates a generation phase error in the
construction
+ * of a component 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 ConstructionException extends BuildException
+{
+ /**
+ * Creation of a new construction exception.
+ * @param message the exception message
+ */
+ public ConstructionException( String message )
+ {
+ super( message );
+ }
+
+ /**
+ * Creation of a new construction exception.
+ * @param message the exception message
+ * @param cause the causal exception
+ */
+ public ConstructionException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ /**
+ * Creation of a new construction exception.
+ * @param message the exception message
+ * @param cause the causal exception
+ */
+ public ConstructionException( String message, Location location )
+ {
+ super( message, location );
+ }
+
+ /**
+ * Creation of a new construction exception.
+ * @param message the exception message
+ * @param location location of the task
+ */
+ public ConstructionException( String message, Throwable cause, Location
location )
+ {
+ super( message, cause, location );
+ }
+}

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ContainerBuilderTask.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ContainerBuilderTask.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,451 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.Serializable;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.rmi.MarshalledObject;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.ArrayList;
+
+import net.dpml.meta.info.Type;
+import net.dpml.meta.info.InfoDescriptor;
+
+import net.dpml.part.Part;
+import net.dpml.part.PartHolder;
+
+import net.dpml.builder.PartBuilder;
+import net.dpml.builder.IntrospectionException;
+
+import net.dpml.composition.data.DeploymentProfile;
+import net.dpml.composition.data.ContainmentProfile;
+import net.dpml.composition.data.ServiceDirective;
+import net.dpml.composition.data.ClasspathDirective;
+import net.dpml.composition.data.FilesetDirective;
+import net.dpml.logging.data.CategoriesDirective;
+
+import net.dpml.meta.info.ServiceDescriptor;
+import net.dpml.meta.info.ReferenceDescriptor;
+
+import net.dpml.magic.tasks.ProjectTask;
+import net.dpml.magic.model.Policy;
+import net.dpml.magic.model.Definition;
+import net.dpml.magic.model.Resource;
+import net.dpml.magic.model.ResourceRef;
+import net.dpml.magic.project.Context;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DynamicElementNS;
+
+/**
+ * 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 ContainerBuilderTask extends ProjectTask implements PartBuilder
+{
+ private final List m_builders = new LinkedList();
+
+ private String m_key;
+ private String m_name;
+ private String m_classname;
+ private ClassloaderDataType m_classpath;
+ private ServicesDataType m_services;
+
+ public void setKey( String key )
+ {
+ m_key = key;
+ }
+
+ public void setName( String name )
+ {
+ m_name = name;
+ }
+
+ public void setClass( String classname )
+ {
+ m_classname = classname;
+ }
+
+ public ComponentBuilderTask createComponent()
+ {
+ Project project = getProject();
+ ComponentBuilderTask builder = new ComponentBuilderTask();
+ builder.setProject( project );
+ m_builders.add( builder );
+ return builder;
+ }
+
+ public ClassloaderDataType createClassloader()
+ {
+ if( m_classpath == null )
+ {
+ m_classpath = new ClassloaderDataType();
+ return m_classpath;
+ }
+ else
+ {
+ final String error =
+ "Illegal attempt to create a duplicate classloader
declaration.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+
+ public ServicesDataType createServices()
+ {
+ if( m_services == null )
+ {
+ m_services = new ServicesDataType();
+ return m_services;
+ }
+ else
+ {
+ final String error =
+ "Illegal attempt to create a duplicate services declaration.";
+ throw new BuildException( error, getLocation() );
+ }
+ }
+
+ public void execute()
+ {
+ Project project = getProject();
+ Path path = getDefinition().getPath( project, Policy.RUNTIME );
+ File classes = getContext().getClassesDirectory();
+ path.createPathElement().setLocation( classes );
+ ClassLoader classloader = new AntClassLoader( project, path );
+ ContainmentProfile profile = buildContainer( classloader );
+
+ File file = getOutputFile();
+ try
+ {
+ URI uri = getDefinition().getArtifactURI( Part.ARTIFACT_TYPE );
+ log( "saving part to: " + uri );
+ URI handler = getPartHandlerURI();
+ byte[] bytes = SerializableObjectHelper.writeToByteArray(
profile );
+ PartHolder holder = new PartHolder( handler, bytes );
+ SerializableObjectHelper.write( holder, file );
+ }
+ catch( IOException ioe )
+ {
+ final String error =
+ "Internal error while attempting to write container part to
file ["
+ + file
+ + "]";
+ throw new BuildException( error, ioe, getLocation() );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ // Builder
+ //---------------------------------------------------------------------
+
+ /**
+ * Return a uri identitifying the builder.
+ *
+ * @return the builder uri
+ */
+ public URI getBuilderURI()
+ {
+ return PART_BUILDER_URI;
+ }
+
+ //---------------------------------------------------------------------
+ // PartBuilder
+ //---------------------------------------------------------------------
+
+ public Part buildPart( ClassLoader classloader )
+ {
+ return buildContainer( classloader );
+ }
+
+ /**
+ * Return the key identifying the part that this builder is building.
+ */
+ public String getKey()
+ {
+ return m_key;
+ }
+
+ /**
+ * Return a urn identitifying the part handler for this builder.
+ *
+ * @return a strategy uri
+ */
+ public URI getPartHandlerURI()
+ {
+ return PART_HANDLER_URI;
+ }
+
+ //---------------------------------------------------------------------
+ // impl
+ //---------------------------------------------------------------------
+
+ private ContainmentProfile buildContainer( ClassLoader classloader )
+ {
+ String name = getName();
+ log( "building container: " + name);
+ DeploymentProfile[] profiles = buildDeploymentProfiles( classloader
);
+ ClasspathDirective classpath = getClasspathDirective();
+ ServiceDirective[] services = getServiceDirectives();
+ CategoriesDirective categories = new CategoriesDirective(); // TODO
+ return new ContainmentProfile( name, classpath, services,
categories, profiles );
+ }
+
+ private ClasspathDirective getClasspathDirective()
+ {
+ if( null == m_classpath )
+ {
+ return constructClasspathDirective();
+ }
+ else
+ {
+ return m_classpath.getClasspathDirective();
+ }
+ }
+
+ private ServiceDirective[] getServiceDirectives()
+ {
+ if( null == m_services )
+ {
+ return new ServiceDirective[0];
+ }
+ else
+ {
+ return m_services.getServiceDirectives();
+ }
+ }
+
+ private DeploymentProfile[] buildDeploymentProfiles( ClassLoader
classloader )
+ {
+ List list = new ArrayList();
+ PartBuilder[] builders = (PartBuilder[]) m_builders.toArray( new
PartBuilder[0] );
+ for( int i=0; i<builders.length; i++ )
+ {
+ try
+ {
+ PartBuilder builder = builders[i];
+ if( builder instanceof Task )
+ {
+ ((Task)builder).setTaskName( "component" );
+ }
+ Part part = builder.buildPart( classloader );
+ if( part instanceof DeploymentProfile )
+ {
+ list.add( part );
+ }
+ else
+ {
+ final String error =
+ "Cannot handle parts that are not castable to
DeploymentProfile.";
+ throw new UnsupportedOperationException( error );
+ }
+ }
+ catch( Exception e )
+ {
+ final String error =
+ "Internal error while attempting to build types.";
+ throw new BuildException( error, e, getLocation() );
+ }
+ }
+ return (DeploymentProfile[]) list.toArray( new DeploymentProfile[0]
);
+ }
+
+ protected String getName()
+ {
+ if( null == m_name )
+ {
+ final String error =
+ "Missing container 'name' attribute.";
+ throw new BuildException( error, getLocation() );
+ }
+ return m_name;
+ }
+
+ private ClasspathDirective constructClasspathDirective()
+ {
+ URI[] uris = createURISequence( ResourceRef.ANY ); // TODO: API,
SPI, IMPL spread
+ FilesetDirective[] filesets = new FilesetDirective[0];
+ return new ClasspathDirective( filesets, uris );
+ }
+
+ private URI[] createURISequence( int category )
+ {
+ Definition def = getDefinition();
+ ArrayList list = new ArrayList();
+ final ResourceRef[] resources =
+ def.getResourceRefs( getProject(), Policy.RUNTIME, category, true
);
+ for( int i=0; i<resources.length; i++ )
+ {
+ final ResourceRef ref = resources[i];
+ final Policy policy = ref.getPolicy();
+ if( policy.isRuntimeEnabled() )
+ {
+ final Resource resource = getIndex().getResource( ref );
+ if( "jar".equals( resource.getInfo().getType() ) )
+ {
+ URI uri = resource.getArtifactURI( "jar" );
+ list.add( uri );
+ }
+ }
+ }
+ if( def.getInfo().isa( "jar" ) )
+ {
+ URI local = def.getArtifactURI( "jar" );
+ list.add( local );
+ }
+ return (URI[]) list.toArray( new URI[0] );
+ }
+
+ private File getOutputFile()
+ {
+ File dir = getContext().getDeliverablesDirectory( Part.ARTIFACT_TYPE
);
+ String filename = getDefinition().getFilename( Part.ARTIFACT_TYPE );
+ File file = new File( dir, filename );
+ File parent = file.getParentFile();
+ if( !parent.exists() )
+ {
+ parent.mkdirs();
+ }
+ return file;
+ }
+
+
//---------------------------------------------------------------------------
+ // utilities
+
//---------------------------------------------------------------------------
+
+ public static class ClassloaderDataType
+ {
+ private final List m_elements = new LinkedList();
+
+ public PathElementDataType createPathelement()
+ {
+ PathElementDataType element = new PathElementDataType();
+ m_elements.add( element );
+ return element;
+ }
+
+ protected ClasspathDirective getClasspathDirective()
+ {
+ PathElementDataType[] elements = (PathElementDataType[])
m_elements.toArray( new PathElementDataType[0] );
+ URI[] uris = new URI[ elements.length ];
+ for( int i=0; i<elements.length; i++ )
+ {
+ PathElementDataType element = elements[i];
+ uris[i] = element.getURI();
+ }
+ FilesetDirective[] filesets = new FilesetDirective[0];
+ return new ClasspathDirective( filesets, uris );
+ }
+
+ public static class PathElementDataType
+ {
+ private URI m_uri;
+
+ public void setUri( URI uri )
+ {
+ m_uri = uri;
+ }
+
+ public URI getURI()
+ {
+ return m_uri;
+ }
+ }
+ }
+
+ public static class ServicesDataType
+ {
+ private final List m_services = new LinkedList();
+
+ public ServiceDataType createService()
+ {
+ ServiceDataType service = new ServiceDataType();
+ m_services.add( service );
+ return service;
+ }
+
+ protected ServiceDirective[] getServiceDirectives()
+ {
+ ServiceDataType[] datatypes = (ServiceDataType[])
m_services.toArray( new ServiceDataType[0] );
+ ServiceDirective[] directives = new ServiceDirective[
datatypes.length ];
+ for( int i=0; i<directives.length; i++ )
+ {
+ ServiceDataType datatype = datatypes[i];
+ directives[i] = datatype.getServiceDirective();
+ }
+ return directives;
+ }
+
+ public static class ServiceDataType
+ {
+ private String m_type;
+ private String m_provider;
+
+ public void setType( String classname )
+ {
+ m_type = classname;
+ }
+
+ public void serProvider( String name )
+ {
+ m_provider = name;
+ }
+
+ protected ServiceDirective getServiceDirective()
+ {
+ ReferenceDescriptor ref = new ReferenceDescriptor( m_type );
+ ServiceDescriptor service = new ServiceDescriptor( ref );
+ return new ServiceDirective( service, m_provider );
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+
+}

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/PartsDataType.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/PartsDataType.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,170 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.net.URI;
+
+import net.dpml.part.Part;
+import net.dpml.builder.PartBuilder;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.DynamicElementNS;
+import org.apache.tools.ant.taskdefs.Sequential;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Location;
+
+/**
+ * A datatype that enables custom part builders.
+ *
+ * @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 PartsDataType extends ProjectComponent implements
DynamicElementNS
+{
+ private List m_builders = new LinkedList();
+ private Task m_owner;
+
+ public PartsDataType( Task owner )
+ {
+ Project project = owner.getProject();
+ setProject( project );
+ m_owner = owner;
+ }
+
+ public ComponentBuilderTask createComponent()
+ {
+ ComponentBuilderTask builder = new ComponentBuilderTask();
+ m_builders.add( builder );
+ return builder;
+ }
+
+ /**
+ * Operation used to construct a custom part type directive.
+ * @param uri the part handler uri
+ * @param name the element name
+ * @param qualified the qualified name
+ */
+ public Object createDynamicElement( String uri, String name, String
qualified )
+ {
+ String path = getProject().replaceProperties( uri );
+ PartBuilder builder = loadPartHandler( path, name );
+ if( null != builder )
+ {
+ m_builders.add( builder );
+ }
+ return builder;
+ }
+
+ private PartBuilder loadPartHandler( String uri, String name ) throws
BuildException
+ {
+ String urn = uri + ":" + name;
+ Object builder = null;
+ PartBuilder partBuilder = null;
+ String target = m_owner.getOwningTarget().getName();
+ Location location = m_owner.getLocation();
+ ClassLoader context = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ Thread.currentThread().setContextClassLoader(
getClass().getClassLoader() );
+ Project project = getProject();
+ builder = project.createDataType( urn );
+ partBuilder = (PartBuilder) builder;
+ return partBuilder ;
+ }
+ catch( ClassCastException e )
+ {
+ final String error =
+ "The custom part builder ["
+ + builder.getClass().getName()
+ + "] established by the uri ["
+ + urn
+ + "] declared by the element <"
+ + name
+ + "> under the task <"
+ + m_owner.getTaskName()
+ + "><parts> within the target <"
+ + target
+ + "> does not implement the net.dpml.metro.tools.PartBuilder
interface.";
+ throw new BuildException( error, e );
+ }
+ catch( BuildException e )
+ {
+ final String error =
+ "Unable to load the plugin from the uri ["
+ + urn
+ + "] to handle the custom part type declared by the element <"
+ + name
+ + "> within <"
+ + m_owner.getTaskName()
+ + "><parts> under the target <"
+ + target
+ + ">.";
+ throw new BuildException( error, e );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected exception while attempting to load the custom part
handler with the uri ["
+ + urn
+ + "] declared by the element <"
+ + name
+ + "> within <"
+ + m_owner.getTaskName()
+ + "><parts> under the target <"
+ + target
+ + ">.";
+ throw new BuildException( error, e );
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( context );
+ }
+ }
+
+ /**
+ * Return the set of parts contained within this container.
+ * @return the contained parts
+ */
+ public PartBuilder[] getPartBuilders()
+ {
+ return (PartBuilder[]) m_builders.toArray( new PartBuilder[0] );
+ }
+
+ /**
+ * Return the set of parts contained within this container.
+ * @return the contained parts
+ */
+ public Part[] getParts( ClassLoader classloader ) throws Exception
+ {
+ PartBuilder[] builders = (PartBuilder[]) m_builders.toArray( new
PartBuilder[0] );
+ Part[] parts = new Part[ builders.length ];
+ for( int i=0; i<builders.length; i++ )
+ {
+ PartBuilder builder = builders[i];
+ parts[i] = builder.buildPart( classloader );
+ }
+ return parts;
+ }
+}

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/SerializableObjectHelper.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/SerializableObjectHelper.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.Serializable;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.net.URI;
+import java.rmi.MarshalledObject;
+
+import net.dpml.builder.BuilderRuntimeException;
+
+/**
+ * A datatype that enables custom part builders.
+ *
+ * @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 SerializableObjectHelper
+{
+ private SerializableObjectHelper()
+ {
+ // static utility class
+ }
+
+ public static void write( Serializable object, File file ) throws
IOException
+ {
+ ObjectOutputStream output = null;
+ FileOutputStream stream = null;
+ try
+ {
+ stream = new FileOutputStream( file );
+ output = new ObjectOutputStream( stream );
+ output.writeObject( object );
+ }
+ catch( IOException ioe )
+ {
+ throw ioe;
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected error while attempting to write an object."
+ + "\ndestination: " + file
+ + "\nclass: " + object.getClass().getName()
+ + "\nreason: " + e.toString();
+ throw new BuilderRuntimeException( error, e );
+ }
+ finally
+ {
+ closeStream( output );
+ }
+ }
+
+ public static byte[] writeToByteArray( Serializable object ) throws
IOException
+ {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ ObjectOutputStream output = null;
+ try
+ {
+ output = new ObjectOutputStream( stream );
+ output.writeObject( object );
+ return stream.toByteArray();
+ }
+ catch( IOException ioe )
+ {
+ throw ioe;
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected error while attempting to write object to a byte
array."
+ + "\nclass: " + object.getClass().getName()
+ + "\nreason: " + e.toString();
+ throw new BuilderRuntimeException( error, e );
+ }
+ finally
+ {
+ closeStream( output );
+ }
+ }
+
+ private static void closeStream( OutputStream out )
+ {
+ if( null != out )
+ {
+ try
+ {
+ out.close();
+ }
+ catch( IOException ioe )
+ {
+ boolean ignoreMe = true;
+ }
+ }
+ }
+}

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilder.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilder.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.net.URI;
+
+import net.dpml.builder.Builder;
+import net.dpml.builder.IntrospectionException;
+
+import net.dpml.part.BadStrategyException;
+
+import net.dpml.meta.info.Type;
+
+/**
+ * The contract for builders that create component 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 interface TypeBuilder extends Builder
+{
+ /**
+ * Return a urn identitifying the type handler for this builder.
+ *
+ * @return a uri identifing the type handler.
+ */
+ URI getTypeHandlerURI();
+
+ /**
+ * Build a part type.
+ * @return the serializable part type.
+ * @exception IntrospectionException if a introspection occurs during
type construction
+ */
+ Type buildType( ClassLoader classloader )
+ throws IntrospectionException, IOException;
+
+}

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,648 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.Serializable;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Properties;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.ArrayList;
+import java.lang.reflect.Method;
+import java.net.URI;
+
+import net.dpml.meta.info.Type;
+import net.dpml.meta.info.ServiceDescriptor;
+import net.dpml.meta.info.DependencyDescriptor;
+import net.dpml.meta.info.InfoDescriptor;
+import net.dpml.meta.info.ContextDescriptor;
+import net.dpml.meta.info.EntryDescriptor;
+import net.dpml.meta.info.CategoryDescriptor;
+import net.dpml.meta.info.PartDescriptor;
+import net.dpml.meta.info.ParameterDescriptor;
+
+import net.dpml.builder.IntrospectionException;
+
+import net.dpml.part.BadStrategyException;
+
+import net.dpml.configuration.Configuration;
+
+import net.dpml.parameters.Parameters;
+
+import net.dpml.magic.model.Policy;
+import net.dpml.magic.model.Definition;
+import net.dpml.magic.project.Context;
+import net.dpml.magic.tasks.ProjectTask;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * The TypeTask creates a serialized descriptor of a component type.
+ *
+ * @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 TypeBuilderTask extends ProjectTask implements TypeBuilder
+{
+ //---------------------------------------------------------------
+ // state
+ //---------------------------------------------------------------
+
+ private String m_name;
+ private String m_classname;
+ //private PartsDataType m_parts;
+ private Class m_class;
+
+ //---------------------------------------------------------------
+ // setters
+ //---------------------------------------------------------------
+
+ public void setName( String name )
+ {
+ m_name = name;
+ }
+
+ public void setClass( String classname )
+ {
+ m_classname = classname;
+ }
+
+ /*
+ public PartsDataType createParts()
+ {
+ if( null == m_parts )
+ {
+ System.out.println( "## creating parts element" );
+ m_parts = new PartsDataType( this );
+ }
+ return m_parts;
+ }
+ */
+
+ //---------------------------------------------------------------
+ // Builder
+ //---------------------------------------------------------------
+
+ /**
+ * Return a urn identitifying the component type strategy that this
+ * builder is supporting.
+ *
+ * @return a uri identifiying the type strategy
+ */
+ public URI getTypeHandlerURI()
+ {
+ return TYPE_HANDLER_URI;
+ }
+
+ /**
+ * Return a uri identitifying the builder.
+ *
+ * @return a uri identifiying the type builder
+ */
+ public URI getBuilderURI()
+ {
+ return TYPE_BUILDER_URI;
+ }
+
+ //---------------------------------------------------------------
+ // TypeBuilder
+ //---------------------------------------------------------------
+
+ public Type buildType( ClassLoader classloader )
+ throws IntrospectionException, IOException
+ {
+ Class subject = loadSubjectClass( classloader );
+ return buildType( subject );
+ }
+
+ public Type buildType( Class subject )
+ throws IntrospectionException, IOException
+ {
+ log( "creating: " + subject.getName() );
+ InfoDescriptor info = createInfoDescriptor( subject );
+ ServiceDescriptor[] services = createServiceDescriptors( subject );
+ DependencyDescriptor[] dependencies = createDependencyDescriptors(
subject );
+ CategoryDescriptor[] categories = new CategoryDescriptor[0];
+ ContextDescriptor context = new ContextDescriptor( null, new
EntryDescriptor[0] );
+ Configuration config = null;
+ ParameterDescriptor[] params = createParameterDescriptors( subject );
+ PartDescriptor[] parts = createPartDescriptors( subject );
+ //PartDescriptor[] parts = createPartDescriptors( subject );
+ return new Type( info, categories, context, services, dependencies,
config, params, parts );
+ }
+
+ //---------------------------------------------------------------
+ // Task
+ //---------------------------------------------------------------
+
+ public void execute()
+ {
+ Project project = getProject();
+ Path path = getDefinition().getPath( project, Policy.RUNTIME );
+ File classes = getContext().getClassesDirectory();
+ path.createPathElement().setLocation( classes );
+ ClassLoader classloader = new AntClassLoader( project, path );
+ Class subject = loadSubjectClass( classloader );
+ String resource = getEmbeddedResourcePath( subject );
+ File file = getEmbeddedOutputFile( resource );
+ try
+ {
+ Type type = buildType( subject );
+ SerializableObjectHelper.write( type, file );
+ }
+ catch( IOException ioe )
+ {
+ final String error =
+ "Internal error while attempting to write type to file ["
+ + file
+ + "]";
+ throw new BuildException( error, ioe, getLocation() );
+ }
+ catch( IntrospectionException e )
+ {
+ final String error =
+ "Internal error while attempting to construct type ["
+ + m_classname
+ + "]";
+ throw new BuildException( error, e, getLocation() );
+ }
+ }
+
+ private String getEmbeddedResourcePath( Class subject )
+ {
+ String classname = subject.getName();
+ String path = classname.replace( '.', '/' );
+ String filename = path + ".type";
+ return filename;
+ }
+
+ private File getEmbeddedOutputFile( String filename )
+ {
+ File classes = getContext().getClassesDirectory();
+ File destination = new File( classes, filename );
+ return destination;
+ }
+
+ //---------------------------------------------------------------
+ // internals
+ //---------------------------------------------------------------
+
+ protected String getName()
+ {
+ if( null == m_name )
+ {
+ return "untitled";
+ }
+ return m_name;
+ }
+
+ protected String getClassname()
+ {
+ if( null == m_classname )
+ {
+ final String error =
+ "Component type does not declare a classname.";
+ throw new BuildException( error, getLocation() );
+ }
+ return m_classname;
+ }
+
+ private InfoDescriptor createInfoDescriptor( Class subject )
+ {
+ String classname = subject.getName();
+ String name = getName();
+ return new InfoDescriptor( name, classname );
+ }
+
+ /**
+ * If the class contains an inner class named "Dependencies" then
+ * resolve the key/inteterface clasname pairs based on the inner class
+ * method names.
+ * @param subject the component implmentation class
+ * @return an array of dependency descriptors
+ */
+ private DependencyDescriptor[] createDependencyDescriptors( Class
subject ) throws IntrospectionException
+ {
+ String classname = subject.getName();
+ Class[] classes = subject.getClasses();
+ Class dependencies = locateClass( "$Dependencies", classes );
+ if( null == dependencies )
+ {
+ return new DependencyDescriptor[0];
+ }
+ else
+ {
+ ArrayList list = new ArrayList();
+ Method[] methods = dependencies.getMethods();
+ for( int i=0; i<methods.length; i++ )
+ {
+ Method method = methods[i];
+ DependencyDescriptor dep = createDependencyDescriptor(
method );
+ list.add( dep );
+ }
+ return (DependencyDescriptor[]) list.toArray( new
DependencyDescriptor[0] );
+ }
+ }
+
+ private DependencyDescriptor createDependencyDescriptor( Method method )
throws IntrospectionException
+ {
+ validateMethodName( method );
+ Class returnType = method.getReturnType();
+ validateNonNullReturnType( method, returnType );
+ validateNonArrayReturnType( method, returnType );
+ validateInterfaceReturnType( method, returnType );
+ validateNoExceptions( method );
+ validateNoParameters( method );
+
+ String key = method.getName().substring( 3 );
+ String type = returnType.getName();
+ return new DependencyDescriptor( key, type );
+ }
+
+ private ServiceDescriptor[] createServiceDescriptors( Class subject )
+ {
+ ArrayList list = new ArrayList();
+ Class[] interfaces = subject.getInterfaces();
+ for( int i=0; i<interfaces.length; i++ )
+ {
+ Class service = interfaces[i];
+ ServiceDescriptor descriptor = createServiceDescriptor( service
);
+ if( null != descriptor )
+ {
+ list.add( descriptor );
+ }
+ }
+ return (ServiceDescriptor[]) list.toArray( new ServiceDescriptor[0]
);
+ }
+
+ public ServiceDescriptor createServiceDescriptor( Class subject )
+ {
+ String type = subject.getName();
+ if( type.startsWith( "java." ) )
+ {
+ return null; // ignore java.* interfaces
+ }
+ else
+ {
+ return new ServiceDescriptor( type );
+ }
+ }
+
+ private PartDescriptor[] createPartDescriptors( Class subject )
+ throws IntrospectionException
+ {
+ String classname = subject.getName();
+ Class[] classes = subject.getClasses();
+ Class parts = locateClass( "$Parts", classes );
+ if( null == parts )
+ {
+ return new PartDescriptor[0];
+ }
+ else
+ {
+ //
+ // For each method in the Parts interface we construct a part
+ // descriptor that establishes the part key and type.
+ //
+
+ Method[] methods = parts.getMethods();
+ ArrayList list = new ArrayList();
+ for( int i=0; i<methods.length; i++ )
+ {
+ Method method = methods[i];
+ PartDescriptor descriptor = createPartDescriptor( method );
+ list.add( descriptor );
+ }
+ return (PartDescriptor[]) list.toArray( new PartDescriptor[0] );
+ }
+ }
+
+ /**
+ * Creation of a new part descriptor using a supplied method and a part
builder.
+ * The method is the method used by the component implementation to get
the part
+ * runtime instance. The part builder establishes the deployment
solution for the
+ * part implementation.
+ */
+ private PartDescriptor createPartDescriptor( Method method )
+ throws IntrospectionException
+ {
+ String name = method.getName();
+ validateNoExceptions( method );
+ if( name.startsWith( "get" ) )
+ {
+ validateNoParameters( method );
+ Class returnType = method.getReturnType();
+ validateNonNullReturnType( method, returnType );
+ validateNonArrayReturnType( method, returnType );
+ String key = getPartKey( method, "get" );
+ String type = returnType.getName();
+ return new PartDescriptor( key, type, PartDescriptor.GET );
+ }
+ else if( name.startsWith( "create" ) )
+ {
+ validateNoParameters( method );
+ Class returnType = method.getReturnType();
+ validateNonNullReturnType( method, returnType );
+ validateNonArrayReturnType( method, returnType );
+ String key = getPartKey( method, "create" );
+ String type = returnType.getName();
+ return new PartDescriptor( key, type, PartDescriptor.CREATE );
+ }
+ else if( name.startsWith( "release" ) )
+ {
+ if( method.getParameterTypes().length == 1 )
+ {
+ Class[] params = method.getParameterTypes();
+ Class param = params [0];
+ Class returnType = method.getReturnType();
+ validateNullReturnType( method, returnType );
+ validateNonArrayType( method, param );
+ String key = getPartKey( method, "create" );
+ String type = param.getName();
+ return new PartDescriptor( key, type, PartDescriptor.RELEASE
);
+ }
+ else
+ {
+ final String error =
+ "The parts release method ["
+ + name
+ + "] does not declare a recognized pattern - no release
parameter was found.";
+ throw new IntrospectionException( error );
+ }
+ }
+ else
+ {
+ final String error =
+ "Part method ["
+ + name
+ + "] does not match the recognized 'get', 'create' or
'release' patterns.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private ParameterDescriptor[] createParameterDescriptors( Class subject
)
+ throws IntrospectionException
+ {
+ String classname = subject.getName();
+ Class[] classes = subject.getClasses();
+ Class param = locateClass( "$Parameters", classes );
+ if( null == param )
+ {
+ return new ParameterDescriptor[0];
+ }
+ else
+ {
+ //
+ // For each method in the Parameters interface we construct a
parameter
+ // descriptor that establishes the part key, type, and required
status.
+ //
+
+ Method[] methods = param.getMethods();
+ ArrayList list = new ArrayList();
+ for( int i=0; i<methods.length; i++ )
+ {
+ Method method = methods[i];
+ ParameterDescriptor descriptor = createParameterDescriptor(
method );
+ list.add( descriptor );
+ }
+ return (ParameterDescriptor[]) list.toArray( new
ParameterDescriptor[0] );
+ }
+ }
+
+ /**
+ * Creation of a new parameter descriptor using a supplied method.
+ * The method is the method used by the component implementation to get
the parameter
+ * instance.
+ */
+ private ParameterDescriptor createParameterDescriptor( Method method )
+ throws IntrospectionException
+ {
+ validateMethodName( method );
+ validateNoExceptions( method );
+
+ String key = getPartKey( method );
+
+ Class returnType = method.getReturnType();
+ if( method.getParameterTypes().length == 0 )
+ {
+ validateNonNullReturnType( method, returnType );
+ validateNonArrayReturnType( method, returnType );
+ String type = returnType.getName();
+ return new ParameterDescriptor( key, type,
ParameterDescriptor.REQUIRED );
+ }
+ else if( method.getParameterTypes().length == 1 )
+ {
+ Class[] params = method.getParameterTypes();
+ Class param = params[0];
+ if( returnType.isAssignableFrom( param ) )
+ {
+ String type = param.getName();
+ return new ParameterDescriptor( key, type,
ParameterDescriptor.OPTIONAL );
+ }
+ else
+ {
+ final String error =
+ "Parameter asessor declares an optional default parameter
class ["
+ + param.getName()
+ + "] which is not assignable to the return type ["
+ + returnType.getName()
+ + "]";
+ throw new IntrospectionException( error );
+ }
+ }
+ else
+ {
+ final String error =
+ "Unable to establish a required or optional parameter method
pattern on the method ["
+ + method.getName()
+ + "]";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private String getPartKey( Method method )
+ {
+ return getPartKey( method, "get" );
+ }
+
+ private String getPartKey( Method method, String prefix )
+ {
+ String name = method.getName();
+ String key = name.substring( prefix.length() );
+ return key;
+ }
+
+ private Class locateClass( String postfix, Class[] classes )
+ {
+ for( int i=0; i<classes.length; i++ )
+ {
+ Class inner = classes[i];
+ String name = inner.getName();
+ if( name.endsWith( postfix ) )
+ {
+ return inner;
+ }
+ }
+ return null;
+ }
+
+ private void validateNonNullReturnType( Method method, Class returnType
) throws IntrospectionException
+ {
+ if( Void.TYPE.equals( returnType ) )
+ {
+ final String error =
+ "Method ["
+ + method.getName()
+ + "] does not declare a return type.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private void validateNullReturnType( Method method, Class returnType )
throws IntrospectionException
+ {
+ if( false == Void.TYPE.equals( returnType ) )
+ {
+ final String error =
+ "Method ["
+ + method.getName()
+ + "] does not declare a null return type.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private void validateNonArrayReturnType( Method method, Class returnType
) throws IntrospectionException
+ {
+ if( null != returnType.getComponentType() )
+ {
+ final String error =
+ "Method ["
+ + method.getName()
+ + "] declares an array return type.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private void validateNonArrayType( Method method, Class type ) throws
IntrospectionException
+ {
+ if( null != type.getComponentType() )
+ {
+ final String error =
+ "Method ["
+ + method.getName()
+ + "] declares an array type.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private void validateInterfaceReturnType( Method method, Class
returnType ) throws IntrospectionException
+ {
+ if( returnType.isInterface() == false )
+ {
+ final String error =
+ "Method ["
+ + method.getName()
+ + "] declares a return type ["
+ + returnType.getName()
+ + "] that is not an interface.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private void validateMethodName( Method method ) throws
IntrospectionException
+ {
+ if( method.getName().startsWith( "get" ) == false )
+ {
+ final String error =
+ "Method ["
+ + method.getName()
+ + "] does not start with 'get'.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private void validateNoExceptions( Method method ) throws
IntrospectionException
+ {
+ Class[] exceptionTypes = method.getExceptionTypes();
+ if( exceptionTypes.length > 0 )
+ {
+ final String error =
+ "Method ["
+ + method.getName()
+ + "] declares one or more exceptions.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private void validateNoParameters( Method method ) throws
IntrospectionException
+ {
+ Class[] parameterTypes = method.getParameterTypes();
+ if( parameterTypes.length > 0 )
+ {
+ final String error =
+ "Method ["
+ + method.getName()
+ + "] declares one or more parameters.";
+ throw new IntrospectionException( error );
+ }
+ }
+
+ private Class loadSubjectClass( ClassLoader classloader )
+ {
+ if( null == m_classname )
+ {
+ final String error =
+ "Missing component descriptor class attribute.";
+ throw new IllegalStateException( error );
+ }
+ try
+ {
+ return classloader.loadClass( m_classname );
+ }
+ catch( ClassNotFoundException e )
+ {
+ final String error =
+ "Component class reference ["
+ + m_classname
+ + "] is not present in the project path.";
+ throw new BuildException( error );
+ }
+ }
+
+ private static URI TYPE_HANDLER_URI = setupURI( "@TYPE-HANDLER-URI@" );
+ private static URI TYPE_BUILDER_URI = setupURI( "@TYPE-BUILDER-URI@" );
+
+ protected static URI setupURI( String spec )
+ {
+ try
+ {
+ return new URI( spec );
+ }
+ catch( URISyntaxException ioe )
+ {
+ return null;
+ }
+ }
+}

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeNotFoundException.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeNotFoundException.java
Wed Mar 23 19:08:48 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.composition.builder;
+
+/**
+ * Exception thrown when an attempt is made to reference an unknown catalog
entry.
+ *
+ * @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 TypeNotFoundException extends Exception
+{
+ private String m_classname;
+
+ public TypeNotFoundException( String classname )
+ {
+ super( classname );
+ m_classname = classname;
+ }
+
+ public String getClassname()
+ {
+ return m_classname;
+ }
+
+}
+

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeWriterTask.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeWriterTask.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,150 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.net.URI;
+
+import net.dpml.meta.info.Type;
+import net.dpml.meta.info.builder.impl.TypeBuilder;
+import net.dpml.meta.info.writer.impl.XMLTypeWriter;
+
+import net.dpml.parameters.Parameters;
+
+import net.dpml.magic.model.Policy;
+import net.dpml.magic.model.Definition;
+import net.dpml.magic.project.Context;
+import net.dpml.magic.tasks.ProjectTask;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * The TypeTask creates a serialized descriptor of a component type.
+ *
+ * @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 TypeWriterTask extends ProjectTask
+{
+ //---------------------------------------------------------------
+ // state
+ //---------------------------------------------------------------
+
+ private String m_classname;
+
+ //---------------------------------------------------------------
+ // setters
+ //---------------------------------------------------------------
+
+ public void setClass( String classname )
+ {
+ m_classname = classname;
+ }
+
+ //---------------------------------------------------------------
+ // Task
+ //---------------------------------------------------------------
+
+ public void execute()
+ {
+ Project project = getProject();
+ Path path = getDefinition().getPath( project, Policy.RUNTIME );
+ File classes = getContext().getClassesDirectory();
+ path.createPathElement().setLocation( classes );
+ ClassLoader classloader = new AntClassLoader( project, path );
+ Class subject = loadSubjectClass( classloader );
+
+ TypeBuilder typeBuilder = new TypeBuilder();
+
+ try
+ {
+ Type type = typeBuilder.buildType( subject );
+ if( null == type )
+ {
+ final String error =
+ "Unable to locate the type [" + getClassname() + "]";
+ throw new BuildException( error, getLocation() );
+ }
+ XMLTypeWriter writer = new XMLTypeWriter();
+ writer.writeType( type, System.out );
+ }
+ catch( Exception e )
+ {
+ final String error =
+ "Internal error while attempting list type.";
+ throw new BuildException( error, e, getLocation() );
+ }
+ }
+
+ //---------------------------------------------------------------
+ // internals
+ //---------------------------------------------------------------
+
+ protected String getClassname()
+ {
+ if( null == m_classname )
+ {
+ final String error =
+ "Task does does not declare a 'class' attribute.";
+ throw new BuildException( error, getLocation() );
+ }
+ return m_classname;
+ }
+
+ private Class locateClass( String postfix, Class[] classes )
+ {
+ for( int i=0; i<classes.length; i++ )
+ {
+ Class inner = classes[i];
+ String name = inner.getName();
+ if( name.endsWith( postfix ) )
+ {
+ return inner;
+ }
+ }
+ return null;
+ }
+
+ private Class loadSubjectClass( ClassLoader classloader )
+ {
+ if( null == m_classname )
+ {
+ final String error =
+ "Missing component descriptor class attribute.";
+ throw new IllegalStateException( error );
+ }
+ try
+ {
+ return classloader.loadClass( m_classname );
+ }
+ catch( ClassNotFoundException e )
+ {
+ final String error =
+ "Component class reference ["
+ + m_classname
+ + "] is not present in the project path.";
+ throw new BuildException( error );
+ }
+ }
+}

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypesTask.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypesTask.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,198 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.Serializable;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URI;
+import java.rmi.MarshalledObject;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.ArrayList;
+
+import net.dpml.meta.info.Type;
+
+import net.dpml.builder.IntrospectionException;
+
+import net.dpml.magic.tasks.ProjectTask;
+import net.dpml.magic.model.Policy;
+import net.dpml.magic.model.Definition;
+import net.dpml.magic.model.Resource;
+import net.dpml.magic.model.ResourceRef;
+import net.dpml.magic.project.Context;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DynamicElementNS;
+
+/**
+ * Task that handles the construction of catalogof type entries.
+ *
+ * @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 TypesTask extends ProjectTask implements DynamicElementNS
+{
+ private List m_builders = new LinkedList();
+
+ public TypeBuilder createType()
+ {
+ Project project = getProject();
+ TypeBuilderTask builder = new TypeBuilderTask();
+ builder.setTaskName( "type" );
+ builder.setProject( project );
+ m_builders.add( builder );
+ return builder;
+ }
+
+ /**
+ * Operation used to construct a custom part type directive.
+ * @param uri the part handler uri
+ * @param name the element name
+ * @param qualified the qualified name
+ */
+ public Object createDynamicElement( String uri, String name, String
qualified )
+ {
+ String path = getProject().replaceProperties( uri );
+ TypeBuilder builder = loadTypeBuilder( path, name );
+ if( null != builder )
+ {
+ m_builders.add( builder );
+ }
+ return builder;
+ }
+
+ public void execute()
+ {
+ Project project = getProject();
+ Path path = getDefinition().getPath( project, Policy.RUNTIME );
+ File classes = getContext().getClassesDirectory();
+ path.createPathElement().setLocation( classes );
+ ClassLoader classloader = new AntClassLoader( project, path );
+ buildTypes( classloader );
+ }
+
+ private void buildTypes( ClassLoader classloader )
+ {
+ TypeBuilder[] builders = (TypeBuilder[]) m_builders.toArray( new
TypeBuilder[0] );
+ for( int i=0; i<builders.length; i++ )
+ {
+ TypeBuilder builder = builders[i];
+ if( builder instanceof Task )
+ {
+ ((Task)builder).setTaskName( "type" );
+ }
+
+ URI strategy = builder.getTypeHandlerURI();
+
+ try
+ {
+ Type type = builder.buildType( classloader );
+ String classname = type.getInfo().getClassname();
+ String resource = getEmbeddedResourcePath( classname );
+ File file = getEmbeddedOutputFile( resource );
+ SerializableObjectHelper.write( type, file );
+ }
+ catch( Exception e )
+ {
+ final String error =
+ "Internal error while attempting to build types.";
+ throw new BuildException( error, e, getLocation() );
+ }
+ }
+ }
+
+ private String getEmbeddedResourcePath( String classname )
+ {
+ String path = classname.replace( '.', '/' );
+ String filename = path + ".type";
+ return filename;
+ }
+
+ private File getEmbeddedOutputFile( String filename )
+ {
+ File classes = getContext().getClassesDirectory();
+ File destination = new File( classes, filename );
+ return destination;
+ }
+
+ private TypeBuilder loadTypeBuilder( String uri, String name ) throws
BuildException
+ {
+ String urn = uri + ":" + name;
+ Object builder = null;
+ TypeBuilder typeBuilder = null;
+ ClassLoader context = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ Thread.currentThread().setContextClassLoader(
getClass().getClassLoader() );
+ Project project = getProject();
+ builder = project.createDataType( urn );
+ typeBuilder = (TypeBuilder) builder;
+ return typeBuilder ;
+ }
+ catch( ClassCastException e )
+ {
+ final String error =
+ "The custom type builder ["
+ + builder.getClass().getName()
+ + "] established by the uri ["
+ + urn
+ + "] declared by the element <"
+ + name
+ + "' does not implement the net.dpml.metro.builder.TypeBuilder
interface.";
+ throw new BuildException( error, e, getLocation() );
+ }
+ catch( BuildException e )
+ {
+ final String error =
+ "Unable to load the plugin from the uri ["
+ + urn
+ + "] to handle the custom type declared by the element <"
+ + name
+ + ">.";
+ throw new BuildException( error, e, getLocation() );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected exception while attempting to load the custom type
handler with the uri ["
+ + urn
+ + "] declared by the element <"
+ + name
+ + ">.";
+ throw new BuildException( error, e, getLocation() );
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( context );
+ }
+ }
+}

Added:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/antlib.xml
==============================================================================
--- (empty file)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/antlib.xml
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+
+<antlib>
+ <taskdef name="type"
classname="net.dpml.composition.builder.TypeBuilderTask"/>
+ <taskdef name="type-writer"
classname="net.dpml.composition.builder.TypeWriterTask"/>
+ <taskdef name="types" classname="net.dpml.composition.builder.TypesTask"/>
+ <taskdef name="container"
classname="net.dpml.composition.builder.ContainerBuilderTask"/>
+ <taskdef name="component"
classname="net.dpml.composition.builder.ComponentBuilderTask"/>
+</antlib>

Added: development/main/metro/composition/control/build.xml
==============================================================================
--- (empty file)
+++ development/main/metro/composition/control/build.xml Wed Mar 23
19:08:48 2005
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="dpml-composition-control" default="install" basedir="."
+ xmlns:transit="antlib:net.dpml.transit"
xmlns:x="plugin:dpml/magic/dpml-magic-core" >
+
+ <transit:import uri="artifact:template:dpml/magic/standard"/>
+
+ <target name="init" depends="standard.init">
+ <x:property key="dpml-composition-builder" feature="uri" type="plugin"
name="builder.plugin"/>
+ <x:property feature="uri" type="plugin" name="control.plugin"/>
+ <filter token="PART-BUILDER-URI" value="${builder.plugin}"/>
+ <filter token="PART-HANDLER-URI" value="${control.plugin}"/>
+ <filter token="PART-CONTROLLER-URI" value="${control.plugin}"/>
+ </target>
+
+ <target name="package" depends="standard.package">
+ <x:export class="net.dpml.composition.control.CompositionController"/>
+ </target>
+
+</project>

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,150 @@
+/*
+ * 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.control;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.io.IOException;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.WeakHashMap;
+
+import net.dpml.part.Part;
+
+import net.dpml.control.PartHandler;
+import net.dpml.control.Controller;
+import net.dpml.control.Monitor;
+import net.dpml.control.Model;
+import net.dpml.control.DuplicateNameException;
+import net.dpml.control.UnsupportedPartTypeException;
+import net.dpml.control.DelegationException;
+import net.dpml.control.HandlerNotFoundException;
+import net.dpml.control.PartNotFoundException;
+
+/**
+ * A initial test controller.
+ *
+ * @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 CompositionController extends CompositionPartHandler implements
Controller
+{
+ //--------------------------------------------------------------------
+ // state
+ //--------------------------------------------------------------------
+
+ private final Monitor m_monitor;
+
+ //--------------------------------------------------------------------
+ // constructor
+ //--------------------------------------------------------------------
+
+ public CompositionController( Monitor monitor )
+ {
+ super();
+ m_monitor = monitor;
+ }
+
+ //--------------------------------------------------------------------
+ // PartHandler
+ //--------------------------------------------------------------------
+
+ /**
+ * Load the model controller.
+ * @return the controller
+ */
+ public Controller getController()
+ {
+ return this;
+ }
+
+ //--------------------------------------------------------------------
+ // Controller
+ //--------------------------------------------------------------------
+
+ public String getName()
+ {
+ return "controller";
+ }
+
+ /**
+ * Return a management view of a part.
+ * @param part the part to present
+ * @return the management view
+ */
+ public Model getModel( Part part ) throws DelegationException
+ {
+ URI uri = part.getPartHandlerURI();
+ if( getURI().equals( uri ) )
+ {
+ return new ModelPerspective( part );
+ }
+ else
+ {
+ try
+ {
+ PartHandler handler = loadPartHandler( uri );
+ Controller controller = handler.getController();
+ return controller.getModel( part );
+ }
+ catch( HandlerNotFoundException e )
+ {
+ final String error =
+ "Requested part handler ["
+ + uri
+ + "] not found.";
+ throw new DelegationException( uri, error, e );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected error raised by delegate while requesting part
model.";
+ throw new DelegationException( uri, error, e );
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ // internal
+ //--------------------------------------------------------------------
+
+ protected Monitor getMonitor()
+ {
+ return m_monitor;
+ }
+
+ //--------------------------------------------------------------------
+ // static utilities
+ //--------------------------------------------------------------------
+
+ private static final URI CONTROLLER_URI = setupURI(
"@PART-CONTROLLER-URI@" );
+
+ protected static URI setupURI( String spec )
+ {
+ try
+ {
+ return new URI( spec );
+ }
+ catch( URISyntaxException ioe )
+ {
+ return null;
+ }
+ }
+}

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,149 @@
+/*
+ * 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.control;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.io.IOException;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.WeakHashMap;
+
+import net.dpml.part.Part;
+
+import net.dpml.control.SystemManager;
+import net.dpml.control.PartHandler;
+import net.dpml.control.Controller;
+import net.dpml.control.Monitor;
+import net.dpml.control.Model;
+import net.dpml.control.DuplicateNameException;
+import net.dpml.control.UnsupportedPartTypeException;
+import net.dpml.control.DelegationException;
+import net.dpml.control.HandlerNotFoundException;
+import net.dpml.control.PartNotFoundException;
+
+/**
+ * The CompositionManager is a top-level manager responsible for the
management
+ * of an arbitary collection of component models.
+ *
+ * @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 CompositionManager extends CompositionController implements
SystemManager
+{
+ //--------------------------------------------------------------------
+ // state
+ //--------------------------------------------------------------------
+
+ private final Set m_models = Collections.synchronizedSet( new HashSet()
);
+
+ //--------------------------------------------------------------------
+ // constructor
+ //--------------------------------------------------------------------
+
+ public CompositionManager()
+ {
+ this( new ConsoleMonitor( "metro", false ) );
+ }
+
+ public CompositionManager( Monitor monitor )
+ {
+ super( monitor );
+ }
+
+ //--------------------------------------------------------------------
+ // SystemManager
+ //--------------------------------------------------------------------
+
+ public String getName()
+ {
+ return "manager";
+ }
+
+ /**
+ * Add a part to the collection of parts managed by this controller.
+ *
+ * @param name the name identifying the part within the collection
+ * @param part the part to add
+ */
+ public Model addPart( URI uri )
+ throws IOException, DelegationException, PartNotFoundException
+ {
+ Part part = loadPart( uri );
+ return addPart( part );
+ }
+
+ /**
+ * Add a model to the management scope of the controller.
+ * @param model the model to add to the controller
+ */
+ public void addModel( Model model )
+ {
+ m_models.add( model );
+ }
+
+ public void start() throws Exception
+ {
+ throw new UnsupportedOperationException( "start" );
+ }
+
+ public void stop()
+ {
+ throw new UnsupportedOperationException( "stop" );
+ }
+
+ //--------------------------------------------------------------------
+ // extras
+ //--------------------------------------------------------------------
+
+ /**
+ * Return an array of managed parts.
+ * @return the parts array
+ */
+ public Model[] getManagedModels()
+ {
+ return (Model[]) m_models.toArray( new Model[0] );
+ }
+
+ /**
+ * Add a part to the collection of parts managed by this controller.
+ *
+ * @param name the name identifying the part within the collection
+ * @param part the part to add
+ */
+ private Model addPart( Part part )
+ throws DelegationException
+ {
+ Model model = getModel( part );
+ m_models.add( model );
+ return model;
+ }
+
+ public void list()
+ {
+ getMonitor().info( "listing models in the controller" );
+ Model[] models = getManagedModels();
+ for( int i=0; i<models.length; i++ )
+ {
+ Model model = models[i];
+ getMonitor().info( "model: " + model );
+ }
+ }
+}

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionPartHandler.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionPartHandler.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,258 @@
+/*
+ * 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.control;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.util.WeakHashMap ;
+import java.net.URI;
+import java.net.URL;
+
+import net.dpml.part.Part;
+import net.dpml.part.PartHolder;
+import net.dpml.part.BadStrategyException;
+
+import net.dpml.control.Controller;
+import net.dpml.control.PartNotFoundException;
+import net.dpml.control.PartHandler;
+import net.dpml.control.PartHandlerRuntimeException;
+import net.dpml.control.HandlerNotFoundException;
+import net.dpml.control.DelegationException;
+
+import net.dpml.transit.TransitException;
+import net.dpml.transit.artifact.Handler;
+import net.dpml.transit.repository.StandardLoader;
+
+/**
+ * Composition part handler.
+ *
+ * @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 abstract class CompositionPartHandler implements PartHandler
+{
+ /**
+ * Map containing the foreign part handlers. The map keys
+ * are the string representation of the handler uri. The entry is the
+ * handler.
+ */
+ private final WeakHashMap m_handlers = new WeakHashMap();
+
+ /**
+ * Transit repository handler used for resolving foreign handlers.
+ */
+ private final StandardLoader m_loader;
+
+ public CompositionPartHandler()
+ {
+ try
+ {
+ m_loader = new StandardLoader();
+ }
+ catch( TransitException e )
+ {
+ final String error =
+ "Internal error during handler initialization.";
+ throw new PartHandlerRuntimeException( error, e );
+ }
+ }
+
+ /**
+ * Returns the uri of this handler.
+ * @return the handler uri
+ */
+ public URI getURI()
+ {
+ return PART_HANDLER_URI;
+ }
+
+ /**
+ * Load the part controller.
+ * @return the controller
+ */
+ public abstract Controller getController();
+
+ /**
+ * Load a part from serialized form. The uri is assumed to be a uri that
+ * can be transformed to a URL from which an input stream to a PartHolder
+ * can be established. If the uri references a foreign part handler the
+ * implementation will attempt to locate and delegate part loading
requests
+ * to the foreign handler.
+ *
+ * @return the part estracted from the part handler referenced by the uri
+ */
+ public Part loadPart( URI uri )
+ throws PartNotFoundException, IOException, DelegationException
+ {
+ return loadSerializedPart( uri );
+ }
+
+ public Part loadPart( byte[] bytes ) throws IOException
+ {
+ try
+ {
+ ByteArrayInputStream input = new ByteArrayInputStream( bytes );
+ ObjectInputStream stream = new ObjectInputStream( input );
+ return (Part) stream.readObject();
+ }
+ catch( IOException e )
+ {
+ throw e;
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected error while attempting to load a part from a byte
array.";
+ throw new PartHandlerRuntimeException( error, e );
+ }
+ }
+
+ /**
+ * Load a part handler giiven a handler uri.
+ * @return the part handler
+ */
+ public PartHandler loadPartHandler( URI uri )
+ throws HandlerNotFoundException, DelegationException, IOException
+ {
+ if( false == getURI().equals( uri ) )
+ {
+ return resolvePartHandler( uri );
+ }
+ else
+ {
+ return this;
+ }
+ }
+
+ private Part loadSerializedPart( URI uri )
+ throws IOException, DelegationException, PartNotFoundException
+ {
+ URL url = resolveURL( uri );
+ InputStream input = url.openStream();
+ if( null == input )
+ {
+ throw new PartNotFoundException( uri );
+ }
+ ObjectInputStream stream = new ObjectInputStream( input );
+ try
+ {
+ PartHolder holder = (PartHolder) stream.readObject();
+ URI foreign = holder.getPartHandlerURI();
+ if( false == getURI().equals( foreign ) )
+ {
+ try
+ {
+ PartHandler handler = resolvePartHandler( uri );
+ return handler.loadPart( holder.getByteArray() );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Delegate raised an error while attempting to load a
serialized part ["
+ + uri
+ + "] using the external handler ["
+ + foreign
+ + "].";
+ throw new DelegationException( foreign, error, e );
+ }
+ }
+ else
+ {
+ return loadPart( holder.getByteArray() );
+ }
+ }
+ catch( IOException e )
+ {
+ throw e;
+ }
+ catch( DelegationException e )
+ {
+ throw e;
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Error loading part handler ["
+ + uri
+ + "].";
+ throw new PartHandlerRuntimeException( error, e );
+ }
+ }
+
+ private URL resolveURL( URI uri ) throws IOException
+ {
+ if( "artifact".equals( uri.getScheme() ) )
+ {
+ return new URL( null, uri.toString(), new Handler() );
+ }
+ else
+ {
+ return uri.toURL();
+ }
+ }
+
+ protected PartHandler resolvePartHandler( URI uri ) throws
HandlerNotFoundException, IOException
+ {
+ if( getURI().equals( uri ) )
+ {
+ return this;
+ }
+ String key = uri.toString();
+ synchronized( m_handlers )
+ {
+ PartHandler handler = (PartHandler) m_handlers.get( key );
+ if( null == handler )
+ {
+ handler = loadHandler( uri );
+ m_handlers.put( key, handler );
+ }
+ return handler;
+ }
+ }
+
+ private PartHandler loadHandler( URI uri ) throws
HandlerNotFoundException
+ {
+ ClassLoader classloader = PartHandler.class.getClassLoader();
+ ConsoleMonitor monitor = new ConsoleMonitor( "manager", true );
+ try
+ {
+ return (PartHandler) m_loader.getPlugin( classloader, uri, new
Object[]{ this, monitor } );
+ }
+ catch( IOException e )
+ {
+ throw new HandlerNotFoundException( uri, e );
+ }
+ }
+
+ private static final URI PART_HANDLER_URI = createStaticURI(
"@PART-HANDLER-URI@" );
+
+ private static URI createStaticURI( String path )
+ {
+ try
+ {
+ return new URI( path );
+ }
+ catch( Throwable e )
+ {
+ return null;
+ }
+ }
+}

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ConsoleMonitor.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ConsoleMonitor.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,110 @@
+/*
+ * 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.control;
+
+import net.dpml.control.Monitor;
+
+
+/**
+ * Monitor supplied to a startable controller.
+ *
+ * @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 ConsoleMonitor implements Monitor
+{
+ private String m_category;
+ private boolean m_debug;
+
+ public ConsoleMonitor( String category, boolean debug )
+ {
+ m_category = category;
+ m_debug = debug;
+ }
+
+ /**
+ * Log the supplied debug level message.
+ * @param mesage the message to log
+ */
+ public void debug( String message )
+ {
+ if( m_debug )
+ {
+ write( "DEBUG", message );
+ }
+ }
+
+ /**
+ * Log the supplied info level message.
+ * @param mesage the message to log
+ */
+ public void info( String message )
+ {
+ write( "INFO ", message );
+ }
+
+ /**
+ * Log the supplied info level message.
+ * @param mesage the message to log
+ */
+ public void warn( String message )
+ {
+ write( "WARN ", message );
+ }
+
+ /**
+ * Log the supplied error level message.
+ * @param mesage the message to log
+ * @param throwable the exception
+ */
+ public void error( String message, Throwable throwable )
+ {
+ write( "ERROR", message );
+ throwable.printStackTrace();
+ }
+
+ /**
+ * Log the monitor of a normal termination.
+ * @param status TRUE if the monitor completed all scheduled activities
+ * without interruption
+ */
+ public void notifyCompletion( boolean status )
+ {
+ debug( "completion notification (" + status + ")" );
+ }
+
+ /**
+ * Log the monitor of a runtime failure.
+ * @param throwable the failure cause
+ */
+ public void notifyFailure( Throwable throwable )
+ {
+ warn( "failure notification" );
+ throwable.printStackTrace();
+ }
+
+ /**
+ * Log the supplied debug level message.
+ * @param mesage the message to log
+ */
+ private void write( String level, String message )
+ {
+ System.out.println( "[" + level + "] (" + m_category + ") " +
message );
+ }
+}

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ModelPerspective.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ModelPerspective.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,53 @@
+/*
+ * 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.control;
+
+import java.io.Serializable;
+
+import net.dpml.part.Part;
+import net.dpml.control.Model;
+
+/**
+ * Implement of a view of a part presented as a managable 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 ModelPerspective implements Model, Serializable
+{
+ private final Part m_part;
+
+ private String m_name;
+
+ public ModelPerspective( Part part )
+ {
+ m_part = part;
+ }
+
+ public void setName( String name )
+ {
+ m_name = name;
+ // notify all part listerns of the name change
+ }
+
+ public String getName()
+ {
+ return m_name;
+ }
+}

Modified:
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultComponentModel.java
==============================================================================
---
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultComponentModel.java
(original)
+++
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultComponentModel.java
Wed Mar 23 19:08:48 2005
@@ -162,32 +162,14 @@

if ( isParameterizable() )
{
- Parameters staticDefaults = type.getParameters();
final Parameters parameters = profile.getParameters();
if ( parameters != null )
{
- if ( null == staticDefaults )
- {
- m_parameters = parameters;
- }
- else
- {
- DefaultParameters temp = new DefaultParameters();
- temp.merge( staticDefaults );
- temp.merge( parameters );
- m_parameters = temp;
- }
+ m_parameters = parameters;
}
else
{
- if ( null == staticDefaults )
- {
- m_parameters = DefaultParameters.EMPTY_PARAMETERS;
- }
- else
- {
- m_parameters = staticDefaults;
- }
+ m_parameters = DefaultParameters.EMPTY_PARAMETERS;
}
}


Modified:
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/Scanner.java
==============================================================================
---
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/Scanner.java
(original)
+++
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/Scanner.java
Wed Mar 23 19:08:48 2005
@@ -72,7 +72,7 @@
ResourceManager.getPackageResources( Scanner.class );

private static final String X_INFO = ".xinfo";
- private static final String X_TYPE = ".xtype";
+ private static final String X_TYPE = ".type";
private static final String X_SERVICE = ".xservice";
private static final String X_PROFILE = ".xprofile";


Added: development/main/metro/composition/testing/build.xml
==============================================================================
--- (empty file)
+++ development/main/metro/composition/testing/build.xml Wed Mar 23
19:08:48 2005
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="dpml-composition-testing" default="install" basedir="."
+ xmlns:transit="antlib:net.dpml.transit"
xmlns:x="plugin:dpml/magic/dpml-magic-core">
+
+ <transit:import uri="artifact:template:dpml/magic/standard"/>
+
+ <target name="build" depends="standard.build">
+
+ <!-- create the types -->
+ <types xmlns="plugin:dpml/composition/dpml-composition-builder">
+ <type class="net.dpml.composition.testing.DefaultWidget"/>
+ <type class="net.dpml.composition.testing.DefaultGizmo"/>
+ </types>
+
+ <!-- create a classic container model -->
+ <container xmlns="plugin:dpml/composition/dpml-composition-builder"
name="acme">
+ <component name="widget"
class="net.dpml.composition.testing.DefaultWidget"/>
+ <component name="gizmo"
class="net.dpml.composition.testing.DefaultGizmo">
+ <parameters>
+ <parameter name="width" value="789"/>
+ <parameter name="height" value="1024"/>
+ </parameters>
+ <dependencies>
+ <dependency key="widget" source="widget"/>
+ </dependencies>
+ <parts>
+ <component name="secret"
class="net.dpml.composition.testing.DefaultWidget"/>
+ </parts>
+ </component>
+ </container>
+
+ </target>
+
+ <!--
+ <target name="package" depends="standard.package">
+ <echo>Writing types</echo>
+ <type-writer class="net.dpml.composition.testing.DefaultWidget"
+ xmlns="plugin:dpml/composition/dpml-composition-builder"/>
+ <type-writer class="net.dpml.composition.testing.DefaultGizmo"
+ xmlns="plugin:dpml/composition/dpml-composition-builder"/>
+ <echo>Building block</echo>
+ </target>
+ -->
+
+</project>

Added:
development/main/metro/composition/testing/src/main/net/dpml/composition/testing/DefaultGizmo.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/src/main/net/dpml/composition/testing/DefaultGizmo.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2004 Stephen J. McConnell.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dpml.composition.testing;
+
+import net.dpml.logging.Logger;
+
+/**
+ * AbstractCompositionTestCase
+ * @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 DefaultGizmo implements Gizmo
+{
+ //------------------------------------------------------------------
+ // state
+ //------------------------------------------------------------------
+
+ private final Logger m_logger;
+ private final Widget m_widget;
+
+ //------------------------------------------------------------------
+ // facards
+ //------------------------------------------------------------------
+
+ public interface Dependencies
+ {
+ Widget getTheAcmeWidget();
+ }
+
+ public interface Parameters
+ {
+ int getWidth();
+
+ int getHeight( int defaultHeight );
+ }
+
+ public interface Parts
+ {
+ Widget createWidget();
+ Widget getWidget();
+ void releaseWidget( Widget widget );
+ }
+
+ //------------------------------------------------------------------
+ // constructor
+ //------------------------------------------------------------------
+
+ /**
+ * Creation of a new widget component.
+ *
+ * @param logger the logging channel assigned by the container
+ * @param dependencies the requested dependencies
+ */
+ public DefaultGizmo( Logger logger, Dependencies dependencies )
+ {
+ m_logger = logger;
+ m_widget = dependencies.getTheAcmeWidget();
+ m_logger.info( "up and running with: " + m_widget.toString() );
+ }
+}

Added:
development/main/metro/composition/testing/src/main/net/dpml/composition/testing/DefaultWidget.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/src/main/net/dpml/composition/testing/DefaultWidget.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2004 Stephen J. McConnell.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dpml.composition.testing;
+
+import net.dpml.logging.Logger;
+
+/**
+ * AbstractCompositionTestCase
+ * @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 DefaultWidget implements Widget
+{
+ //------------------------------------------------------------------
+ // state
+ //------------------------------------------------------------------
+
+ private final Logger m_logger;
+
+ //------------------------------------------------------------------
+ // constructor
+ //------------------------------------------------------------------
+
+ /**
+ * Creation of a new widget component.
+ *
+ * @param logger the logging channel asign by the container
+ */
+ public DefaultWidget( Logger logger )
+ {
+ m_logger = logger;
+ m_logger.info( "up and running" );
+ }
+}

Added:
development/main/metro/composition/testing/src/main/net/dpml/composition/testing/Gizmo.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/src/main/net/dpml/composition/testing/Gizmo.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+/**
+ * Sample gizmo service.
+ * @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 Gizmo
+{
+}

Added:
development/main/metro/composition/testing/src/main/net/dpml/composition/testing/Widget.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/src/main/net/dpml/composition/testing/Widget.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+/**
+ * Sample widget service.
+ * @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 Widget
+{
+}

Modified: development/main/metro/index.xml
==============================================================================
--- development/main/metro/index.xml (original)
+++ development/main/metro/index.xml Wed Mar 23 19:08:48 2005
@@ -3,6 +3,7 @@
<index key="dpml-metro">

<import uri="${dpml.transit.uri}"/>
+ <import uri="${dpml.magic.uri}"/>

<!--
Metro Modules
@@ -22,7 +23,50 @@
</dependencies>
</project>

- <!-- FROM PUBLIC INDEX -->
+ <!-- Automation -->
+
+ <project basedir="automation/part">
+ <info>
+ <group>dpml/automation</group>
+ <name>dpml-automation-part</name>
+ <version>1.0.0</version>
+ <status>SNAPSHOT</status>
+ <types>
+ <type>jar</type>
+ </types>
+ </info>
+ </project>
+
+ <project basedir="automation/control">
+ <info>
+ <group>dpml/automation</group>
+ <name>dpml-automation-control</name>
+ <version>1.0.0</version>
+ <status>SNAPSHOT</status>
+ <types>
+ <type>jar</type>
+ </types>
+ </info>
+ <dependencies>
+ <include key="dpml-automation-part"/>
+ </dependencies>
+ </project>
+
+ <project basedir="automation/builder">
+ <info>
+ <group>dpml/automation</group>
+ <name>dpml-automation-builder</name>
+ <version>1.0.0</version>
+ <status>SNAPSHOT</status>
+ <types>
+ <type>jar</type>
+ </types>
+ </info>
+ <dependencies>
+ <include key="dpml-automation-part"/>
+ <include key="dpml-automation-control"/>
+ </dependencies>
+ </project>

<!-- Activity -->

@@ -303,6 +347,7 @@
</types>
</info>
<dependencies>
+ <include key="dpml-automation-part"/>
<include key="dpml-transit-main"/>
<include key="dpml-meta-api"/>
<include key="dpml-util-i18n"/>
@@ -399,6 +444,65 @@
</dependencies>
</project>

+ <project basedir="composition/builder">
+ <info>
+ <group>dpml/metro/tools</group>
+ <name>dpml-composition-builder</name>
+ <version>1.0.0</version>
+ <status>SNAPSHOT</status>
+ <types>
+ <type>jar</type>
+ </types>
+ </info>
+ <dependencies>
+ <include key="dpml-meta-api"/>
+ <include key="dpml-meta-tools"/>
+ <include key="dpml-automation-builder"/>
+ <include key="dpml-magic-core"/>
+ <include key="dpml-logging-spi"/>
+ <include key="dpml-configuration-api"/>
+ <include key="dpml-configuration-impl"/>
+ <include key="dpml-parameters-api"/>
+ <include key="dpml-parameters-impl"/>
+ <include key="dpml-composition-api"/>
+ </dependencies>
+ </project>
+
+ <project basedir="composition/control">
+ <info>
+ <group>dpml/metro/private</group>
+ <name>dpml-composition-control</name>
+ <version>1.0.0</version>
+ <status>SNAPSHOT</status>
+ <types>
+ <type>jar</type>
+ </types>
+ </info>
+ <dependencies>
+ <include key="dpml-automation-control"/>
+ <include key="dpml-composition-impl"/>
+ </dependencies>
+ </project>
+
+ <project basedir="composition/testing">
+ <info>
+ <group>dpml/test</group>
+ <name>dpml-composition-testing</name>
+ <version>1.0.0</version>
+ <status>SNAPSHOT</status>
+ <types>
+ <type>jar</type>
+ <type>part</type>
+ </types>
+ </info>
+ <dependencies>
+ <include key="dpml-logging-api"/>
+ </dependencies>
+ <plugins>
+ <include key="dpml-composition-builder"/>
+ </plugins>
+ </project>
+
<!-- Utitlities -->

<project basedir="util/defaults">

Added:
development/main/metro/meta/api/src/main/net/dpml/meta/info/ParameterDescriptor.java
==============================================================================
--- (empty file)
+++
development/main/metro/meta/api/src/main/net/dpml/meta/info/ParameterDescriptor.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,197 @@
+/*
+ * 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.meta.info;
+
+import java.io.Serializable;
+
+/**
+ * A parameter descriptor identifies a key, return type and
+ * default value flag. All descriptors within a set must contain unique
+ * keys. Default value types must correspoind to the method return type.
+ * directive keys are established using the convention of removed 'get'
+ * and replacing the remaining first cahrater with the lowercase equivalent.
+ * For example, the method 'getHeight()' establishes the key 'height' and
+ * a require value status. The 'long getWidgth( long defaultWidgth )'
+ * method establish the 'width' key, the 'long' return type, and optional
+ * status.
+ *
+ * <source>
+ * public class DefaultWidget
+ * {
+ * public interface Parameters
+ * {
+ * int getHeight();
+ * long getWidgth( long defaultWidgth );
+ * }
+ *
+ * public DefaultWidget( Parameters parts )
+ * {
+ * // does stuff with the supplied parameters
+ * }
+ * }
+ *
+ * </source>
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: ReferenceDescriptor.java 1874 2005-02-22 17:47:49Z
mcconnell $
+ */
+public final class ParameterDescriptor
+ implements Serializable
+{
+ public static final boolean OPTIONAL= false;
+ public static final boolean REQUIRED = true;
+
+ /**
+ * The key.
+ */
+ private final String m_key;
+
+ /**
+ * The type classname (normally the return type).
+ */
+ private final String m_type;
+
+ /**
+ * The required status of the parameter.
+ */
+ private final boolean m_required;
+
+ /**
+ * Construct a parameter descriptor with the supplied key, type, usiung
+ * the default required status.
+ *
+ * @param key the key resolved from the method name
+ * @param type the argument type corresponding to the method return
+ * @exception NullPointerException if key or type is null
+ */
+ public ParameterDescriptor( final String key, final String type ) throws
NullPointerException
+ {
+ this( key, type, REQUIRED );
+ }
+
+ /**
+ * Construct a parameter descriptor with the supplied key, type, and
+ * required status flag.
+ *
+ * @param key the key resolved from the method name
+ * @param type the argument type corresponding to the method return
+ * @param required TRUE if required
+ * @exception NullPointerException if key or type is null
+ */
+ public ParameterDescriptor( final String key, final String type, boolean
required )
+ throws NullPointerException, IllegalArgumentException
+ {
+ if ( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
+ if ( null == type )
+ {
+ throw new NullPointerException( "type" );
+ }
+
+ m_key = key;
+ m_type = type;
+ m_required = required;
+ }
+
+ /**
+ * Return the key.
+ *
+ * @return the key
+ */
+ public String getKey()
+ {
+ return m_key;
+ }
+
+ /**
+ * Return the return type.
+ *
+ * @return the type classname
+ */
+ public String getType()
+ {
+ return m_type;
+ }
+
+ /**
+ * Return the required status of the parameter.
+ *
+ * @return the required status
+ */
+ public boolean isRequired()
+ {
+ return m_required;
+ }
+
+ /**
+ * Return the optional status of the parameter.
+ *
+ * @return the optional status
+ */
+ public boolean isOptional()
+ {
+ return ( !isRequired() );
+ }
+
+ /**
+ * Compare this object with another for equality.
+ * @param other the object to compare this object with
+ * @return TRUE if the supplied object is equal
+ */
+ public boolean equals( Object other )
+ {
+ boolean match = false;
+
+ if( false == ( other instanceof ParameterDescriptor ) )
+ {
+ return false;
+ }
+ else
+ {
+ ParameterDescriptor param = (ParameterDescriptor) other;
+ if( false == m_key.equals( param.getKey() ) )
+ {
+ return false;
+ }
+ else if( false == m_type.equals( param.getType() ) )
+ {
+ return false;
+ }
+ else
+ {
+ return ( m_required == param.isRequired() );
+ }
+ }
+ }
+
+ /**
+ * Returns the cashcode.
+ * @return the hascode value
+ */
+ public int hashCode()
+ {
+ int hash = m_key.hashCode();
+ hash ^= m_type.hashCode();
+ hash ^= new Boolean( m_required ).hashCode();
+ return hash;
+ }
+}

Added:
development/main/metro/meta/api/src/main/net/dpml/meta/info/PartDescriptor.java
==============================================================================
--- (empty file)
+++
development/main/metro/meta/api/src/main/net/dpml/meta/info/PartDescriptor.java
Wed Mar 23 19:08:48 2005
@@ -0,0 +1,194 @@
+/*
+ * 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.meta.info;
+
+import java.io.Serializable;
+
+/**
+ * A part descriptor identifies a key, access semantics and return type
+ * based on the method signatures within an internal Parts interface.
+ *
+ * <source>
+ * public class DefaultWidget
+ * {
+ * public interface Parts
+ * {
+ * Gizmo createGizmo();
+ * Gizmo getGizmo();
+ * void releaseGizmo( Gizmo gizmo );
+ * }
+ *
+ * public DefaultWidget( Parts parts )
+ * {
+ * // does stuff with the supplied parts
+ * }
+ * }
+ *
+ * </source>
+ *
+ * In the above example the Parts interface declares three directivesm each
containing
+ * the key 'gizmo', the Gizmo classname as the return type, and assigned with
+ * the CREATE_METHOD, GET_METHOD and RELEASE_METHOD semantics respectively.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: ReferenceDescriptor.java 1874 2005-02-22 17:47:49Z
mcconnell $
+ */
+public final class PartDescriptor
+ implements Serializable
+{
+ public static final int GET = 0;
+ public static final int CREATE = 1;
+ public static final int RELEASE = -1;
+
+ /**
+ * The key.
+ */
+ private final String m_key;
+
+ /**
+ * The type classname (normally the return type).
+ */
+ private final String m_type;
+
+ /**
+ * The method semantics flag - one of GET, CREATE or RELEASE.
+ */
+ private final int m_semantic;
+
+ /**
+ * Construct a part descriptor with the supplied key, type and default
get semantics.
+ *
+ * @param key the key resolved from the method name
+ * @param type the argument type corresponding to the method return type
+ * for get and create methods, and the single parameter for the
release method
+ * @param semantic the operation semantics ( GET, CREATE or RELEASE )
+ * @exception NullPointerException if key or type is null
+ */
+ public PartDescriptor( final String key, final String type ) throws
NullPointerException
+ {
+ this( key, type, GET );
+ }
+
+ /**
+ * Construct a part descriptor with the supplied key, type and semantic.
+ *
+ * @param key the key resolved from the method name
+ * @param type the argument type corresponding to the method return type
+ * for get and create methods, and the single parameter for the
release method
+ * @param semantic the operation semantics ( GET, CREATE or RELEASE )
+ * @exception NullPointerException if key or type is null
+ * @exception IllegalArgumentException if the semantic value is invalid
+ */
+ public PartDescriptor( final String key, final String type, int semantic
)
+ throws NullPointerException, IllegalArgumentException
+ {
+ if ( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
+ if ( null == type )
+ {
+ throw new NullPointerException( "type" );
+ }
+ if( ( semantic < RELEASE) || ( semantic > CREATE ) )
+ {
+ final String error =
+ "Semantic argument is out of range.";
+ throw new IllegalArgumentException( error );
+ }
+
+ m_key = key;
+ m_type = type;
+ m_semantic = semantic;
+ }
+
+ /**
+ * Return the key.
+ *
+ * @return the key
+ */
+ public String getKey()
+ {
+ return m_key;
+ }
+
+ /**
+ * Return the return type.
+ *
+ * @return the type classname
+ */
+ public String getType()
+ {
+ return m_type;
+ }
+
+ /**
+ * Return the semantics for the part reference.
+ *
+ * @return the semantic identifier
+ */
+ public int getSemantic()
+ {
+ return m_semantic;
+ }
+
+ /**
+ * Compare this object with another for equality.
+ * @param other the object to compare this object with
+ * @return TRUE if the supplied object is equal
+ */
+ public boolean equals( Object other )
+ {
+ boolean match = false;
+
+ if( false == ( other instanceof PartDescriptor ) )
+ {
+ return false;
+ }
+ else
+ {
+ PartDescriptor part = (PartDescriptor) other;
+ if( false == m_key.equals( part.getKey() ) )
+ {
+ return false;
+ }
+ else if( false == m_type.equals( part.getType() ) )
+ {
+ return false;
+ }
+ else
+ {
+ return m_semantic == part.getSemantic();
+ }
+ }
+ }
+
+ /**
+ * Returns the cashcode.
+ * @return the hascode value
+ */
+ public int hashCode()
+ {
+ int hash = m_key.hashCode();
+ hash ^= m_type.hashCode();
+ hash ^= m_semantic;
+ return hash;
+ }
+}

Modified:
development/main/metro/meta/api/src/main/net/dpml/meta/info/Type.java
==============================================================================
--- development/main/metro/meta/api/src/main/net/dpml/meta/info/Type.java
(original)
+++ development/main/metro/meta/api/src/main/net/dpml/meta/info/Type.java
Wed Mar 23 19:08:48 2005
@@ -53,8 +53,8 @@
private final ServiceDescriptor[] m_services;
private final DependencyDescriptor[] m_dependencies;
private final CategoryDescriptor[] m_loggers;
- private final Parameters m_parameters;
-
+ private final ParameterDescriptor[] m_parameters;
+ private final PartDescriptor[] m_parts;

/**
* Creation of a new Type instance using a supplied component descriptor,
@@ -80,7 +80,8 @@
final ServiceDescriptor[] services,
final DependencyDescriptor[] dependencies,
final Configuration defaults,
- final Parameters params )
+ final ParameterDescriptor[] params,
+ final PartDescriptor[] parts )
throws NullPointerException
{
if ( null == descriptor )
@@ -110,7 +111,24 @@
m_services = services;
m_dependencies = dependencies;
m_configuration = defaults;
- m_parameters = params;
+
+ if( null == params )
+ {
+ m_parameters = new ParameterDescriptor[0];
+ }
+ else
+ {
+ m_parameters = params;
+ }
+
+ if( null == parts )
+ {
+ m_parts = new PartDescriptor[0];
+ }
+ else
+ {
+ m_parts = parts;
+ }
}

/**
@@ -251,16 +269,26 @@
}

/**
- * Returns the default parameters supplied with the type.
+ * Returns the parameter descriptors for the type.
*
- * @return the default parameters or null if no packaged defaults
+ * @return the parameter descriptors
*/
- public Parameters getParameters()
+ public ParameterDescriptor[] getParameters()
{
return m_parameters;
}

/**
+ * Returns the part dependencies declared by this compoent type.
+ *
+ * @return the part descriptors
+ */
+ public PartDescriptor[] getParts()
+ {
+ return m_parts;
+ }
+
+ /**
* Return a string representation of the type.
* @return the stringified type
*/
@@ -297,16 +325,35 @@
return false;
}

- if( null == m_parameters )
+ if( m_parameters.length != t.m_parameters.length )
{
- if( ! ( null == t.m_parameters ) )
- return false;
+ return false;
}
else
{
- if( ! m_parameters.equals( t.m_parameters ) )
+ for( int i=0; i<m_parameters.length; i++ )
+ {
+ if( ! m_parameters[i].equals( t.m_parameters[i] ) )
+ {
+ return false;
+ }
+ }
+ }
+
+ if( m_parts.length != t.m_parts.length )
+ {
return false;
}
+ else
+ {
+ for( int i=0; i<m_parts.length; i++ )
+ {
+ if( ! m_parts[i].equals( t.m_parts[i] ) )
+ {
+ return false;
+ }
+ }
+ }

if( ! m_context.equals( t.m_context ) )
return false;
@@ -337,17 +384,20 @@
{
int hash = m_descriptor.hashCode();
hash ^= m_context.hashCode();
-
if( m_configuration != null )
{
hash ^= m_configuration.hashCode();
}
-
- if( m_parameters != null )
+ for( int i = 0; i < m_parameters.length; i++ )
{
- hash ^= m_parameters.hashCode();
+ hash ^= m_parameters[i].hashCode();
+ hash = hash - 163611323;
+ }
+ for( int i = 0; i < m_parts.length; i++ )
+ {
+ hash ^= m_parts[i].hashCode();
+ hash = hash - 163611323;
}
-
for( int i = 0; i < m_services.length; i++ )
{
hash ^= m_services[i].hashCode();
@@ -363,7 +413,6 @@
hash ^= m_loggers[i].hashCode();
hash = hash + 471312761;
}
-
return hash;
}
}

Modified:
development/main/metro/meta/api/src/test/net/dpml/meta/info/test/TypeTestCase.java
==============================================================================
---
development/main/metro/meta/api/src/test/net/dpml/meta/info/test/TypeTestCase.java
(original)
+++
development/main/metro/meta/api/src/test/net/dpml/meta/info/test/TypeTestCase.java
Wed Mar 23 19:08:48 2005
@@ -37,14 +37,14 @@
import net.dpml.meta.info.InfoDescriptor;
import net.dpml.meta.info.ReferenceDescriptor;
import net.dpml.meta.info.ServiceDescriptor;
+import net.dpml.meta.info.ParameterDescriptor;
+import net.dpml.meta.info.PartDescriptor;
import net.dpml.meta.info.Type;

import net.dpml.configuration.Configuration;

import net.dpml.configuration.impl.DefaultConfiguration;

-import net.dpml.parameters.Parameters;
-
import net.dpml.parameters.impl.DefaultParameters;


@@ -62,7 +62,8 @@
private ServiceDescriptor[] m_services;
private DependencyDescriptor[] m_dependencies;
private Configuration m_defaults;
- private Parameters m_parameters;
+ private ParameterDescriptor[] m_parameters;
+ private PartDescriptor[] m_parts;
private ReferenceDescriptor m_reference;
private String m_key;

@@ -87,24 +88,30 @@
m_dependencies = new DependencyDescriptor[] {
new DependencyDescriptor("role", m_reference)
};
+ m_parameters = new ParameterDescriptor[] {
+ new ParameterDescriptor( "key",
ReferenceDescriptor.class.getName() )
+ };
m_defaults = new DefaultConfiguration("default");
- m_parameters = DefaultParameters.EMPTY_PARAMETERS;
+ m_parts = new PartDescriptor[] {
+ new PartDescriptor( "key", ReferenceDescriptor.class.getName() )
+ };
}

private void checkType(Type type)
{
assertNotNull(type);
- checkArray(m_loggers, type.getCategories());
+ checkArray( m_loggers, type.getCategories());
assertEquals( m_defaults, type.getConfiguration() );
- assertEquals( m_parameters , type.getParameters() );
+ checkArray( m_parameters , type.getParameters() );
assertEquals( m_context, type.getContext());
- checkArray(m_dependencies, type.getDependencies());
- assertEquals(m_dependencies[0],
type.getDependency(m_dependencies[0].getKey()));
+ checkArray( m_dependencies, type.getDependencies());
+ assertEquals( m_dependencies[0],
type.getDependency(m_dependencies[0].getKey()));
assertEquals( m_descriptor, type.getInfo() );
assertEquals( m_services[0], type.getService(m_reference));
assertEquals( m_services[0], type.getService(
m_services[0].getReference().getClassname()));
- checkArray(m_services, type.getServices());
- assertTrue(type.isaCategory(m_loggers[0].getName()));
+ checkArray( m_services, type.getServices());
+ checkArray( m_parts, type.getParts());
+ assertTrue( type.isaCategory(m_loggers[0].getName()));
assertTrue( !type.isaCategory( "fake name" ) );
}

@@ -122,7 +129,7 @@
Type type =
new Type(
m_descriptor, m_loggers, m_context, m_services, m_dependencies,
- m_defaults, m_parameters );
+ m_defaults, m_parameters, m_parts );
checkType(type);
}

@@ -131,7 +138,7 @@
Type type =
new Type(
m_descriptor, m_loggers, m_context, m_services, m_dependencies,
- m_defaults, m_parameters );
+ m_defaults, m_parameters, m_parts );

checkType( type );


Modified:
development/main/metro/meta/impl/src/main/net/dpml/meta/info/builder/impl/TypeBuilder.java
==============================================================================
---
development/main/metro/meta/impl/src/main/net/dpml/meta/info/builder/impl/TypeBuilder.java
(original)
+++
development/main/metro/meta/impl/src/main/net/dpml/meta/info/builder/impl/TypeBuilder.java
Wed Mar 23 19:08:48 2005
@@ -147,19 +147,8 @@
// get the input stream for the .xtype resource
//

- String path =
- classname.replace( '.', '/' ) + ".xtype";
- InputStream inputStream =
- classLoader.getResourceAsStream( path );
-
- if( null == inputStream )
- {
- path =
- classname.replace( '.', '/' ) + ".xinfo";
- inputStream =
- classLoader.getResourceAsStream( path );
- }
-
+ String path = classname.replace( '.', '/' ) + ".xinfo";
+ InputStream inputStream = classLoader.getResourceAsStream( path );
if( null == inputStream )
{
final String message =
@@ -187,6 +176,7 @@
defaults = new DefaultConfiguration( "configuration", (String)
null );
}

+ /*
final String xparams =
classname.replace( '.', '/' ) + ".xparams";
final InputStream paramsStream =
@@ -213,12 +203,13 @@
{
params = null;
}
+ */

//
// build the type
//

- return xmlTypeFactory.createType( classname, xinfo, defaults, params
);
+ return xmlTypeFactory.createType( classname, xinfo, defaults );
}

private Configuration resolveConfiguration( ClassLoader classloader,
Configuration config )

Modified:
development/main/metro/meta/impl/src/main/net/dpml/meta/info/builder/impl/XMLTypeCreator.java
==============================================================================
---
development/main/metro/meta/impl/src/main/net/dpml/meta/info/builder/impl/XMLTypeCreator.java
(original)
+++
development/main/metro/meta/impl/src/main/net/dpml/meta/info/builder/impl/XMLTypeCreator.java
Wed Mar 23 19:08:48 2005
@@ -42,6 +42,8 @@
import net.dpml.meta.info.CategoryDescriptor;
import net.dpml.meta.info.ReferenceDescriptor;
import net.dpml.meta.info.ServiceDescriptor;
+import net.dpml.meta.info.ParameterDescriptor;
+import net.dpml.meta.info.PartDescriptor;
import net.dpml.meta.info.Type;

import net.dpml.meta.info.builder.BuildException;
@@ -49,8 +51,6 @@

import net.dpml.meta.info.impl.ConfigurationBuilder;

-import net.dpml.parameters.Parameters;
-
import org.xml.sax.InputSource;

/**
@@ -88,7 +88,7 @@

final InputSource input = new InputSource( inputStream );
final Configuration xinfo = ConfigurationBuilder.build( input );
- return createType( classname, xinfo, (Configuration) null, null );
+ return createType( classname, xinfo, (Configuration) null );
}

/**
@@ -105,25 +105,6 @@
final String classname, final Configuration info, final
Configuration defaults )
throws BuildException
{
- return createType( classname, info, defaults, null );
- }
-
- /**
- * Create an {@link Type} object for a specified classname from
- * specified configuration data.
- *
- * @param classname The classname of Component
- * @param info the Type configuration
- * @param defaults the default configuration
- * @param params the default static parameters
- * @return the created Type
- * @throws BuildException if an error occurs
- */
- public Type createType(
- final String classname, final Configuration info, final
Configuration defaults,
- Parameters params )
- throws BuildException
- {
final String topLevelName = info.getName();
if( !topLevelName.equals( "type" ) )
{
@@ -155,12 +136,18 @@
configuration = info.getChild( "services" );
final ServiceDescriptor[] services = buildServices( configuration );

+ configuration = info.getChild( "parameters" );
+ final ParameterDescriptor[] params = buildParameters( configuration
);
+
+ configuration = info.getChild( "parts" );
+ final PartDescriptor[] parts = buildParts( configuration );
+
configuration = info.getChild( "dependencies" );
final DependencyDescriptor[] dependencies =
buildDependencies( configuration );

return new Type(
- descriptor, loggers, context, services, dependencies, defaults,
params );
+ descriptor, loggers, context, services, dependencies, defaults,
params, parts );
}


@@ -452,4 +439,121 @@

return new ReferenceDescriptor( type, version );
}
+
+ /**
+ * A utility method to build an array of {@link ParameterDescriptor}
+ * objects from specified configuration.
+ *
+ * @param configuration the parameters configuration
+ * @return the created ParameterDescriptor
+ * @throws BuildException if an error occurs
+ */
+ public ParameterDescriptor[] buildParameters( final Configuration
configuration )
+ throws BuildException
+ {
+ final Configuration[] elements = configuration.getChildren(
"parameter" );
+ final ArrayList dependencies = new ArrayList();
+
+ for( int i = 0; i < elements.length; i++ )
+ {
+ final ParameterDescriptor param =
+ buildParameterDescriptor( elements[ i ] );
+ dependencies.add( param );
+ }
+
+ return (ParameterDescriptor[])dependencies.toArray( new
ParameterDescriptor[ 0 ] );
+ }
+
+ /**
+ * A utility method to build a {@link ParameterDescriptor}
+ * object from specified configuration.
+ *
+ * @param parameter the parameter configuration
+ * @return the created DependencyDescriptor
+ * @throws BuildException if an error occurs
+ */
+ protected ParameterDescriptor buildParameterDescriptor( final
Configuration config )
+ throws BuildException
+ {
+ try
+ {
+ String key = config.getAttribute( "key" );
+ String type = config.getAttribute( "type" );
+ boolean required = config.getAttributeAsBoolean( "required",
true );
+ return new ParameterDescriptor( key, type, required );
+ }
+ catch( ConfigurationException e )
+ {
+ final String error =
+ "Mallformed configuration - check usage of key, type and/or
required attributes.";
+ throw new BuildException( error, e );
+ }
+ }
+
+ /**
+ * A utility method to build an array of {@link ParameterDescriptor}
+ * objects from specified configuration.
+ *
+ * @param configuration the parameters configuration
+ * @return the created ParameterDescriptor
+ * @throws BuildException if an error occurs
+ */
+ public PartDescriptor[] buildParts( final Configuration configuration )
+ throws BuildException
+ {
+ final Configuration[] elements = configuration.getChildren( "part" );
+ final ArrayList list = new ArrayList();
+
+ for( int i = 0; i < elements.length; i++ )
+ {
+ final PartDescriptor param =
+ buildPartDescriptor( elements[ i ] );
+ list.add( param );
+ }
+
+ return (PartDescriptor[])list.toArray( new PartDescriptor[ 0 ] );
+ }
+
+ /**
+ * A utility method to build a {@link ParameterDescriptor}
+ * object from specified configuration.
+ *
+ * @param parameter the parameter configuration
+ * @return the created DependencyDescriptor
+ * @throws BuildException if an error occurs
+ */
+ protected PartDescriptor buildPartDescriptor( final Configuration config
)
+ throws BuildException
+ {
+ try
+ {
+ String key = config.getAttribute( "key" );
+ String type = config.getAttribute( "type" );
+ String semantic = config.getAttribute( "semantic", "get" );
+ if( "get".equals( semantic ) )
+ {
+ return new PartDescriptor( key, type, PartDescriptor.GET );
+ }
+ if( "create".equals( semantic ) )
+ {
+ return new PartDescriptor( key, type, PartDescriptor.CREATE
);
+ }
+ if( "release".equals( semantic ) )
+ {
+ return new PartDescriptor( key, type, PartDescriptor.RELEASE
);
+ }
+ else
+ {
+ final String error =
+ "Semantic keywork [" + semantic + "] not recognized.";
+ throw new BuildException( error );
+ }
+ }
+ catch( ConfigurationException e )
+ {
+ final String error =
+ "Mallformed configuration - check usage of key, type and/or
semantic attributes.";
+ throw new BuildException( error, e );
+ }
+ }
}

Modified:
development/main/metro/meta/spi/src/main/net/dpml/meta/info/builder/TypeFactory.java
==============================================================================
---
development/main/metro/meta/spi/src/main/net/dpml/meta/info/builder/TypeFactory.java
(original)
+++
development/main/metro/meta/spi/src/main/net/dpml/meta/info/builder/TypeFactory.java
Wed Mar 23 19:08:48 2005
@@ -47,18 +47,5 @@
Type createType( String path, Configuration xinfo, Configuration
defaults )
throws Exception;

- /**
- * Create a {@link Type} using a supplied type configuration and default
configuration
- *
- * @param path the class resource name of component type that we are
looking up
- * @param xinfo the configuration fragment for the type
- * @param defaults the configuration fragment for the default
configuration
- * @param params the default parameters
- * @return the newly created {@link Type}
- * @exception Exception if an error occurs
- */
- Type createType( String path, Configuration xinfo, Configuration
defaults, Parameters params )
- throws Exception;
-

}

Modified:
development/main/metro/meta/tools/src/main/net/dpml/meta/info/tags/TypeTag.java
==============================================================================
---
development/main/metro/meta/tools/src/main/net/dpml/meta/info/tags/TypeTag.java
(original)
+++
development/main/metro/meta/tools/src/main/net/dpml/meta/info/tags/TypeTag.java
Wed Mar 23 19:08:48 2005
@@ -27,6 +27,8 @@
import net.dpml.meta.info.InfoDescriptor;
import net.dpml.meta.info.CategoryDescriptor;
import net.dpml.meta.info.ServiceDescriptor;
+import net.dpml.meta.info.ParameterDescriptor;
+import net.dpml.meta.info.PartDescriptor;
import net.dpml.meta.info.Type;

import com.thoughtworks.qdox.model.DocletTag;
@@ -125,8 +127,15 @@
new DependencyTag( getJavaClass(), isNative() ).getDependencies();
final ContextDescriptor context = new ContextTag( getJavaClass(),
isNative() ).getContext();

+ //
+ // unsuppported elements
+ //
+
+ final ParameterDescriptor[] params = new ParameterDescriptor[0];
+ final PartDescriptor[] parts = new PartDescriptor[0];
+
return new Type(
- info, loggers, context, services, dependencies, null, null );
+ info, loggers, context, services, dependencies, null, params,
parts );
}

private String getName(DocletTag tag)



  • svn commit: r2122 - in development/main/metro: . automation automation/builder automation/builder/src automation/builder/src/main automation/builder/src/main/net automation/builder/src/main/net/dpml automation/builder/src/main/net/dpml/builder automation/control automation/control/src automation/control/src/main automation/control/src/main/net automation/control/src/main/net/dpml automation/control/src/main/net/dpml/control automation/part automation/part/src automation/part/src/main automation/part/src/main/net automation/part/src/main/net/dpml automation/part/src/main/net/dpml/part composition/api composition/api/src/main/net/dpml/composition/data composition/builder composition/builder/src composition/builder/src/main composition/builder/src/main/net composition/builder/src/main/net/dpml composition/builder/src/main/net/dpml/composition composition/builder/src/main/net/dpml/composition/builder composition/control composition/control/src composition/control/src/main composition/control/src/main/net composition/control/src/main/net/dpml composition/control/src/main/net/dpml/composition composition/control/src/main/net/dpml/composition/control composition/impl/src/main/net/dpml/composition/model/impl composition/testing composition/testing/src composition/testing/src/main composition/testing/src/main/net composition/testing/src/main/net/dpml composition/testing/src/main/net/dpml/composition composition/testing/src/main/net/dpml/composition/testing meta/api/src/main/net/dpml/meta/info meta/api/src/test/net/dpml/meta/info/test meta/impl/src/main/net/dpml/meta/info/builder/impl meta/spi/src/main/net/dpml/meta/info/builder meta/tools/src/main/net/dpml/meta/info/tags, mcconnell, 03/23/2005

Archive powered by MHonArc 2.6.24.

Top of Page