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.module.admininterface;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.core.HierarchyManager;
38 import info.magnolia.cms.core.NodeData;
39 import info.magnolia.cms.core.Path;
40 import info.magnolia.cms.exchange.ExchangeException;
41 import info.magnolia.cms.exchange.Syndicator;
42 import info.magnolia.cms.gui.control.ControlImpl;
43 import info.magnolia.cms.gui.control.Tree;
44 import info.magnolia.cms.gui.misc.Sources;
45 import info.magnolia.cms.i18n.Messages;
46 import info.magnolia.cms.i18n.MessagesManager;
47 import info.magnolia.cms.i18n.MessagesUtil;
48 import info.magnolia.cms.security.AccessDeniedException;
49 import info.magnolia.cms.servlets.CommandBasedMVCServletHandler;
50 import info.magnolia.cms.util.AlertUtil;
51 import info.magnolia.cms.util.ContentUtil;
52 import info.magnolia.cms.util.ExclusiveWrite;
53 import info.magnolia.commands.CommandsManager;
54 import info.magnolia.context.Context;
55 import info.magnolia.context.MgnlContext;
56 import info.magnolia.module.admininterface.commands.BaseActivationCommand;
57 import info.magnolia.objectfactory.Classes;
58
59 import java.io.IOException;
60 import java.util.Iterator;
61
62 import javax.jcr.PathNotFoundException;
63 import javax.jcr.RepositoryException;
64 import javax.servlet.http.HttpServletRequest;
65 import javax.servlet.http.HttpServletResponse;
66
67 import org.apache.commons.chain.Command;
68 import org.apache.commons.lang.StringUtils;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71
72
73
74
75
76
77
78
79
80 public class AdminTreeMVCHandler extends CommandBasedMVCServletHandler {
81
82
83
84
85 protected static final String COMMAND_SHOW_TREE = "show";
86
87 protected static final String COMMAND_COPY_NODE = "copy";
88
89 protected static final String COMMAND_MOVE_NODE = "move";
90
91 protected static final String COMMAND_ACTIVATE = "activate";
92
93 protected static final String COMMAND_DEACTIVATE = "deactivate";
94
95 protected static final String COMMAND_CREATE_NODE = "createNode";
96
97 protected static final String COMMAND_DELETE_NODE = "delete";
98
99 protected static final String COMMAND_SAVE_VALUE = "saveValue";
100
101
102
103
104
105 protected static final String VIEW_TREE = "tree";
106
107 protected static final String VIEW_CREATE = "create";
108
109 protected static final String VIEW_VALUE = "value";
110
111 protected static final String VIEW_NOTHING = "nothing";
112
113 protected static final String VIEW_COPY_MOVE = "copymove";
114
115
116
117
118 private static Logger log = LoggerFactory.getLogger(AdminTreeMVCHandler.class);
119
120
121
122
123 protected Tree tree;
124
125
126
127
128 private String treeClass = Tree.class.getName();
129
130
131
132
133
134 private String configurationClass;
135
136
137
138
139 protected AdminTreeConfiguration configuration;
140
141 protected String newNodeName = "untitled";
142
143 protected String createItemType = Tree.ITEM_TYPE_NODEDATA;
144
145 protected String path;
146
147 protected String pathOpen;
148
149 protected String pathSelected;
150
151 protected String rootPath;
152
153
154
155
156 protected String displayValue;
157
158 protected String newPath;
159
160 private String repository;
161
162 private String i18nBasename;
163
164
165
166
167 protected boolean browseMode;
168
169 private boolean enableDeleteConfirmation = true;
170
171
172
173
174
175 public String getRepository() {
176 if (repository == null) {
177 repository = this.getName();
178 }
179 return repository;
180 }
181
182 public void setRepository(String repository) {
183 this.repository = repository;
184 }
185
186
187
188
189 public HierarchyManager getHierarchyManager() {
190 return MgnlContext.getHierarchyManager(this.getRepository());
191 }
192
193 public AdminTreeMVCHandler(String name, HttpServletRequest request, HttpServletResponse response) {
194 super(name, request, response);
195 }
196
197 @Override
198 public void init() {
199 super.init();
200
201 path = this.getRequest().getParameter("path");
202 if (StringUtils.isEmpty(path)) {
203 if(StringUtils.isNotEmpty(this.getRootPath())){
204 path = this.getRootPath();
205 }
206 else{
207 path = "/";
208 }
209 }
210
211 pathOpen = this.getRequest().getParameter("pathOpen");
212 pathSelected = this.getRequest().getParameter("pathSelected");
213
214 this.setBrowseMode(StringUtils.equals(this.getRequest().getParameter("browseMode"), "true"));
215 }
216
217
218
219
220
221 @Override
222 public String getCommand() {
223
224 if (StringUtils.isNotEmpty(super.getCommand())) {
225 return super.getCommand();
226 }
227
228 if (StringUtils.isNotEmpty(this.getRequest().getParameter("treeAction"))) {
229 int treeAction = Integer.parseInt(this.getRequest().getParameter("treeAction"));
230
231 if (treeAction == Tree.ACTION_COPY) {
232 return COMMAND_COPY_NODE;
233 }
234 if (treeAction == Tree.ACTION_MOVE) {
235 return COMMAND_MOVE_NODE;
236 }
237 if (treeAction == Tree.ACTION_ACTIVATE) {
238 return COMMAND_ACTIVATE;
239 }
240 if (treeAction == Tree.ACTION_DEACTIVATE) {
241 return COMMAND_DEACTIVATE;
242 }
243
244 return this.getRequest().getParameter("treeAction");
245 }
246
247
248 if (this.getRequest().getParameter("createItemType") != null) {
249 return COMMAND_CREATE_NODE;
250 }
251
252 if (this.getRequest().getParameter("deleteNode") != null) {
253 return COMMAND_DELETE_NODE;
254 }
255
256
257 if (this.getRequest().getParameter("saveName") != null
258 || this.getRequest().getParameter("saveValue") != null
259
260 || "true".equals(this.getRequest().getParameter("isNodeDataValue"))
261
262 || "true".equals(this.getRequest().getParameter("isNodeDataType"))) {
263 return COMMAND_SAVE_VALUE;
264 }
265
266 return COMMAND_SHOW_TREE;
267 }
268
269
270
271
272 @Override
273 protected Context getCommandContext(String commandName) {
274 Context context = MgnlContext.getInstance();
275
276
277 context.put(Context.ATTRIBUTE_REPOSITORY, this.getRepository());
278
279 if ("activate".equals(commandName) || "deactivate".equals(commandName)) {
280 context.put(BaseActivationCommand.ATTRIBUTE_SYNDICATOR, getActivationSyndicator(this.pathSelected));
281 if (this.pathSelected != null) {
282 try {
283 final String uuid = MgnlContext.getHierarchyManager(repository).getContent(this.pathSelected).getUUID();
284
285 context.put(Context.ATTRIBUTE_UUID, uuid);
286
287 final String realPath = MgnlContext.getSystemContext().getHierarchyManager(repository).getContentByUUID(uuid).getHandle();
288 context.put(Context.ATTRIBUTE_PATH, realPath);
289 } catch (RepositoryException e) {
290
291 log.error("Failed to retrieve content node [{}:{}].", this.repository, this.pathSelected);
292 }
293 }
294 } else if (this.pathSelected != null) {
295
296
297 context.put(Context.ATTRIBUTE_PATH, this.pathSelected);
298 }
299
300 return context;
301 }
302
303
304
305
306 @Override
307 protected Command findCommand(String commandName) {
308 Command cmd = super.findCommand(commandName);
309 if (cmd == null) {
310 cmd = CommandsManager.getInstance().getCommand(CommandsManager.DEFAULT_CATALOG, commandName);
311 }
312 return cmd;
313 }
314
315
316
317
318 @Override
319 protected String getViewNameAfterExecution(String commandName, Context ctx) {
320 return VIEW_TREE;
321 }
322
323
324
325
326 public String show() {
327 return VIEW_TREE;
328 }
329
330
331
332
333
334 public String createNode() {
335 getTree().setPath(path);
336 synchronized (ExclusiveWrite.getInstance()) {
337 String name = getTree().createNode(this.getNewNodeName(), createItemType);
338 setNewNodeName(name);
339 }
340 return VIEW_TREE;
341 }
342
343
344
345
346 public String copy() {
347 try {
348 synchronized (ExclusiveWrite.getInstance()) {
349 copyOrMove(Tree.ACTION_COPY);
350 }
351 }
352 catch (Exception e) {
353 log.error("can't copy", e);
354 AlertUtil.setMessage(MessagesManager.get("tree.error.copy") + " " + AlertUtil.getExceptionMessage(e));
355 }
356 return VIEW_COPY_MOVE;
357 }
358
359
360
361
362 public String move() {
363 try {
364 synchronized (ExclusiveWrite.getInstance()) {
365 copyOrMove(Tree.ACTION_MOVE);
366 }
367 }
368 catch (Exception e) {
369 log.error("can't move", e);
370 AlertUtil.setMessage(MessagesManager.get("tree.error.move") + " " + AlertUtil.getExceptionMessage(e));
371 }
372 return VIEW_COPY_MOVE;
373
374 }
375
376
377
378
379
380
381 private void copyOrMove(int action) throws ExchangeException, RepositoryException {
382 String pathClipboard = this.getRequest().getParameter("pathClipboard");
383 int pasteType = Integer.parseInt(this.getRequest().getParameter("pasteType"));
384 newPath = pasteNode(pathClipboard, pathSelected, pasteType, action);
385
386 if (pasteType == Tree.PASTETYPE_SUB) {
387 pathOpen = pathSelected;
388 }
389 else {
390
391 pathOpen = pathSelected.substring(0, pathSelected.lastIndexOf("/"));
392 }
393
394 pathSelected = null;
395 }
396
397 public void deleteNode(String parentPath, String label) throws ExchangeException, RepositoryException {
398 Content parentNode = getHierarchyManager().getContent(parentPath);
399 String path;
400 if (!parentPath.equals("/")) {
401 path = parentPath + "/" + label;
402 }
403 else {
404 path = "/" + label;
405 }
406 this.deactivateNode(path);
407 parentNode.delete(label);
408 parentNode.save();
409 }
410
411 public void deleteNode(String path) throws Exception {
412 String parentPath = StringUtils.substringBeforeLast(path, "/");
413 String label = StringUtils.substringAfterLast(path, "/");
414 deleteNode(parentPath, label);
415 }
416
417 public String delete() {
418 String deleteNode = this.getRequest().getParameter("deleteNode");
419 try {
420 synchronized (ExclusiveWrite.getInstance()) {
421 deleteNode(path, deleteNode);
422 }
423 }
424 catch (Exception e) {
425 log.error("can't delete", e);
426 AlertUtil.setMessage(MessagesManager.get("tree.error.delete") + " " + AlertUtil.getExceptionMessage(e));
427 }
428 return VIEW_TREE;
429 }
430
431
432
433
434
435
436
437 public Syndicator getActivationSyndicator(String path) {
438
439 return null;
440 }
441
442
443
444
445
446
447
448 public void deactivateNode(String path) throws ExchangeException, RepositoryException {
449 if (MgnlContext.getHierarchyManager(this.getRepository()).isNodeData(path)) {
450 return;
451 }
452 CommandsManager cm = CommandsManager.getInstance();
453
454 Command cmd = cm.getCommand(this.getName(), "deactivate");
455 if (cmd == null) {
456 cmd = cm.getCommand(CommandsManager.DEFAULT_CATALOG, "deactivate");
457 }
458
459 if (cmd == null) {
460 log.error("deactivate command not found, deactivation will not be performed");
461 return;
462 }
463
464 Context ctx = this.getCommandContext("deactivate");
465
466
467 ctx.setAttribute(Context.ATTRIBUTE_PATH, path, Context.LOCAL_SCOPE);
468 try {
469 cmd.execute(ctx);
470 }
471 catch (Exception e) {
472 throw new ExchangeException(e);
473 }
474
475 }
476
477 public Content copyMoveNode(String source, String destination, boolean move) throws ExchangeException,
478 RepositoryException {
479
480 final HierarchyManager hm = getHierarchyManager();
481 if (hm.isExist(destination)) {
482 String parentPath = StringUtils.substringBeforeLast(destination, "/");
483 String label = StringUtils.substringAfterLast(destination, "/");
484 label = Path.getUniqueLabel(getHierarchyManager(), parentPath, label);
485 destination = parentPath + "/" + label;
486 }
487 if (move) {
488 if (destination.indexOf(source + "/") == 0) {
489
490
491 return null;
492 }
493 try {
494 hm.moveTo(source, destination);
495 }
496 catch (Exception e) {
497
498 return null;
499 }
500 }
501 else {
502
503 hm.copyTo(source, destination);
504 }
505 Content newContent = hm.getContent(destination);
506 try {
507 newContent.updateMetaData();
508 if (!move) {
509
510 newContent.getMetaData().setUnActivated();
511 }
512 updateChildMetaData(move, newContent);
513 }
514 catch (Exception e) {
515 if (log.isDebugEnabled()) {
516 log.debug("Exception caught: " + e.getMessage(), e);
517 }
518 }
519 newContent.save();
520 return newContent;
521 }
522
523 private void updateChildMetaData(boolean move, Content newContent) throws RepositoryException, AccessDeniedException {
524
525 for (Iterator iter = newContent.getChildren().iterator(); iter.hasNext();) {
526 Content child = (Content) iter.next();
527 child.updateMetaData();
528 if (!move) {
529
530 child.getMetaData().setUnActivated();
531 }
532 updateChildMetaData(move, child);
533 }
534 }
535
536 public void moveNode(String source, String destination) throws ExchangeException, RepositoryException {
537 this.copyMoveNode(source, destination, true);
538 }
539
540 public void copyNode(String source, String destination) throws ExchangeException, RepositoryException {
541 this.copyMoveNode(source, destination, false);
542 }
543
544 public String renameNode(String newLabel) throws AccessDeniedException, ExchangeException, PathNotFoundException,
545 RepositoryException {
546 String returnValue;
547 String parentPath = StringUtils.substringBeforeLast(this.getPath(), "/");
548 newLabel = Path.getValidatedLabel(newLabel);
549
550
551 if (this.getPath().endsWith("/" + newLabel)) {
552 return newLabel;
553 }
554
555 String dest = parentPath + "/" + newLabel;
556 if (getHierarchyManager().isExist(dest)) {
557 newLabel = Path.getUniqueLabel(getHierarchyManager(), parentPath, newLabel);
558 dest = parentPath + "/" + newLabel;
559 }
560
561
562
563 log.info("Moving node from " + this.getPath() + " to " + dest);
564 if (getHierarchyManager().isNodeData(this.getPath())) {
565 Content parentPage = getHierarchyManager().getContent(parentPath);
566 NodeData newNodeData = parentPage.createNodeData(newLabel);
567 NodeData existingNodeData = getHierarchyManager().getNodeData(this.getPath());
568 newNodeData.setValue(existingNodeData.getValue());
569 existingNodeData.delete();
570 dest = parentPath;
571 }
572 else {
573 Content current = getHierarchyManager().getContent(this.getPath());
574 ContentUtil.rename(current, newLabel);
575 current.getParent().save();
576 }
577
578 Content newPage = getHierarchyManager().getContent(dest);
579 returnValue = newLabel;
580 newPage.updateMetaData();
581 newPage.save();
582
583 return returnValue;
584 }
585
586
587
588
589
590 public String saveValue() {
591 String saveName = this.getRequest().getParameter("saveName");
592 Tree tree = getTree();
593
594
595 boolean isNodeDataValue = "true".equals(this.getRequest().getParameter("isNodeDataValue"));
596
597
598 boolean isNodeDataType = "true".equals(this.getRequest().getParameter("isNodeDataType"));
599
600 String value = StringUtils.defaultString(this.getRequest().getParameter("saveValue"));
601 displayValue = StringUtils.EMPTY;
602
603 boolean isMeta = "true".equals(this.getRequest().getParameter("isMeta"));
604
605 boolean isLabel = "true".equals(this.getRequest().getParameter("isLabel"));
606
607 if (isNodeDataValue || isNodeDataType) {
608 tree.setPath(StringUtils.substringBeforeLast(path, "/"));
609 saveName = StringUtils.substringAfterLast(path, "/");
610 }
611 else {
612
613 tree.setPath(path);
614 }
615
616 if (isLabel) {
617 displayValue = rename(value);
618 }
619 else if (isNodeDataType) {
620 int type = Integer.valueOf(value).intValue();
621 synchronized (ExclusiveWrite.getInstance()) {
622 displayValue = tree.saveNodeDataType(saveName, type);
623 }
624 }
625 else {
626 synchronized (ExclusiveWrite.getInstance()) {
627 displayValue = tree.saveNodeData(saveName, value, isMeta);
628 }
629 }
630
631
632 displayValue = StringUtils.defaultString(this.getRequest().getParameter("displayValue"), value);
633
634 displayValue = encodeHTML(displayValue);
635
636 return VIEW_VALUE;
637 }
638
639 public String encodeHTML(String value){
640 value = value.replace("<", "<");
641 value = value.replace(">", ">");
642 return value;
643 }
644
645
646
647
648
649
650 protected String rename(String value) {
651 try {
652 synchronized (ExclusiveWrite.getInstance()) {
653 return renameNode(value);
654 }
655 }
656 catch (Exception e) {
657 log.error("can't rename", e);
658 AlertUtil.setMessage(MessagesManager.get("tree.error.rename") + " " + AlertUtil.getExceptionMessage(e));
659 }
660 return StringUtils.EMPTY;
661 }
662
663 public String pasteNode(String pathOrigin, String pathSelected, int pasteType, int action)
664 throws ExchangeException, RepositoryException {
665 boolean move = false;
666 if (action == Tree.ACTION_MOVE) {
667 move = true;
668 }
669 String label = StringUtils.substringAfterLast(pathOrigin, "/");
670 String slash = "/";
671 if (pathSelected.equals("/")) {
672 slash = StringUtils.EMPTY;
673 }
674 String destination = pathSelected + slash + label;
675 if (pasteType == Tree.PASTETYPE_SUB && action != Tree.ACTION_COPY && destination.equals(pathOrigin)) {
676
677 pasteType = Tree.PASTETYPE_LAST;
678 }
679 if (pasteType == Tree.PASTETYPE_SUB) {
680 destination = pathSelected + slash + label;
681 Content touchedContent = this.copyMoveNode(pathOrigin, destination, move);
682 if (touchedContent == null) {
683 return StringUtils.EMPTY;
684 }
685 return touchedContent.getHandle();
686
687 }
688 else if (pasteType == Tree.PASTETYPE_LAST) {
689
690 try {
691 Content touchedContent = getHierarchyManager().getContent(pathOrigin);
692 return touchedContent.getHandle();
693 }
694 catch (RepositoryException re) {
695 return StringUtils.EMPTY;
696 }
697 }
698 else {
699 try {
700
701 String nameSelected = StringUtils.substringAfterLast(pathSelected, "/");
702 String nameOrigin = StringUtils.substringAfterLast(pathOrigin, "/");
703 Content tomove = getHierarchyManager().getContent(pathOrigin);
704 Content selected = getHierarchyManager().getContent(pathSelected);
705
706
707 if (tomove.getParent().getHandle().equals(selected.getParent().getHandle())) {
708
709 if (move) {
710 tomove.getParent().orderBefore(nameOrigin, nameSelected);
711
712 tomove.updateMetaData();
713
714 tomove.getParent().save();
715 }
716 else {
717 Content newNode = this.copyMoveNode(pathOrigin, pathOrigin, move);
718 tomove.getParent().orderBefore(newNode.getName(), nameSelected);
719 tomove.getParent().save();
720 }
721
722 }
723 else {
724 String newOrigin = selected.getParent().getHandle() + "/" + nameOrigin;
725
726 if (newOrigin.startsWith("//")) {
727 newOrigin = StringUtils.removeStart(newOrigin, "/");
728 }
729 Content newNode = this.copyMoveNode(pathOrigin, newOrigin, move);
730
731 if (pasteType == Tree.PASTETYPE_ABOVE) {
732 newNode.getParent().orderBefore(newNode.getName(), nameSelected);
733 newNode.getParent().save();
734 }
735 }
736 return tomove.getHandle();
737 }
738 catch (RepositoryException re) {
739 re.printStackTrace();
740 log.error("Problem when pasting node", re);
741 return StringUtils.EMPTY;
742 }
743 }
744 }
745
746
747
748
749
750
751 @Override
752 public void renderHtml(String view) throws IOException {
753 StringBuffer html = new StringBuffer(500);
754
755
756 if (AlertUtil.isMessageSet()) {
757 html.append("<input type=\"hidden\" id=\"mgnlMessage\" value=\"");
758 html.append(ControlImpl.escapeHTML(AlertUtil.getMessage()));
759 html.append("\" />");
760 }
761
762 if (VIEW_TREE.equals(view) || VIEW_CREATE.equals(view) || VIEW_COPY_MOVE.equals(view)) {
763
764 if (!view.equals(VIEW_CREATE)) {
765 getTree().setPathOpen(pathOpen);
766 getTree().setPathSelected(pathSelected);
767 }
768
769
770 if (view.equals(VIEW_COPY_MOVE)) {
771
772
773 html.append("<input type=\"hidden\" id=\"mgnlSelectNode\" value=\"");
774 html.append(newPath);
775 html.append("\" />");
776 }
777
778 renderTree(html);
779 }
780
781
782 else if (view.equals(VIEW_VALUE)) {
783 html.append(displayValue);
784 }
785 this.getResponse().getWriter().print(html);
786 }
787
788
789
790
791
792 protected void renderTree(StringBuffer html) {
793 String mode = StringUtils.defaultString(this.getRequest().getParameter("treeMode"));
794 boolean snippetMode = mode.equals("snippet");
795 Tree tree = getTree();
796
797 tree.setJavascriptTree("mgnlTreeControl");
798 tree.setBrowseMode(this.isBrowseMode());
799
800 if (!snippetMode) {
801
802
803 html.append("<html>\n");
804 html.append("<head>\n");
805 html.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n");
806 renderHeaderIncludes(html);
807 html.append("<title>Magnolia</title>\n");
808 html.append("</head>\n");
809 html.append("<body class=\"mgnlBgDark\">");
810 }
811
812 tree.setSnippetMode(snippetMode);
813 tree.setHeight(50);
814
815 tree.setPath(path);
816
817 this.getConfiguration().prepareTree(tree, this.isBrowseMode(), this.getRequest());
818 this.getConfiguration().prepareContextMenu(tree, this.isBrowseMode(), this.getRequest());
819 this.getConfiguration().prepareFunctionBar(tree, this.isBrowseMode(), this.getRequest());
820
821 if (!snippetMode) {
822 html.append("<div id=\"");
823 html.append(tree.getJavascriptTree());
824 html.append("_DivSuper\" style=\"display:block;\">");
825 }
826 html.append(tree.getHtml());
827 if (!snippetMode) {
828 html.append("</div>");
829 }
830
831 if (!snippetMode) {
832 html.append("</body></html>");
833 }
834 }
835
836
837
838
839 protected void renderHeaderIncludes(StringBuffer html) {
840 html.append(new Sources(this.getRequest().getContextPath()).getHtmlJs());
841 html.append(new Sources(this.getRequest().getContextPath()).getHtmlCss());
842 }
843
844 protected void setTree(Tree tree) {
845 this.tree = tree;
846 }
847
848 protected Tree getTree() {
849 if (tree == null) {
850 tree = Classes.quietNewInstance(getTreeClass(), getName(), getRepository());
851
852 if (tree == null) {
853
854 log.warn("The {} Tree class is probably using the deprecated (String name, String repository, HttpServletRequest request) constructor. Please use the (String name, String repository) constructor instead.", getTreeClass());
855 tree = Classes.quietNewInstance(this.getTreeClass(), getName(), getRepository(), getRequest());
856 }
857 tree.setRootPath(this.getRootPath());
858 }
859 return tree;
860 }
861
862
863 public String getNewNodeName() {
864 return this.newNodeName;
865 }
866
867
868 public void setNewNodeName(String newNodeName) {
869 this.newNodeName = newNodeName;
870 }
871
872 protected String getPath() {
873 return path;
874 }
875
876 protected String getPathSelected() {
877 return pathSelected;
878 }
879
880
881 public String getCreateItemType() {
882 return this.createItemType;
883 }
884
885
886 public void setCreateItemType(String createItemType) {
887 this.createItemType = createItemType;
888 }
889
890
891
892
893 public boolean isBrowseMode() {
894 return browseMode;
895 }
896
897
898
899
900 public void setBrowseMode(boolean browseMode) {
901 this.browseMode = browseMode;
902 }
903
904
905
906
907
908
909 public AdminTreeConfiguration getConfiguration() {
910 if (this.configuration == null) {
911 if (getConfigurationClass() == null) {
912 return null;
913 }
914 final AdminTreeConfiguration treeConfiguration = Classes.quietNewInstance(getConfigurationClass());
915 setConfiguration(treeConfiguration);
916 }
917 return this.configuration;
918 }
919
920
921
922
923 public void setConfiguration(AdminTreeConfiguration configuration) {
924 this.configuration = configuration;
925 final Messages messages = MessagesUtil.chainWithDefault(getI18nBasename());
926 configuration.setMessages(messages);
927 if (configuration instanceof AbstractTreeConfiguration) {
928 ((AbstractTreeConfiguration) configuration).setEnableDeleteConfirmation(isEnableDeleteConfirmation());
929 }
930 }
931
932 public String getConfigurationClass() {
933 return configurationClass;
934 }
935
936 public void setConfigurationClass(String configClass) {
937 this.configurationClass = configClass;
938 }
939
940 public String getTreeClass() {
941 return treeClass;
942 }
943
944 public void setTreeClass(String treeClass) {
945 this.treeClass = treeClass;
946 }
947
948 public String getI18nBasename() {
949 return i18nBasename;
950 }
951
952 public void setI18nBasename(String i18nBasename) {
953 this.i18nBasename = i18nBasename;
954 }
955
956 public String getRootPath() {
957 return rootPath;
958 }
959
960 public void setRootPath(String rootPath) {
961 this.rootPath = rootPath;
962 }
963
964 public boolean isEnableDeleteConfirmation() {
965 return enableDeleteConfirmation;
966 }
967
968 public void setEnableDeleteConfirmation(boolean enableConfirmation) {
969 this.enableDeleteConfirmation = enableConfirmation;
970 AdminTreeConfiguration conf = getConfiguration();
971 if (conf != null && conf instanceof AbstractTreeConfiguration) {
972 ((AbstractTreeConfiguration) conf).setEnableDeleteConfirmation(isEnableDeleteConfirmation());
973 }
974 }
975 }