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.ui;
20
21 import java.io.IOException;
22 import java.util.Collection;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27
28 import javax.el.ELException;
29 import javax.faces.FacesException;
30 import javax.faces.application.StateManager;
31 import javax.faces.component.UIComponent;
32 import javax.faces.event.PhaseId;
33 import javax.faces.view.facelets.FaceletContext;
34 import javax.faces.view.facelets.FaceletException;
35 import javax.faces.view.facelets.TagAttribute;
36 import javax.faces.view.facelets.TagConfig;
37 import javax.faces.view.facelets.TagHandler;
38
39 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
40 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
41 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
42 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
43 import org.apache.myfaces.view.facelets.TemplateClient;
44 import org.apache.myfaces.view.facelets.tag.ComponentContainerHandler;
45 import org.apache.myfaces.view.facelets.tag.TagHandlerUtils;
46 import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 @JSFFaceletTag(name="ui:decorate")
62 public final class DecorateHandler extends TagHandler implements TemplateClient, ComponentContainerHandler
63 {
64
65 private static final Logger log = Logger.getLogger(DecorateHandler.class.getName());
66
67
68
69
70
71 @JSFFaceletAttribute(
72 name="template",
73 className="javax.el.ValueExpression",
74 deferredValueType="java.lang.String")
75 private final TagAttribute _template;
76
77 private final Map<String, DefineHandler> _handlers;
78
79 private final ParamHandler[] _params;
80
81
82
83
84 public DecorateHandler(TagConfig config)
85 {
86 super(config);
87 _template = getRequiredAttribute("template");
88 _handlers = new HashMap<String, DefineHandler>();
89
90 for (DefineHandler handler : TagHandlerUtils.findNextByType(nextHandler, DefineHandler.class))
91 {
92 _handlers.put(handler.getName(), handler);
93 if (log.isLoggable(Level.FINE))
94 {
95 log.fine(tag + " found Define[" + handler.getName() + "]");
96 }
97 }
98
99 Collection<ParamHandler> params = TagHandlerUtils.findNextByType(nextHandler, ParamHandler.class);
100 if (!params.isEmpty())
101 {
102 int i = 0;
103 _params = new ParamHandler[params.size()];
104 for (ParamHandler handler : params)
105 {
106 _params[i++] = handler;
107 }
108 }
109 else
110 {
111 _params = null;
112 }
113 }
114
115
116
117
118
119
120
121 @Override
122 public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
123 ELException
124 {
125
126
127
128
129
130
131
132
133
134
135
136 AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
137 actx.pushClient(this);
138 FaceletCompositionContext fcc = FaceletCompositionContext.getCurrentInstance(ctx);
139 String uniqueId = null;
140 try
141 {
142 if (!_template.isLiteral())
143 {
144 uniqueId = actx.generateUniqueFaceletTagId(
145 fcc.startComponentUniqueIdSection(), tagId);
146 }
147 else if (_params != null)
148 {
149 uniqueId = actx.generateUniqueFaceletTagId(
150 fcc.generateUniqueComponentId(), tagId);
151 }
152 if (_params != null)
153 {
154
155
156 for (int i = 0; i < _params.length; i++)
157 {
158 _params[i].apply(ctx, parent, _params[i].getName(ctx), _params[i].getValue(ctx), uniqueId);
159 }
160 }
161
162 String path;
163 boolean markInitialState = false;
164 if (!_template.isLiteral())
165 {
166
167
168 String restoredPath = (String) ComponentSupport.restoreInitialTagState(ctx, fcc, parent, uniqueId);
169 if (restoredPath != null)
170 {
171
172
173 if (!PhaseId.RESTORE_VIEW.equals(ctx.getFacesContext().getCurrentPhaseId()))
174 {
175 path = this._template.getValue(ctx);
176 if (path == null || path.length() == 0)
177 {
178 return;
179 }
180 if (!path.equals(restoredPath))
181 {
182 markInitialState = true;
183 }
184 }
185 else
186 {
187 path = restoredPath;
188 }
189 }
190 else
191 {
192
193 path = this._template.getValue(ctx);
194 }
195 ComponentSupport.saveInitialTagState(ctx, fcc, parent, uniqueId, path);
196 }
197 else
198 {
199 path = _template.getValue(ctx);
200 }
201 try
202 {
203 boolean oldMarkInitialState = false;
204 Boolean isBuildingInitialState = null;
205 if (markInitialState)
206 {
207
208 oldMarkInitialState = fcc.isMarkInitialState();
209 fcc.setMarkInitialState(true);
210 isBuildingInitialState = (Boolean) ctx.getFacesContext().getAttributes().put(
211 StateManager.IS_BUILDING_INITIAL_STATE, Boolean.TRUE);
212 }
213 try
214 {
215 ctx.includeFacelet(parent, path);
216 }
217 finally
218 {
219 if (markInitialState)
220 {
221
222 if (isBuildingInitialState == null)
223 {
224 ctx.getFacesContext().getAttributes().remove(
225 StateManager.IS_BUILDING_INITIAL_STATE);
226 }
227 else
228 {
229 ctx.getFacesContext().getAttributes().put(
230 StateManager.IS_BUILDING_INITIAL_STATE, isBuildingInitialState);
231 }
232 fcc.setMarkInitialState(oldMarkInitialState);
233 }
234 }
235 }
236 finally
237 {
238
239 actx.popClient(this);
240 }
241 }
242 finally
243 {
244 if (!_template.isLiteral())
245 {
246 fcc.endComponentUniqueIdSection();
247 }
248 }
249 if (!_template.isLiteral() && fcc.isUsingPSSOnThisView() && fcc.isRefreshTransientBuildOnPSS() &&
250 !fcc.isRefreshingTransientBuild())
251 {
252
253 ComponentSupport.markComponentToRestoreFully(ctx.getFacesContext(), parent);
254 }
255 if (!_template.isLiteral() && fcc.isDynamicComponentSection())
256 {
257 ComponentSupport.markComponentToRefreshDynamically(ctx.getFacesContext(), parent);
258 }
259 }
260
261 @Override
262 public boolean apply(FaceletContext ctx, UIComponent parent, String name) throws IOException, FacesException,
263 FaceletException, ELException
264 {
265 if (name != null)
266 {
267 DefineHandler handler = _handlers.get(name);
268 if (handler != null)
269 {
270 handler.applyDefinition(ctx, parent);
271 return true;
272 }
273 else
274 {
275 return false;
276 }
277 }
278 else
279 {
280 this.nextHandler.apply(ctx, parent);
281 return true;
282 }
283 }
284 }