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.
