Author: kentam
Date: Fri Aug  6 16:41:51 2004
New Revision: 36052

Added:
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssembler.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyContext.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyException.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlReferences.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlAssembler.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientManifest.java
   (contents, props changed)
Modified:
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlBean.java
   
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/ControlInterface.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlAnnotationProcessor.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessorFactory.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/strings.properties
Log:
Checkpoint controls assembly infrastructure.  Assembly is a build-time
process where controls have the opportunity to examine and side-effect their
clients.  For example, a control might want to inject deployment descriptor
entries into its client.  A spec coming soon..



Added: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssembler.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssembler.java
 Fri Aug  6 16:41:51 2004
@@ -0,0 +1,29 @@
+package org.apache.beehive.controls.api.bean;
+
+/*
+ * 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:$
+ */
+
+/**
+ * This interface provides the methods that can be called at assembly-time
+ * by build tools.
+ */
+public interface ControlAssembler
+{
+    void assemble(ControlAssemblyContext cac) throws ControlAssemblyException;
+}
+

Added: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyContext.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyContext.java
   Fri Aug  6 16:41:51 2004
@@ -0,0 +1,89 @@
+package org.apache.beehive.controls.api.bean;
+
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+/**
+ * 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).
+ */
+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)
+     */
+    Class getControlPublicInterface();
+
+    /**
+     * @return an annotation on the interface returned by
+     * getControlInterface()
+     */
+    <T extends Annotation> T
+        getControlAnnotation(Class<T> annotationClass);
+
+    /**
+     * @return an annotation on a method on the interface
+     * returned by getControlInterface()
+     */
+    <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)
+     */
+    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.
+     */
+    File createCompilableOutputFile(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.
+     */
+    File getClassesOutputDir();
+}

Added: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyException.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlAssemblyException.java
 Fri Aug  6 16:41:51 2004
@@ -0,0 +1,32 @@
+package org.apache.beehive.controls.api.bean;
+
+/*
+ * 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:$
+ */
+
+public class ControlAssemblyException extends Exception
+{
+    public ControlAssemblyException( String msg )
+    {
+        super( msg );
+    }
+
+    public ControlAssemblyException( String msg, Throwable cause )
+    {
+        super( msg, cause );
+    }
+}

Modified: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlBean.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlBean.java
      (original)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlBean.java
      Fri Aug  6 16:41:51 2004
@@ -40,7 +40,7 @@
      *
      * @see java.beans.beancontext.BeanContext
      */
-    public BeanContext getBeanContext();
+    BeanContext getBeanContext();
 
     /**
      * Returns the 
<code>org.apache.beehive.controls.api.context.ControlBeanContext</code> instance
@@ -48,19 +48,19 @@
      * context for the control.</b>  It is the context that would be the 
parent context for
      * any nested controls hosted by this control.
      */
-    public ControlBeanContext getControlBeanContext();
+    ControlBeanContext getControlBeanContext();
 
     /**
      * Returns the unique control ID associated with the Java ControlBean.  
This control ID
      * is guaranteed to be unique within the containing 
<code>BeanContext</code>
      * @return the control ID
      */
-    public String getControlID();
+    String getControlID();
 
     /**
      * Returns the Java Control public interface for the ControlBean.  This 
interface defines
      * the operations and events exposed by the Java Control to its clients.
      * @return the control public interface
      */
-    public Class getControlInterface();
+    Class getControlInterface();
 }

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
    Fri Aug  6 16:41:51 2004
@@ -37,5 +37,11 @@
      *  method is called at assembly time - if left Void then no
      *  special assembly is needed
      */
-    Class assemblyHelperClass() default java.lang.Void.class;
+    Class assemblyHelperClass() default java.lang.Void.class; // DEPRECATED
+
+    /**
+     * Class that implements ControlAssembler, which gets called at assembly 
time.
+     * Default implementation does nothing.
+     */
+    Class<? extends ControlAssembler> assembler() default 
DefaultControlAssembler.class;
 }

Modified: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlInterface.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlInterface.java
 (original)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlInterface.java
 Fri Aug  6 16:41:51 2004
