1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.view.facelets.tag.jsf;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import javax.el.ValueExpression;
26 import javax.faces.FacesWrapper;
27 import javax.faces.component.EditableValueHolder;
28 import javax.faces.component.UIComponent;
29 import javax.faces.context.FacesContext;
30 import javax.faces.validator.Validator;
31 import javax.faces.view.EditableValueHolderAttachedObjectHandler;
32 import javax.faces.view.facelets.ComponentHandler;
33 import javax.faces.view.facelets.FaceletContext;
34 import javax.faces.view.facelets.MetaRuleset;
35 import javax.faces.view.facelets.TagAttribute;
36 import javax.faces.view.facelets.TagException;
37 import javax.faces.view.facelets.TagHandlerDelegate;
38 import javax.faces.view.facelets.ValidatorHandler;
39 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
40
41 import org.apache.myfaces.shared.renderkit.JSFAttr;
42 import org.apache.myfaces.shared.util.WebConfigParamUtils;
43 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
44 import org.apache.myfaces.view.facelets.compiler.FaceletsCompilerUtils;
45 import org.apache.myfaces.view.facelets.tag.MetaRulesetImpl;
46
47
48
49
50
51
52
53
54
55
56
57
58 public class ValidatorTagHandlerDelegate extends TagHandlerDelegate
59 implements EditableValueHolderAttachedObjectHandler, FacesWrapper<ValidatorHandler>
60 {
61
62
63
64
65
66
67 public final static String VALIDATOR_ID_EXCLUSION_LIST_KEY
68 = "org.apache.myfaces.validator.VALIDATOR_ID_EXCLUSION_LIST";
69
70
71
72
73 @JSFWebConfigParam(defaultValue="false", expectedValues="true, false", since = "2.2.10", group="validation")
74 private final static String BEAN_BEFORE_JSF_VALIDATION
75 = "org.apache.myfaces.validator.BEAN_BEFORE_JSF_VALIDATION";
76
77 private final static String BEAN_BEFORE_JSF_PROPERTY = "oam.beanBeforeJsf";
78
79 private ValidatorHandler _delegate;
80
81
82
83
84
85 private final boolean _wrapMode;
86
87 private Boolean _beanBeforeJsfValidation;
88
89 public ValidatorTagHandlerDelegate(ValidatorHandler delegate)
90 {
91 _delegate = delegate;
92
93
94
95
96
97
98
99 _wrapMode = FaceletsCompilerUtils.hasChildren(_delegate.getValidatorConfig());
100 _beanBeforeJsfValidation = null;
101 }
102
103 @Override
104 public void apply(FaceletContext ctx, UIComponent parent) throws IOException
105 {
106
107 FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx);
108
109 if (_wrapMode)
110 {
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 String validatorId = _delegate.getValidatorConfig().getValidatorId();
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 try
164 {
165 mctx.pushEnclosingValidatorIdToStack(validatorId, this);
166 _delegate.applyNextHandler(ctx, parent);
167 }
168 finally
169 {
170 mctx.popEnclosingValidatorIdToStack();
171 }
172
173
174
175
176
177
178
179
180
181 }
182 else
183 {
184
185 if (!ComponentHandler.isNew(parent))
186 {
187 return;
188 }
189
190
191 if (parent instanceof EditableValueHolder)
192 {
193 applyAttachedObject(ctx.getFacesContext(), parent);
194 }
195 else if (UIComponent.isCompositeComponent(parent))
196 {
197 if (getFor() == null)
198 {
199 throw new TagException(_delegate.getTag(), "is nested inside a composite component"
200 + " but does not have a for attribute.");
201 }
202 mctx.addAttachedObjectHandler(parent, _delegate);
203 }
204 else
205 {
206 throw new TagException(_delegate.getTag(),
207 "Parent not composite component or an instance of EditableValueHolder: " + parent);
208 }
209 }
210 }
211
212
213
214
215
216
217
218 protected Validator createValidator(FaceletContext ctx)
219 {
220 if (_delegate.getValidatorId(ctx) == null)
221 {
222 throw new TagException(_delegate.getTag(), "Default behavior invoked of requiring " +
223 "a validator-id passed in the constructor, must override ValidateHandler(ValidatorConfig)");
224 }
225 return ctx.getFacesContext().getApplication().createValidator(_delegate.getValidatorId(ctx));
226 }
227
228 @Override
229 public MetaRuleset createMetaRuleset(Class type)
230 {
231 MetaRuleset metaRuleset = new MetaRulesetImpl(_delegate.getTag(), type);
232
233
234 metaRuleset.ignore(JSFAttr.BINDING_ATTR).ignore(JSFAttr.DISABLED_ATTR);
235
236 metaRuleset.ignore(JSFAttr.FOR_ATTR);
237
238 return metaRuleset;
239 }
240
241 @SuppressWarnings("unchecked")
242 public void applyAttachedObject(FacesContext context, UIComponent parent)
243 {
244
245 FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(
246 FaceletContext.FACELET_CONTEXT_KEY);
247
248
249
250
251
252 if (_delegate.isDisabled(faceletContext))
253 {
254
255 String validatorId = _delegate.getValidatorConfig().getValidatorId();
256 if (validatorId != null && !"".equals(validatorId))
257 {
258 List<String> exclusionList = (List<String>) parent.getAttributes()
259 .get(VALIDATOR_ID_EXCLUSION_LIST_KEY);
260 if (exclusionList == null)
261 {
262 exclusionList = new ArrayList<String>();
263 parent.getAttributes().put(VALIDATOR_ID_EXCLUSION_LIST_KEY, exclusionList);
264 }
265 exclusionList.add(validatorId);
266 }
267 }
268 else
269 {
270
271
272
273 EditableValueHolder evh = (EditableValueHolder) parent;
274 ValueExpression ve = null;
275 Validator v = null;
276 if (_delegate.getBinding() != null)
277 {
278 ve = _delegate.getBinding().getValueExpression(faceletContext, Validator.class);
279 v = (Validator) ve.getValue(faceletContext);
280 }
281 if (v == null)
282 {
283 v = this.createValidator(faceletContext);
284 if (ve != null)
285 {
286 ve.setValue(faceletContext, v);
287 }
288 }
289 if (v == null)
290 {
291 throw new TagException(_delegate.getTag(), "No Validator was created");
292 }
293 _delegate.setAttributes(faceletContext, v);
294 if (shouldBeanBeforeJsfValidationEnabled(context))
295 {
296 parent.getAttributes().put(BEAN_BEFORE_JSF_PROPERTY, Boolean.TRUE);
297 }
298 evh.addValidator(v);
299 }
300 }
301
302 private boolean shouldBeanBeforeJsfValidationEnabled(FacesContext context)
303 {
304 if (_beanBeforeJsfValidation == null)
305 {
306 _beanBeforeJsfValidation = WebConfigParamUtils.getBooleanInitParameter(context.getExternalContext(),
307 BEAN_BEFORE_JSF_VALIDATION, false);
308 }
309 return _beanBeforeJsfValidation;
310 }
311
312
313 public String getFor()
314 {
315 TagAttribute forAttribute = _delegate.getTagAttribute("for");
316
317 if (forAttribute == null)
318 {
319 return null;
320 }
321 else
322 {
323 return forAttribute.getValue();
324 }
325 }
326
327 public String getValidationGroups(FaceletContext ctx)
328 {
329 TagAttribute attribute = _delegate.getTagAttribute("validationGroups");
330
331 if (attribute == null)
332 {
333 return null;
334 }
335 else
336 {
337 return attribute.getValue(ctx);
338 }
339 }
340
341 public ValidatorHandler getWrapped()
342 {
343 return _delegate;
344 }
345
346 }