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.composite;
20
21 import java.beans.BeanDescriptor;
22 import java.beans.BeanInfo;
23 import java.beans.PropertyDescriptor;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28
29 import javax.faces.component.UIComponent;
30 import javax.faces.view.facelets.FaceletContext;
31 import javax.faces.view.facelets.FaceletHandler;
32
33 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
34 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
35 import org.apache.myfaces.view.facelets.el.CompositeComponentELUtils;
36 import org.apache.myfaces.view.facelets.tag.TagHandlerUtils;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public final class CompositeComponentDefinitionTagHandler implements FaceletHandler
58 {
59 private final FaceletHandler _nextHandler;
60
61 private boolean _cacheable;
62
63
64
65
66
67
68
69
70 private BeanInfo _cachedBeanInfo;
71
72 private InterfaceHandler _interfaceHandler;
73
74 private ImplementationHandler _implementationHandler;
75
76 public CompositeComponentDefinitionTagHandler(FaceletHandler next)
77 {
78 this._nextHandler = next;
79
80 _cacheable = true;
81
82 _interfaceHandler = TagHandlerUtils.findFirstNextByType(_nextHandler, InterfaceHandler.class);
83
84 _implementationHandler = TagHandlerUtils.findFirstNextByType(_nextHandler, ImplementationHandler.class);
85
86 Collection<InterfaceDescriptorCreator> metadataInterfaceHandlerList =
87 TagHandlerUtils.findNextByType( _nextHandler, InterfaceDescriptorCreator.class);
88
89 for (InterfaceDescriptorCreator handler : metadataInterfaceHandlerList)
90 {
91 if (!handler.isCacheable())
92 {
93 _cacheable = false;
94 break;
95 }
96 }
97 if (!_cacheable)
98 {
99 for (InterfaceDescriptorCreator handler : metadataInterfaceHandlerList)
100 {
101 handler.setCacheable(false);
102 }
103 }
104 }
105
106 public void apply(FaceletContext ctx, UIComponent parent)
107 throws IOException
108 {
109 FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx);
110 AbstractFaceletContext actx = (AbstractFaceletContext)ctx;
111 UIComponent compositeBaseParent = actx.isBuildingCompositeComponentMetadata() ? parent : parent.getParent();
112
113
114
115 if (_interfaceHandler != null)
116 {
117 if (!compositeBaseParent.getAttributes().containsKey(CompositeComponentELUtils.LOCATION_KEY))
118 {
119 compositeBaseParent.getAttributes()
120 .put(CompositeComponentELUtils.LOCATION_KEY, this._interfaceHandler.getLocation());
121 }
122 }
123 else if (_implementationHandler != null)
124 {
125 if (!compositeBaseParent.getAttributes().containsKey(CompositeComponentELUtils.LOCATION_KEY))
126 {
127 compositeBaseParent.getAttributes()
128 .put(CompositeComponentELUtils.LOCATION_KEY, this._implementationHandler.getLocation());
129 }
130 }
131
132
133
134 if ( actx.isBuildingCompositeComponentMetadata() )
135 {
136 CompositeComponentBeanInfo tempBeanInfo =
137 (CompositeComponentBeanInfo) compositeBaseParent.getAttributes()
138 .get(UIComponent.BEANINFO_KEY);
139
140 if (tempBeanInfo == null)
141 {
142 if (_cacheable)
143 {
144 if (_cachedBeanInfo == null)
145 {
146 _cachedBeanInfo = _createCompositeComponentMetadata(ctx, compositeBaseParent);
147 compositeBaseParent.getAttributes().put(
148 UIComponent.BEANINFO_KEY, _cachedBeanInfo);
149
150 try
151 {
152 mctx.pushCompositeComponentToStack(compositeBaseParent);
153
154
155 if (!compositeBaseParent.getAttributes().containsKey(CompositeComponentELUtils.LEVEL_KEY))
156 {
157 compositeBaseParent.getAttributes()
158 .put(CompositeComponentELUtils.LEVEL_KEY, mctx.getCompositeComponentLevel());
159 }
160
161 _nextHandler.apply(ctx, parent);
162
163 Collection<String> declaredDefaultValues = null;
164
165 for (PropertyDescriptor pd : _cachedBeanInfo.getPropertyDescriptors())
166 {
167 if (pd.getValue("default") != null)
168 {
169 if (declaredDefaultValues == null)
170 {
171 declaredDefaultValues = new ArrayList<String>();
172 }
173 declaredDefaultValues.add(pd.getName());
174 }
175 }
176 if (declaredDefaultValues == null)
177 {
178 declaredDefaultValues = Collections.emptyList();
179 }
180 _cachedBeanInfo.getBeanDescriptor().
181 setValue(UIComponent.ATTRS_WITH_DECLARED_DEFAULT_VALUES, declaredDefaultValues);
182 }
183 finally
184 {
185 mctx.popCompositeComponentToStack();
186 }
187 }
188 else
189 {
190
191
192 compositeBaseParent.getAttributes().put(
193 UIComponent.BEANINFO_KEY, _cachedBeanInfo);
194 }
195 }
196 else
197 {
198 tempBeanInfo = _createCompositeComponentMetadata(ctx, compositeBaseParent);
199 compositeBaseParent.getAttributes().put(
200 UIComponent.BEANINFO_KEY, tempBeanInfo);
201
202 try
203 {
204 mctx.pushCompositeComponentToStack(compositeBaseParent);
205
206
207 if (!compositeBaseParent.getAttributes().containsKey(CompositeComponentELUtils.LEVEL_KEY))
208 {
209 compositeBaseParent.getAttributes()
210 .put(CompositeComponentELUtils.LEVEL_KEY, mctx.getCompositeComponentLevel());
211 }
212
213 _nextHandler.apply(ctx, parent);
214
215 Collection<String> declaredDefaultValues = null;
216
217 for (PropertyDescriptor pd : tempBeanInfo.getPropertyDescriptors())
218 {
219 if (pd.getValue("default") != null)
220 {
221 if (declaredDefaultValues == null)
222 {
223 declaredDefaultValues = new ArrayList<String>();
224 }
225 declaredDefaultValues.add(pd.getName());
226 }
227 }
228 if (declaredDefaultValues == null)
229 {
230 declaredDefaultValues = Collections.emptyList();
231 }
232 tempBeanInfo.getBeanDescriptor().
233 setValue(UIComponent.ATTRS_WITH_DECLARED_DEFAULT_VALUES, declaredDefaultValues);
234 }
235 finally
236 {
237 mctx.popCompositeComponentToStack();
238 }
239 }
240 }
241 }
242 else
243 {
244 try
245 {
246 mctx.pushCompositeComponentToStack(compositeBaseParent);
247
248
249 if (!compositeBaseParent.getAttributes().containsKey(CompositeComponentELUtils.LEVEL_KEY))
250 {
251 compositeBaseParent.getAttributes()
252 .put(CompositeComponentELUtils.LEVEL_KEY, mctx.getCompositeComponentLevel());
253 }
254
255 _nextHandler.apply(ctx, parent);
256 }
257 finally
258 {
259 mctx.popCompositeComponentToStack();
260 }
261 }
262 }
263
264 private CompositeComponentBeanInfo _createCompositeComponentMetadata(
265 FaceletContext ctx, UIComponent parent)
266 {
267 BeanDescriptor descriptor = new BeanDescriptor(parent.getClass());
268 CompositeComponentBeanInfo beanInfo = new CompositeComponentBeanInfo(descriptor);
269 return beanInfo;
270 }
271 }