1 18 package org.apache.beehive.netui.compiler; 19 20 import org.apache.beehive.netui.compiler.genmodel.GenStrutsApp; 21 import org.apache.beehive.netui.compiler.grammar.ControllerGrammar; 22 import org.apache.beehive.netui.compiler.grammar.WebappPathOrActionType; 23 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationInstance; 24 import org.apache.beehive.netui.compiler.typesystem.declaration.ClassDeclaration; 25 import org.apache.beehive.netui.compiler.typesystem.declaration.FieldDeclaration; 26 import org.apache.beehive.netui.compiler.typesystem.declaration.Modifier; 27 import org.apache.beehive.netui.compiler.typesystem.declaration.PackageDeclaration; 28 import org.apache.beehive.netui.compiler.typesystem.declaration.TypeDeclaration; 29 import org.apache.beehive.netui.compiler.typesystem.env.AnnotationProcessorEnvironment; 30 import org.apache.beehive.netui.compiler.typesystem.type.DeclaredType; 31 import org.apache.beehive.netui.compiler.typesystem.type.TypeInstance; 32 import org.apache.xmlbeans.XmlException; 33 34 import java.io.File ; 35 import java.io.IOException ; 36 import java.util.Collection ; 37 import java.util.Iterator ; 38 39 40 public class PageFlowChecker 41 extends FlowControllerChecker 42 implements JpfLanguageConstants 43 { 44 public PageFlowChecker( AnnotationProcessorEnvironment env, Diagnostics diagnostics, FlowControllerInfo fcInfo ) 45 { 46 super( env, fcInfo, diagnostics ); 47 } 48 49 protected void checkField( FieldDeclaration field, TypeDeclaration jclass ) 50 { 51 AnnotationInstance sfFieldAnn = CompilerUtils.getAnnotation( field, SHARED_FLOW_FIELD_TAG_NAME ); 56 57 if ( sfFieldAnn != null ) 58 { 59 String sharedFlowName = CompilerUtils.getString( sfFieldAnn, NAME_ATTR, true ); 60 assert sharedFlowName != null; 61 62 Collection sharedFlowRefs = 63 getFCSourceFileInfo().getMergedControllerAnnotation().getSharedFlowRefs(); 64 65 boolean foundOne = false; 66 67 if ( sharedFlowRefs != null ) 68 { 69 for ( Iterator ii = sharedFlowRefs.iterator(); ii.hasNext(); ) 70 { 71 AnnotationInstance sharedFlowRef = ( AnnotationInstance ) ii.next(); 72 if ( sharedFlowName.equals( CompilerUtils.getString( sharedFlowRef, NAME_ATTR, true ) ) ) 73 { 74 foundOne = true; 75 76 TypeInstance sfType = CompilerUtils.getTypeInstance( sharedFlowRef, TYPE_ATTR, true ); 77 TypeInstance ft = field.getType(); 78 79 if ( ! ( sfType instanceof DeclaredType ) 80 || ! CompilerUtils.isAssignableFrom( ft, ( ( DeclaredType ) sfType ).getDeclaration() ) ) 81 { 82 getDiagnostics().addError( 83 field, "error.field-not-assignable", 84 CompilerUtils.getDeclaration( ( DeclaredType ) sfType ).getQualifiedName() ); 85 } 86 } 87 } 88 } 89 90 if ( ! foundOne ) 91 { 92 getDiagnostics().addError( sfFieldAnn, "error.no-matching-shared-flow-declared", 93 SHARED_FLOW_REF_TAG_NAME, sharedFlowName ); 94 } 95 } 96 else if ( CompilerUtils.isAssignableFrom( SHARED_FLOW_BASE_CLASS, field.getType(), getEnv() ) 97 && ! CompilerUtils.isAssignableFrom( GLOBALAPP_BASE_CLASS, field.getType(), getEnv() ) ) 98 { 99 getDiagnostics().addWarning( field, "warning.shared-flow-field-no-annotation", 102 field.getSimpleName(), SHARED_FLOW_BASE_CLASS, 103 ANNOTATION_INTERFACE_PREFIX + SHARED_FLOW_FIELD_TAG_NAME ); 104 } 105 106 super.checkField( field, jclass ); 107 } 108 109 protected void doAdditionalClassChecks( ClassDeclaration jpfClass ) 110 { 111 checkForOverlappingClasses( jpfClass, JPF_BASE_CLASS, JPF_FILE_EXTENSION_DOT, "error.overlapping-pageflows" ); 113 114 PackageDeclaration pkg = jpfClass.getPackage(); 115 File jpfFile = CompilerUtils.getSourceFile( jpfClass, true ); 116 File parentDir = jpfFile.getParentFile(); 117 118 String jpfPackageName = pkg.getQualifiedName(); 122 123 if ( jpfPackageName != null && jpfPackageName.length() > 0 ) 124 { 125 String expectedPackage = parentDir.getAbsolutePath().replace( '\\', '/' ).replace( '/', '.' ); 126 127 if ( ! expectedPackage.endsWith( jpfPackageName ) ) 128 { 129 getDiagnostics().addError( jpfClass, "error.wrong-package-for-directory", parentDir.getPath() ); 130 } 131 } 132 133 if ( jpfClass.getSimpleName().equals( pkg.getQualifiedName() ) ) 138 { 139 getDiagnostics().addWarning( jpfClass, "warning.classname-same-as-package" ); 140 } 141 142 boolean isAbstract = jpfClass.hasModifier( Modifier.ABSTRACT ); 146 FlowControllerInfo fcInfo = getFCSourceFileInfo(); 147 148 if ( ! WebappPathOrActionType.actionExists( BEGIN_ACTION_NAME, jpfClass, null, getEnv(), fcInfo, true ) 149 && ! isAbstract ) 150 { 151 getDiagnostics().addError( jpfClass, "error.no-begin-action" ); 152 } 153 154 if ( fcInfo.isNested() ) 159 { 160 MergedControllerAnnotation mca = fcInfo.getMergedControllerAnnotation(); 161 addReturnActions( mca.getSimpleActions(), fcInfo, jpfClass, CONDITIONAL_FORWARDS_ATTR ); 162 addReturnActions( mca.getForwards(), fcInfo, jpfClass, null ); 163 164 if ( ! isAbstract && fcInfo.countReturnActions() == 0 ) 165 { 166 getDiagnostics().addError( jpfClass, "error.no-return-action", 167 ANNOTATION_INTERFACE_PREFIX + FORWARD_TAG_NAME, 168 RETURN_ACTION_ATTR ); 169 } 170 } 171 } 172 173 private void addReturnActions( Collection forwardAnnotations, FlowControllerInfo fcInfo, 174 TypeDeclaration outerType, String childArrayAttr ) 175 { 176 for ( Iterator ii = forwardAnnotations.iterator(); ii.hasNext(); ) 177 { 178 AnnotationInstance ann = ( AnnotationInstance ) ii.next(); 179 String returnAction = CompilerUtils.getString( ann, RETURN_ACTION_ATTR, true ); 180 if ( returnAction != null ) fcInfo.addReturnAction( returnAction, ann, outerType ); 181 182 if ( childArrayAttr != null ) 183 { 184 Collection children = CompilerUtils.getAnnotationArray( ann, childArrayAttr, true ); 185 if ( children != null ) addReturnActions( children, fcInfo, outerType, null ); 186 } 187 } 188 } 189 190 protected String getDesiredBaseClass( ClassDeclaration jclass ) 191 { 192 return JPF_BASE_CLASS; 193 } 194 195 protected GenStrutsApp createStrutsApp( ClassDeclaration jclass ) 196 throws XmlException, IOException , FatalCompileTimeException 197 { 198 File sourceFile = CompilerUtils.getSourceFile( jclass, true ); 199 return new GenStrutsApp( sourceFile, jclass, getEnv(), getFCSourceFileInfo(), true, getDiagnostics() ); 200 } 201 202 protected AnnotationGrammar getControllerGrammar() 203 { 204 return new JpfControllerGrammar(); 205 } 206 207 private class JpfControllerGrammar 208 extends ControllerGrammar 209 { 210 public JpfControllerGrammar() 211 { 212 super( PageFlowChecker.this.getEnv(), PageFlowChecker.this.getDiagnostics(), 213 PageFlowChecker.this.getRuntimeVersionChecker(), PageFlowChecker.this.getFCSourceFileInfo() ); 214 addMemberType( NESTED_ATTR, new AnnotationMemberType( null, this ) ); 215 addMemberType( LONGLIVED_ATTR, new AnnotationMemberType( null, this ) ); 216 } 217 } 218 } 219 | Popular Tags |