1 18 package org.apache.beehive.netui.compiler.grammar; 19 20 import org.apache.beehive.netui.compiler.AnnotationMemberType; 21 import org.apache.beehive.netui.compiler.CompilerUtils; 22 import org.apache.beehive.netui.compiler.Diagnostics; 23 import org.apache.beehive.netui.compiler.FlowControllerInfo; 24 import org.apache.beehive.netui.compiler.JpfLanguageConstants; 25 import org.apache.beehive.netui.compiler.RuntimeVersionChecker; 26 import org.apache.beehive.netui.compiler.FatalCompileTimeException; 27 import org.apache.beehive.netui.compiler.typesystem.declaration.*; 28 import org.apache.beehive.netui.compiler.typesystem.env.AnnotationProcessorEnvironment; 29 import org.apache.beehive.netui.compiler.typesystem.type.DeclaredType; 30 import org.apache.beehive.netui.compiler.typesystem.type.TypeInstance; 31 32 33 public class ActionGrammar 34 extends BaseFlowControllerGrammar 35 implements JpfLanguageConstants 36 { 37 public ActionGrammar( AnnotationProcessorEnvironment env, Diagnostics diags, 38 RuntimeVersionChecker rvc, FlowControllerInfo fcInfo ) 39 { 40 super( env, diags, null, rvc, fcInfo ); 41 42 addMemberType( LOGIN_REQUIRED_ATTR, new AnnotationMemberType( null, this ) ); 43 addMemberType( ROLES_ALLOWED_ATTR, new RolesAllowedType( this ) ); 44 addMemberType( READONLY_ATTR, new AnnotationMemberType( VERSION_8_SP2_STRING, this ) ); 45 addMemberType( USE_FORM_BEAN_ATTR, new UseFormBeanType() ); 46 addMemberType( PREVENT_DOUBLE_SUBMIT_ATTR, new AnnotationMemberType( null, this ) ); 47 addMemberType( DO_VALIDATION_ATTR, new DoValidateType() ); 48 49 addMemberArrayGrammar( FORWARDS_ATTR, new ForwardGrammar( env, diags, null, rvc, fcInfo ) ); 50 addMemberArrayGrammar( CATCHES_ATTR, new CatchGrammar( env, diags, null, rvc, ACTION_TAG_NAME, fcInfo ) ); 51 addMemberArrayGrammar( VALIDATABLE_PROPERTIES_ATTR, new ValidatablePropertyGrammar( env, diags, rvc ) ); 52 addMemberGrammar( VALIDATION_ERROR_FORWARD_ATTR, new ActionForwardGrammar() ); 53 } 54 55 public String [][] getMutuallyExclusiveAttrs() 56 { 57 return null; 58 } 59 60 public String [][] getRequiredAttrs() 61 { 62 return null; 63 } 64 65 protected boolean onBeginCheck( AnnotationInstance annotation, AnnotationInstance[] parentAnnotations, 66 MemberDeclaration classMember ) 67 throws FatalCompileTimeException 68 { 69 TypeInstance argType = getFormBeanType( annotation, classMember ); 73 TypeDeclaration argTypeDecl = null; 74 75 if ( ! ( argType instanceof DeclaredType ) ) 76 { 77 if ( argType != null ) 78 { 79 getDiagnostics().addError( annotation, "error.action-invalid-form-bean-type", argType.toString() ); 80 argType = null; 81 } 82 } 83 else 84 { 85 argTypeDecl = CompilerUtils.getDeclaration( ( DeclaredType ) argType ); 86 boolean isClass = argTypeDecl instanceof ClassDeclaration; 87 88 if ( isClass && ! CompilerUtils.hasDefaultConstructor( argTypeDecl ) ) 89 { 90 getDiagnostics().addError( annotation, "error.action-form-bean-no-default-constructor", 91 argTypeDecl.getQualifiedName() ); 92 } 93 94 if ( ! argTypeDecl.hasModifier( Modifier.PUBLIC ) ) 95 { 96 getDiagnostics().addError( annotation, "error.action-form-bean-not-public", 97 argTypeDecl.getQualifiedName() ); 98 } 99 100 if ( isClass && argTypeDecl.getDeclaringType() != null && ! argTypeDecl.hasModifier( Modifier.STATIC ) ) 101 { 102 getDiagnostics().addError( annotation, "error.action-form-bean-not-static", 103 argTypeDecl.getQualifiedName() ); 104 } 105 106 if ( CompilerUtils.getAnnotationValue( annotation, VALIDATION_ERROR_FORWARD_ATTR, true ) == null 110 && hasValidationAnnotations( argTypeDecl ) ) 111 { 112 Boolean doValidation = CompilerUtils.getBoolean( annotation, DO_VALIDATION_ATTR, true ); 113 114 if ( doValidation == null || doValidation.booleanValue() ) 115 { 116 getDiagnostics().addWarning( 117 annotation, "warning.validatable-formbean-no-forward", 118 ANNOTATION_INTERFACE_PREFIX + annotation.getAnnotationType().getDeclaration().getSimpleName(), 119 VALIDATION_ERROR_FORWARD_ATTR, argTypeDecl.getQualifiedName() ); 120 } 121 } 122 } 123 124 getFlowControllerInfo().addAction( getActionName( annotation, classMember ), 128 argTypeDecl != null ? argTypeDecl.getQualifiedName() : null ); 129 130 TypeInstance useFormBeanType = getUseFormBeanType( annotation, classMember ); 135 136 if ( useFormBeanType != null && useFormBeanType instanceof DeclaredType ) 137 { 138 if ( argType == null ) 139 { 140 String memberFormTypeName = CompilerUtils.getDeclaration( ( DeclaredType ) useFormBeanType ).getQualifiedName(); 141 getDiagnostics().addError( annotation, "error.action-mismatched-form", USE_FORM_BEAN_ATTR, 142 memberFormTypeName ); 143 } 144 else if ( ! CompilerUtils.isAssignableFrom( argTypeDecl, useFormBeanType )) 145 { 146 String memberFormTypeName = CompilerUtils.getDeclaration( ( DeclaredType ) useFormBeanType ).getQualifiedName(); 147 getDiagnostics().addError( annotation, "error.action-mismatched-form", USE_FORM_BEAN_ATTR, 148 memberFormTypeName ); 149 } 150 } 151 152 return true; 153 } 154 155 protected String getActionName( AnnotationInstance annotation, MemberDeclaration classMember ) 156 { 157 assert classMember instanceof MethodDeclaration : classMember.getClass().getName(); 158 return classMember.getSimpleName(); 159 } 160 161 private static boolean hasValidationAnnotations( TypeDeclaration type ) 162 { 163 165 MethodDeclaration[] methods = type.getMethods(); 166 167 for ( int i = 0; i < methods.length; i++ ) 168 { 169 MethodDeclaration method = methods[i]; 170 AnnotationInstance[] annotations = method.getAnnotationInstances(); 171 172 for ( int j = 0; j < annotations.length; j++ ) 173 { 174 AnnotationInstance ann = annotations[j]; 175 String annotationName = CompilerUtils.getDeclaration( ann.getAnnotationType() ).getQualifiedName(); 176 int pos = annotationName.indexOf( ANNOTATION_QUALIFIER ); 177 178 if ( pos != -1 ) 179 { 180 if ( annotationName.substring( pos + ANNOTATION_QUALIFIER.length() ).startsWith( "Validat" ) ) 181 { 182 return true; 183 } 184 } 185 } 186 } 187 188 return false; 189 } 190 191 protected static TypeInstance getUseFormBeanType( AnnotationInstance annotation, MemberDeclaration classMember ) 192 { 193 String formBeanFieldName = CompilerUtils.getString( annotation, USE_FORM_BEAN_ATTR, true ); 194 195 if ( formBeanFieldName != null ) 196 { 197 FieldDeclaration formBeanField = 198 CompilerUtils.findField( CompilerUtils.getOutermostClass( classMember ), formBeanFieldName ); 199 200 if ( formBeanField != null ) 201 { 202 return CompilerUtils.getGenericBoundsType( formBeanField.getType() ); 203 } 204 } 205 206 return null; 207 } 208 209 protected TypeInstance getFormBeanType( AnnotationInstance annotation, MemberDeclaration classMember ) 210 { 211 assert classMember instanceof MethodDeclaration : classMember.getClass().getName(); 212 MethodDeclaration method = ( MethodDeclaration ) classMember; 213 ParameterDeclaration[] parameters = method.getParameters(); 214 int nParameters = parameters.length; 215 216 if ( nParameters > 1 ) getDiagnostics().addError( method, "error.action-method-wrong-arg" ); 217 if ( nParameters > 0 ) return CompilerUtils.getGenericBoundsType( parameters[0].getType() ); 218 219 return null; 220 } 221 222 private class DoValidateType 223 extends AnnotationMemberType 224 { 225 public DoValidateType() 226 { 227 super( null, ActionGrammar.this ); 228 } 229 230 231 public Object onCheck( AnnotationTypeElementDeclaration valueDecl, AnnotationValue member, 232 AnnotationInstance[] parentAnnotations, MemberDeclaration classMember, 233 int annotationArrayIndex ) 234 { 235 if ( ( ( Boolean ) member.getValue() ).booleanValue() ) 239 { 240 AnnotationInstance parentAnnotation = parentAnnotations[ parentAnnotations.length - 1 ]; 241 242 if ( CompilerUtils.getAnnotation( parentAnnotation, VALIDATION_ERROR_FORWARD_ATTR, true ) == null ) 243 { 244 addError( member, "error.validate-with-no-validation-error-forward", DO_VALIDATION_ATTR, 245 VALIDATION_ERROR_FORWARD_ATTR ); 246 } 247 } 248 249 return null; 250 } 251 } 252 253 private class ActionForwardGrammar 254 extends ForwardGrammar 255 { 256 public ActionForwardGrammar() 257 { 258 super( ActionGrammar.this.getEnv(), ActionGrammar.this.getDiagnostics(), null, 259 ActionGrammar.this.getRuntimeVersionChecker(), ActionGrammar.this.getFlowControllerInfo() ); 260 ExternalPathOrActionType baseForwardType = 261 new ExternalPathOrActionType( false, null, this, ActionGrammar.this.getFlowControllerInfo() ); 262 addMemberType( PATH_ATTR, new ForwardToExternalPathType( baseForwardType, null, ActionGrammar.this ) ); 263 } 264 } 265 266 private class UseFormBeanType 267 extends WritableFieldType 268 { 269 public UseFormBeanType() 270 { 271 super( OBJECT_CLASS_NAME, USE_FORM_BEAN_ATTR, null, ActionGrammar.this ); 272 } 273 274 275 public Object onCheck( AnnotationTypeElementDeclaration valueDecl, AnnotationValue value, 276 AnnotationInstance[] parentAnnotations, MemberDeclaration classMember, 277 int annotationArrayIndex ) 278 { 279 FieldDeclaration memberField = 280 ( FieldDeclaration ) super.onCheck( valueDecl, value, parentAnnotations, classMember, 281 annotationArrayIndex ); 282 283 if ( memberField != null ) 284 { 285 AnnotationInstance parentAnnotation = parentAnnotations[parentAnnotations.length - 1]; 290 if ( CompilerUtils.getBoolean( parentAnnotation, READONLY_ATTR, false ).booleanValue() ) 291 { 292 addWarning( value, "warning.use-form-bean-on-readonly-action", READONLY_ATTR, USE_FORM_BEAN_ATTR, 293 memberField.getSimpleName() ); 294 } 295 } 296 297 return memberField; 298 } 299 } 300 } 301 | Popular Tags |