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