1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.primefaces.extensions.component.layout;
23
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.Map;
28 import java.util.logging.Logger;
29
30 import javax.el.ValueExpression;
31 import javax.faces.application.ResourceDependency;
32 import javax.faces.component.UIComponent;
33 import javax.faces.component.UIComponentBase;
34 import javax.faces.component.behavior.ClientBehaviorHolder;
35 import javax.faces.context.FacesContext;
36 import javax.faces.context.ResponseWriter;
37 import javax.faces.event.AjaxBehaviorEvent;
38 import javax.faces.event.FacesEvent;
39
40 import org.primefaces.component.api.Widget;
41 import org.primefaces.extensions.event.CloseEvent;
42 import org.primefaces.extensions.event.OpenEvent;
43 import org.primefaces.extensions.event.ResizeEvent;
44 import org.primefaces.util.Constants;
45 import org.primefaces.util.FastStringWriter;
46 import org.primefaces.util.LangUtils;
47
48
49
50
51
52
53
54 @ResourceDependency(library = "primefaces", name = "jquery/jquery.js")
55 @ResourceDependency(library = "primefaces", name = "jquery/jquery-plugins.js")
56 @ResourceDependency(library = "primefaces", name = "core.js")
57 @ResourceDependency(library = "primefaces-extensions", name = "primefaces-extensions.js")
58 @ResourceDependency(library = "primefaces-extensions", name = "layout/layout.css")
59 @ResourceDependency(library = "primefaces-extensions", name = "layout/layout.js")
60 public class Layout extends UIComponentBase implements Widget, ClientBehaviorHolder {
61
62 public static final String POSITION_SEPARATOR = "_";
63 public static final String STYLE_CLASS = "ui-layout-";
64 public static final String STYLE_CLASS_PANE = "ui-layout-unit ui-panel ui-widget ui-widget-content ui-corner-all";
65 public static final String STYLE_CLASS_PANE_WITH_SUBPANES = "ui-corner-all pe-layout-pane-withsubpanes";
66 public static final String STYLE_CLASS_PANE_HEADER = "ui-layout-unit-header ui-panel-titlebar ui-widget-header ui-corner-top pe-layout-pane-header ";
67 public static final String STYLE_CLASS_PANE_CONTENT = "ui-layout-unit-content pe-layout-pane-content ui-panel-content";
68 public static final String STYLE_CLASS_LAYOUT_CONTENT = "ui-layout-content ui-panel-content";
69
70 public static final String PANE_POSITION_CENTER = "center";
71 public static final String PANE_POSITION_NORTH = "north";
72 public static final String PANE_POSITION_SOUTH = "south";
73 public static final String PANE_POSITION_WEST = "west";
74 public static final String PANE_POSITION_EAST = "east";
75
76 public static final String COMPONENT_TYPE = "org.primefaces.extensions.component.Layout";
77 public static final String COMPONENT_FAMILY = "org.primefaces.extensions.component";
78 private static final String DEFAULT_RENDERER = "org.primefaces.extensions.component.LayoutRenderer";
79
80 private static final Collection<String> EVENT_NAMES = Collections
81 .unmodifiableCollection(Arrays.asList(OpenEvent.NAME, CloseEvent.NAME, ResizeEvent.NAME));
82 private static final Logger LOG = Logger.getLogger(Layout.class.getName());
83
84 private ResponseWriter originalWriter;
85 private FastStringWriter fsw;
86 private boolean buildOptions;
87
88
89
90
91
92
93 @SuppressWarnings("java:S115")
94 public enum PropertyKeys {
95
96 widgetVar,
97 fullPage,
98 options,
99 style,
100 styleClass,
101 state,
102 stateCookie,
103 togglerTip_open("Open"),
104 togglerTip_closed("Close"),
105 resizerTip("Resize"),
106 sliderTip("Slide"),
107 maskPanesEarly;
108
109
110 private final String toString;
111
112 PropertyKeys(final String toString) {
113 this.toString = toString;
114 }
115
116 PropertyKeys() {
117 toString = null;
118 }
119
120 @Override
121 public String toString() {
122 return ((toString != null) ? toString : super.toString());
123 }
124 }
125
126 public Layout() {
127 setRendererType(DEFAULT_RENDERER);
128 }
129
130 @Override
131 public String getFamily() {
132 return COMPONENT_FAMILY;
133 }
134
135 public String getWidgetVar() {
136 return (String) getStateHelper().eval(PropertyKeys.widgetVar, null);
137 }
138
139 public void setWidgetVar(final String widgetVar) {
140 getStateHelper().put(PropertyKeys.widgetVar, widgetVar);
141 }
142
143 public boolean isFullPage() {
144 return (Boolean) getStateHelper().eval(PropertyKeys.fullPage, true);
145 }
146
147 public void setFullPage(final boolean fullPage) {
148 getStateHelper().put(PropertyKeys.fullPage, fullPage);
149 }
150
151 public Object getOptions() {
152 return getStateHelper().eval(PropertyKeys.options, null);
153 }
154
155 public void setOptions(final Object options) {
156 getStateHelper().put(PropertyKeys.options, options);
157 }
158
159 public String getStyle() {
160 return (String) getStateHelper().eval(PropertyKeys.style, null);
161 }
162
163 public void setStyle(final String style) {
164 getStateHelper().put(PropertyKeys.style, style);
165 }
166
167 public String getStyleClass() {
168 return (String) getStateHelper().eval(PropertyKeys.styleClass, null);
169 }
170
171 public void setStyleClass(final String styleClass) {
172 getStateHelper().put(PropertyKeys.styleClass, styleClass);
173 }
174
175 public String getState() {
176 return (String) getStateHelper().eval(PropertyKeys.state, null);
177 }
178
179 public void setState(final String state) {
180 getStateHelper().put(PropertyKeys.state, state);
181 }
182
183 public boolean isStateCookie() {
184 return (Boolean) getStateHelper().eval(PropertyKeys.stateCookie, false);
185 }
186
187 public void setStateCookie(final boolean stateCookie) {
188 getStateHelper().put(PropertyKeys.stateCookie, stateCookie);
189 }
190
191 public String getTogglerTipOpen() {
192 return (String) getStateHelper().eval(PropertyKeys.togglerTip_open, null);
193 }
194
195 public void setTogglerTipOpen(final String togglerTipOpen) {
196 getStateHelper().put(PropertyKeys.togglerTip_open, togglerTipOpen);
197 }
198
199 public String getTogglerTipClosed() {
200 return (String) getStateHelper().eval(PropertyKeys.togglerTip_closed, null);
201 }
202
203 public void setTogglerTipClosed(final String togglerTipClosed) {
204 getStateHelper().put(PropertyKeys.togglerTip_closed, togglerTipClosed);
205 }
206
207 public String getResizerTip() {
208 return (String) getStateHelper().eval(PropertyKeys.resizerTip, null);
209 }
210
211 public void setResizerTip(final String resizerTip) {
212 getStateHelper().put(PropertyKeys.resizerTip, resizerTip);
213 }
214
215 public String getSliderTip() {
216 return (String) getStateHelper().eval(PropertyKeys.sliderTip, null);
217 }
218
219 public void setSliderTip(final String sliderTip) {
220 getStateHelper().put(PropertyKeys.sliderTip, sliderTip);
221 }
222
223 public boolean isMaskPanesEarly() {
224 return (Boolean) getStateHelper().eval(PropertyKeys.maskPanesEarly, false);
225 }
226
227 public void setMaskPanesEarly(final boolean maskPanesEarly) {
228 getStateHelper().put(PropertyKeys.maskPanesEarly, maskPanesEarly);
229 }
230
231 @Override
232 public Collection<String> getEventNames() {
233 return EVENT_NAMES;
234 }
235
236 @Override
237 public void processDecodes(final FacesContext fc) {
238 if (isSelfRequest(fc)) {
239 decode(fc);
240 }
241 else {
242 super.processDecodes(fc);
243 }
244 }
245
246 @Override
247 public void processValidators(final FacesContext fc) {
248 if (!isSelfRequest(fc)) {
249 super.processValidators(fc);
250 }
251 }
252
253 @Override
254 public void processUpdates(final FacesContext fc) {
255 if (!isSelfRequest(fc)) {
256 super.processUpdates(fc);
257 }
258
259 final String state = fc.getExternalContext().getRequestParameterMap().get(getClientId(fc) + "_state");
260 if (LangUtils.isNotBlank(state)) {
261 final ValueExpression stateVE = getValueExpression(PropertyKeys.state.toString());
262 if (stateVE != null) {
263
264 stateVE.setValue(fc.getELContext(), state);
265 getStateHelper().remove(PropertyKeys.state);
266 }
267 }
268 }
269
270 @Override
271 public void queueEvent(final FacesEvent event) {
272 final FacesContext context = FacesContext.getCurrentInstance();
273
274 if (isSelfRequest(context)) {
275 final Map<String, String> params = context.getExternalContext().getRequestParameterMap();
276 final String eventName = params.get(Constants.RequestParams.PARTIAL_BEHAVIOR_EVENT_PARAM);
277 final String clientId = getClientId(context);
278
279 final AjaxBehaviorEvent behaviorEvent = (AjaxBehaviorEvent) event;
280 final LayoutPane pane = getLayoutPane(this, params.get(clientId + "_pane"));
281 if (pane == null) {
282 LOG.warning("LayoutPane by request parameter '" + params.get(clientId + "_pane") + "' was not found");
283
284 return;
285 }
286
287 if (OpenEvent.NAME.equals(eventName)) {
288 final OpenEvent openEvent = new OpenEvent(pane, behaviorEvent.getBehavior());
289 openEvent.setPhaseId(behaviorEvent.getPhaseId());
290 super.queueEvent(openEvent);
291
292 return;
293 }
294 else if (CloseEvent.NAME.equals(eventName)) {
295 final CloseEvent closeEvent = new CloseEvent(pane, behaviorEvent.getBehavior());
296 closeEvent.setPhaseId(behaviorEvent.getPhaseId());
297 super.queueEvent(closeEvent);
298
299 return;
300 }
301 else if (ResizeEvent.NAME.equals(eventName)) {
302 final double width = Double.parseDouble(params.get(clientId + "_width"));
303 final double height = Double.parseDouble(params.get(clientId + "_height"));
304
305 final ResizeEvent resizeEvent = new ResizeEvent(pane, behaviorEvent.getBehavior(), width, height);
306 resizeEvent.setPhaseId(behaviorEvent.getPhaseId());
307 super.queueEvent(resizeEvent);
308
309 return;
310 }
311 }
312
313 super.queueEvent(event);
314 }
315
316 public static LayoutPane getLayoutPane(final UIComponent component, final String combinedPosition) {
317 for (final UIComponent child : component.getChildren()) {
318 if (child instanceof LayoutPane) {
319 if (((LayoutPane) child).getCombinedPosition().equals(combinedPosition)) {
320 return (LayoutPane) child;
321 }
322 else {
323 final LayoutPane pane = getLayoutPane(child, combinedPosition);
324 if (pane != null) {
325 return pane;
326 }
327 }
328 }
329 }
330
331 return null;
332 }
333
334 public ResponseWriter getOriginalWriter() {
335 return originalWriter;
336 }
337
338 public void setOriginalWriter(final ResponseWriter originalWriter) {
339 this.originalWriter = originalWriter;
340 }
341
342 public FastStringWriter getFastStringWriter() {
343 return fsw;
344 }
345
346 public void setFastStringWriter(final FastStringWriter fsw) {
347 this.fsw = fsw;
348 }
349
350 public boolean isBuildOptions() {
351 return buildOptions;
352 }
353
354 public void setBuildOptions(final boolean buildOptions) {
355 this.buildOptions = buildOptions;
356 }
357
358 public void removeOptions() {
359 getStateHelper().remove(PropertyKeys.options);
360 }
361
362 public boolean isNested() {
363 return getParent() instanceof LayoutPane;
364 }
365
366 public boolean isElementLayout() {
367 return !isNested() && !isFullPage();
368 }
369
370 private boolean isSelfRequest(final FacesContext context) {
371 return getClientId(context)
372 .equals(context.getExternalContext().getRequestParameterMap().get(
373 Constants.RequestParams.PARTIAL_SOURCE_PARAM));
374 }
375
376 }