{
TypeMirror fieldType = f.getType();
// Make sure that this field doesn't try to override another that's inherited.
String fieldName = f.getSimpleName();
TypeDeclaration declaringType = f.getDeclaringType();
if ( declaringType instanceof ClassDeclaration )
{
for ( ClassType i = ( ( ClassDeclaration ) declaringType ).getSuperclass(); i != null; i = i.getSuperclass() )
{
ClassDeclaration decl = i.getDeclaration();
if ( decl != null )
{
for ( FieldDeclaration baseClassField : decl.getFields() )
{
if ( fieldName.equals( baseClassField.getSimpleName() ) )
{
Collection<Modifier> modifiers = baseClassField.getModifiers();
if ( modifiers.contains( Modifier.PROTECTED ) || modifiers.contains( Modifier.PUBLIC ) )
{
printError( f, "control.field.override", decl.getQualifiedName() );
}
}
}
}
}
}
// Valid control field instances can be of an interface type
// or a class type.
if ( fieldType instanceof InterfaceType )
{
// Valid interface type decls must be annotated w/ @ControlInterface
// or @ControlExtension.
Declaration fieldTypeDecl = ((InterfaceType)fieldType).getDeclaration();
if ( fieldTypeDecl.getAnnotation(ControlInterface.class) == null &&
fieldTypeDecl.getAnnotation(ControlExtension.class) == null )
printError( f, "control.field.bad.interfacetype" );
}
else if ( fieldType instanceof ClassType )
{
// Valid class type decls must implements the ControlBean API.
// Walk the implementation inheritance hierarchy, seeing if one of the
// classes implements ControlBean.
//
// REVIEW: Does NOT check if the interfaces might implement ControlBean!
// This is unnecessary for our impl, since our generated bean class directly
// implements ControlBean, but other impls may choose to do otherwise.
boolean foundControlBean = false;
ClassType classType = (ClassType)fieldType;
if (classType.getDeclaration() != null)
{
outer: while ( classType != null )
{
Collection<InterfaceType> intfs = classType.getSuperinterfaces();
for ( InterfaceType intfType : intfs )
{
if ( intfType.getDeclaration().getQualifiedName().equals( "org.apache.beehive.controls.api.bean.ControlBean" ) )
{
foundControlBean = true;
break outer;
}
}
classType = classType.getSuperclass();
}
if ( !foundControlBean )
printError( f, "control.field.bad.classtype" );
// Valid generated beans should only "implement" the control interface/extension, and no others
classType = (ClassType)fieldType;
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
{
// TODO: This could be a ControlBean type that is going to be generated by
// the current APT processing iteration. It should be possible to do more
// specific verification here using the getTypeDeclaration API on
// AnnotationProcessorEnvironment. In any event, the implementation of
// getControlInterface will properly handle this case, and if it cannot a
// malformed type error will be generated.
}
}
else
{
printError( f, "control.field.bad.type" );
}
// Enforce any versioning requirements this control field has.
//
// Since our generate() does some detailed grovelling of control types, make sure that
// will not result in an error by doing that grovelling now. Control types may be
// malformed if the source for those types has errors (yet the apt type may still exist!).
try
{
InterfaceDeclaration controlIntfOrExt = getControlInterfaceOrExtension(fieldType);
InterfaceDeclaration controlIntf = getMostDerivedControlInterface( controlIntfOrExt );
if ( controlIntf != null )
{
enforceVersionRequired( f, controlIntf );
}
else
{
printError( f, "control.field.type.malformed" );
}
}
catch ( CodeGenerationException cge )
{
printError( f, "control.field.type.malformed" );
}
assert declaringType != null : "Field " + f + " has no declaring type!";
if ( declaringType.getDeclaringType() != null )
printError( f, "control.field.in.inner.class" );
Collection<Modifier> mods = f.getModifiers();
if ( mods.contains( Modifier.TRANSIENT ))