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 tempBeanInfo = _createCompositeComponentMetadata(compositeBaseParent);
147 compositeBaseParent.getAttributes().put(
148 UIComponent.BEANINFO_KEY, tempBeanInfo);
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 : tempBeanInfo.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 tempBeanInfo.getBeanDescriptor().
181 setValue(UIComponent.ATTRS_WITH_DECLARED_DEFAULT_VALUES, declaredDefaultValues);
182 }
183 finally
184 {
185 mctx.popCompositeComponentToStack();
186
187 _cachedBeanInfo = tempBeanInfo;
188 }
189 }
190 else
191 {
192
193
194 compositeBaseParent.getAttributes().put(
195 UIComponent.BEANINFO_KEY, _cachedBeanInfo);
196 }
197 }
198 else
199 {
200 tempBeanInfo = _createCompositeComponentMetadata(compositeBaseParent);
201 compositeBaseParent.getAttributes().put(
202 UIComponent.BEANINFO_KEY, tempBeanInfo);
203
204 try
205 {
206 mctx.pushCompositeComponentToStack(compositeBaseParent);
207
208
209 if (!compositeBaseParent.getAttributes().containsKey(CompositeComponentELUtils.LEVEL_KEY))
210 {
211 compositeBaseParent.getAttributes()
212 .put(CompositeComponentELUtils.LEVEL_KEY, mctx.getCompositeComponentLevel());
213 }
214
215 _nextHandler.apply(ctx, parent);
216
217 Collection<String> declaredDefaultValues = null;
218
219 for (PropertyDescriptor pd : tempBeanInfo.getPropertyDescriptors())
220 {
221 if (pd.getValue("default") != null)
222 {
223 if (declaredDefaultValues == null)
224 {
225 declaredDefaultValues = new ArrayList<String>();
226 }
227 declaredDefaultValues.add(pd.getName());
228 }
229 }
230 if (declaredDefaultValues == null)
231 {
232 declaredDefaultValues = Collections.emptyList();
233 }
234 tempBeanInfo.getBeanDescriptor().
235 setValue(UIComponent.ATTRS_WITH_DECLARED_DEFAULT_VALUES, declaredDefaultValues);
236 }
237 finally
238 {
239 mctx.popCompositeComponentToStack();
240 }
241 }
242 }
243 }
244 else
245 {
246 try
247 {
248 mctx.pushCompositeComponentToStack(compositeBaseParent);
249
250
251 if (!compositeBaseParent.getAttributes().containsKey(CompositeComponentELUtils.LEVEL_KEY))
252 {
253 compositeBaseParent.getAttributes()
254 .put(CompositeComponentELUtils.LEVEL_KEY, mctx.getCompositeComponentLevel());
255 }
256
257 _nextHandler.apply(ctx, parent);
258 }
259 finally
260 {
261 mctx.popCompositeComponentToStack();
262 }
263 }
264 }
265
266 private CompositeComponentBeanInfo _createCompositeComponentMetadata(UIComponent parent)
267 {
268 BeanDescriptor descriptor = new BeanDescriptor(parent.getClass());
269 CompositeComponentBeanInfo beanInfo = new CompositeComponentBeanInfo(descriptor);
270 return beanInfo;
271 }
272 }