@@ -30,7 +30,14 @@
 @Target({ElementType.TYPE})
 public @interface ControlInterface
 {
-    static public final String INTERFACE_NAME = "<InterfaceName>";
-    public String defaultBinding() default INTERFACE_NAME + "Impl";
-    public Class<? extends ControlChecker> checkerClass() default 
DefaultControlChecker.class;
+    /**
+     * Placeholder string used in defaultBinding attr.  Tools and runtime 
should replace
+     * instances of INTERFACE_NAME found in values of defaultBinding with the 
fully
+     * qualified name of the interface annotated with @ControlInterface.
+     */
+    static final String INTERFACE_NAME = "<InterfaceName>";
+
+    String defaultBinding() default INTERFACE_NAME + "Impl";
+    Class<? extends ControlChecker> checkerClass() default 
DefaultControlChecker.class; // DEPRECATED
+    Class<? extends ControlChecker> checker() default 
DefaultControlChecker.class;
 }

Added: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlReferences.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/ControlReferences.java
        Fri Aug  6 16:41:51 2004
@@ -0,0 +1,37 @@
+package org.apache.beehive.controls.api.bean;
+/*
+ * 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.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The ControlReferences annotation type is used to annotate a control client
+ * type, listing any control types that the client uses purely programmatically
+ * (and not declaratively).  Tools will treat the union of the set of types
+ * annotated w/ @Control and the types listed in @ControlReferences as the
+ * complete set of controls used by a client.
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED]({ElementType.TYPE})
+public @interface ControlReferences
+{
+    Class[] value() default {};
+}

Added: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlAssembler.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/bean/DefaultControlAssembler.java
  Fri Aug  6 16:41:51 2004
@@ -0,0 +1,28 @@
+package org.apache.beehive.controls.api.bean;
+/*
+ * B E A   S Y S T E M S
+ * Copyright 2001-2004  BEA Systems, Inc.
+ *
+ * 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:$
+ */
+
+/**
+ * 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 void assemble(ControlAssemblyContext cac) throws 
ControlAssemblyException { };
+}

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
       (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
       Fri Aug  6 16:41:51 2004
@@ -474,13 +474,7 @@
         ControlInterface intfAnnot = 
                     
(ControlInterface)controlClass.getAnnotation(ControlInterface.class);
         String implBinding = intfAnnot.defaultBinding();
-        int intfIndex = implBinding.indexOf(ControlInterface.INTERFACE_NAME);
-        if (intfIndex >= 0)
-        {
-            implBinding = implBinding.substring(0,intfIndex) + 
controlClass.getName() +
-                          implBinding.substring(intfIndex +
-                                                
ControlInterface.INTERFACE_NAME.length());
-        }
+        implBinding = resolveDefaultBinding( implBinding, 
controlClass.getName() );
         try
         {
             return controlClass.getClassLoader().loadClass(implBinding);
@@ -489,6 +483,26 @@
         {
             throw new ControlException("Unable to load control 
implementation", cnfe);
         }
+    }
+
+    /**
+     * Implements the default control implementation binding algorithm ( 
<InterfaceName> + "Impl" ).  See
+     * documentation for the 
org.apache.beehive.controls.api.bean.ControlInterface annotation.
+     *
+     * @param implBinding the value of the defaultBinding attribute returned 
from a ControlInterface annotation
+     * @param controlClass the actual name of the interface decorated by the 
ControlInterface annotation
+     * @return the resolved defaultBinding value
+     */
+    public static String resolveDefaultBinding( String implBinding, String 
controlClass )
+    {
+        int intfIndex = implBinding.indexOf(ControlInterface.INTERFACE_NAME);
+        if (intfIndex >= 0)
+        {
+            implBinding = implBinding.substring(0,intfIndex) + controlClass +
+                          implBinding.substring(intfIndex +
+                                                
ControlInterface.INTERFACE_NAME.length());
+        }
+        return implBinding;
     }
 
     //

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlAnnotationProcessor.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlAnnotationProcessor.java
      (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlAnnotationProcessor.java
      Fri Aug  6 16:41:51 2004
@@ -30,6 +30,7 @@
 import com.sun.mirror.apt.AnnotationProcessor;
 import com.sun.mirror.apt.AnnotationProcessorFactory;
 import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import com.sun.mirror.apt.Filer;
 import com.sun.mirror.declaration.AnnotationTypeDeclaration;
 import com.sun.mirror.declaration.Declaration;
 
@@ -70,6 +71,22 @@
         if (genClass != null)
         {
             _typeMap.put(decl, genClass);
+
+            try
+            {
+                List<GeneratorOutput> genList = 
genClass.getGeneratorOutput(env.getFiler());
+                if (genList == null || genList.size() == 0)
+                    return;
+
+                for (GeneratorOutput genOut : genList)
+                {
+                    getGenerator().generate(genOut);
+                }
+            }
+            catch (IOException ioe)
+            {
+                throw new CodeGenerationException("Type generation failure for 
class=" + genClass, ioe);
+            }
         }
     }
 
@@ -79,23 +96,6 @@
         GenClass genClass = _typeMap.get(decl);
         if (genClass == null)
             return;
-
-        AnnotationProcessorEnvironment env = 
getAnnotationProcessorEnvironment();
-        try
-        {
-            List<GeneratorOutput> genList = 
genClass.getGeneratorOutput(env.getFiler());
-            if (genList == null || genList.size() == 0)
-                return;
-
-            for (GeneratorOutput genOut : genList)
-            {
-                getGenerator().generate(genOut);
-            }
-        }
-        catch (IOException ioe)
-        {
-            throw new CodeGenerationException("Code generation failure: ", 
ioe);
-        }
     }
 
     /**

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java
        (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java
        Fri Aug  6 16:41:51 2004
@@ -29,12 +29,17 @@
 import java.util.*;
 
 import org.apache.beehive.controls.runtime.generator.CodeGenerationException;
+import org.apache.beehive.controls.runtime.bean.ControlBeanContext;
 import org.apache.beehive.controls.api.bean.Control;
 import org.apache.beehive.controls.api.bean.ControlBean;
 import org.apache.beehive.controls.api.bean.ControlInterface;
 import org.apache.beehive.controls.api.bean.ControlExtension;
 import java.util.Iterator;
 import java.util.Set;
+import java.lang.annotation.Annotation;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.IOException;
 
 public class ControlClientAnnotationProcessor extends 
TwoPhaseAnnotationProcessor
 {
@@ -53,8 +58,90 @@
 
         // if @Control is used on something other than a field, the Java lang
         // checker should produce an error due to the @Target violation.
+
+        if ( d instanceof TypeDeclaration )
+            checkControlClientType( (TypeDeclaration)d );
     }
 
+    /**
+     * Each control client requires a manifest that documents the controls 
that it references.
+     *
+     * @throws CodeGenerationException
+     */
+    @Override
+    public void generate() throws CodeGenerationException
+    {
+        super.generate();
+
+        // The annotation processor may be passed multiple control client 
types.  Build a map that
+        // links each control client type with the set of control types that 
it uses.
+
+        Map<TypeDeclaration,Set<TypeMirror>> clientsMap = new 
HashMap<TypeDeclaration,Set<TypeMirror>>();
+
+        for (AnnotationTypeDeclaration atd : _atds)
+        {
+            if (atd.getSimpleName().equals("Control") )
+            {
+                Collection<Declaration> decls = 
_env.getDeclarationsAnnotatedWith(atd);
+                for (Declaration decl : decls)
+                {
+                    if ( decl instanceof FieldDeclaration )
+                    {
+                        FieldDeclaration fd = (FieldDeclaration)decl;
+                        TypeDeclaration clientType = fd.getDeclaringType();
+                        Set<TypeMirror> controlTypes = clientsMap.get( 
clientType );
+                        if ( controlTypes == null )
+                        {
+                            controlTypes = new HashSet<TypeMirror>();
+                            clientsMap.put( clientType, controlTypes );
+                        }
+
+                        controlTypes.add( fd.getType() );
+                    }
+                }
+            }
+        }
+
+        // For each client type, emit a controls client manifest in the same 
dir as the
+        // client type's class.
+
+        // TODO: support @ClientReferences
+
+        Filer f = getAnnotationProcessorEnvironment().getFiler();
+        Set<TypeDeclaration> clientTypes = clientsMap.keySet();
+        for ( TypeDeclaration clientType : clientTypes )
+        {
+            String clientPkg = clientType.getPackage().getQualifiedName();
+            File clientManifestName = new File( clientType.getSimpleName() + 
".controls.properties" );
+
+            ControlClientManifest mf = new ControlClientManifest( 
clientType.getQualifiedName() );
+
+            try
+            {
+                Set<TypeMirror> controlTypes = clientsMap.get( clientType );
+                for ( TypeMirror controlType : controlTypes )
+                {
+                    InterfaceType controlIntfOrExt = 
getControlInterfaceOrExtension(controlType);
+                    InterfaceType controlIntf = 
getMostDerivedControlInterface( controlIntfOrExt );
+
+                    ControlInterface annot = 
controlIntf.getDeclaration().getAnnotation(ControlInterface.class);
+                    String defBinding = annot.defaultBinding();
+
+                    defBinding = ControlBeanContext.resolveDefaultBinding( 
defBinding, controlIntf.toString() );
+
+                    mf.addControlType( controlIntfOrExt.toString(), defBinding 
);
+                }
+
+                mf.emit( f, clientPkg, clientManifestName );
+            }
+            catch ( IOException ie )
+            {
+                printError( clientType, "controls.client.manifest.ioerror" );
+                ie.printStackTrace( );
+            }
+        }
+    }
+    
     @Override
     public void generate(Declaration decl)
     {
@@ -104,6 +191,18 @@
              }
              if ( !foundControlBean )
                  printError( f, "control.field.bad.classtype" );
