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.fluidgrid;
23
24 import java.util.*;
25
26 import javax.faces.FacesException;
27 import javax.faces.application.ResourceDependency;
28 import javax.faces.component.ContextCallback;
29 import javax.faces.component.UIComponent;
30 import javax.faces.component.UINamingContainer;
31 import javax.faces.component.behavior.ClientBehaviorHolder;
32 import javax.faces.component.visit.VisitCallback;
33 import javax.faces.component.visit.VisitContext;
34 import javax.faces.context.FacesContext;
35 import javax.faces.event.AjaxBehaviorEvent;
36 import javax.faces.event.FacesEvent;
37 import javax.faces.event.PhaseId;
38
39 import org.primefaces.component.api.Widget;
40 import org.primefaces.extensions.component.base.AbstractDynamicData;
41 import org.primefaces.extensions.event.LayoutCompleteEvent;
42 import org.primefaces.extensions.model.common.KeyData;
43 import org.primefaces.extensions.model.fluidgrid.FluidGridItem;
44 import org.primefaces.util.Constants;
45
46
47
48
49
50
51
52 @ResourceDependency(library = "primefaces", name = "jquery/jquery.js")
53 @ResourceDependency(library = "primefaces", name = "jquery/jquery-plugins.js")
54 @ResourceDependency(library = "primefaces", name = "core.js")
55 @ResourceDependency(library = "primefaces-extensions", name = "primefaces-extensions.js")
56 @ResourceDependency(library = "primefaces-extensions", name = "fluidgrid/fluidgrid.css")
57 @ResourceDependency(library = "primefaces-extensions", name = "fluidgrid/fluidgrid.js")
58 public class FluidGrid extends AbstractDynamicData implements Widget, ClientBehaviorHolder {
59
60 public static final String COMPONENT_TYPE = "org.primefaces.extensions.component.FluidGrid";
61 public static final String COMPONENT_FAMILY = "org.primefaces.extensions.component";
62 public static final String DEFAULT_RENDERER = "org.primefaces.extensions.component.FluidGridRenderer";
63
64 private static final Collection<String> EVENT_NAMES = Collections
65 .unmodifiableCollection(Arrays.asList("layoutComplete"));
66
67 private Map<String, UIFluidGridItem> items;
68
69
70
71
72
73
74 @SuppressWarnings("java:S115")
75 protected enum PropertyKeys {
76
77 widgetVar,
78 style,
79 styleClass,
80 hGutter,
81 vGutter,
82 fitWidth,
83 originLeft,
84 originTop,
85 resizeBound,
86 stamp,
87 transitionDuration,
88 hasImages
89
90 }
91
92 public FluidGrid() {
93 setRendererType(DEFAULT_RENDERER);
94 }
95
96 @Override
97 public String getFamily() {
98 return COMPONENT_FAMILY;
99 }
100
101 public String getWidgetVar() {
102 return (String) getStateHelper().eval(PropertyKeys.widgetVar, null);
103 }
104
105 public void setWidgetVar(final String widgetVar) {
106 getStateHelper().put(PropertyKeys.widgetVar, widgetVar);
107 }
108
109 public String getStyle() {
110 return (String) getStateHelper().eval(PropertyKeys.style, null);
111 }
112
113 public void setStyle(final String style) {
114 getStateHelper().put(PropertyKeys.style, style);
115 }
116
117 public String getStyleClass() {
118 return (String) getStateHelper().eval(PropertyKeys.styleClass, null);
119 }
120
121 public void setStyleClass(final String styleClass) {
122 getStateHelper().put(PropertyKeys.styleClass, styleClass);
123 }
124
125 public int gethGutter() {
126 return (Integer) getStateHelper().eval(PropertyKeys.hGutter, 0);
127 }
128
129 public void sethGutter(final int hGutter) {
130 getStateHelper().put(PropertyKeys.hGutter, hGutter);
131 }
132
133 public int getvGutter() {
134 return (Integer) getStateHelper().eval(PropertyKeys.vGutter, 0);
135 }
136
137 public void setvGutter(final int vGutter) {
138 getStateHelper().put(PropertyKeys.vGutter, vGutter);
139 }
140
141 public boolean isFitWidth() {
142 return (Boolean) getStateHelper().eval(PropertyKeys.fitWidth, false);
143 }
144
145 public void setFitWidth(final boolean fitWidth) {
146 getStateHelper().put(PropertyKeys.fitWidth, fitWidth);
147 }
148
149 public boolean isOriginLeft() {
150 return (Boolean) getStateHelper().eval(PropertyKeys.originLeft, true);
151 }
152
153 public void setOriginLeft(final boolean originLeft) {
154 getStateHelper().put(PropertyKeys.originLeft, originLeft);
155 }
156
157 public boolean isOriginTop() {
158 return (Boolean) getStateHelper().eval(PropertyKeys.originTop, true);
159 }
160
161 public void setOriginTop(final boolean originTop) {
162 getStateHelper().put(PropertyKeys.originTop, originTop);
163 }
164
165 public boolean isResizeBound() {
166 return (Boolean) getStateHelper().eval(PropertyKeys.resizeBound, true);
167 }
168
169 public void setResizeBound(final boolean resizeBound) {
170 getStateHelper().put(PropertyKeys.resizeBound, resizeBound);
171 }
172
173 public String getStamp() {
174 return (String) getStateHelper().eval(PropertyKeys.stamp, null);
175 }
176
177 public void setStamp(final String stamp) {
178 getStateHelper().put(PropertyKeys.stamp, stamp);
179 }
180
181 public String getTransitionDuration() {
182 return (String) getStateHelper().eval(PropertyKeys.transitionDuration, "0.4s");
183 }
184
185 public void setTransitionDuration(final String transitionDuration) {
186 getStateHelper().put(PropertyKeys.transitionDuration, transitionDuration);
187 }
188
189 public boolean isHasImages() {
190 return (Boolean) getStateHelper().eval(PropertyKeys.hasImages, false);
191 }
192
193 public void setHasImages(final boolean hasImages) {
194 getStateHelper().put(PropertyKeys.hasImages, hasImages);
195 }
196
197 @Override
198 public Collection<String> getEventNames() {
199 return EVENT_NAMES;
200 }
201
202 @Override
203 public void queueEvent(final FacesEvent event) {
204 final FacesContext context = FacesContext.getCurrentInstance();
205 final Map<String, String> params = context.getExternalContext().getRequestParameterMap();
206 final String eventName = params.get(Constants.RequestParams.PARTIAL_BEHAVIOR_EVENT_PARAM);
207
208 if ("layoutComplete".equals(eventName)) {
209 if (event instanceof AjaxBehaviorEvent && isSelfRequest(context)) {
210 final LayoutCompleteEvent layoutCompleteEvent = new LayoutCompleteEvent(this,
211 ((AjaxBehaviorEvent) event).getBehavior());
212 layoutCompleteEvent.setPhaseId(event.getPhaseId());
213
214 super.queueEvent(layoutCompleteEvent);
215 }
216 }
217 else {
218 super.queueEvent(event);
219 }
220 }
221
222 private boolean isSelfRequest(final FacesContext context) {
223 return getClientId(context).equals(
224 context.getExternalContext().getRequestParameterMap().get(Constants.RequestParams.PARTIAL_SOURCE_PARAM));
225 }
226
227 public UIFluidGridItem getItem(final String type) {
228 final UIFluidGridItem item = getItems().get(type);
229
230 if (item == null) {
231 throw new FacesException("UIFluidGridItem to type " + type + " was not found");
232 }
233 else {
234 return item;
235 }
236 }
237
238 protected Map<String, UIFluidGridItem> getItems() {
239 if (items == null) {
240 items = new HashMap<>();
241 for (final UIComponent child : getChildren()) {
242 if (child instanceof UIFluidGridItem) {
243 final UIFluidGridItem fluidGridItem = (UIFluidGridItem) child;
244 items.put(fluidGridItem.getType(), fluidGridItem);
245 }
246 }
247 }
248
249 return items;
250 }
251
252 protected static void checkModelInstance(Object value) {
253 if (!(value instanceof Collection<?>)) {
254 throw new FacesException("Value in FluidGrid must be of type Collection / List");
255 }
256 }
257
258 @Override
259 protected KeyData findData(final String key) {
260 final Object value = getValue();
261 if (value == null) {
262 return null;
263 }
264
265 checkModelInstance(value);
266
267 final Collection<FluidGridItem> col = (Collection<FluidGridItem>) value;
268 for (final FluidGridItem fluidGridItem : col) {
269 if (key.equals(fluidGridItem.getKey())) {
270 return fluidGridItem;
271 }
272 }
273
274 return null;
275 }
276
277 @Override
278 protected void processChildren(final FacesContext context, final PhaseId phaseId) {
279 if (context.getExternalContext().getRequestParameterMap()
280 .containsKey(getClientId(context) + "_layoutComplete")) {
281
282
283 return;
284 }
285
286 if (getVar() != null) {
287
288 final Object value = getValue();
289 if (value != null) {
290 checkModelInstance(value);
291
292 final Collection<FluidGridItem> col = (Collection<FluidGridItem>) value;
293 for (final FluidGridItem fluidGridItem : col) {
294 processFluidGridDynamicItems(context, phaseId, fluidGridItem);
295 }
296 }
297
298 resetData();
299 }
300 else {
301
302 processFluidGridStaticItems(context, phaseId);
303 }
304 }
305
306 @Override
307 protected boolean visitChildren(final VisitContext context, final VisitCallback callback) {
308 if (getVar() != null) {
309
310 final Object value = getValue();
311 if (value == null) {
312 return false;
313 }
314
315 checkModelInstance(value);
316
317 final Collection<FluidGridItem> col = (Collection<FluidGridItem>) value;
318 for (final FluidGridItem fluidGridItem : col) {
319 if (visitFluidGridDynamicItems(context, callback, fluidGridItem)) {
320 return true;
321 }
322 }
323
324 resetData();
325 }
326 else {
327
328 if (visitFluidGridStaticItems(context, callback)) {
329 return true;
330 }
331 }
332
333 return false;
334 }
335
336 @Override
337 protected boolean invokeOnChildren(final FacesContext context, final String clientId, final ContextCallback callback) {
338
339 final Object value = getValue();
340 if (value == null) {
341 return false;
342 }
343
344 checkModelInstance(value);
345
346 if (getChildCount() > 0) {
347
348
349 String key = clientId.substring(getClientId().length() + 1);
350 key = key.substring(0, key.indexOf(UINamingContainer.getSeparatorChar(context)));
351
352 final Collection<FluidGridItem> fluidGridItems = (Collection<FluidGridItem>) value;
353 for (final FluidGridItem fluidGridItem : fluidGridItems) {
354
355
356 if (fluidGridItem.getKey().equals(key)) {
357
358
359 UIFluidGridItem uiFluidGridItem = null;
360 if (getVar() == null) {
361 for (final UIComponent child : getChildren()) {
362 if (child instanceof UIFluidGridItem && ((UIFluidGridItem) child).getType().equals(fluidGridItem.getType())) {
363 uiFluidGridItem = (UIFluidGridItem) child;
364 }
365 }
366 }
367 else {
368 uiFluidGridItem = (UIFluidGridItem) getChildren().get(0);
369 }
370
371 if (uiFluidGridItem == null) {
372 continue;
373 }
374
375 try {
376
377 setData(fluidGridItem);
378
379
380 if (uiFluidGridItem.invokeOnComponent(context, clientId, callback)) {
381 return true;
382 }
383 }
384 finally {
385 resetData();
386 }
387
388 }
389 }
390 }
391
392 return false;
393 }
394
395 private void processFluidGridDynamicItems(final FacesContext context, final PhaseId phaseId,
396 final FluidGridItem fluidGridItem) {
397 for (final UIComponent kid : getChildren()) {
398 if (!(kid instanceof UIFluidGridItem) || !kid.isRendered()
399 || !((UIFluidGridItem) kid).getType().equals(fluidGridItem.getType())) {
400 continue;
401 }
402
403 for (final UIComponent grandkid : kid.getChildren()) {
404 if (!grandkid.isRendered()) {
405 continue;
406 }
407
408 setData(fluidGridItem);
409 if (getData() == null) {
410 return;
411 }
412
413 if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
414 grandkid.processDecodes(context);
415 }
416 else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
417 grandkid.processValidators(context);
418 }
419 else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
420 grandkid.processUpdates(context);
421 }
422 else {
423 throw new IllegalArgumentException();
424 }
425 }
426 }
427 }
428
429 private void processFluidGridStaticItems(final FacesContext context, final PhaseId phaseId) {
430 for (final UIComponent kid : getChildren()) {
431 if (!(kid instanceof UIFluidGridItem) || !kid.isRendered()) {
432 continue;
433 }
434
435 for (final UIComponent grandkid : kid.getChildren()) {
436 if (!grandkid.isRendered()) {
437 continue;
438 }
439
440 if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
441 grandkid.processDecodes(context);
442 }
443 else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
444 grandkid.processValidators(context);
445 }
446 else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
447 grandkid.processUpdates(context);
448 }
449 else {
450 throw new IllegalArgumentException();
451 }
452 }
453 }
454 }
455
456 private boolean visitFluidGridDynamicItems(final VisitContext context, final VisitCallback callback,
457 final FluidGridItem fluidGridItem) {
458 if (getChildCount() > 0) {
459 for (final UIComponent child : getChildren()) {
460 if (child instanceof UIFluidGridItem
461 && ((UIFluidGridItem) child).getType().equals(fluidGridItem.getType())) {
462 setData(fluidGridItem);
463 if (getData() == null) {
464 return false;
465 }
466
467 if (child.visitTree(context, callback)) {
468 return true;
469 }
470 }
471 }
472 }
473
474 return false;
475 }
476
477 private boolean visitFluidGridStaticItems(final VisitContext context, final VisitCallback callback) {
478 if (getChildCount() > 0) {
479 for (final UIComponent child : getChildren()) {
480 if (child instanceof UIFluidGridItem && child.visitTree(context, callback)) {
481 return true;
482 }
483 }
484 }
485
486 return false;
487 }
488
489 @Override
490 public Object saveState(FacesContext context) {
491
492 items = null;
493
494 return super.saveState(context);
495 }
496 }