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