View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.extensions.validator.util;
20  
21  import org.apache.myfaces.extensions.validator.core.ExtValContext;
22  import org.apache.myfaces.extensions.validator.core.ExtValCoreConfiguration;
23  import org.apache.myfaces.extensions.validator.core.ValidationModuleKey;
24  import org.apache.myfaces.extensions.validator.core.ProjectStageName;
25  import org.apache.myfaces.extensions.validator.core.el.AbstractELHelperFactory;
26  import org.apache.myfaces.extensions.validator.core.el.ELHelper;
27  import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;
28  import org.apache.myfaces.extensions.validator.core.factory.ClassMappingFactory;
29  import org.apache.myfaces.extensions.validator.core.factory.FacesMessageFactory;
30  import org.apache.myfaces.extensions.validator.core.factory.FactoryNames;
31  import org.apache.myfaces.extensions.validator.core.factory.NameMapperAwareFactory;
32  import org.apache.myfaces.extensions.validator.core.initializer.component.ComponentInitializer;
33  import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;
34  import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationEntry;
35  import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;
36  import org.apache.myfaces.extensions.validator.core.interceptor.MetaDataExtractionInterceptor;
37  import org.apache.myfaces.extensions.validator.core.interceptor.PropertyValidationInterceptor;
38  import org.apache.myfaces.extensions.validator.core.interceptor.ValidationExceptionInterceptor;
39  import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;
40  import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
41  import org.apache.myfaces.extensions.validator.core.metadata.extractor.ComponentMetaDataExtractorFactory;
42  import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;
43  import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;
44  import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
45  import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
46  import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
47  import org.apache.myfaces.extensions.validator.core.storage.FacesMessageStorage;
48  import org.apache.myfaces.extensions.validator.core.storage.StorageManager;
49  import org.apache.myfaces.extensions.validator.core.validation.SkipValidationEvaluator;
50  import org.apache.myfaces.extensions.validator.core.validation.message.resolver.MessageResolver;
51  import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameterExtractor;
52  import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameterExtractorFactory;
53  import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverityInterpreter;
54  import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;
55  import org.apache.myfaces.extensions.validator.internal.Priority;
56  import org.apache.myfaces.extensions.validator.internal.ToDo;
57  import org.apache.myfaces.extensions.validator.internal.UsageCategory;
58  import org.apache.myfaces.extensions.validator.internal.UsageInformation;
59  import org.apache.myfaces.extensions.validator.ExtValInformation;
60  
61  import javax.faces.application.FacesMessage;
62  import javax.faces.component.UIComponent;
63  import javax.faces.context.FacesContext;
64  import javax.faces.validator.ValidatorException;
65  import java.util.Map;
66  import java.util.HashMap;
67  import java.util.MissingResourceException;
68  import java.util.List;
69  import java.util.ArrayList;
70  import java.util.logging.Logger;
71  import java.lang.annotation.Annotation;
72  
73  /**
74   * @since 1.x.1
75   */
76  @SuppressWarnings({"unchecked"})
77  @UsageInformation(UsageCategory.INTERNAL)
78  public class ExtValUtils
79  {
80      private static final Logger LOGGER = Logger.getLogger(ExtValUtils.class.getName());
81  
82      private static final String JAVAX_FACES_REQUIRED = "javax.faces.component.UIInput.REQUIRED";
83      private static final String JAVAX_FACES_REQUIRED_DETAIL = "javax.faces.component.UIInput.REQUIRED_detail";
84  
85      private static final String JAVAX_FACES_MAXIMUM = "javax.faces.validator.LengthValidator.MAXIMUM";
86      private static final String JAVAX_FACES_MAXIMUM_DETAIL = "javax.faces.validator.LengthValidator.MAXIMUM_detail";
87  
88      public static ValidationStrategy getValidationStrategyForMetaData(String metaDataKey)
89      {
90          return ((ClassMappingFactory<String, ValidationStrategy>) ExtValContext.getContext()
91                  .getFactoryFinder()
92                  .getFactory(FactoryNames.VALIDATION_STRATEGY_FACTORY, ClassMappingFactory.class))
93                  .create(metaDataKey);
94      }
95  
96      public static void registerMetaDataToValidationStrategyNameMapper(
97              NameMapper<String> metaDataToValidationStrategyNameMapper)
98      {
99          (ExtValContext.getContext()
100                 .getFactoryFinder()
101                 .getFactory(FactoryNames.VALIDATION_STRATEGY_FACTORY, NameMapperAwareFactory.class))
102                 .register(metaDataToValidationStrategyNameMapper);
103     }
104 
105     public static void deregisterMetaDataToValidationStrategyNameMapper(
106             Class<? extends NameMapper> metaDataToValidationStrategyNameMapperClass)
107     {
108         (ExtValContext.getContext()
109                 .getFactoryFinder()
110                 .getFactory(FactoryNames.VALIDATION_STRATEGY_FACTORY, NameMapperAwareFactory.class))
111                 .deregister(metaDataToValidationStrategyNameMapperClass);
112     }
113 
114     public static void denyMetaDataToValidationStrategyNameMapper(
115             Class<? extends NameMapper> metaDataToValidationStrategyNameMapperClass)
116     {
117         (ExtValContext.getContext()
118                 .getFactoryFinder()
119                 .getFactory(FactoryNames.VALIDATION_STRATEGY_FACTORY, NameMapperAwareFactory.class))
120                 .deny(metaDataToValidationStrategyNameMapperClass);
121     }
122 
123     public static MetaDataTransformer getMetaDataTransformerForValidationStrategy(ValidationStrategy validationStrategy)
124     {
125         return ((ClassMappingFactory<ValidationStrategy, MetaDataTransformer>) ExtValContext
126                 .getContext().getFactoryFinder()
127                 .getFactory(FactoryNames.META_DATA_TRANSFORMER_FACTORY, ClassMappingFactory.class))
128                 .create(validationStrategy);
129     }
130 
131     public static void registerValidationStrategyToMetaDataTransformerNameMapper(
132             NameMapper<ValidationStrategy> validationStrategyToMetaDataTransformerNameMapper)
133     {
134         (ExtValContext.getContext()
135                 .getFactoryFinder()
136                 .getFactory(FactoryNames.META_DATA_TRANSFORMER_FACTORY, NameMapperAwareFactory.class))
137                 .register(validationStrategyToMetaDataTransformerNameMapper);
138     }
139 
140     public static void deregisterValidationStrategyToMetaDataTransformerNameMapper(
141             Class<? extends NameMapper> validationStrategyToMetaDataTransformerNameMapperClass)
142     {
143         (ExtValContext.getContext()
144                 .getFactoryFinder()
145                 .getFactory(FactoryNames.META_DATA_TRANSFORMER_FACTORY, NameMapperAwareFactory.class))
146                 .deregister(validationStrategyToMetaDataTransformerNameMapperClass);
147     }
148 
149     public static void denyValidationStrategyToMetaDataTransformerNameMapper(
150             Class<? extends NameMapper> validationStrategyToMetaDataTransformerNameMapperClass)
151     {
152         (ExtValContext.getContext()
153                 .getFactoryFinder()
154                 .getFactory(FactoryNames.META_DATA_TRANSFORMER_FACTORY, NameMapperAwareFactory.class))
155                 .deny(validationStrategyToMetaDataTransformerNameMapperClass);
156     }
157 
158     public static MetaDataExtractor getComponentMetaDataExtractor()
159     {
160         return ExtValContext.getContext().getFactoryFinder()
161                 .getFactory(FactoryNames.COMPONENT_META_DATA_EXTRACTOR_FACTORY, ComponentMetaDataExtractorFactory.class)
162                 .create();
163     }
164 
165     public static MetaDataExtractor getComponentMetaDataExtractorWith(Map<String, Object> properties)
166     {
167         return ExtValContext.getContext().getFactoryFinder()
168                 .getFactory(FactoryNames.COMPONENT_META_DATA_EXTRACTOR_FACTORY, ComponentMetaDataExtractorFactory.class)
169                 .createWith(properties);
170     }
171 
172     public static void configureComponentWithMetaData(FacesContext facesContext,
173                                                       UIComponent uiComponent,
174                                                       Map<String, Object> metaData)
175     {
176         for (ComponentInitializer componentInitializer : ExtValContext.getContext().getComponentInitializers())
177         {
178             componentInitializer.configureComponent(facesContext, uiComponent, metaData);
179         }
180     }
181 
182     public static boolean executeAfterThrowingInterceptors(UIComponent uiComponent,
183                                                            MetaDataEntry metaDataEntry,
184                                                            Object convertedObject,
185                                                            ValidatorException validatorException,
186                                                            ValidationStrategy validatorExceptionSource)
187     {
188         boolean result = true;
189 
190         if (metaDataEntry == null)
191         {
192             metaDataEntry = new MetaDataEntry();
193         }
194 
195         for (ValidationExceptionInterceptor validationExceptionInterceptor : ExtValContext.getContext()
196                 .getValidationExceptionInterceptors())
197         {
198             if (!validationExceptionInterceptor.afterThrowing(
199                     uiComponent, metaDataEntry, convertedObject, validatorException, validatorExceptionSource))
200             {
201                 result = false;
202             }
203         }
204 
205         return result;
206     }
207 
208     public static MetaDataExtractor createInterceptedMetaDataExtractor(final MetaDataExtractor metaDataExtractor)
209     {
210         return createInterceptedMetaDataExtractorWith(metaDataExtractor, null);
211     }
212 
213     public static MetaDataExtractor createInterceptedMetaDataExtractorFor(
214             final MetaDataExtractor metaDataExtractor, Class moduleKey)
215     {
216         Map<String, Object> properties = new HashMap<String, Object>();
217 
218         if(moduleKey != null)
219         {
220             properties.put(ValidationModuleKey.class.getName(), moduleKey);
221         }
222         return createInterceptedMetaDataExtractorWith(metaDataExtractor, properties);
223     }
224 
225     public static MetaDataExtractor createInterceptedMetaDataExtractorWith(
226             final MetaDataExtractor metaDataExtractor, final Map<String, Object> properties)
227     {
228         return new MetaDataExtractor()
229         {
230             public PropertyInformation extract(FacesContext facesContext, Object object)
231             {
232                 PropertyInformation result = metaDataExtractor.extract(facesContext, object);
233 
234                 addProperties(result, properties);
235                 invokeMetaDataExtractionInterceptors(result, properties);
236 
237                 return result;
238             }
239         };
240     }
241 
242     private static void addProperties(PropertyInformation result, Map<String, Object> properties)
243     {
244         if(properties != null)
245         {
246             Map<String, Object> customProperties = getCustomProperties(result);
247             customProperties.putAll(properties);
248         }
249     }
250 
251     private static Map<String, Object> getCustomProperties(PropertyInformation propertyInformation)
252     {
253         if(!propertyInformation.containsInformation(PropertyInformationKeys.CUSTOM_PROPERTIES))
254         {
255             propertyInformation.setInformation(
256                     PropertyInformationKeys.CUSTOM_PROPERTIES, new HashMap<String, Object>());
257         }
258 
259         return (Map<String, Object>) propertyInformation.getInformation(PropertyInformationKeys.CUSTOM_PROPERTIES);
260     }
261 
262     private static void invokeMetaDataExtractionInterceptors(PropertyInformation result, Map<String, Object> properties)
263     {
264         for (MetaDataExtractionInterceptor metaDataExtractionInterceptor :
265                 ExtValContext.getContext().getMetaDataExtractionInterceptorsWith(properties))
266         {
267             metaDataExtractionInterceptor.afterExtracting(result);
268         }
269     }
270 
271     public static MessageResolver getMessageResolverForValidationStrategy(ValidationStrategy validationStrategy)
272     {
273         return ((ClassMappingFactory<ValidationStrategy, MessageResolver>) ExtValContext.getContext()
274                 .getFactoryFinder()
275                 .getFactory(FactoryNames.MESSAGE_RESOLVER_FACTORY, ClassMappingFactory.class))
276                 .create(validationStrategy);
277     }
278 
279     public static void registerValidationStrategyToMessageResolverNameMapper(
280             NameMapper<ValidationStrategy> validationStrategyToMsgResolverNameMapper)
281     {
282         (ExtValContext.getContext()
283                 .getFactoryFinder()
284                 .getFactory(FactoryNames.MESSAGE_RESOLVER_FACTORY, NameMapperAwareFactory.class))
285                 .register(validationStrategyToMsgResolverNameMapper);
286     }
287 
288     public static void deregisterValidationStrategyToMessageResolverNameMapper(
289             Class<? extends NameMapper> validationStrategyToMessageResolverNameMapperClass)
290     {
291         (ExtValContext.getContext()
292                 .getFactoryFinder()
293                 .getFactory(FactoryNames.MESSAGE_RESOLVER_FACTORY, NameMapperAwareFactory.class))
294                 .deregister(validationStrategyToMessageResolverNameMapperClass);
295     }
296 
297     public static void denyValidationStrategyToMessageResolverNameMapper(
298             Class<? extends NameMapper> validationStrategyToMessageResolverNameMapperClass)
299     {
300         (ExtValContext.getContext()
301                 .getFactoryFinder()
302                 .getFactory(FactoryNames.MESSAGE_RESOLVER_FACTORY, NameMapperAwareFactory.class))
303                 .deny(validationStrategyToMessageResolverNameMapperClass);
304     }
305 
306     public static ELHelper getELHelper()
307     {
308         return ExtValContext.getContext().getFactoryFinder()
309                 .getFactory(FactoryNames.EL_HELPER_FACTORY, AbstractELHelperFactory.class).create();
310     }
311 
312     public static FacesMessage createFacesMessage(String summary, String detail)
313     {
314         return createFacesMessage(FacesMessage.SEVERITY_ERROR, summary, detail);
315     }
316 
317     public static FacesMessage createFacesMessage(FacesMessage.Severity severity, String summary, String detail)
318     {
319         return ExtValContext.getContext().getFactoryFinder()
320                 .getFactory(FactoryNames.FACES_MESSAGE_FACTORY, FacesMessageFactory.class)
321                 .create(severity, summary, detail);
322     }
323 
324     public static FacesMessage convertFacesMessage(FacesMessage facesMessage)
325     {
326         return ExtValContext.getContext().getFactoryFinder()
327                 .getFactory(FactoryNames.FACES_MESSAGE_FACTORY, FacesMessageFactory.class)
328                 .convert(facesMessage);
329     }
330 
331     public static PropertyDetails createPropertyDetailsForNewTarget(MetaDataEntry metaDataEntry,
332                                                                     String targetExpression)
333     {
334         Object baseObject;
335         if (getELHelper().isELTermWellFormed(targetExpression))
336         {
337             ValueBindingExpression vbe = new ValueBindingExpression(targetExpression);
338 
339             String expression = vbe.getExpressionString();
340             baseObject = getELHelper().getValueOfExpression(FacesContext.getCurrentInstance(), vbe.getBaseExpression());
341             return new PropertyDetails(
342                     expression.substring(2, expression.length() - 1), baseObject, vbe.getProperty());
343         }
344 
345         PropertyDetails original = metaDataEntry.getProperty(
346                 PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);
347 
348         String newBaseKey = original.getKey().substring(0, original.getKey().lastIndexOf(".") + 1);
349         String newKey = newBaseKey + targetExpression;
350 
351         baseObject = ReflectionUtils.getBaseOfPropertyChain(original.getBaseObject(), targetExpression);
352         return new PropertyDetails(
353                 newKey, baseObject, targetExpression.substring(targetExpression.lastIndexOf(".") + 1,
354                         targetExpression.length()));
355     }
356 
357     @UsageInformation(UsageCategory.INTERNAL)
358     public static void tryToPlaceLabel(FacesMessage facesMessage, String label, int index)
359     {
360         if (facesMessage.getSummary() != null && facesMessage.getSummary().contains("{" + index + "}"))
361         {
362             facesMessage.setSummary(facesMessage.getSummary().replace("{" + index + "}", label));
363         }
364 
365         if (facesMessage.getDetail() != null && facesMessage.getDetail().contains("{" + index + "}"))
366         {
367             facesMessage.setDetail(facesMessage.getDetail().replace("{" + index + "}", label));
368         }
369     }
370 
371     @UsageInformation(UsageCategory.INTERNAL)
372     public static void replaceWithDefaultMaximumMessage(FacesMessage facesMessage, int maxLength)
373     {
374         String facesRequiredMessage = JsfUtils.getMessageFromApplicationMessageBundle(JAVAX_FACES_MAXIMUM);
375         String facesRequiredMessageDetail = facesRequiredMessage;
376 
377         //use try/catch for easier sync between trunk/branch
378         try
379         {
380             if (JsfUtils.getMessageFromApplicationMessageBundle(JAVAX_FACES_MAXIMUM_DETAIL) != null)
381             {
382                 facesRequiredMessageDetail = JsfUtils
383                         .getMessageFromApplicationMessageBundle(JAVAX_FACES_MAXIMUM_DETAIL);
384             }
385         }
386         catch (MissingResourceException missingResourceException)
387         {
388             //jsf 1.2 doesn't have a detail message
389         }
390 
391         facesRequiredMessage = facesRequiredMessage.replace("{0}", "" + maxLength);
392         facesRequiredMessageDetail = facesRequiredMessageDetail.replace("{0}", "" + maxLength);
393 
394         facesMessage.setSummary(facesRequiredMessage);
395         facesMessage.setDetail(facesRequiredMessageDetail);
396     }
397 
398     @UsageInformation(UsageCategory.INTERNAL)
399     public static void replaceWithDefaultRequiredMessage(FacesMessage facesMessage)
400     {
401         String facesRequiredMessage = JsfUtils.getMessageFromApplicationMessageBundle(JAVAX_FACES_REQUIRED);
402         String facesRequiredMessageDetail = facesRequiredMessage;
403 
404         //use try/catch for easier sync between trunk/branch
405         try
406         {
407             if (JsfUtils.getMessageFromApplicationMessageBundle(JAVAX_FACES_REQUIRED_DETAIL) != null)
408             {
409                 facesRequiredMessageDetail = JsfUtils
410                         .getMessageFromApplicationMessageBundle(JAVAX_FACES_REQUIRED_DETAIL);
411             }
412         }
413         catch (MissingResourceException missingResourceException)
414         {
415             //jsf 1.2 doesn't have a detail message
416         }
417 
418         facesMessage.setSummary(facesRequiredMessage);
419         facesMessage.setDetail(facesRequiredMessageDetail);
420     }
421 
422     public static boolean isSkipableValidationStrategy(Class<? extends ValidationStrategy> targetClass)
423     {
424         for (Class currentClass : getSkipValidationSupportClassList())
425         {
426             if (isSkipValidationSupported(currentClass, targetClass))
427             {
428                 return true;
429             }
430         }
431 
432         return false;
433     }
434 
435     public static boolean processMetaDataEntryAfterSkipValidation(
436             Class<? extends ValidationStrategy> targetClass, MetaDataEntry entry)
437     {
438         return isSkipableValidationStrategy(targetClass) &&
439                 Boolean.TRUE.equals(entry.getProperty(PropertyInformationKeys.SKIP_VALIDATION, Boolean.class));
440     }
441 
442     public static List<Class> getSkipValidationSupportClassList()
443     {
444         List<StaticConfiguration<String, String>> staticConfigurationList = ExtValContext.getContext()
445                 .getStaticConfiguration(StaticConfigurationNames.SKIP_VALIDATION_SUPPORT_CONFIG);
446 
447         List<Class> markerList = new ArrayList<Class>();
448 
449         Class currentClass;
450         for (StaticConfiguration<String, String> currentEntry : staticConfigurationList)
451         {
452             for (StaticConfigurationEntry<String, String> currentConfigurationEntry : currentEntry.getMapping())
453             {
454                 currentClass = ClassUtils.tryToLoadClassForName(currentConfigurationEntry.getTarget());
455 
456                 if (currentClass != null)
457                 {
458                     markerList.add(currentClass);
459                 }
460                 else
461                 {
462                     LOGGER.warning("configuration entry provides an invalid entry: "
463                             + currentConfigurationEntry.getTarget());
464                 }
465             }
466         }
467 
468         return markerList;
469     }
470 
471     @SuppressWarnings({"unchecked"})
472     public static boolean isSkipValidationSupported(Class currentClass, Class targetClass)
473     {
474         if (currentClass.isAnnotation())
475         {
476             if (targetClass.isAnnotationPresent(currentClass))
477             {
478                 return true;
479             }
480         }
481         else
482         {
483             if (currentClass.isAssignableFrom(targetClass))
484             {
485                 return true;
486             }
487         }
488 
489         return false;
490     }
491 
492     public static ValidationParameterExtractor getValidationParameterExtractor()
493     {
494         if(isValidationParameterExtractionDeactivated())
495         {
496             return new ValidationParameterExtractor() {
497 
498                 public Map<Object, List<Object>> extract(Annotation annotation)
499                 {
500                     return new HashMap<Object, List<Object>>();
501                 }
502 
503                 public List<Object> extract(Annotation annotation, Object key)
504                 {
505                     return new ArrayList<Object>();
506                 }
507 
508                 public <T> List<T> extract(Annotation annotation, Object key, Class<T> valueType)
509                 {
510                     return new ArrayList<T>();
511                 }
512 
513                 public <T> T extract(Annotation annotation, Object key, Class<T> valueType, Class valueId)
514                 {
515                     return null;
516                 }
517             };
518         }
519         return ExtValContext.getContext().getFactoryFinder().getFactory(
520                 FactoryNames.VALIDATION_PARAMETER_EXTRACTOR_FACTORY, ValidationParameterExtractorFactory.class)
521                 .create();
522     }
523 
524     public static Class getValidationParameterClassFor(Class source)
525     {
526          ClassMappingFactory<Class, Class> validationParameterFactory = ExtValContext.getContext().getFactoryFinder()
527                  .getFactory(FactoryNames.VALIDATION_PARAMETER_FACTORY, ClassMappingFactory.class);
528 
529         return validationParameterFactory.create(source);
530     }
531 
532     private static boolean isValidationParameterExtractionDeactivated()
533     {
534         return ExtValCoreConfiguration.get().deactivateValidationParameters();
535     }
536 
537     public static boolean executeLocalBeforeValidationInterceptors(FacesContext facesContext,
538                                                                    UIComponent uiComponent,
539                                                                    Object convertedObject,
540                                                                    String propertyKey,
541                                                                    Object properties,
542                                                                    Annotation annotation)
543     {
544         Map<String, Object> propertyMap = new HashMap<String, Object>();
545         List<PropertyValidationInterceptor> propertyValidationInterceptors = getValidationParameterExtractor().extract(
546                 annotation, PropertyValidationInterceptor.class, PropertyValidationInterceptor.class);
547         boolean result = true;
548 
549         if (properties != null)
550         {
551             propertyMap.put(propertyKey, properties);
552         }
553         propertyMap.put(Annotation.class.getName(), annotation);
554 
555         for (PropertyValidationInterceptor propertyValidationInterceptor : propertyValidationInterceptors)
556         {
557             if (!propertyValidationInterceptor
558                     .beforeValidation(facesContext, uiComponent, convertedObject, propertyMap))
559             {
560                 result = false;
561             }
562         }
563 
564         return result;
565     }
566 
567     public static void executeLocalAfterValidationInterceptors(FacesContext facesContext,
568                                                                UIComponent uiComponent,
569                                                                Object convertedObject,
570                                                                String propertyKey,
571                                                                Object properties,
572                                                                Annotation annotation)
573     {
574         Map<String, Object> propertyMap = new HashMap<String, Object>();
575         List<PropertyValidationInterceptor> propertyValidationInterceptors = getValidationParameterExtractor().extract(
576                 annotation, PropertyValidationInterceptor.class, PropertyValidationInterceptor.class);
577 
578         if (properties != null)
579         {
580             propertyMap.put(propertyKey, properties);
581             propertyMap.put(Annotation.class.getName(), annotation);
582         }
583 
584         for (PropertyValidationInterceptor propertyValidationInterceptor : propertyValidationInterceptors)
585         {
586             propertyValidationInterceptor.afterValidation(facesContext, uiComponent, convertedObject, propertyMap);
587         }
588     }
589 
590     @ToDo(value = Priority.MEDIUM, description = "is renaming ok?")
591     public static boolean executeGlobalBeforeValidationInterceptors(FacesContext facesContext,
592                                                                     UIComponent uiComponent,
593                                                                     Object convertedObject,
594                                                                     String propertyKey,
595                                                                     Object properties,
596                                                                     Class moduleKey)
597     {
598         Map<String, Object> propertyMap = new HashMap<String, Object>();
599         boolean result = true;
600 
601         if (properties != null)
602         {
603             propertyMap.put(propertyKey, properties);
604         }
605 
606         List<PropertyValidationInterceptor> propertyValidationInterceptors =
607                 ExtValContext.getContext().getPropertyValidationInterceptorsFor(moduleKey);
608 
609         for (PropertyValidationInterceptor propertyValidationInterceptor : propertyValidationInterceptors)
610         {
611             if (!propertyValidationInterceptor
612                     .beforeValidation(facesContext, uiComponent, convertedObject, propertyMap))
613             {
614                 result = false;
615             }
616         }
617 
618         return result;
619     }
620 
621     @ToDo(value = Priority.MEDIUM, description = "is renaming ok?")
622     public static void executeGlobalAfterValidationInterceptors(FacesContext facesContext,
623                                                                 UIComponent uiComponent,
624                                                                 Object convertedObject,
625                                                                 String propertyKey,
626                                                                 Object properties,
627                                                                 Class moduleKey)
628     {
629         Map<String, Object> propertyMap = new HashMap<String, Object>();
630 
631         if (properties != null)
632         {
633             propertyMap.put(propertyKey, properties);
634         }
635 
636         List<PropertyValidationInterceptor> propertyValidationInterceptors =
637                 ExtValContext.getContext().getPropertyValidationInterceptorsFor(moduleKey);
638 
639         for (PropertyValidationInterceptor propertyValidationInterceptor : propertyValidationInterceptors)
640         {
641             propertyValidationInterceptor.afterValidation(facesContext, uiComponent, convertedObject, propertyMap);
642         }
643     }
644 
645     public static <T> T getStorage(Class<T> storageType, String storageName)
646     {
647         T storage = getCachedStorage(storageType, storageName);
648 
649         if(storage != null)
650         {
651             return storage;
652         }
653         storage = (T) getStorageManagerFactory().create(storageType).create(storageName);
654 
655         cacheStorageForRequest(storageType, storageName, storage);
656 
657         return storage;
658     }
659 
660     private static <T> T getCachedStorage(Class<T> storageType, String storageName)
661     {
662         Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
663 
664         String key = createStorageKey(storageType.getName(), storageName);
665         return (T)requestMap.get(key);
666     }
667 
668     private static <T> void cacheStorageForRequest(Class<T> storageType, String storageName, T storage)
669     {
670         Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
671 
672         String key = createStorageKey(storageType.getName(), storageName);
673         requestMap.put(key, storage);
674     }
675 
676     private static String createStorageKey(String storageType, String storageName)
677     {
678         StringBuilder key = new StringBuilder("cachedStorage:");
679         key.append(storageType);
680         key.append(":");
681         key.append(storageName);
682         return key.toString();
683     }
684 
685     public static void resetStorage(Class storageType, String storageName)
686     {
687         resetCachedStorage(storageType.getName(), storageName);
688 
689         getStorageManagerFactory().create(storageType).reset(storageName);
690     }
691 
692     private static void resetCachedStorage(String storageType, String storageName)
693     {
694         String key = createStorageKey(storageType, storageName);
695 
696         Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
697         requestMap.put(key, null);
698     }
699 
700     private static ClassMappingFactory<Class, StorageManager> getStorageManagerFactory()
701     {
702         return (ExtValContext.getContext()
703                 .getFactoryFinder()
704                 .getFactory(FactoryNames.STORAGE_MANAGER_FACTORY, ClassMappingFactory.class));
705     }
706 
707     public static Map<String, Object> getTransformedMetaData(FacesContext facesContext, UIComponent uiComponent)
708     {
709         return getTransformedMetaDataFor(facesContext, uiComponent, null);
710     }
711 
712     public static Map<String, Object> getTransformedMetaDataFor(
713             FacesContext facesContext, UIComponent uiComponent, Class moduleKey)
714     {
715         Map<String, Object> properties = new HashMap<String, Object>();
716 
717         if(moduleKey != null)
718         {
719             properties.put(ValidationModuleKey.class.getName(), moduleKey);
720         }
721 
722         return getTransformedMetaDataWith(facesContext, uiComponent, properties);
723     }
724 
725     public static Map<String, Object> getTransformedMetaDataFor(
726             FacesContext facesContext, PropertyInformation propertyInformation, Class moduleKey)
727     {
728         Map<String, Object> properties = new HashMap<String, Object>();
729 
730         if (moduleKey != null)
731         {
732             properties.put(ValidationModuleKey.class.getName(), moduleKey);
733         }
734 
735         return getTransformedMetaDataWith(facesContext, propertyInformation, properties);
736     }
737 
738     public static Map<String, Object> getTransformedMetaDataWith(
739             FacesContext facesContext, UIComponent uiComponent, Map<String, Object> properties)
740     {
741         ValidationStrategy validationStrategy;
742 
743         SkipValidationEvaluator skipValidationEvaluator = ExtValContext.getContext().getSkipValidationEvaluator();
744         MetaDataExtractor metaDataExtractor = getComponentMetaDataExtractorWith(properties);
745 
746         Map<String, Object> metaData;
747         Map<String, Object> metaDataResult = new HashMap<String, Object>();
748 
749         for (MetaDataEntry entry : metaDataExtractor.extract(facesContext, uiComponent).getMetaDataEntries())
750         {
751             metaData = new HashMap<String, Object>();
752             validationStrategy = getValidationStrategyForMetaData(entry.getKey());
753 
754             if (validationStrategy != null)
755             {
756                 metaData = transformMetaData(
757                         facesContext, uiComponent, validationStrategy, skipValidationEvaluator, metaData, entry);
758 
759                 if (!isComponentInitializationSkipped(metaData, entry, validationStrategy))
760                 {
761                     //don't break maybe there are constraints which don't support the skip-mechanism
762                     metaDataResult.putAll(metaData);
763                 }
764             }
765         }
766 
767         return metaDataResult;
768     }
769 
770     public static Map<String, Object> getTransformedMetaDataWith(FacesContext facesContext,
771                                                                  PropertyInformation propertyInformation,
772                                                                  Map<String, Object> properties)
773     {
774         ValidationStrategy validationStrategy;
775 
776         // This is called as part of the MetaData extraction in the default process. 
777         // So we need to do it here also before the transformations are run.
778         for (MetaDataExtractionInterceptor metaDataExtractionInterceptor :
779                 ExtValContext.getContext().getMetaDataExtractionInterceptorsWith(properties))
780         {
781             metaDataExtractionInterceptor.afterExtracting(propertyInformation);
782         }
783 
784         SkipValidationEvaluator skipValidationEvaluator = ExtValContext.getContext().getSkipValidationEvaluator();
785 
786         Map<String, Object> metaData;
787         Map<String, Object> metaDataResult = new HashMap<String, Object>();
788 
789         for (MetaDataEntry entry : propertyInformation.getMetaDataEntries())
790         {
791             metaData = new HashMap<String, Object>();
792             validationStrategy = getValidationStrategyForMetaData(entry.getKey());
793 
794             if (validationStrategy != null)
795             {
796                 metaData = transformMetaData(
797                         facesContext, null, validationStrategy, skipValidationEvaluator, metaData, entry);
798 
799                 if (!isComponentInitializationSkipped(metaData, entry, validationStrategy))
800                 {
801                     //don't break maybe there are constraints which don't support the skip-mechanism
802                     metaDataResult.putAll(metaData);
803                 }
804             }
805         }
806 
807         return metaDataResult;
808     }
809 
810     private static Map<String, Object> transformMetaData(FacesContext facesContext, UIComponent uiComponent,
811                                                          ValidationStrategy validationStrategy,
812                                                          SkipValidationEvaluator skipValidationEvaluator,
813                                                          Map<String, Object> metaData, MetaDataEntry entry)
814     {
815         if (!skipValidationEvaluator.skipValidation(facesContext, uiComponent, validationStrategy, entry))
816         {
817             MetaDataTransformer metaDataTransformer = getMetaDataTransformerForValidationStrategy(validationStrategy);
818 
819             if (metaDataTransformer != null)
820             {
821                 LOGGER.fine(metaDataTransformer.getClass().getName() + " instantiated");
822 
823                 metaData = metaDataTransformer.convertMetaData(entry);
824             }
825             else
826             {
827                 metaData = null;
828             }
829 
830             if (metaData == null)
831             {
832                 return new HashMap<String, Object>();
833             }
834         }
835         return metaData;
836     }
837 
838     private static boolean isComponentInitializationSkipped(Map<String, Object> metaData, MetaDataEntry entry,
839                                                             ValidationStrategy validationStrategy)
840     {
841         return metaData.isEmpty() ||
842                 (Boolean.TRUE.equals(entry.getProperty(PropertyInformationKeys.SKIP_VALIDATION, Boolean.class)) &&
843                         isSkipableValidationStrategy(ProxyUtils.getUnproxiedClass(
844                                 validationStrategy.getClass(), ValidationStrategy.class)));
845     }
846 
847     public static boolean interpretEmptyStringValuesAsNull()
848     {
849         //to deactivate: the parameter has to be explicitly false
850         return ExtValCoreConfiguration.get().interpretEmptyStringSubmittedValuesAsNull();
851     }
852 
853     public static boolean validateEmptyFields()
854     {
855         return ExtValCoreConfiguration.get().validateEmptyFields();
856     }
857 
858     public static PropertyDetails getPropertyDetails(PropertyInformation propertyInformation)
859     {
860         return propertyInformation.getInformation(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);
861     }
862 
863     public static void tryToThrowValidatorExceptionForComponentId(
864             String clientId, FacesMessage facesMessage, Throwable throwable)
865     {
866         UIComponent targetComponent = findComponent(clientId);
867 
868         tryToThrowValidatorExceptionForComponent(targetComponent, facesMessage, throwable);
869     }
870 
871     public static void tryToThrowValidatorExceptionForComponent(
872             UIComponent uiComponent, FacesMessage facesMessage, Throwable throwable)
873     {
874         ViolationSeverityInterpreter interpreter =
875                 ExtValContext.getContext().getViolationSeverityInterpreter();
876 
877         FacesContext facesContext = FacesContext.getCurrentInstance();
878 
879         if (interpreter.severityCausesValidatorException(facesContext, uiComponent, facesMessage.getSeverity()))
880         {
881             if (throwable == null)
882             {
883                 throw new ValidatorException(facesMessage);
884             }
885             else
886             {
887                 throw new ValidatorException(facesMessage, throwable);
888             }
889         }
890         else
891         {
892             tryToAddViolationMessageForComponent(uiComponent, facesMessage);
893         }
894     }
895 
896     public static void tryToAddViolationMessageForComponentId(String clientId, FacesMessage facesMessage)
897     {
898         UIComponent targetComponent = findComponent(clientId);
899 
900         if (targetComponent == null && clientId != null)
901         {
902             tryToAddViolationMessageForTestClientId(clientId, facesMessage);
903             return;
904         }
905         tryToAddViolationMessageForComponent(targetComponent, facesMessage);
906     }
907 
908     @ToDo(value = Priority.MEDIUM, description = "required for test frameworks - goal: remove it")
909     private static void tryToAddViolationMessageForTestClientId(String clientId, FacesMessage facesMessage)
910     {
911         ViolationSeverityInterpreter interpreter =
912                 ExtValContext.getContext().getViolationSeverityInterpreter();
913 
914         FacesContext facesContext = FacesContext.getCurrentInstance();
915 
916         if (interpreter.severityCausesViolationMessage(facesContext, null, facesMessage.getSeverity()))
917         {
918             addFacesMessage(clientId, facesMessage);
919         }
920         tryToBlocksNavigationForComponent(null, facesMessage);
921     }
922 
923     public static void tryToAddViolationMessageForComponent(UIComponent uiComponent, FacesMessage facesMessage)
924     {
925         ViolationSeverityInterpreter interpreter =
926                 ExtValContext.getContext().getViolationSeverityInterpreter();
927 
928         FacesContext facesContext = FacesContext.getCurrentInstance();
929 
930         if (interpreter.severityCausesViolationMessage(facesContext, uiComponent, facesMessage.getSeverity()))
931         {
932             if (uiComponent != null)
933             {
934                 addFacesMessage(uiComponent.getClientId(facesContext), facesMessage);
935             }
936             else
937             {
938                 addFacesMessage(null, facesMessage);
939             }
940         }
941         tryToBlocksNavigationForComponent(uiComponent, facesMessage);
942     }
943 
944     public static void addFacesMessage(FacesMessage facesMessage)
945     {
946         addFacesMessage(null, facesMessage);
947     }
948 
949     public static void addFacesMessage(String clientId, FacesMessage facesMessage)
950     {
951         FacesMessageStorage storage = getStorage(FacesMessageStorage.class, FacesMessageStorage.class.getName());
952 
953         if (storage != null)
954         {
955             storage.addFacesMessage(clientId, facesMessage);
956         }
957         else
958         {
959             FacesContext.getCurrentInstance().addMessage(clientId, facesMessage);
960         }
961     }
962 
963     public static void tryToBlocksNavigationForComponentId(String clientId, FacesMessage facesMessage)
964     {
965         UIComponent targetComponent = findComponent(clientId);
966 
967         tryToBlocksNavigationForComponent(targetComponent, facesMessage);
968     }
969 
970     public static void tryToBlocksNavigationForComponent(UIComponent uiComponent, FacesMessage facesMessage)
971     {
972         ViolationSeverityInterpreter interpreter =
973                 ExtValContext.getContext().getViolationSeverityInterpreter();
974 
975         FacesContext facesContext = FacesContext.getCurrentInstance();
976 
977         if (interpreter.severityBlocksNavigation(facesContext, uiComponent, facesMessage.getSeverity()))
978         {
979             facesContext.renderResponse();
980         }
981     }
982 
983     public static boolean severityBlocksSubmitForComponentId(String clientId, FacesMessage facesMessage)
984     {
985         ViolationSeverityInterpreter interpreter =
986                 ExtValContext.getContext().getViolationSeverityInterpreter();
987 
988         FacesContext facesContext = FacesContext.getCurrentInstance();
989         UIComponent targetComponent = findComponent(clientId);
990 
991         return interpreter.severityBlocksSubmit(facesContext, targetComponent, facesMessage.getSeverity());
992     }
993 
994     //available for add-ons - not used internally due to performance reasons
995     public static boolean severityShowsIndicationForComponentId(String clientId, FacesMessage facesMessage)
996     {
997         ViolationSeverityInterpreter interpreter =
998                 ExtValContext.getContext().getViolationSeverityInterpreter();
999 
1000         FacesContext facesContext = FacesContext.getCurrentInstance();
1001         UIComponent targetComponent = findComponent(clientId);
1002 
1003         return interpreter.severityShowsIndication(facesContext, targetComponent, facesMessage.getSeverity());
1004     }
1005 
1006     private static UIComponent findComponent(String clientId)
1007     {
1008         UIComponent targetComponent = null;
1009 
1010         if (clientId != null)
1011         {
1012             targetComponent = FacesContext.getCurrentInstance().getViewRoot().findComponent(clientId);
1013         }
1014         return targetComponent;
1015     }
1016 
1017     /**
1018      * @return true if component initialization for required validation is activated
1019      */
1020     public static boolean isRequiredInitializationActive()
1021     {
1022         return ExtValCoreConfiguration.get().activateRequiredInitialization();
1023     }
1024 
1025     /**
1026      * needed for some component libs - if required initialization is used e.g. for visual indicators
1027      * but features like severity aware validation aren't used.
1028      * in such a case it's possible to use the required attribute.
1029      *
1030      * @return false to deactivate the final reset of the value of the required attribute
1031      */
1032     public static boolean isRequiredResetActivated()
1033     {
1034         return ExtValCoreConfiguration.get().deactivateRequiredAttributeSupport();
1035     }
1036 
1037     public static ProjectStageName getDefaultStageName()
1038     {
1039         return createProjectStageName("Production");
1040     }
1041 
1042     public static ProjectStageName createProjectStageName(String name)
1043     {
1044         return DefaultProjectName.createProjectStageName(name);
1045     }
1046 
1047     public static boolean isExtValDeactivated()
1048     {
1049         return "true".equalsIgnoreCase(System
1050                 .getProperty(ExtValInformation.EXTENSIONS_VALIDATOR_BASE_PACKAGE_NAME +
1051                     ".DEACTIVATE_ALL", "false"));
1052     }
1053 }