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