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.core.interceptor;
20  
21  import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
22  import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
23  import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;
24  import org.apache.myfaces.extensions.validator.core.validation.message.LabeledMessage;
25  import org.apache.myfaces.extensions.validator.core.validation.exception.RequiredValidatorException;
26  import org.apache.myfaces.extensions.validator.core.InvocationOrder;
27  import org.apache.myfaces.extensions.validator.internal.UsageInformation;
28  import org.apache.myfaces.extensions.validator.internal.UsageCategory;
29  import org.apache.myfaces.extensions.validator.internal.ToDo;
30  import org.apache.myfaces.extensions.validator.internal.Priority;
31  import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
32  import org.apache.myfaces.extensions.validator.util.ExtValUtils;
33  
34  import javax.faces.component.UIComponent;
35  import javax.faces.component.html.HtmlInputText;
36  import javax.faces.component.html.HtmlInputSecret;
37  import javax.faces.component.html.HtmlSelectBooleanCheckbox;
38  import javax.faces.component.html.HtmlSelectOneListbox;
39  import javax.faces.component.html.HtmlSelectOneMenu;
40  import javax.faces.component.html.HtmlSelectOneRadio;
41  import javax.faces.component.html.HtmlSelectManyCheckbox;
42  import javax.faces.component.html.HtmlSelectManyListbox;
43  import javax.faces.component.html.HtmlSelectManyMenu;
44  import javax.faces.component.html.HtmlInputTextarea;
45  import javax.faces.context.FacesContext;
46  import javax.faces.validator.ValidatorException;
47  import javax.faces.application.FacesMessage;
48  import java.lang.annotation.Annotation;
49  import java.util.logging.Logger;
50  
51  /**
52   * @since 1.x.1
53   */
54  @InvocationOrder(100)
55  @UsageInformation(UsageCategory.INTERNAL)
56  public class HtmlCoreComponentsValidationExceptionInterceptor implements ValidationExceptionInterceptor
57  {
58      protected final Logger logger = Logger.getLogger(getClass().getName());
59  
60      public boolean afterThrowing(UIComponent uiComponent,
61                                   MetaDataEntry metaDataEntry,
62                                   Object convertedObject,
63                                   ValidatorException validatorException,
64                                   ValidationStrategy validatorExceptionSource)
65      {
66          if(processComponent(uiComponent))
67          {
68              FacesContext facesContext = FacesContext.getCurrentInstance();
69              FacesMessage facesMessage = ExtValUtils.convertFacesMessage(validatorException.getFacesMessage());
70  
71              tryToUseInlineMessage(uiComponent, validatorException);
72  
73              tryToUseLabel(facesContext, uiComponent, metaDataEntry, facesMessage);
74  
75              tryToBlocksNavigation(uiComponent, metaDataEntry, facesMessage);
76          }
77          return true;
78      }
79  
80      private void tryToUseInlineMessage(UIComponent uiComponent, ValidatorException validatorException)
81      {
82          FacesMessage facesMessage = validatorException.getFacesMessage();
83          String inlineMessage;
84  
85          if(validatorException instanceof RequiredValidatorException)
86          {
87              inlineMessage = getInlineRequiredMessage(uiComponent);
88  
89              if(inlineMessage != null)
90              {
91                  facesMessage.setSummary(inlineMessage);
92                  facesMessage.setDetail(inlineMessage);
93              }
94          }
95          else
96          {
97              //
98              inlineMessage = getInlineValidatorMessage(uiComponent);
99  
100             if(inlineMessage != null)
101             {
102                 facesMessage.setSummary(inlineMessage);
103                 facesMessage.setDetail(inlineMessage);
104             }
105         }
106     }
107 
108     private void tryToUseLabel(FacesContext facesContext,
109                                UIComponent uiComponent,
110                                MetaDataEntry metaDataEntry,
111                                FacesMessage facesMessage)
112     {
113         String label = (String) ReflectionUtils.tryToInvokeMethod(uiComponent,
114             ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "getLabel"));
115 
116         if(label == null)
117         {
118             label = uiComponent.getClientId(facesContext);
119         }
120 
121         //override the label if the annotation provides a label
122         if(metaDataEntry != null && metaDataEntry.getProperty(PropertyInformationKeys.LABEL) != null)
123         {
124             label = metaDataEntry.getProperty(PropertyInformationKeys.LABEL, String.class);
125         }
126 
127         if(facesMessage instanceof LabeledMessage)
128         {
129             ((LabeledMessage)facesMessage).setLabelText(label);
130         }
131         //if someone uses a normal faces message
132         else
133         {
134             for(int i = 0; i < 3; i++)
135             {
136                 ExtValUtils.tryToPlaceLabel(facesMessage, label, i);
137             }
138         }
139     }
140 
141     @ToDo(value = Priority.MEDIUM, description = "check if it is still required here")
142     private void tryToBlocksNavigation(UIComponent uiComponent, MetaDataEntry metaDataEntry, FacesMessage facesMessage)
143     {
144         if(metaDataEntry != null && metaDataEntry.getValue() instanceof Annotation)
145         {
146             //correct severity is e.g. provided by ViolationSeverityValidationExceptionInterceptor
147             ExtValUtils.tryToBlocksNavigationForComponent(uiComponent, facesMessage);
148         }
149     }
150 
151     private String getInlineRequiredMessage(UIComponent uiComponent)
152     {
153         return (String)ReflectionUtils.tryToInvokeMethod(uiComponent,
154                 ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "getRequiredMessage"));
155     }
156 
157     private String getInlineValidatorMessage(UIComponent uiComponent)
158     {
159         return (String)ReflectionUtils.tryToInvokeMethod(uiComponent,
160                 ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "getValidatorMessage"));
161     }
162 
163     protected boolean processComponent(UIComponent uiComponent)
164     {
165         return uiComponent instanceof HtmlInputText ||
166                 uiComponent instanceof HtmlInputSecret ||
167                 uiComponent instanceof HtmlSelectBooleanCheckbox ||
168                 uiComponent instanceof HtmlSelectOneListbox ||
169                 uiComponent instanceof HtmlSelectOneMenu ||
170                 uiComponent instanceof HtmlSelectOneRadio ||
171                 uiComponent instanceof HtmlSelectManyCheckbox ||
172                 uiComponent instanceof HtmlSelectManyListbox ||
173                 uiComponent instanceof HtmlSelectManyMenu ||
174                 uiComponent instanceof HtmlInputTextarea;
175     }
176 }