1 18 package org.apache.beehive.netui.compiler.genmodel; 19 20 import org.apache.beehive.netui.compiler.CompilerUtils; 21 import org.apache.beehive.netui.compiler.JpfLanguageConstants; 22 import org.apache.beehive.netui.compiler.MergedControllerAnnotation; 23 import org.apache.beehive.netui.compiler.Diagnostics; 24 import org.apache.beehive.netui.compiler.FatalCompileTimeException; 25 import org.apache.beehive.netui.compiler.model.FormBeanModel; 26 import org.apache.beehive.netui.compiler.model.validation.ValidationModel; 27 import org.apache.beehive.netui.compiler.model.validation.ValidatorConstants; 28 import org.apache.beehive.netui.compiler.model.validation.ValidatorRule; 29 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationInstance; 30 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationValue; 31 import org.apache.beehive.netui.compiler.typesystem.declaration.ClassDeclaration; 32 import org.apache.beehive.netui.compiler.typesystem.declaration.MethodDeclaration; 33 import org.apache.beehive.netui.compiler.typesystem.declaration.Modifier; 34 import org.apache.beehive.netui.compiler.typesystem.declaration.TypeDeclaration; 35 import org.apache.beehive.netui.compiler.typesystem.declaration.ParameterDeclaration; 36 import org.apache.beehive.netui.compiler.typesystem.type.DeclaredType; 37 import org.apache.beehive.netui.compiler.typesystem.type.TypeInstance; 38 import org.apache.beehive.netui.compiler.typesystem.type.ClassType; 39 import org.apache.beehive.netui.compiler.typesystem.env.AnnotationProcessorEnvironment; 40 import org.apache.xmlbeans.XmlException; 41 42 import java.io.File ; 43 import java.io.FileNotFoundException ; 44 import java.io.FileOutputStream ; 45 import java.io.IOException ; 46 import java.io.PrintStream ; 47 import java.util.Collection ; 48 import java.util.Iterator ; 49 import java.util.List ; 50 import java.util.Locale ; 51 import java.util.Map ; 52 import java.util.ArrayList ; 53 54 public class GenValidationModel 55 extends ValidationModel 56 implements JpfLanguageConstants, ValidatorConstants 57 { 58 private static final String STRUTS_VALIDATION_PREFIX = "jpf-validation"; 59 private static final ValidatorRuleFactory VALIDATOR_RULE_FACTORY = new DefaultValidatorRuleFactory(); 60 61 private GenStrutsApp _strutsApp; 62 private File _mergeFile; 63 private AnnotationProcessorEnvironment _env; 64 65 66 public GenValidationModel( ClassDeclaration jclass, GenStrutsApp strutsApp, AnnotationProcessorEnvironment env ) 67 throws FatalCompileTimeException 68 { 69 MergedControllerAnnotation mca = strutsApp.getFlowControllerInfo().getMergedControllerAnnotation(); 70 _strutsApp = strutsApp; 71 setValidatorVersion( mca.getValidatorVersion() ); 72 addRulesFromBeans( jclass ); 73 addRulesFromActions( jclass, mca ); 74 addRulesFromClass( mca ); 75 String mergeFileName = mca.getValidatorMerge(); 76 _mergeFile = strutsApp.getMergeFile( mergeFileName ); 77 _env = env; 78 } 79 80 private void addRulesFromBeans( ClassDeclaration jclass ) 81 { 82 Collection innerTypes = CompilerUtils.getClassNestedTypes( jclass ); 86 87 for ( Iterator ii = innerTypes.iterator(); ii.hasNext(); ) 88 { 89 TypeDeclaration innerType = ( TypeDeclaration ) ii.next(); 90 if ( innerType instanceof ClassDeclaration 91 && innerType.hasModifier( Modifier.PUBLIC ) 92 && innerType.hasModifier( Modifier.STATIC ) ) 93 { 94 addRulesFromBeanClass( ( ClassDeclaration ) innerType ); 95 } 96 } 97 } 98 99 private void addRulesFromBeanClass( ClassDeclaration beanClass ) 100 { 101 Collection properties = CompilerUtils.getBeanProperties( beanClass, true ); 102 103 for ( Iterator ii = properties.iterator(); ii.hasNext(); ) 104 { 105 CompilerUtils.BeanPropertyDeclaration property = ( CompilerUtils.BeanPropertyDeclaration ) ii.next(); 106 MethodDeclaration getter = property.getGetter(); 107 String propertyName = property.getPropertyName(); 108 109 if ( getter != null ) 110 { 111 AnnotationInstance[] annotations = getter.getAnnotationInstances(); 115 116 if ( annotations != null ) 117 { 118 List formNames = getFormBeanNames( beanClass ); 119 120 for ( Iterator j = formNames.iterator(); j.hasNext(); ) 121 { 122 String formName = ( String ) j.next(); 123 124 for ( int i = 0; i < annotations.length; i++ ) 125 { 126 AnnotationInstance ann = annotations[i]; 127 128 if ( CompilerUtils.isJpfAnnotation( ann, VALIDATABLE_PROPERTY_TAG_NAME ) ) 129 { 130 addRulesFromAnnotation( ann, formName, propertyName ); 134 } 135 } 136 } 137 } 138 } 139 } 140 } 141 142 143 private void addRulesFromAnnotation( AnnotationInstance validationFieldAnn, String entityName, String propertyName ) 144 { 145 Collection localeRulesAnnotations = 149 CompilerUtils.getAnnotationArray( validationFieldAnn, LOCALE_RULES_ATTR, false ); 150 String displayName = CompilerUtils.getString( validationFieldAnn, DISPLAY_NAME_ATTR, true ); 151 String displayNameKey = CompilerUtils.getString( validationFieldAnn, DISPLAY_NAME_KEY_ATTR, true ); 152 RuleInfo ruleInfo = new RuleInfo( entityName, propertyName, displayName, displayNameKey ); 153 154 155 for ( Iterator ii = localeRulesAnnotations.iterator(); ii.hasNext(); ) 156 { 157 AnnotationInstance ann = ( AnnotationInstance ) ii.next(); 158 addFieldRules( ann, ruleInfo, false ); 159 } 160 161 addFieldRules( validationFieldAnn, ruleInfo, true ); 162 } 163 164 private void addRulesFromActions( ClassDeclaration jclass, MergedControllerAnnotation mca ) 165 { 166 MethodDeclaration[] methods = CompilerUtils.getClassMethods( jclass, ACTION_TAG_NAME ); 167 168 for ( int i = 0; i < methods.length; i++ ) 169 { 170 MethodDeclaration method = methods[i]; 171 AnnotationInstance actionAnnotation = CompilerUtils.getAnnotation( method, ACTION_TAG_NAME ); 172 assert actionAnnotation != null; 173 addRulesFromActionAnnotation( actionAnnotation, method.getSimpleName() ); 174 175 ParameterDeclaration[] parameters = method.getParameters(); 176 if ( parameters.length > 0 ) 177 { 178 TypeInstance type = parameters[0].getType(); 179 180 if ( type instanceof ClassType ) 181 { 182 ClassDeclaration classDecl = ( ( ClassType ) type ).getClassTypeDeclaration(); 183 if ( classDecl.getDeclaringType() == null ) addRulesFromBeanClass( classDecl ); 184 } 185 } 186 } 187 188 189 Collection simpleActions = mca.getSimpleActions(); 190 191 if ( simpleActions != null ) 192 { 193 for ( Iterator ii = simpleActions.iterator(); ii.hasNext(); ) 194 { 195 AnnotationInstance simpleAction = ( AnnotationInstance ) ii.next(); 196 String actionName = CompilerUtils.getString( simpleAction, NAME_ATTR, true ); 197 assert actionName != null; addRulesFromActionAnnotation( simpleAction, actionName ); 199 } 200 } 201 } 202 203 private void addRulesFromActionAnnotation( AnnotationInstance actionAnnotation, String actionName ) 204 { 205 Collection validatablePropertyAnnotations = 206 CompilerUtils.getAnnotationArray( actionAnnotation, VALIDATABLE_PROPERTIES_ATTR, false ); 207 208 for ( Iterator ii = validatablePropertyAnnotations.iterator(); ii.hasNext(); ) 209 { 210 AnnotationInstance validationFieldAnnotation = ( AnnotationInstance ) ii.next(); 211 String propertyName = CompilerUtils.getString( validationFieldAnnotation, PROPERTY_NAME_ATTR, true ); 212 assert propertyName != null; assert ! propertyName.equals( "" ); 215 String actionPath = '/' + actionName; addRulesFromAnnotation( validationFieldAnnotation, actionPath, propertyName ); 220 } 221 } 222 223 226 private List getFormBeanNames( TypeDeclaration beanType ) 227 { 228 String actualType = CompilerUtils.getLoadableName( beanType ); 229 List formBeans = _strutsApp.getFormBeansByActualType( actualType, null ); 230 ArrayList formBeanNames = new ArrayList (); 231 232 if ( formBeans == null ) 233 { 234 String beanClassName = CompilerUtils.getFormClassName( beanType, _strutsApp.getEnv() ); 235 String formName = _strutsApp.getFormNameForType( actualType, false ); 236 FormBeanModel formBean = new FormBeanModel( formName, beanClassName, actualType, false, _strutsApp ); 237 _strutsApp.addFormBean( formBean ); 238 formBeanNames.add( formBean.getName() ); 239 } 240 else 241 { 242 for ( Iterator i = formBeans.iterator(); i.hasNext(); ) 243 { 244 FormBeanModel formBeanModel = ( FormBeanModel ) i.next(); 245 formBeanNames.add( formBeanModel.getName() ); 246 } 247 } 248 249 return formBeanNames; 250 } 251 252 private void addRulesFromClass( MergedControllerAnnotation mca ) 253 { 254 Collection validationBeanAnnotations = mca.getValidatableBeans(); 255 256 for ( Iterator ii = validationBeanAnnotations.iterator(); ii.hasNext(); ) 257 { 258 AnnotationInstance validationBeanAnnotation = ( AnnotationInstance ) ii.next(); 259 DeclaredType beanType = CompilerUtils.getDeclaredType( validationBeanAnnotation, TYPE_ATTR, true ); 260 assert beanType != null; 262 Collection validationFieldAnnotations = 263 CompilerUtils.getAnnotationArray( validationBeanAnnotation, VALIDATABLE_PROPERTIES_ATTR, false ); 264 265 for ( Iterator i2 = validationFieldAnnotations.iterator(); i2.hasNext(); ) 266 { 267 AnnotationInstance validationFieldAnnotation = ( AnnotationInstance ) i2.next(); 268 String propName = CompilerUtils.getString( validationFieldAnnotation, PROPERTY_NAME_ATTR, true ); 269 assert propName != null; assert ! propName.equals( "" ); 272 List formNames = getFormBeanNames( CompilerUtils.getDeclaration( beanType ) ); 277 278 for ( Iterator j = formNames.iterator(); j.hasNext(); ) 279 { 280 String formName = ( String ) j.next(); 281 addRulesFromAnnotation( validationFieldAnnotation, formName, propName ); 282 } 283 } 284 } 285 } 286 287 290 private void addFieldRules( AnnotationInstance rulesContainerAnnotation, RuleInfo ruleInfo, 291 boolean applyToAllLocales ) 292 { 293 Locale locale = null; 297 298 if ( ! applyToAllLocales ) 299 { 300 String language = CompilerUtils.getString( rulesContainerAnnotation, LANGUAGE_ATTR, true ); 301 302 if ( language != null ) 307 { 308 String country = CompilerUtils.getString( rulesContainerAnnotation, COUNTRY_ATTR, true ); 309 String variant = CompilerUtils.getString( rulesContainerAnnotation, VARIANT_ATTR, true ); 310 311 language = language.trim(); 312 if ( country != null ) country = country.trim(); 313 if ( variant != null ) variant = variant.trim(); 314 315 if ( country != null && variant != null ) locale = new Locale ( language, country, variant ); 316 else if ( country != null ) locale = new Locale ( language, country ); 317 else locale = new Locale ( language ); 318 } 319 } 320 321 Map valuesPresent = rulesContainerAnnotation.getElementValues(); 322 323 for ( Iterator ii = valuesPresent.entrySet().iterator(); ii.hasNext(); ) 324 { 325 Map.Entry entry = ( Map.Entry ) ii.next(); 326 AnnotationValue value = ( AnnotationValue ) entry.getValue(); 327 Object val = value.getValue(); 328 329 if ( val instanceof AnnotationInstance ) 330 { 331 addFieldRuleFromAnnotation( ruleInfo, ( AnnotationInstance ) val, locale, applyToAllLocales ); 332 } 333 else if ( val instanceof List ) 334 { 335 List annotations = CompilerUtils.getAnnotationArray( value ); 336 337 for ( Iterator i3 = annotations.iterator(); i3.hasNext(); ) 338 { 339 AnnotationInstance i = ( AnnotationInstance ) i3.next(); 340 addFieldRuleFromAnnotation( ruleInfo, i, locale, applyToAllLocales ); 341 } 342 } 343 } 344 345 setEmpty( false ); } 347 348 private void addFieldRuleFromAnnotation( RuleInfo ruleInfo, AnnotationInstance annotation, Locale locale, 349 boolean applyToAllLocales ) 350 { 351 352 ValidatorRule rule = getFieldRule( ruleInfo.getEntityName(), ruleInfo.getFieldName(), annotation ); 353 354 if ( rule != null ) 355 { 356 if ( applyToAllLocales ) 357 { 358 addFieldRuleForAllLocales( ruleInfo, rule ); 359 } 360 else 361 { 362 addFieldRule( ruleInfo, rule, locale ); 363 } 364 } 365 } 366 367 private static ValidatorRule getFieldRule( String entityName, String propertyName, AnnotationInstance ruleAnnotation ) 368 { 369 ValidatorRule rule = VALIDATOR_RULE_FACTORY.getFieldRule( entityName, propertyName, ruleAnnotation ); 370 371 if ( rule != null ) 372 { 373 rule.setMessage( CompilerUtils.getString( ruleAnnotation, MESSAGE_ATTR, true ) ); 377 rule.setMessageKey( CompilerUtils.getString( ruleAnnotation, MESSAGE_KEY_ATTR, true ) ); 378 rule.setBundle( CompilerUtils.getString( ruleAnnotation, BUNDLE_NAME_ATTR, true ) ); 379 if ( rule.getMessage() != null ) assert rule.getMessageKey() == null; 381 addMessageArgs( rule, ruleAnnotation ); 385 } 386 387 return rule; 388 } 389 390 protected static void addMessageArgs( ValidatorRule rule, AnnotationInstance annotation ) 391 { 392 List messageArgs = 393 CompilerUtils.getAnnotationArray( annotation, MESSAGE_ARGS_ATTR, true ); 394 395 if ( messageArgs != null ) 396 { 397 int inferredPosition = 0; 398 for ( Iterator ii = messageArgs.iterator(); ii.hasNext(); ) 399 { 400 AnnotationInstance ann = ( AnnotationInstance ) ii.next(); 401 String arg = CompilerUtils.getString( ann, ARG_ATTR, true ); 402 String bundle = CompilerUtils.getString( ann, BUNDLE_NAME_ATTR, true ); 403 Integer position = CompilerUtils.getInteger( ann, POSITION_ATTR, true ); 404 405 if ( position == null ) 406 { 407 position = new Integer ( inferredPosition ); 408 } 409 410 if ( arg != null ) 411 { 412 rule.setArg( arg, false, bundle, position ); 413 } 414 else 415 { 416 String argKey = CompilerUtils.getString( ann, ARG_KEY_ATTR, true ); 417 if ( argKey != null ) rule.setArg( argKey, true, bundle, position ); 418 } 419 420 inferredPosition++; 421 } 422 } 423 } 424 425 protected String getHeaderComment( File mergeFile ) 426 throws FatalCompileTimeException 427 { 428 return _strutsApp.getHeaderComment( mergeFile ); 429 } 430 431 public void writeToFile() 432 throws FileNotFoundException , XmlException, IOException , FatalCompileTimeException 433 { 434 String outputFile = 435 CompilerUtils.getWebBuildRoot( _env ) + _strutsApp.getOutputFileURI( STRUTS_VALIDATION_PREFIX ); 436 PrintStream printStream = new PrintStream ( new FileOutputStream ( outputFile ) ); 437 writeXml( printStream, _mergeFile ); 438 printStream.close(); 439 } 440 441 public String getOutputFileURI() 442 { 443 return _strutsApp.getOutputFileURI( STRUTS_VALIDATION_PREFIX ); 444 } 445 } 446 | Popular Tags |