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.Iterator;
24 import java.util.Map;
25
26 import javax.faces.component.UIComponent;
27 import javax.faces.context.FacesContext;
28 import javax.faces.el.ValueBinding;
29
30 import org.apache.commons.chain.Context;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.shale.clay.component.Clay;
34 import org.apache.shale.clay.config.Globals;
35 import org.apache.shale.clay.config.beans.AttributeBean;
36 import org.apache.shale.clay.config.beans.Attributes;
37 import org.apache.shale.clay.config.beans.ComponentBean;
38
39 /***
40 * <p>
41 * This <code>Command</code> is used to build <strong>parent</strong> and
42 * <strong>child</strong> <code>UIComponent</code>'s from the
43 * <code>displayElement</code> in the {@link org.apache.shale.clay.component.chain.ClayContext}.
44 * </p>
45 */
46 public class CreateComponentCommand extends AbstractCommand {
47
48 /***
49 * <p>
50 * Common Logger utility.
51 * </p>
52 */
53 private static Log log;
54 static {
55 log = LogFactory.getLog(CreateComponentCommand.class);
56 }
57
58
59 /***
60 * <p>
61 * Creates a new faces component from the component metadata.
62 * </p>
63 * @param context common chains
64 * @return <code>true</code> if the chain is complete
65 * @exception Exception propagated up to the top of the chain
66 */
67 public boolean execute(Context context) throws Exception {
68
69 boolean isFinal = true;
70
71 ClayContext clayContext = (ClayContext) context;
72 if (clayContext == null) {
73 throw new NullPointerException(getMessages()
74 .getMessage("clay.null.clayContext"));
75 }
76
77 ComponentBean displayElement = clayContext.getDisplayElement();
78 if (displayElement == null) {
79 throw new NullPointerException(getMessages()
80 .getMessage("clay.null.componentBean"));
81 }
82
83 UIComponent parent = clayContext.getParent();
84 if (parent == null) {
85 throw new NullPointerException(getMessages()
86 .getMessage("clay.null.parentBean"));
87 }
88
89 FacesContext facesContext = clayContext.getFacesContext();
90 if (facesContext == null) {
91 throw new NullPointerException(getMessages()
92 .getMessage("clay.null.facesContext"));
93 }
94
95
96 Map symbolTable = new Attributes();
97
98 symbolTable.putAll(clayContext.getSymbols());
99
100 symbolTable.putAll(displayElement.getSymbols());
101
102 clayContext.setSymbols(symbolTable);
103
104
105 realizeSymbols(clayContext);
106
107 UIComponent child = null;
108 String facetName = displayElement.getFacetName();
109 if (facetName != null) {
110 facetName = replaceMnemonic(clayContext, facetName);
111 }
112 if (facetName != null) {
113 child = parent.getFacet(displayElement.getFacetName());
114 }
115 if (child == null) {
116 child = this.findComponentByJspId(parent, displayElement.getJspId());
117 }
118
119 String id = null;
120 if (child == null) {
121 id = displayElement.getId();
122
123 if (id == null) {
124 id = facesContext.getViewRoot().createUniqueId();
125 } else {
126 id = replaceMnemonic(clayContext, id);
127 }
128 } else {
129 id = child.getId();
130 }
131
132
133
134
135
136 if (id == null || id.indexOf('@') > -1) {
137
138 if (id == null) {
139 id = displayElement.getId();
140 }
141
142 throw new RuntimeException(getMessages().getMessage("create.component.invalid.id",
143 new Object[] {id, symbolTable}));
144 }
145
146 if (child == null) {
147 try {
148 AttributeBean attr = displayElement.getAttribute("binding");
149 if (attr != null
150 && attr.getValue() != null) {
151
152 clayContext.setAttribute(attr);
153 String expr = replaceMnemonic(clayContext);
154 ValueBinding vb = facesContext.getApplication().createValueBinding(expr);
155 child = facesContext.getApplication().createComponent(vb, facesContext,
156 displayElement.getComponentType());
157 child.setValueBinding("binding", vb);
158
159 } else {
160
161 child = facesContext.getApplication().createComponent(
162 displayElement.getComponentType());
163 }
164
165 } catch (Exception e) {
166 log.error(getMessages().getMessage("create.component.error",
167 new Object[] { displayElement }), e);
168 throw e;
169 }
170
171 child.setId(id);
172 child.getAttributes().put(Globals.CLAY_JSPID_ATTRIBUTE, displayElement.getJspId());
173 if (facetName != null) {
174 parent.getFacets().put(facetName, child);
175
176 if (log.isDebugEnabled()) {
177 log.debug(getMessages().getMessage("create.facet.component",
178 new Object[] { id, displayElement.getJsfid()}));
179 }
180
181 } else {
182 parent.getChildren().add(clayContext.getChildIndex(), child);
183
184 if (log.isDebugEnabled()) {
185 log.debug(getMessages().getMessage("create.component",
186 new Object[] { id, displayElement.getJsfid(), new Integer(clayContext.getChildIndex()) }));
187 }
188
189 }
190
191 if (child instanceof Clay) {
192
193
194
195 child.getAttributes().put(Globals.CLAY_RESERVED_ATTRIBUTE, displayElement);
196 }
197
198
199 isFinal = false;
200 } else {
201 if (log.isDebugEnabled()) {
202 log.debug(getMessages().getMessage("create.component.exists",
203 new Object[] { id, displayElement.getJsfid(), new Integer(clayContext.getChildIndex()) }));
204 }
205 }
206
207
208 if (child instanceof Clay) {
209
210 symbolTable.putAll(((Clay) child).getSymbols());
211
212 ((Clay) child).getSymbols().putAll(symbolTable);
213
214
215 clayContext.setSymbols(symbolTable);
216
217
218 realizeSymbols(clayContext);
219 }
220
221
222
223
224 clayContext.setChild(child);
225
226 return isFinal;
227 }
228
229 /***
230 * <p>Searches through the parent's children looking for a child
231 * component having a matching "org.apache.shale.clay.jspid" attribute.
232 * </p>
233 * @param parent owning <code>UIComponent</code>
234 * @param id target jsfid
235 * @return the child <code>UIComponent</code> if a match is found; otherwise;
236 * a <code>null</code> value.
237 */
238 private UIComponent findComponentByJspId(UIComponent parent, String id) {
239 Iterator ci = parent.getChildren().iterator();
240 while (ci.hasNext()) {
241 UIComponent child = (UIComponent) ci.next();
242 String jspId = (String) child.getAttributes().get(Globals.CLAY_JSPID_ATTRIBUTE);
243 if (jspId != null && jspId.equals(id)) {
244 return child;
245 }
246 }
247 return null;
248 }
249 }