+
+             // Valid generated beans should only "implement" the control 
interface/extension, and no others
+             Collection<InterfaceType> intfs = classType.getSuperinterfaces();
+             if ( intfs.size() != 1 )
+                 printError( f, "control.field.bad.classtype.badinterface" );
+
+             for ( InterfaceType intfType : intfs )
+             {
+                 if ( 
intfType.getDeclaration().getAnnotation(ControlExtension.class) == null &&
+                      
intfType.getDeclaration().getAnnotation(ControlInterface.class) == null)
+                     printError( f, 
"control.field.bad.classtype.badinterface");
+             }
          }
          else
          {
@@ -122,8 +221,72 @@
          if ( f.getModifiers().contains( Modifier.STATIC ))
              printError( f, "static.control.field" );
     }
-    
-        
+
+    private void checkControlClientType( TypeDeclaration t )
+    {
+        // TODO: validate @ControlReferences
+    }
+
+    /**
+     * Given a InterfaceType or ClassType, returns the InterfaceType for the 
control type's
+     * public interface/extension.
+     * @param intfOrBeanClass
+     * @return
+     */
+    private InterfaceType getControlInterfaceOrExtension( TypeMirror 
intfOrBeanClass )
+    {
+        if (intfOrBeanClass instanceof InterfaceType)
+        {
+            return (InterfaceType)intfOrBeanClass;
+        }
+        else if (intfOrBeanClass instanceof ClassType)
+        {
+            ClassType classType = (ClassType)intfOrBeanClass;
+            Collection<InterfaceType> intfs = classType.getSuperinterfaces(); 
// direct supers only
+
+            // per the code in checkControlField, this set must be of size 1
+            // and the 1 super interface must be a control interface/extension
+            assert ( intfs.size() == 1 );
+            for ( InterfaceType intfType : intfs )
+                return intfType;
+        }
+        else
+        {
+            throw new CodeGenerationException( "Param not a interface or class 
type");
+        }
+
+        return null;
+    }
+
+    /**
+     * Given a control interface or extension, do a BFS of its inheritance 
heirarchy for
+     * the first one marked with @ControlInterface.  This represents the point 
in the
+     * heirarchy where use of @ControlExtension changes to use of 
@ControlInterface.
+     *
+     * @param controlIntfOrExt an interface annotated with @ControlInterface 
or @ControlExtension.
+     * @return most derived interface in the heirarchy annotated with 
@ControlInterface, null
+     *         if no such interface found.
+     */
+    private InterfaceType getMostDerivedControlInterface( InterfaceType 
controlIntfOrExt )
+    {
+        Queue<InterfaceType> q = new LinkedList<InterfaceType>();
+
+        InterfaceType ci = controlIntfOrExt;
+        while ( ci != null )
+        {
+            if ( ci.getDeclaration().getAnnotation(ControlInterface.class) != 
null )
+                break;
+
+            Collection<InterfaceType> supers = ci.getSuperinterfaces();
+            for ( InterfaceType s : supers )
+                q.offer( s );
+
+            ci = q.poll();
+        }
+
+        return ci;
+    }
+
     private final void printError( Declaration d, String id )
     {
         getAnnotationProcessorEnvironment().getMessager().printError(

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessorFactory.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessorFactory.java
 (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessorFactory.java
 Fri Aug  6 16:41:51 2004
@@ -35,6 +35,7 @@
             Collections.unmodifiableCollection(
                 Arrays.asList(new String[] {
                         
org.apache.beehive.controls.api.bean.Control.class.getName(),
+                        
org.apache.beehive.controls.api.bean.ControlReferences.class.getName()
                     }));
 
     private static final Collection<String> _supportedOptions =

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientManifest.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientManifest.java
   Fri Aug  6 16:41:51 2004
@@ -0,0 +1,121 @@
+package org.apache.beehive.controls.runtime.generator.apt;
+
+/*
+ * 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 com.sun.mirror.apt.Filer;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * The controls client manifest (aka "client manifest") surfaces the set of
+ * control types used by a client, and make the assembly process more
+ * efficient.  The control client annotation processor generates a client
+ * manifest documenting the set of used control types.  This manifest is a
+ * java.util.Properties file that specifies:
+ * 
+ * - classname of the control client
+ * - classnames of each control type used by that control client (the set
+ *   identified by @Control and @ControlReference usages) and the
+ *   corresponding default implementation binding
+ *
+ * Example client manifest:
+ *
+ * FooImpl.controls.properties
+ * ---------------------------
+ * .client.name=org.acme.controls.FooImpl
+ * 
org.acme.controls.CustomerDbBean=org.apache.beehive.controls.scl.DatabaseControlImpl
+ * 
org.acme.controls.DailyTimerBean=org.apache.beehive.controls.scl.TimerControlImpl
+ *
+ * The manifest is a generated artifact and is not user-editable.  Ideally, 
the apt
+ * environment optimizes the writing of the manifest such that it's only 
written
+ * to disk when changes occur (allowing external build tools to use the 
timestamp of
+ * the manifest to determine whether assembly on a client needs to occur).
+ */
+public class ControlClientManifest
+{
+    public final static String CLIENT_NAME_PROP     = ".client.name";
+    public final static String BEEHIVE_VERSION_PROP = ".beehive.version";
+    public final static String FILE_EXTENSION       = ".controls.properties";
+
+    /**
+     * Loads a ControlClientManifest from an existing manifest file.
+     * @param f the manifest file
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    public ControlClientManifest( File f ) throws FileNotFoundException, 
IOException
+    {
+        if ( !f.exists() )
+            throw new FileNotFoundException( "Control manifest file=" + f + " 
not found");
+
+        FileInputStream fis = new FileInputStream( f );
+        _properties.load( fis );
+
+        String client = _properties.getProperty( CLIENT_NAME_PROP );
+        if ( client == null || client.equals("") )
+            throw new IOException( "Control client manifest missing client 
name" );
+    }
+
+    /**
+     * Creates a new ControlClientManifest
+     * @param client the fully qualified classname of the control client
+     */
+    public ControlClientManifest( String client )
+    {
+        if ( client == null || client.equals("") )
+            throw new RuntimeException( "Missing or empty client name" );
+
+        _properties.setProperty( CLIENT_NAME_PROP, client );
+    }
+
+    /**
+     * 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
+     */
+    public void addControlType( String intf, String impl )
+    {
+        _properties.setProperty( intf, impl );
+    }
+
+    /**
+     * Emits the manifest via an apt Filer implementation
+     * @param f an apt Filer
+     * @param pkg the package structure to place the manifest in
+     * @param mf the name of the manifest
+     * @throws IOException
+     */
+    public void emit( Filer f, String pkg, File mf ) throws IOException
+    {
+        PrintWriter pw = f.createTextFile( Filer.Location.CLASS_TREE, pkg, mf, 
null );
+
+        pw.println( "# Apache Beehive Controls client manifest 
(auto-generated, do not edit!)");
+        Set props = _properties.keySet();
+        for ( Object p : props )
+        {
+            String name = (String)p;
+            String value = _properties.getProperty( name );
+            pw.println( name + "=" + value );
+        }
+    }
+
+    private Properties _properties = new Properties();
+}
+

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/strings.properties
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/strings.properties
   (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/strings.properties
   Fri Aug  6 16:41:51 2004
@@ -6,6 +6,10 @@
 A control field's type must implement 
org.apache.beehive.controls.api.bean.ControlBean if it's a class. \
 Verify the type of the control field declaration implements ControlBean.
 
+control.field.bad.classtype.badinterface=\
+If a control field's type is a class, that class must implement the control's 
public interface/extension and no other interface. \
+Verify the type of the control field declaration implements only the public 
interface/extension.
+
 control.field.bad.type=\
 A control field must be of a class or interface type. \
 Verify the type of the control field declaration is a class or interface.
@@ -25,4 +29,7 @@
 static.control.field =\
 A control can not be declared as static. \
 Remove the static modifier from the control declaration.
+
+controls.client.manifest.ioerror= \
+An error occurred writing the controls client manifest.
 

Reply via email to