Author: kentam
Date: Mon Aug  9 00:49:13 2004
New Revision: 36096

Added:
   
incubator/beehive/trunk/controls/drt/controls/org/apache/beehive/controls/test/composition/NestedAssembler.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/ControlAssembler.java
      - copied, changed from rev 36052, 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssembler.java
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/ControlAssemblyContext.java
      - copied, changed from rev 36052, 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyContext.java
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/ControlAssemblyException.java
      - copied, changed from rev 36052, 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyException.java
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/DefaultControlAssembler.java
      - copied, changed from rev 36052, 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlAssembler.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/AssembleTask.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/Assembler.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/BaseAssemblyContext.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/EJBAssemblyContext.java
   (contents, props changed)
Removed:
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssembler.java
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyContext.java
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyException.java
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlAssembler.java
Modified:
   incubator/beehive/trunk/controls/drt/build.xml
   
incubator/beehive/trunk/controls/drt/controls/org/apache/beehive/controls/test/composition/NestedImpl.jcs
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlImplementation.java
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlChecker.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientManifest.java
Log:
Initial implementation of controls assembly.



Modified: incubator/beehive/trunk/controls/drt/build.xml
==============================================================================
--- incubator/beehive/trunk/controls/drt/build.xml      (original)
+++ incubator/beehive/trunk/controls/drt/build.xml      Mon Aug  9 00:49:13 2004
@@ -7,6 +7,8 @@
 
     <taskdef name="apt" 
classname="org.apache.beehive.controls.runtime.generator.AptTask" 
              classpath="../build/jars/controls.jar" onerror="report" />
+    <taskdef name="assemble" 
classname="org.apache.beehive.controls.runtime.assembly.AssembleTask" 
+             classpath="../build/jars/controls.jar" onerror="report" />
 
     <!-- New V9 DRT Domain specific properties -->
     <property name="test.root" location="${basedir}"/>
@@ -85,6 +87,18 @@
              classpathref="drt.classpath" 
              srcExtensions="*.java,*.jcx,*.jcs" >
         </apt>
+        <!-- Do control assembly. -->
+        <assemble moduleDir="${build.beans}"
+                  srcOutputDir="${build.beansrc}"
+                  
contextFactoryClassname="org.apache.beehive.controls.runtime.assembly.EJBAssemblyContext$Factory">
+            <classpath>
+                <path refid="drt.classpath"/>
+                <pathelement location="${build.beans}"/>
+            </classpath>
+            <fileset dir="${build.beans}">
+                <include name="**/*.controls.properties"/>
+            </fileset>
+        </assemble>
         <jar destfile="${build.jars}/drtbeans.jar"  basedir="${build.beans}" />
     </target>
 

Added: 
incubator/beehive/trunk/controls/drt/controls/org/apache/beehive/controls/test/composition/NestedAssembler.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/drt/controls/org/apache/beehive/controls/test/composition/NestedAssembler.java
     Mon Aug  9 00:49:13 2004
@@ -0,0 +1,17 @@
+package org.apache.beehive.controls.test.composition;
+
+import org.apache.beehive.controls.api.assembly.ControlAssembler;
+import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
+
+public class NestedAssembler implements ControlAssembler
+{
+    public void assemble( ControlAssemblyContext cac )
+    {
+        System.out.println( "NestedAssembler:" );
+        System.out.println( "    context type=" + cac.getClass().getName() );
+        System.out.println( "    module=" + cac.getModuleDir() );
+        System.out.println( "    control type=" + cac.getControlType() );
+        System.out.println( "    control default impl=" + 
cac.getDefaultImplClassName() );
+    }
+}
+

Modified: 
incubator/beehive/trunk/controls/drt/controls/org/apache/beehive/controls/test/composition/NestedImpl.jcs
==============================================================================
--- 
incubator/beehive/trunk/controls/drt/controls/org/apache/beehive/controls/test/composition/NestedImpl.jcs
   (original)
+++ 
incubator/beehive/trunk/controls/drt/controls/org/apache/beehive/controls/test/composition/NestedImpl.jcs
   Mon Aug  9 00:49:13 2004
