2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.shale.clay.component.chain;
22
23 import java.util.Map;
24
25 import javax.faces.component.UIComponent;
26 import javax.faces.context.FacesContext;
27 import javax.faces.convert.Converter;
28 import javax.faces.el.PropertyNotFoundException;
29 import javax.faces.el.ValueBinding;
30
31 import org.apache.commons.chain.Command;
32 import org.apache.commons.chain.Context;
33 import org.apache.shale.clay.config.beans.AttributeBean;
34 import org.apache.shale.clay.config.beans.ComponentBean;
35 import org.apache.shale.util.ConverterHelper;
36 import org.apache.shale.util.PropertyHelper;
37
38 /***
39 * <p>
40 * This is the catch all <code>Command</code> to handle all attributes that
41 * are not an "action", "actionListener", "validator" and "valueChangeListener".
42 * This <code>Command</code> is invoked from the
43 * {@link AssignPropertiesCommand} chain.
44 * <p>
45 */
46 public class PropertyValueCommand extends AbstractCommand implements Command {
47
48 /***
49 * <p>Helper class to provide access to the properties of JavaBeans.</p>
50 */
51 private PropertyHelper propertyHelper = new PropertyHelper();
52
53 /***
54 * <p>Helper class to provide access to by-type JavaServer Faces
55 * <code>Converter</code> capabilities.</p>
56 */
57 private ConverterHelper converterHelper = new ConverterHelper();
58
59 /***
60 * <p>Sets a property value on the target component. If the data
61 * type of the target bean property is not a String and the property
62 * value is a String, the data type is converted to the target type
63 * using the <code>ConverterHelper</code>. The value is applied to
64 * the component using <code>PropertyHelper</code>.</p>
65 *
66 * @param context faces context
67 * @param target object with the property
68 * @param propertyName name of the target property
69 * @param propertyValue value of the target property
70 */
71 private void setProperty(FacesContext context, Object target, String propertyName, Object propertyValue) {
72 Class classz = null;
73 StringBuffer actualPropertyName = new StringBuffer(propertyName);
74
75 try {
76 classz = propertyHelper.getType(target, actualPropertyName.toString());
77 } catch (PropertyNotFoundException e) {
78 if (propertyName.length() > "isX".length() && propertyName.startsWith("is")) {
79 actualPropertyName.delete(0, 2);
80 actualPropertyName.setCharAt(0, Character.toLowerCase(actualPropertyName.charAt(0)));
81
82 classz = propertyHelper.getType(target, actualPropertyName.toString());
83 } else {
84 throw e;
85 }
86
87 }
88
89 if (classz != Object.class && classz != propertyValue.getClass()
90 && propertyValue.getClass() == String.class) {
91
92 Object targetValue = converterHelper.asObject(context, classz, (String) propertyValue);
93 propertyHelper.setValue(target, actualPropertyName.toString(), targetValue);
94 } else {
95 propertyHelper.setValue(target, actualPropertyName.toString(), propertyValue);
96 }
97
98 }
99
100
101 /***
102 * <p>
103 * Looks at the {@link AttributeBean} on the {@link ClayContext} to see
104 * if the value is a binding EL. If it is not it just updates the component
105 * with the value. If the attribute is a value binding expression, then a
106 * <code>ValueBinding</code> is created. If the attribute uses early binding
107 * the <code>ValueBinding</code> is executed and result applied to the component.
108 * Otherwise, the binding expression is applied to the component in a prepared state.
109 * A <code>true</code> value is always returned because this is the default handler.
110 * </p>
111 *
112 * @param context common chains
113 * @return <code>true</code> if the chain is complete
114 * @exception Exception propagated up to the top of the chain
115 */
116 public boolean execute(Context context) throws Exception {
117
118 boolean isFinal = true;
119
120 ClayContext clayContext = (ClayContext) context;
121 if (clayContext == null) {
122 throw new NullPointerException(getMessages().getMessage("clay.null.clayContext"));
123 }
124 AttributeBean attributeBean = clayContext.getAttribute();
125 if (attributeBean == null) {
126 throw new NullPointerException(getMessages().getMessage("clay.null.attributeBean"));
127 }
128 Object child = clayContext.getChild();
129 if (child == null) {
130 throw new NullPointerException(getMessages().getMessage("clay.null.childComponent"));
131 }
132 ComponentBean displayElement = clayContext.getDisplayElement();
133 if (displayElement == null) {
134 throw new NullPointerException(getMessages().getMessage("clay.null.componentBean"));
135 }
136 FacesContext facesContext = clayContext.getFacesContext();
137 if (facesContext == null) {
138 throw new NullPointerException(getMessages().getMessage("clay.null.facesContext"));
139 }
140
141
142 if (attributeBean.getName().equals("binding")
143 && !(child instanceof UIComponent)) {
144 return isFinal;
145
146 }
147
148 if (attributeBean.getName().equals("converterId")
149 && child instanceof Converter) {
150 return isFinal;
151 }
152
153 String expr = replaceMnemonic(clayContext);
154
155
156 if (expr == null) {
157 return isFinal;
158 }
159
160
161 String bindingType = attributeBean.getBindingType();
162 if (bindingType == null) {
163 bindingType = AttributeBean.BINDING_TYPE_NONE;
164 }
165
166
167 boolean isEL = isValueReference(expr);
168
169 boolean isVB = ((bindingType.equals(AttributeBean.BINDING_TYPE_VALUE))
170 && (child instanceof UIComponent));
171
172 boolean isEarly = bindingType.equals(AttributeBean.BINDING_TYPE_EARLY);
173
174 if (isEL && isVB) {
175 getTagUtils().setValueBinding((UIComponent) child, attributeBean.getName(), expr);
176 } else if (isEL && isEarly) {
177 ValueBinding vb = facesContext.getApplication().createValueBinding(expr);
178 Object value = vb.getValue(facesContext);
179 try {
180 setProperty(facesContext, child, attributeBean.getName(), value);
181 } catch (Exception e) {
182 if (child instanceof UIComponent) {
183 ((UIComponent) child).getAttributes().put(attributeBean.getName(), expr);
184 } else {
185 throw e;
186 }
187 }
188 } else {
189 try {
190 setProperty(facesContext, child, attributeBean.getName(), expr);
191 } catch (Exception e) {
192 if (child instanceof UIComponent) {
193 ((UIComponent) child).getAttributes().put(attributeBean.getName(), expr);
194 } else {
195 if (child.getClass().getName().equals("org.apache.shale.validator.CommonsValidator")) {
196 Map vars = (Map) propertyHelper.getValue(child, "vars");
197
198
199 vars.put(attributeBean.getName(), expr);
200 } else {
201 throw e;
202 }
203 }
204 }
205 }
206
207 return isFinal;
208 }
209
210 }