1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.equalvalidator;
20
21 import javax.faces.FacesException;
22 import javax.faces.FactoryFinder;
23 import javax.faces.application.FacesMessage;
24 import javax.faces.component.EditableValueHolder;
25 import javax.faces.component.UIComponent;
26 import javax.faces.context.FacesContext;
27 import javax.faces.convert.Converter;
28 import javax.faces.convert.ConverterException;
29 import javax.faces.el.ValueBinding;
30 import javax.faces.render.RenderKit;
31 import javax.faces.render.RenderKitFactory;
32 import javax.faces.render.Renderer;
33 import javax.faces.validator.ValidatorException;
34
35 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
36 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFValidator;
37 import org.apache.myfaces.validator.ValidatorBase;
38
39
40
41
42
43
44
45
46
47
48
49
50 @JSFValidator(
51 name = "t:validateEqual",
52 clazz = "org.apache.myfaces.custom.equalvalidator.EqualValidator",
53 tagClass = "org.apache.myfaces.custom.equalvalidator.ValidateEqualTag",
54 serialuidtag = "-3249115551944863108L")
55 public abstract class AbstractEqualValidator extends ValidatorBase {
56
57
58
59
60 public static final String VALIDATOR_ID = "org.apache.myfaces.validator.Equal";
61
62
63
64
65
66 public static final String EQUAL_MESSAGE_ID = "org.apache.myfaces.Equal.INVALID";
67
68 public AbstractEqualValidator(){
69 }
70
71
72 public void validate(
73 FacesContext facesContext,
74 UIComponent uiComponent,
75 Object value)
76 throws ValidatorException {
77
78 if (facesContext == null) throw new NullPointerException("facesContext");
79 if (uiComponent == null) throw new NullPointerException("uiComponent");
80
81 if (value == null)
82 {
83 return;
84 }
85
86 String forId = getFor();
87 forId = (forId != null && forId.length() > 0) ? forId : getForId();
88 if (forId == null) {
89 throw new FacesException("No id set to compare. Use 'for' in jsp mode and 'forId' in facelets mode");
90 }
91 UIComponent foreignComp = uiComponent.getParent().findComponent(forId);
92 if(foreignComp==null)
93 throw new FacesException("Unable to find component '" + forId + "' (calling findComponent on component '" + uiComponent.getId() + "')");
94 if(false == foreignComp instanceof EditableValueHolder)
95 throw new FacesException("Component '" + foreignComp.getId() + "' does not implement EditableValueHolder");
96 EditableValueHolder foreignEditableValueHolder = (EditableValueHolder) foreignComp;
97
98 if (foreignEditableValueHolder.isRequired() && foreignEditableValueHolder.getValue()== null ) {
99 return;
100 }
101
102 Object foreignValue;
103 if (foreignEditableValueHolder.isValid())
104 {
105 foreignValue = foreignEditableValueHolder.getValue();
106 }
107 else
108 {
109 try
110 {
111 foreignValue = getConvertedValueNonValid(facesContext, foreignComp);
112 }
113 catch(ConverterException e)
114 {
115
116
117
118
119
120
121
122
123 return;
124 }
125 }
126
127
128 if (null == foreignValue)
129 {
130 return;
131 }
132
133
134 Object[] args = {value.toString(),(foreignValue==null) ? foreignComp.getId():foreignValue.toString()};
135
136 if(foreignEditableValueHolder.getValue()==null || !foreignValue.toString().equals(value.toString()) )
137 {
138 throw new ValidatorException(getFacesMessage(EQUAL_MESSAGE_ID, args));
139 }
140
141 }
142
143
144
145 protected Renderer getRenderer(FacesContext context, UIComponent foreignComponent)
146 {
147 if (context == null) throw new NullPointerException("context");
148 String rendererType = foreignComponent.getRendererType();
149 if (rendererType == null) return null;
150 String renderKitId = context.getViewRoot().getRenderKitId();
151 RenderKitFactory rkf = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
152 RenderKit renderKit = rkf.getRenderKit(context, renderKitId);
153 Renderer renderer = renderKit.getRenderer(foreignComponent.getFamily(), rendererType);
154 if (renderer == null)
155 {
156 getFacesContext().getExternalContext().log("No Renderer found for component " + foreignComponent + " (component-family=" + foreignComponent.getFamily() + ", renderer-type=" + rendererType + ")");
157 }
158 return renderer;
159 }
160
161 protected Converter findUIOutputConverter(FacesContext facesContext, UIComponent component)
162 {
163 Converter converter = ((EditableValueHolder)component).getConverter();
164 if (converter != null) return converter;
165
166
167 ValueBinding vb = component.getValueBinding("value");
168 if (vb == null) return null;
169
170 Class valueType = vb.getType(facesContext);
171 if (valueType == null) return null;
172
173 if (String.class.equals(valueType)) return null;
174 if (Object.class.equals(valueType)) return null;
175
176 try
177 {
178 return facesContext.getApplication().createConverter(valueType);
179 }
180 catch (FacesException e)
181 {
182 getFacesContext().getExternalContext().log("No Converter for type " + valueType.getName() + " found", e);
183 return null;
184 }
185 }
186
187
188
189
190 protected Object getConvertedValueNonValid(FacesContext facesContext, UIComponent component)
191 throws ConverterException
192 {
193 Object componentValueObject;
194 Object submittedValue = ((EditableValueHolder) component).getSubmittedValue();
195 if (submittedValue == null)
196 {
197 componentValueObject = null;
198 }
199 else
200 {
201 Renderer renderer = getRenderer(facesContext, component);
202 if (renderer != null)
203 {
204 componentValueObject = renderer.getConvertedValue(facesContext, component, submittedValue);
205 }
206 else if (submittedValue instanceof String)
207 {
208 Converter converter = findUIOutputConverter(facesContext, component);
209 if (converter != null)
210 {
211 componentValueObject = converter.getAsObject(facesContext, component, (String)submittedValue);
212 }
213 else
214 {
215 componentValueObject = submittedValue;
216 }
217 }else{
218 componentValueObject = submittedValue;
219 }
220 }
221 return componentValueObject;
222 }
223
224
225
226
227
228
229
230
231
232
233
234
235
236 public abstract String getFor();
237
238
239
240
241 public abstract void setFor(String string);
242
243
244
245
246
247
248 @JSFProperty(faceletsOnly=true)
249 public abstract String getForId();
250
251
252
253
254
255
256 public abstract void setForId(String string);
257
258 }