1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.cms.gui.dialog;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.core.ItemType;
38 import info.magnolia.cms.core.NodeData;
39 import info.magnolia.cms.i18n.Messages;
40 import info.magnolia.cms.i18n.MessagesManager;
41 import info.magnolia.cms.i18n.MessagesUtil;
42 import info.magnolia.cms.util.AlertUtil;
43 import info.magnolia.cms.util.ContentUtil;
44 import info.magnolia.cms.util.NodeDataUtil;
45 import info.magnolia.cms.util.RequestFormUtil;
46 import info.magnolia.util.EscapeUtil;
47
48 import java.io.IOException;
49 import java.io.Writer;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Collections;
53 import java.util.Comparator;
54 import java.util.Date;
55 import java.util.Hashtable;
56 import java.util.Iterator;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.regex.Pattern;
60
61 import javax.jcr.PathNotFoundException;
62 import javax.jcr.RepositoryException;
63 import javax.servlet.http.HttpServletRequest;
64 import javax.servlet.http.HttpServletResponse;
65 import javax.servlet.http.HttpSession;
66
67 import org.apache.commons.lang.BooleanUtils;
68 import org.apache.commons.lang.StringUtils;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71
72
73
74
75
76 public abstract class DialogControlImpl implements DialogControl {
77
78 private static final String REQUIRED_PROPERTY = "required";
79
80 public static final String VALIDATION_PATTERN_PROPERTY = "validationPattern";
81
82 public static final String DEFAULT_VALUE_PROPERTY = "defaultValue";
83
84 private static final String I18N_BASENAME_PROPERTY = "i18nBasename";
85
86 public static final String SESSION_ATTRIBUTENAME_DIALOGOBJECT = "mgnlSessionAttribute";
87
88 public static final String SESSION_ATTRIBUTENAME_DIALOGOBJECT_REMOVE = "mgnlSessionAttributeRemove";
89
90
91
92
93 private static Logger log = LoggerFactory.getLogger(DialogControlImpl.class);
94
95
96
97
98 private HttpServletRequest request;
99
100
101
102
103 private HttpServletResponse response;
104
105
106
107
108 private Content storageNode;
109
110
111
112
113 private Map config = new Hashtable();
114
115
116
117
118 private final List subs = new ArrayList();
119
120
121
122
123 private List options = new ArrayList();
124
125
126
127
128
129 private String id = "mgnlControl";
130
131 protected String value;
132
133
134
135
136 private List values;
137
138 private DialogControlImpl parent;
139
140 private DialogControlImpl topParent;
141
142
143
144
145
146 private Messages messages;
147
148
149
150 @Override
151 public void init(HttpServletRequest request, HttpServletResponse response, Content storageNode, Content configNode)
152 throws RepositoryException {
153
154 if (log.isDebugEnabled()) {
155 log.debug("Init " + getClass().getName());
156 }
157
158 this.storageNode = storageNode;
159 this.request = request;
160 this.response = response;
161
162 this.initializeConfig(configNode);
163 }
164
165
166
167
168 @Override
169 public void drawHtml(Writer out) throws IOException {
170 this.drawHtmlPreSubs(out);
171 this.drawSubs(out);
172 this.drawHtmlPostSubs(out);
173 }
174
175 public void addSub(Object o) {
176 this.getSubs().add(o);
177 if(o instanceof DialogControlImpl){
178 ((DialogControlImpl)o).setParent(this);
179 }
180 }
181
182 public void setConfig(String key, String value) {
183 if (value != null) {
184 this.config.put(key, value);
185 }
186 }
187
188 public void setConfig(String key, boolean value) {
189 this.config.put(key, BooleanUtils.toBooleanObject(value).toString());
190 }
191
192 public void setConfig(String key, int value) {
193 this.config.put(key, Integer.toString(value));
194 }
195
196 public String getConfigValue(String key, String nullValue) {
197 if (this.config.containsKey(key)) {
198 return (String) this.config.get(key);
199 }
200
201 return nullValue;
202 }
203
204 public String getConfigValue(String key) {
205 return this.getConfigValue(key, StringUtils.EMPTY);
206 }
207
208 public void setValue(String s) {
209 this.value = s;
210 }
211
212 public String getValue() {
213 if (this.value == null) {
214 if (this.getStorageNode() != null) {
215 this.value = readValue();
216 if(this instanceof UUIDDialogControl){
217 String repository = ((UUIDDialogControl)this).getRepository();
218 this.value = ContentUtil.uuid2path(repository, this.value);
219 }
220 }
221 RequestFormUtil params = new RequestFormUtil(request);
222 if (params.getParameter(this.getName()) != null) {
223 this.value = params.getParameter(this.getName());
224 }
225
226 if (this.value == null && StringUtils.isNotEmpty(getConfigValue(DEFAULT_VALUE_PROPERTY))) {
227 return this.getMessage(this.getConfigValue(DEFAULT_VALUE_PROPERTY));
228 }
229
230 if (this.value == null) {
231 this.value = StringUtils.EMPTY;
232 }
233 }
234 return this.value;
235 }
236
237 protected String readValue() {
238 try {
239 if(!this.getStorageNode().hasNodeData(this.getName())){
240 return null;
241 }
242 }
243 catch (RepositoryException e) {
244 log.error("can't read nodedata [" + this.getName() + "]", e);
245 return null;
246 }
247 return this.getStorageNode().getNodeData(this.getName()).getString();
248 }
249
250 public void setSaveInfo(boolean b) {
251 this.setConfig("saveInfo", b);
252 }
253
254
255
256
257
258 public void setName(String s) {
259 this.setConfig("name", s);
260 }
261
262
263
264
265
266 public String getName() {
267 return EscapeUtil.escapeXss(this.getConfigValue("name"));
268 }
269
270 public void addOption(Object o) {
271 this.getOptions().add(o);
272 }
273
274 public Content getStorageNode() {
275 return this.storageNode;
276 }
277
278 public void setLabel(String s) {
279 this.config.put("label", s);
280 }
281
282 public void setDescription(String s) {
283 this.config.put("description", s);
284 }
285
286 public void removeSessionAttribute() {
287 String name = this.getConfigValue(SESSION_ATTRIBUTENAME_DIALOGOBJECT);
288 HttpServletRequest request = this.getRequest();
289 if (request == null) {
290 request = this.getTopParent().getRequest();
291 }
292 try {
293 HttpSession httpsession = request.getSession(false);
294 if (httpsession != null) {
295 httpsession.removeAttribute(name);
296 }
297 }
298 catch (Exception e) {
299 if (log.isDebugEnabled()) {
300 log.debug("removeSessionAttribute() for " + name + " failed because this.request is null");
301 }
302 }
303 }
304
305 public HttpServletRequest getRequest() {
306 return this.request;
307 }
308
309 public void setOptions(List options) {
310 this.options = options;
311 }
312
313 protected void drawHtmlPreSubs(Writer out) throws IOException {
314
315 }
316
317 protected void drawSubs(Writer out) throws IOException {
318 Iterator it = this.getSubs().iterator();
319 int i = 0;
320 while (it.hasNext()) {
321
322 String dsId = this.getId() + "_" + i;
323 DialogControlImpl ds = (DialogControlImpl) it.next();
324
325 ds.setParent(this);
326 ds.setId(dsId);
327 ds.drawHtml(out);
328 i++;
329 }
330 }
331
332 protected void drawHtmlPostSubs(Writer out) throws IOException {
333
334 }
335
336 public DialogControlImpl getParent() {
337 return this.parent;
338 }
339
340 protected void setTopParent(DialogControlImpl top) {
341 this.topParent = top;
342 }
343
344 public DialogControlImpl getTopParent() {
345 DialogControlImpl topParent = this;
346 if(this.topParent == null){
347 while(topParent.getParent() != null){
348 topParent = topParent.getParent();
349 }
350 this.topParent = topParent;
351 }
352 return this.topParent;
353 }
354
355 public List getSubs() {
356 return this.subs;
357 }
358
359
360
361
362
363
364 public DialogControlImpl getSub(String name) {
365 DialogControlImpl found;
366 for (Iterator iter = subs.iterator(); iter.hasNext();) {
367 Object control = iter.next();
368
369
370 if (control instanceof DialogControlImpl) {
371 if (StringUtils.equals(((DialogControlImpl) control).getName(), name)) {
372 return (DialogControlImpl) control;
373 }
374 found = ((DialogControlImpl) control).getSub(name);
375 if (found != null) {
376 return found;
377 }
378 }
379 }
380 return null;
381 }
382
383 protected HttpServletResponse getResponse() {
384 return this.response;
385 }
386
387
388
389
390 protected void clearWebsiteNode() {
391 this.storageNode = null;
392 }
393
394 public String getId() {
395 return this.id;
396 }
397
398 public String getLabel() {
399 return this.getConfigValue("label", StringUtils.EMPTY);
400 }
401
402 public String getDescription() {
403 return this.getConfigValue("description", StringUtils.EMPTY);
404 }
405
406 public List getOptions() {
407 return this.options;
408 }
409
410 public List getValues() {
411 if (this.values == null) {
412 this.values = readValues();
413
414 if(this instanceof UUIDDialogControl){
415 String repository = ((UUIDDialogControl)this).getRepository();
416 List pathes = new ArrayList();
417 for (Iterator iter = this.values.iterator(); iter.hasNext();) {
418 String uuid = (String) iter.next();
419 String path = ContentUtil.uuid2path(repository, uuid);
420 pathes.add(path);
421 }
422 this.values = pathes;
423 }
424
425 if (request != null) {
426 RequestFormUtil params = new RequestFormUtil(request);
427 String[] values = params.getParameterValues(this.getName());
428 if (values != null && values.length > 0) {
429 this.values.clear();
430 for (int i = 0; i < values.length; i++) {
431 String value = values[i];
432 this.values.add(value);
433 }
434 }
435 }
436 }
437
438 return this.values;
439 }
440
441 protected List readValues() {
442 List values = new ArrayList();
443 if (this.getStorageNode() != null) {
444 try {
445 NodeData node = this.getStorageNode().getNodeData(this.getName());
446 if(node.isMultiValue() == NodeData.MULTIVALUE_TRUE) {
447 values = NodeDataUtil.getValuesStringList(node.getValues());
448 } else {
449 Collection<NodeData> nodeDataCollection = this.getStorageNode().getContent(this.getName()).getNodeDataCollection();
450 List<NodeData> nodeDatas = new ArrayList<NodeData>(nodeDataCollection);
451 Collections.sort(nodeDatas, new Comparator<NodeData> () {
452 @Override
453 public int compare(NodeData o1, NodeData o2) {
454 return o1.getName().compareTo(o2.getName());
455 }
456 });
457 Iterator<NodeData> it = nodeDatas.iterator();
458 while (it.hasNext()) {
459 NodeData data = it.next();
460 values.add(data.getString());
461 }
462 }
463 }
464 catch (PathNotFoundException e) {
465
466 }
467 catch (RepositoryException re) {
468 log.error("can't set values", re);
469 }
470 }
471 return values;
472 }
473
474
475
476
477 public void setSessionAttribute() {
478 String name = SESSION_ATTRIBUTENAME_DIALOGOBJECT + "_" + this.getName() + "_" + new Date().getTime();
479 this.setConfig(SESSION_ATTRIBUTENAME_DIALOGOBJECT, name);
480 HttpServletRequest request = this.getRequest();
481 if (request == null) {
482 request = this.getTopParent().getRequest();
483 }
484 try {
485
486
487 HttpSession httpsession = request.getSession(true);
488 httpsession.setAttribute(name, this);
489 }
490 catch (Exception e) {
491 log.error("setSessionAttribute() for " + name + " failed because this.request is null");
492 }
493 }
494
495 private void setId(String id) {
496 this.id = id;
497 }
498
499 private void initializeConfig(Content configNodeParent) throws RepositoryException {
500
501
502 Map config = new Hashtable();
503
504 if (configNodeParent == null) {
505
506 return;
507 }
508
509
510 Iterator itProps = configNodeParent.getNodeDataCollection().iterator();
511 while (itProps.hasNext()) {
512 NodeData data = (NodeData) itProps.next();
513 String name = data.getName();
514 String value = data.getString();
515 config.put(name, value);
516 }
517
518 config.put("handle", configNodeParent.getHandle());
519
520
521 if (!config.containsKey("name")) {
522 config.put("name", configNodeParent.getName());
523 }
524
525 this.config = config;
526
527 Iterator it = configNodeParent.getChildren(ItemType.CONTENTNODE).iterator();
528 while (it.hasNext()) {
529 Content configNode = (Content) it.next();
530
531
532 while(configNode.hasNodeData("reference")){
533 configNode = configNode.getNodeData("reference").getReferencedContent();
534 }
535
536 String controlType = configNode.getNodeData("controlType").getString();
537
538 if (StringUtils.isEmpty(controlType)) {
539 String name = configNode.getName();
540 if (!name.startsWith("options")) {
541 log.debug("Missing control type for configNode " + name);
542 }
543 continue;
544 }
545
546 if (log.isDebugEnabled()) {
547 log.debug("Loading control \"" + controlType + "\" for " + configNode.getHandle());
548 }
549 DialogControl dialogControl = DialogFactory
550 .loadDialog(request, response, this.getStorageNode(), configNode);
551 this.addSub(dialogControl);
552 }
553 }
554
555 private void setParent(DialogControlImpl parent) {
556 this.parent = parent;
557 }
558
559
560
561
562
563
564 protected Messages getMessages() {
565 if (messages == null) {
566
567 if (this.getParent() == null) {
568 messages = MessagesManager.getMessages();
569 }
570 else {
571
572 messages = this.getParent().getMessages();
573 }
574
575 String basename = this.getConfigValue(I18N_BASENAME_PROPERTY);
576 if (StringUtils.isNotEmpty(basename)) {
577
578 messages = MessagesUtil.chain(basename, messages);
579 }
580 }
581 return messages;
582 }
583
584
585
586
587
588
589 public String getMessage(String key) {
590 return this.getMessages().getWithDefault(key, key);
591 }
592
593
594
595
596
597
598
599 public String getMessage(String key, Object[] args) {
600 return this.getMessages().getWithDefault(key, args, key);
601 }
602
603
604
605
606
607 public boolean validate() {
608
609 if (this.isRequired()) {
610 boolean valueFound = false;
611 for (Iterator iter = this.getValues().iterator(); iter.hasNext();) {
612 String value = (String) iter.next();
613 if(!StringUtils.isEmpty(value)){
614 valueFound = true;
615 break;
616 }
617 }
618 if (!valueFound && StringUtils.isEmpty(this.getValue())) {
619 setValidationMessage("dialogs.validation.required");
620 return false;
621 }
622 }
623 if(StringUtils.isNotEmpty(getValidationPattern()) && StringUtils.isNotEmpty(this.getValue())){
624 if(!Pattern.matches(getValidationPattern(), this.getValue())){
625 setValidationMessage("dialogs.validation.invalid");
626 return false;
627 }
628 }
629 for (Iterator iter = this.getSubs().iterator(); iter.hasNext();) {
630 DialogControl sub = (DialogControl) iter.next();
631 if (sub instanceof DialogControlImpl) {
632 DialogControlImpl subImpl = (DialogControlImpl) sub;
633 subImpl.setParent(this);
634 if (!subImpl.validate()) {
635 return false;
636 }
637 }
638
639 }
640 return true;
641 }
642
643 protected void setValidationMessage(String msg) {
644 String name = this.getMessage(this.getLabel());
645 String tabName = "";
646 if (this.getParent() instanceof DialogTab) {
647 DialogTab tab = (DialogTab) this.getParent();
648 tabName = tab.getMessage(tab.getLabel());
649 }
650 AlertUtil.setMessage(this.getMessage(msg, new Object[]{name, tabName, this.getValue()}));
651 }
652
653 public String getValidationPattern() {
654 return this.getConfigValue(VALIDATION_PATTERN_PROPERTY);
655 }
656
657
658
659
660
661 public boolean isRequired() {
662 if (BooleanUtils.toBoolean(this.getConfigValue(REQUIRED_PROPERTY))) {
663 return true;
664 }
665 return false;
666 }
667
668 public void setRequired(boolean required) {
669 this.setConfig(REQUIRED_PROPERTY, BooleanUtils.toStringTrueFalse(required));
670 }
671
672
673
674
675 public Content getWebsiteNode() {
676 return getStorageNode();
677 }
678
679 }