@@ -5,7 +5,7 @@
 import org.apache.beehive.controls.api.bean.ControlImplementation;
 import org.apache.beehive.controls.api.events.Client;
 
[EMAIL PROTECTED]
[EMAIL PROTECTED]( assembler=NestedAssembler.class )
 public class NestedImpl implements Nested
 { 
     @Client Return  returnClient;

Copied: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/ControlAssembler.java
 (from rev 36052, 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssembler.java)
==============================================================================
--- 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssembler.java
 (original)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/ControlAssembler.java
     Mon Aug  9 00:49:13 2004
@@ -1,4 +1,4 @@
-package org.apache.beehive.controls.api.bean;
+package org.apache.beehive.controls.api.assembly;
 
 /*
  * Copyright 2004 The Apache Software Foundation.

Copied: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/ControlAssemblyContext.java
 (from rev 36052, 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyContext.java)
==============================================================================
--- 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyContext.java
   (original)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/ControlAssemblyContext.java
       Mon Aug  9 00:49:13 2004
@@ -1,4 +1,4 @@
-package org.apache.beehive.controls.api.bean;
+package org.apache.beehive.controls.api.assembly;
 
 /*
  * Copyright 2004 The Apache Software Foundation.
@@ -21,69 +21,125 @@
 import java.io.File;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.util.Map;
 
 /**
- * Control assemblers are passed a ControlAssemblyContext at the time they are 
invoked; the context
- * allows the assemblers to interact with their external environment (checking 
files, side-effecting
- * deployment descriptors, etc).
+ * Control assemblers are passed a ControlAssemblyContext at the time they are
+ * invoked; the context allows the assemblers to interact with their external
+ * environment (checking files, side-effecting deployment descriptors, emitting
+ * code parameterized by the specifics of the control extension, etc).
+ *
+ * Beehive provides ControlAssemblyContext implementations that expose the
+ * standard environments of J2EE applications and modules.  Vendor-specific
+ * implementations may provide access to their specific environment 
information,
+ * such as vendor-specific descriptors, via definition and implementation
+ * of additional interfaces.  ControlAssemblers should use reflection to
+ * determine if the ControlAssemblyContext implementation they are passed
+ * supports a particular set of environment features.
  */
 public interface ControlAssemblyContext
 {
     /**
-     * @return the control bean class
-     */
-    Class getControlBeanClass();
-
-    /**
-     * @return the control interface that the control bean implements
-     * (with annotation ControlExtension or ControlInterface)
-     */
-    Class getControlInterface();
-
-    /**
-     * @return the parent to the control interface that has the
-     * ControlInterface annotation (can return the same as
-     * getControlInterface() if the bean is an instance of a
-     * non-extended control)
+     * Providers of ControlAssemblyContext implementations MUST implement
+     * Factory and newInstance to return their implementation.
+     */ 
+    interface Factory
+    {
+        /**
+         * Creates a new instance of a ControlAssemblyContext implementation.
+         *
+         * @param controlIntfOrExt public interface/extension of the control
+         *                         type being assembled
+         * @param bindings map of control implementation bindings, null
+         *                 means use defaults.
+         * @param moduleRoot file root of the J2EE module containing the
+         *                   control clients to be assembled
+         * @param srcOutputRoot file root of a location where assemblers
+         *                      should output any sources they create that
+         *                      may need further processing before use.
+         * @return a new instance of a ControlAssemblyContext implementation
+         */
+        ControlAssemblyContext newInstance( Class controlIntfOrExt,
+                                            Map<String,String> bindings,
+                                            File moduleRoot,
+                                            File srcOutputRoot )
+            throws ControlAssemblyException;
+    }
+
+    /**
+     * Providers of ControlAssemblyContext implementations may implement
+     * EJBModule to provide access to an EJB module environment.
+     */
+    interface EJBModule
+    {
+        // TODO: Provide more abstract helpers for common tasks.
+        // E.g. addResourceRef().
+
+        File getEjbJarXml();
+    }
+
+    /**
+     * Providers of ControlAssemblyContext implementations may implement
+     * WebAppModule to provide access to a webapp module environment.
+     */
+    interface WebAppModule
+    {
+        File getWebXml();
+    }
+
+    /**
+     * Providers of ControlAssemblyContext implementations may implement
+     * EntAppModule to provide access to an enterprise application module
+     * environment.
+     */
+    interface EntAppModule
+    {
+        File getApplicationXml();
+    }
+
+    /**
+     * @return the interface type of the control being assembled (annotated
+     * w/ ControlExtension or ControlInterface)
+     */
+    Class getControlType();
+
+    /**
+     * @return the most derived interface of the control being assembled that
+     * is annotated with ControlInterface (may return the same as
+     * getControlType() if the control type is non-extended)
      */
-    Class getControlPublicInterface();
+    Class getMostDerivedControlInterface();
 
     /**
      * @return an annotation on the interface returned by
-     * getControlInterface()
+     * getControlType()
      */
     <T extends Annotation> T
         getControlAnnotation(Class<T> annotationClass);
 
     /**
      * @return an annotation on a method on the interface
-     * returned by getControlInterface()
+     * returned by getControlType()
      */
     <T extends Annotation> T
         getControlMethodAnnotation(Class<T> annotationClass, Method m)
             throws NoSuchMethodException;
 
     /**
-     * @return the defaultImpl member of the ControlInterface
-     * annotation on the interface returned by
-     * getControlPublicInterface() (or empty string if defaulted)
+     * @return the defaultBinding member of the ControlInterface
      */
     String getDefaultImplClassName();
 
     /**
-     * @return a File into which compilable source (.java) can be put.
-     * This will result in a file called resourceName.java (in the
-     * directory given by packageName).
-     * These files will be automatically compiled and the .class files
-     * so generated made available to the control client at runtime.
+     * @return a File into which Java source can be written.
+     * Results in a file called <className>.java (in the
+     * directory given by <packageName>).
      */
-    File createCompilableOutputFile(String packageName,
+    File createJavaOutputFile(String packageName,
         String className);
 
     /**
-     * @return the output directory (mostly for .class files but resource
-     * files can be put there too) which will be put on the referrer's
-     * classpath at runtime.
+     * @return the root of the module for which assembly is taking place.
      */
-    File getClassesOutputDir();
+    File getModuleDir();
 }

Copied: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/ControlAssemblyException.java
 (from rev 36052, 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyException.java)
==============================================================================
--- 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyException.java
 (original)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/ControlAssemblyException.java
     Mon Aug  9 00:49:13 2004
@@ -1,4 +1,4 @@
-package org.apache.beehive.controls.api.bean;
+package org.apache.beehive.controls.api.assembly;
 
 /*
  * Copyright 2004 The Apache Software Foundation.

Copied: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/DefaultControlAssembler.java
 (from rev 36052, 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlAssembler.java)
==============================================================================
--- 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlAssembler.java
  (original)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/assembly/DefaultControlAssembler.java
      Mon Aug  9 00:49:13 2004
@@ -1,4 +1,4 @@
-package org.apache.beehive.controls.api.bean;
+package org.apache.beehive.controls.api.assembly;
 /*
  * B E A   S Y S T E M S
  * Copyright 2001-2004  BEA Systems, Inc.
@@ -22,7 +22,7 @@
  * The default or "empty" control assembler that's assigned to an 
@ControlImplementation's
  * assembler attribute if none is provided.
  */
-public class DefaultControlAssembler implements ControlAssembler
+public final class DefaultControlAssembler implements ControlAssembler
 {
     public void assemble(ControlAssemblyContext cac) throws 
ControlAssemblyException { };
 }

Modified: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlImplementation.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlImplementation.java
    (original)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlImplementation.java
    Mon Aug  9 00:49:13 2004
@@ -23,6 +23,9 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.apache.beehive.controls.api.assembly.ControlAssembler;
+import org.apache.beehive.controls.api.assembly.DefaultControlAssembler;
+
 /**
  * The ControlImplementation annotation type is used to annotate the 
implementation class for a
  * Java Control.  It marks the class as a control implementation and (in the 
future) parameterizes

Modified: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlChecker.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlChecker.java
    (original)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlChecker.java
    Mon Aug  9 00:49:13 2004
@@ -25,7 +25,7 @@
  * The default or "empty" control checker that assigned to an 
@ControlInterface's
  * controlChecker attribute if none is provided.
  */
-public class DefaultControlChecker implements ControlChecker
+public final class DefaultControlChecker implements ControlChecker
 {
     public void check(Declaration decl, AnnotationProcessorEnvironment env) { 
};
 }

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/AssembleTask.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/AssembleTask.java
 Mon Aug  9 00:49:13 2004
@@ -0,0 +1,207 @@
+package org.apache.beehive.controls.runtime.assembly;
+
+/*
+ * Copyright 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.
+ *
+ * $Header:$
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.beehive.controls.runtime.generator.apt.ControlClientManifest;
+import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
+
+/**
+ * AssembleTask defines a custom ant task to perform control assembly.
+ */
+public class AssembleTask extends Task
+{
+    public AssembleTask()
+    {
+        // do nothing
+    }
+
+    public void setContextFactoryClassName(String contextFactoryClassName)
+    {
+        _contextFactoryClassName = contextFactoryClassName;
+    }
+
+    public void setModuleDir( File moduleDir )
+    {
+        _moduleDir = moduleDir;
+    }
+
+    public void setSrcOutputDir( File srcOutputDir )
+    {
+        _srcOutputDir = srcOutputDir;
+    }
+
+    public void setBindingFile(File bindingFile)
+    {
+        _bindingFile = bindingFile;
+    }
+
+    public FileSet createFileset()
+    {
+        _clientManifestFileSet = new FileSet();
+        return _clientManifestFileSet;
+    }
+
+    // used to set classpath as an attribute
+    public void setClasspath(Path classpath)
+    {
+        _classPath = new Path(getProject());
+        _classPath.append(classpath);
+    }
+
+    // used to set classpath as a nested element
+    public Path createClasspath()
+    {
+        _classPath = new Path(getProject());
+        return _classPath;
+    }
+
+    public void execute()
+    {
+        validateAttributeSettings();
+
+        if (_clientManifestFileSet == null)
+        {
+            log("No input fileset specified, nothing to do.");
+            return;
+        }
+
+        // get list of input files as list of ControlRefs files
+        File filesetDir = _clientManifestFileSet.getDir(getProject());
+        String[] clientManifests = _clientManifestFileSet.
+            getDirectoryScanner(getProject()).getIncludedFiles();
+
+        if (clientManifests.length == 0)
+        {
+            log("Input fileset contained no files, nothing to do.");
+            return;
+        }
+
+        List<File> manifestFiles = new ArrayList<File>();
+        for ( String mf : clientManifests )
+        {
+            File f = new File(filesetDir, mf );
+            if (!f.exists())
+            {
+                log("File " + f.getAbsolutePath() +
+                        " in input fileset does not exist.");
+                continue;
+            }
+
+            manifestFiles.add(f);
+        }
+
+        // REVIEW: nested control usage is handled poorly right now.
+        // Need to refine how we pick up control client manifests, especially
+        // for manifests inside control jars (instead of blindly scanning and
+        // including all manifests inside all jars, should base it on actual 
nested
+        // control usage as analyzed by starting at non-control clients).
+        try
+        {
+            // Build map of control types to assemble by scanning supplied 
manifests
+
+            Map<String,String> controlTypesToImpls = new 
HashMap<String,String>();
+
+            for ( File mf : manifestFiles )
+            {
+                ControlClientManifest ccmf = new ControlClientManifest( mf );
+                List<String> controlTypes = ccmf.getControlTypes();
+                for ( String ct : controlTypes )
+                    controlTypesToImpls.put( ct, ccmf.getDefaultImpl( ct ) );
+            }
+
+            // Build classloader to do loading
+
+            String[] classpaths = _classPath == null ? new String[0] : 
_classPath.list();
+            ClassLoader cl = buildClassLoader( classpaths, 
Assembler.class.getClassLoader() );
+
+            Assembler.assemble( _moduleDir, _srcOutputDir, 
_contextFactoryClassName, controlTypesToImpls, cl );
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            throw new BuildException("Assembly failed.", e);
+        }
+    }
+
+    private void validateAttributeSettings() throws BuildException
+    {
+        if (_contextFactoryClassName == null)
+            throw new BuildException("The contextFactoryClassName attribute 
must be set");
+
+        if (_moduleDir == null)
+            throw new BuildException("The moduleDir attribute must be set");
+
+        if (_srcOutputDir == null)
+            throw new BuildException("The srcOutputDir attribute must be set");
+    }
+
+    private ClassLoader buildClassLoader( String[] paths, ClassLoader parentCL)
+        throws ControlAssemblyException
+    {
+        List list = new ArrayList();
+        for (int i=0; i<paths.length; i++)
+        {
+            try
+            {
+                File file = new File(paths[i]);
+                String filePath = file.getCanonicalPath();
+                // ending slash is important for URLs that represent 
directories
+                if (!filePath.toLowerCase().endsWith(".jar") &&
+                    !filePath.endsWith("/") )
+                {
+                    filePath += "/";
+                }
+                URL url = new URL("file:" + filePath);
+                list.add(url);
+            }
+            catch (IOException e)
+            {
+                throw new ControlAssemblyException("Unable to include path " +
+                    paths[i] + " in classpath. Caught " +
+                    e.getClass().getName() + " trying to form this path as a 
URL.", e);
+            }
+        }
+
+        URL[] urlArray = new URL[list.size()];
+        urlArray = (URL[])list.toArray(urlArray);
+
+        return new URLClassLoader(urlArray, parentCL);
+    }
+
+    // ant parameter values
+    private String  _contextFactoryClassName;
+    private File    _moduleDir;
+    private File    _srcOutputDir;
+    private File    _bindingFile;
+    private Path    _classPath;
+    private FileSet _clientManifestFileSet;
+}

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/Assembler.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/Assembler.java
    Mon Aug  9 00:49:13 2004
@@ -0,0 +1,103 @@
+package org.apache.beehive.controls.runtime.assembly;
+
+/*
+ * Copyright 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.
+ *
+ * $Header:$
+ */
+
+import org.apache.beehive.controls.api.bean.ControlImplementation;
+import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
+import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
+import org.apache.beehive.controls.api.assembly.ControlAssembler;
+import org.apache.beehive.controls.api.assembly.DefaultControlAssembler;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+
+public class Assembler
+{
+    /**
+     * Executes basic assembly algorithm.  For each control type & impl 
specified, query each impl for the presence
+     * of an assembler -- for each assembler present, build the specified 
ControlAssemblyContext implementation,
+     * create an instance of the assembler and execute it.
+     *
+     * @param moduleRoot dir root of the module
+     * @param srcOutputRoot dir where assemblers can output source files
+     * @param factoryName name of the ControlAssemblyContext factory to use
+     * @param controlTypeToImpl map of control type name to control impl for 
all control types to be assembled in this module
+     * @param cl classloader used to load factories and assemblers
+     * @throws ControlAssemblyException
+     * @throws IOException
+     */
+    public static void assemble( File moduleRoot,
+                                 File srcOutputRoot,
+                                 String factoryName,
+                                 Map<String,String> controlTypeToImpl,
+                                 ClassLoader cl )
+        throws ControlAssemblyException, IOException
+    {
+        if ( !moduleRoot.exists() || !srcOutputRoot.exists() )
+            throw new IOException( "Directories " + moduleRoot + " or " + 
srcOutputRoot + " don't exist!");
+
+        if ( factoryName == null )
+            throw new ControlAssemblyException( "Missing context factory 
names" );
+
+        if ( cl == null )
+            throw new ControlAssemblyException( "Must specify a classloader" );
+
+        ClassLoader origCL = Thread.currentThread().getContextClassLoader();
+        Thread.currentThread().setContextClassLoader( cl );
+
+        try
+        {
+            // Create the requested ControlAssemblyContext.Factory
+            Class factoryClass = cl.loadClass( factoryName );
+            ControlAssemblyContext.Factory factory = 
(ControlAssemblyContext.Factory)factoryClass.newInstance();
+
+            // Iterate over control types
+            Set<String> controlTypes = controlTypeToImpl.keySet();
+            for ( String ct : controlTypes )
+            {
+                // Search for applicable ControlAssemblers as specified on the 
control impls
+                String cImpl = controlTypeToImpl.get( ct );
+                Class cImplClass = cl.loadClass( cImpl );
+
+                ControlImplementation a = 
(ControlImplementation)cImplClass.getAnnotation(ControlImplementation.class);
+                if ( a == null )
+                    throw new ControlAssemblyException( "Control 
implementation class=" + cImpl + " missing ControlImplementation annotation" );
+
+                // For each non-default ControlAssembler, create one and call 
it.
+                Class<? extends ControlAssembler> assemblerClass = 
a.assembler();
+                if ( !assemblerClass.equals(DefaultControlAssembler.class) )
+                {
+                    ControlAssembler assembler = assemblerClass.newInstance();
+                    ControlAssemblyContext cac = factory.newInstance( 
cl.loadClass(ct), null, moduleRoot, srcOutputRoot );
+                    assembler.assemble( cac );
+                }
+            }
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace( );
+        }
+        finally
+        {
+            Thread.currentThread().setContextClassLoader( origCL );
+        }
+    }
+}

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/BaseAssemblyContext.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/BaseAssemblyContext.java
  Mon Aug  9 00:49:13 2004
@@ -0,0 +1,135 @@
+package org.apache.beehive.controls.runtime.assembly;
+
+/*
+ * Copyright 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.
+ *
+ * $Header:$
+ */
+
+import org.apache.beehive.controls.api.bean.ControlInterface;
+import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
+import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
+import org.apache.beehive.controls.runtime.bean.ControlBeanContext;
+
+import java.io.File;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * Base ControlAssemblyContext implementation
+ */
+public abstract class BaseAssemblyContext implements ControlAssemblyContext
+{
+    protected BaseAssemblyContext( Class controlIntfOrExt, Map<String,String> 
bindings,
+                                   File moduleRoot, File srcOutputRoot )
+        throws ControlAssemblyException
+    {
+        _controlIntfOrExt = controlIntfOrExt;
+        _bindings = bindings;
+        _moduleRoot = moduleRoot;
+        _srcOutputRoot = srcOutputRoot;
+
+        // Compute and cache "most derived ControlInterface"
+        Queue<Class> q = new LinkedList<Class>();
+        Class ci = controlIntfOrExt;
+
+        while ( ci != null )
+        {
+            if ( ci.isAnnotationPresent(ControlInterface.class) )
+            {
+                _controlMostDerivedIntf = ci;
+                break;
+            }
+
+            Class[] supers = ci.getInterfaces();
+            for ( Class s : supers )
+                q.offer( s );
+
+            ci = q.poll();
+        }
+
+        if ( _controlMostDerivedIntf == null )
+            throw new ControlAssemblyException( "Invalid control type: " + 
controlIntfOrExt.getName() );
+    }
+
+    public Class getControlType()
+    {
+        return _controlIntfOrExt;
+    }
+
+    public Class getMostDerivedControlInterface()
+    {
+        return _controlMostDerivedIntf;
+    }
+
+    // TODO - if we want to override class annotations on instance
+    // then here is where we will do it
+    public <T extends Annotation> T
+        getControlAnnotation(Class<T> annotationClass)
+    {
+        Class controlInterface = getControlType();
+        return (T)controlInterface.getAnnotation(annotationClass);
+    }
+
+    public <T extends Annotation> T
+        getControlMethodAnnotation(Class<T> annotationClass, Method m)
+            throws NoSuchMethodException
+    {
+        Class controlInterface = getControlType();
+        Method controlMethod = controlInterface.getMethod(
+                m.getName(), m.getParameterTypes());
+
+        return (T)controlMethod.getAnnotation(annotationClass);
+    }
+
+    public String getDefaultImplClassName()
+    {
+        Class ci = getMostDerivedControlInterface();
+        ControlInterface a = (ControlInterface)
+            ci.getAnnotation(ControlInterface.class);
+
+        return ControlBeanContext.resolveDefaultBinding( a.defaultBinding(), 
ci.getName() );
+    }
+
+    public File createJavaOutputFile(String packageName, String className)
+    {
+        File dir = null;
+        if (packageName != null && packageName != "")
+        {
+            dir = new File(_srcOutputRoot,
+                packageName.replace('/', File.separatorChar));
+            dir.mkdirs();
+        }
+        else
+        {
+            dir = _srcOutputRoot;
+        }
+
+        return new File(dir, className + ".java");
+    }
+
+    public File getModuleDir()
+    {
+        return _moduleRoot;
+    }
+
+    private File _moduleRoot;
+    private File _srcOutputRoot;
+    private Class _controlIntfOrExt;
+    private Map<String,String> _bindings;
+
+    private Class _controlMostDerivedIntf;
+}

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/EJBAssemblyContext.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/assembly/EJBAssemblyContext.java
   Mon Aug  9 00:49:13 2004
@@ -0,0 +1,56 @@
+package org.apache.beehive.controls.runtime.assembly;
+
+/*
+ * Copyright 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.
+ *
+ * $Header:$
+ */
+
+import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
+import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ * A ControlAssemblyContext implementation supporting standard EJB modules
+ */
+public class EJBAssemblyContext extends BaseAssemblyContext
+                                implements ControlAssemblyContext.EJBModule
+{
+    public static class Factory implements ControlAssemblyContext.Factory
+    {
+        public EJBAssemblyContext newInstance( Class controlIntfOrExt,
+                                               Map<String,String> bindings,
+                                               File moduleRoot,
+                                               File srcOutputRoot )
+            throws ControlAssemblyException
+        {
+            return new EJBAssemblyContext( controlIntfOrExt, bindings, 
moduleRoot, srcOutputRoot );
+        }
+    }
+
+    private EJBAssemblyContext( Class controlIntfOrExt, Map<String,String> 
bindings,
+                                File moduleRoot, File srcOutputRoot )
+        throws ControlAssemblyException
+    {
+        super( controlIntfOrExt, bindings, moduleRoot, srcOutputRoot );
+    }
+
+    public File getEjbJarXml()
+    {
+        return new File( getModuleDir(), "META-INF" + File.separator + 
"ejb-jar.xml");
+    }
+}

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientManifest.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientManifest.java
   (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientManifest.java
   Mon Aug  9 00:49:13 2004
@@ -86,6 +86,14 @@
     }
 
     /**
+     * @return the name of the control client in this manifest
+     */
+    public String getControlClient()
+    {
+        return _properties.getProperty( CLIENT_NAME_PROP );
+    }
+
+    /**
      * Adds a new control type to the manifest
      * @param intf fully qualified name of the control type
      * @param impl fully qualified name of the default implementation for the 
control type
@@ -93,6 +101,35 @@
     public void addControlType( String intf, String impl )
     {
         _properties.setProperty( intf, impl );
+    }
+
+    /**
+     * @return a list of all control types listed in the manifest
+     */
+    public List<String> getControlTypes()
+    {
+        ArrayList<String> l = new ArrayList<String>();
+
+        Set keys = _properties.keySet();
+        for ( Object k : keys )
+        {
+            String propname = (String)k;
+            if ( propname.equals( CLIENT_NAME_PROP ) )
+                continue;
+
+            l.add( propname );
+        }
+
+        return l;
+    }
+
+    /**
+     * @param controlType
+     * @return the default implementation for the control type listed in the 
manifest
+     */
+    public String getDefaultImpl( String controlType )
+    {
+        return (String)_properties.get( controlType );
     }
 
     /**

Reply via email to