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.control;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.core.HierarchyManager;
38 import info.magnolia.cms.core.ItemType;
39 import info.magnolia.cms.core.NodeData;
40 import info.magnolia.cms.core.Path;
41 import info.magnolia.cms.util.MetaDataUtil;
42 import info.magnolia.cms.util.NodeDataUtil;
43 import info.magnolia.context.MgnlContext;
44 import info.magnolia.freemarker.FreemarkerUtil;
45
46 import java.util.ArrayList;
47 import java.util.Collection;
48 import java.util.Collections;
49 import java.util.Comparator;
50 import java.util.HashMap;
51 import java.util.HashSet;
52 import java.util.Iterator;
53 import java.util.List;
54 import java.util.Map;
55 import java.util.Set;
56 import java.util.TreeSet;
57
58 import javax.jcr.PropertyType;
59 import javax.jcr.RepositoryException;
60 import javax.jcr.Value;
61 import javax.servlet.http.HttpServletRequest;
62
63 import org.apache.commons.lang.StringEscapeUtils;
64 import org.apache.commons.lang.StringUtils;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67
68
69
70
71
72
73 public class Tree extends ControlImpl {
74
75 public static final String DOCROOT = "/.resources/controls/tree/";
76
77 public static final String ICONDOCROOT = "/.resources/icons/16/";
78
79 public static final String DEFAULT_ICON = ICONDOCROOT + "cubes.gif";
80
81 public static final String DEFAULT_ICON_CONTENT = ICONDOCROOT + "document_plain_earth.gif";
82
83 public static final String DEFAULT_ICON_CONTENTNODE = DEFAULT_ICON;
84
85 public static final String DEFAULT_ICON_NODEDATA = ICONDOCROOT + "cube_green.gif";
86
87 public static final String ITEM_TYPE_NODEDATA = "mgnl:nodeData";
88
89 public static final int ACTION_MOVE = 0;
90
91 public static final int ACTION_COPY = 1;
92
93 public static final int ACTION_ACTIVATE = 2;
94
95 public static final int ACTION_DEACTIVATE = 3;
96
97 public static final int PASTETYPE_ABOVE = 0;
98
99 public static final int PASTETYPE_BELOW = 1;
100
101 public static final int PASTETYPE_SUB = 2;
102
103 public static final int PASTETYPE_LAST = 3;
104
105
106
107
108 private static Logger log = LoggerFactory.getLogger(Tree.class);
109
110 private String repository;
111
112 private String pathOpen;
113
114 private String pathCurrent;
115
116 private String pathSelected;
117
118 private String rootPath;
119
120 private int indentionWidth = 15;
121
122 private List<String> itemTypes = new ArrayList<String>();
123
124 private Set<String> strictTypes = new HashSet<String>();
125
126 private int height = 400;
127
128 private Map icons = new HashMap();
129
130 private String iconOndblclick;
131
132 private String shifterExpand = DOCROOT + "shifter_EXPAND.gif";
133
134 private String shifterCollaspe = DOCROOT + "shifter_COLLAPSE.gif";
135
136 private String shifterEmpty = DOCROOT + "shifter_EMPTY.gif";
137
138 private boolean drawShifter = true;
139
140 private String javascriptTree = "mgnlTreeControl";
141
142 private List columns = new ArrayList();
143
144 private ContextMenu menu;
145
146 private Comparator sortComparator;
147
148
149
150
151 private FunctionBar functionBar;
152
153 private boolean snippetMode = true;
154
155 private String columnResizer = DOCROOT + "columnResizer.gif";
156
157 private boolean browseMode;
158
159
160
161
162 private HierarchyManager hm;
163
164
165
166
167 @Deprecated
168 public Tree(String name, String repository, HttpServletRequest request) {
169 this(name, repository);
170 }
171
172
173
174
175
176
177 public Tree(String name, String repository) {
178 this.setName(name);
179 this.setRepository(repository);
180 this.setMenu(new ContextMenu(this.getJavascriptTree()));
181 this.setFunctionBar(new FunctionBar(this.getJavascriptTree()));
182
183 this.setHierarchyManager(MgnlContext.getHierarchyManager(this.getRepository()));
184
185
186 this.setIcon(ItemType.CONTENT.getSystemName(), DEFAULT_ICON_CONTENT);
187 this.setIcon(ItemType.CONTENTNODE.getSystemName(), DEFAULT_ICON_CONTENTNODE);
188 this.setIcon(ITEM_TYPE_NODEDATA, DEFAULT_ICON_NODEDATA);
189 }
190
191
192
193
194
195
196
197 @Deprecated
198 public Tree(String repository, HttpServletRequest request) {
199 this(repository, repository, request);
200 }
201
202 public void setRepository(String s) {
203 this.repository = s;
204 }
205
206 public String getRepository() {
207 return this.repository;
208 }
209
210 public void setPathOpen(String s) {
211 this.pathOpen = s;
212 }
213
214 public String getPathOpen() {
215 return this.pathOpen;
216 }
217
218
219
220
221
222 public void setPathSelected(String s) {
223 if (StringUtils.isNotEmpty(s)) {
224 if (StringUtils.isEmpty(this.getPathOpen())) {
225 this.setPathOpen(StringUtils.substringBeforeLast(s, "/"));
226 }
227 }
228 this.pathSelected = s;
229 }
230
231 public String getPathSelected() {
232 return this.pathSelected;
233 }
234
235 public String getPath() {
236 if (super.getPath() != null) {
237 return super.getPath();
238 }
239
240 return ("/");
241 }
242
243 protected void setPathCurrent(String s) {
244 this.pathCurrent = s;
245 }
246
247 protected String getPathCurrent() {
248 return this.pathCurrent;
249 }
250
251 public void setIndentionWidth(int i) {
252 this.indentionWidth = i;
253 }
254
255 public int getIndentionWidth() {
256 return this.indentionWidth;
257 }
258
259 public List getItemTypes() {
260 return this.itemTypes;
261 }
262
263
264
265
266
267 public void addItemType(String s) {
268 addItemType(s, null);
269 }
270
271
272
273
274
275
276
277
278
279
280 public void addItemType(String type, String icon) {
281 addItemType(type, icon, true);
282 }
283
284
285
286
287
288
289
290
291
292 public void addItemType(String type, String icon, boolean strict) {
293 this.itemTypes.add(type);
294 if (icon != null) {
295 setIcon(type, icon);
296 }
297 if (strict) {
298 strictTypes.add(type);
299 } else {
300 strictTypes.remove(type);
301 }
302 }
303
304
305
306
307
308 public void addItemType(ItemType s) {
309 addItemType(s.getSystemName(), null);
310 }
311
312
313
314
315
316 public void setIconPage(String src) {
317 this.setIcon(ItemType.CONTENT.getSystemName(), src);
318 }
319
320 public String getIconPage() {
321 return this.getIcon(ItemType.CONTENT.getSystemName());
322 }
323
324
325
326
327
328 public void setIconContentNode(String src) {
329 this.setIcon(ItemType.CONTENTNODE.getSystemName(), src);
330 }
331
332 public String getIconContentNode() {
333 return this.getIcon(ItemType.CONTENTNODE.getSystemName());
334 }
335
336
337
338
339
340 public void setIconNodeData(String src) {
341 this.setIcon(ITEM_TYPE_NODEDATA, src);
342 }
343
344 public String getIconNodeData() {
345 return this.getIcon(ITEM_TYPE_NODEDATA);
346 }
347
348 protected String getIcon(String itemType) {
349 return (String) icons.get(itemType);
350 }
351
352 protected String getIcon(Content node, NodeData nodedata, String itemType) {
353 if(icons.containsKey(itemType)){
354 return (String) icons.get(itemType);
355 }
356 return DEFAULT_ICON;
357 }
358
359 public void setIcon(String typeName, String icon) {
360 icons.put(typeName, icon);
361 }
362
363
364
365
366
367 public void setIconOndblclick(String s) {
368 this.iconOndblclick = s;
369 }
370
371 public String getIconOndblclick() {
372 return this.iconOndblclick;
373 }
374
375
376
377
378
379
380 public void setShifterExpand(String src) {
381 this.shifterExpand = src;
382 }
383
384 public String getShifterExpand() {
385 return this.shifterExpand;
386 }
387
388
389
390
391
392
393 public void setShifterCollapse(String src) {
394 this.shifterCollaspe = src;
395 }
396
397 public String getShifterCollapse() {
398 return this.shifterCollaspe;
399 }
400
401
402
403
404
405
406 public void setShifterEmpty(String src) {
407 this.shifterEmpty = src;
408 }
409
410 public String getShifterEmpty() {
411 return this.shifterEmpty;
412 }
413
414 public void setDrawShifter(boolean b) {
415 this.drawShifter = b;
416 }
417
418 public boolean getDrawShifter() {
419 return this.drawShifter;
420 }
421
422 public void setHeight(int i) {
423 this.height = i;
424 }
425
426 public int getHeight() {
427 return this.height;
428 }
429
430
431
432
433
434 public void setColums(List al) {
435 this.columns = al;
436 }
437
438 public List getColumns() {
439 return this.columns;
440 }
441
442 public TreeColumn getColumns(int col) {
443 return (TreeColumn) this.getColumns().get(col);
444 }
445
446 public void addColumn(TreeColumn tc) {
447 tc.setJavascriptTree(this.getJavascriptTree());
448 this.getColumns().add(tc);
449 }
450
451
452
453
454
455 public void setJavascriptTree(String variableName) {
456 this.javascriptTree = variableName;
457 this.menu.setName(variableName + "Menu");
458 }
459
460 public String getJavascriptTree() {
461 return this.javascriptTree;
462 }
463
464
465
466
467
468
469 public void setSnippetMode(boolean b) {
470 this.snippetMode = b;
471 }
472
473 public boolean getSnippetMode() {
474 return this.snippetMode;
475 }
476
477
478 public void setColumnResizer(String src) {
479 this.columnResizer = src;
480 }
481
482 public String getColumnResizer() {
483 return this.columnResizer;
484 }
485
486 public String createNode(String itemType) {
487 return this.createNode("untitled", itemType);
488 }
489
490
491
492
493
494
495
496 public String createNode(String label, String itemType) {
497 try {
498 Content parentNode = getHierarchyManager().getContent(this.getPath());
499 String name = getUniqueLabel(label);
500 if (itemType.equals(ITEM_TYPE_NODEDATA)) {
501 parentNode.createNodeData(name);
502 } else {
503 Content newNode;
504 newNode = parentNode.createContent(name, itemType);
505 newNode.getMetaData().setAuthorId(MgnlContext.getUser().getName());
506 newNode.getMetaData().setCreationDate();
507 newNode.getMetaData().setModificationDate();
508 }
509 parentNode.save();
510 return name;
511 } catch (Exception e) {
512 log.error(e.getMessage(), e);
513 return StringUtils.EMPTY;
514 }
515
516 }
517
518 public String saveNodeData(String nodeDataName, String value, boolean isMeta) {
519 String returnValue = StringUtils.EMPTY;
520 try {
521 Content content = getHierarchyManager().getContent(this.getPath());
522 if (!isMeta) {
523 NodeData node;
524 int type = PropertyType.STRING;
525 if (!content.getNodeData(nodeDataName).isExist()) {
526 node = content.createNodeData(nodeDataName);
527 }
528 else {
529 node = content.getNodeData(nodeDataName);
530 type = node.getType();
531 }
532
533 if (node.isMultiValue() != NodeData.MULTIVALUE_TRUE) {
534 switch (type) {
535 case PropertyType.STRING:
536 node.setValue(value);
537 break;
538 case PropertyType.BOOLEAN:
539 if (value.equals("true")) {
540 node.setValue(true);
541 }
542 else {
543 node.setValue(false);
544 }
545 break;
546 case PropertyType.DOUBLE:
547 try {
548 node.setValue(Double.valueOf(value).doubleValue());
549 }
550 catch (Exception e) {
551 node.setValue(0);
552 }
553 break;
554 case PropertyType.LONG:
555 try {
556 node.setValue(Long.valueOf(value).longValue());
557 }
558 catch (Exception e) {
559 node.setValue(0);
560 }
561 break;
562 case PropertyType.DATE:
563
564 break;
565 }
566 }
567 content.updateMetaData();
568 content.save();
569 returnValue = NodeDataUtil.getValueString(node);
570 }
571 else {
572 content.getMetaData().setProperty(nodeDataName, value);
573 content.updateMetaData();
574 content.save();
575 returnValue = MetaDataUtil.getPropertyValueString(content, nodeDataName);
576 }
577 }
578 catch (Exception e) {
579 if (log.isDebugEnabled()) {
580 log.debug("Exception caught: " + e.getMessage(), e);
581 }
582 }
583 return returnValue;
584 }
585
586 public String saveNodeDataType(String nodeDataName, int type) {
587 try {
588 Content content = getHierarchyManager().getContent(this.getPath());
589 Value value = null;
590 if (content.getNodeData(nodeDataName).isExist()) {
591 value = content.getNodeData(nodeDataName).getValue();
592 content.deleteNodeData(nodeDataName);
593 }
594 NodeData node = content.createNodeData(nodeDataName);
595 if (value != null && node.isMultiValue() != NodeData.MULTIVALUE_TRUE) {
596 switch (type) {
597 case PropertyType.STRING:
598 node.setValue(value.getString());
599 break;
600 case PropertyType.BOOLEAN:
601 if (value != null && value.getBoolean()) {
602 node.setValue(true);
603 }
604 else {
605 node.setValue(false);
606 }
607 break;
608 case PropertyType.DOUBLE:
609 try {
610 node.setValue(value.getDouble());
611 }
612 catch (Exception e) {
613 node.setValue(0);
614 }
615 break;
616 case PropertyType.LONG:
617 try {
618 node.setValue(value.getLong());
619 }
620 catch (Exception e) {
621 node.setValue(0);
622 }
623 break;
624 case PropertyType.DATE:
625
626 break;
627 }
628 }
629 content.updateMetaData();
630 content.save();
631 return PropertyType.nameFromValue(content.getNodeData(nodeDataName).getType());
632
633 }
634 catch (Exception e) {
635 if (log.isDebugEnabled()) {
636 log.debug("Exception caught: " + e.getMessage(), e);
637 }
638 }
639 return StringUtils.EMPTY;
640 }
641
642
643
644
645
646
647 protected String getUniqueLabel(String label) {
648 String slash = "/";
649 boolean isRoot = false;
650 if ("/".equals(getPath())) {
651 isRoot = true;
652 slash = StringUtils.EMPTY;
653 }
654 if (getHierarchyManager().isExist(this.getPath() + slash + label)) {
655
656 if (isRoot) {
657 label = Path.getUniqueLabel(getHierarchyManager(), StringUtils.EMPTY, label);
658 } else {
659 label = Path.getUniqueLabel(getHierarchyManager(), this.getPath(), label);
660 }
661 }
662 return label;
663 }
664
665 public String getHtml() {
666 StringBuffer html = new StringBuffer();
667 html.append(this.getHtmlPre());
668
669 if (!this.getSnippetMode()) {
670 html.append(this.getHtmlHeader());
671 }
672 this.setPathCurrent(this.getPath());
673 html.append(this.getHtmlChildren());
674 if (!this.getSnippetMode()) {
675 html.append(this.getHtmlFooter());
676 }
677 html.append(this.getHtmlPost());
678 return html.toString();
679 }
680
681 public String getHtmlHeader() {
682
683 StringBuffer str = new StringBuffer();
684 try {
685 Map params = populateTemplateParameters();
686 str.append(FreemarkerUtil.process("info/magnolia/cms/gui/control/TreeHeader.ftl", params));
687 }
688 catch (Exception e) {
689 log.error("can't render tree header", e);
690 }
691 return str.toString();
692 }
693
694 public String getHtmlFooter() {
695 StringBuffer html = new StringBuffer();
696 html.append("</div>");
697
698 Map params = populateTemplateParameters();
699
700
701 html.append(FreemarkerUtil.process("info/magnolia/cms/gui/control/TreeFooter.ftl", params));
702
703 return html.toString();
704 }
705
706 protected Map populateTemplateParameters() {
707 boolean permissionWrite = true;
708 try {
709 Content root = getHierarchyManager().getContent(this.getPath());
710 permissionWrite = root.isGranted(info.magnolia.cms.security.Permission.WRITE);
711 }
712 catch (RepositoryException e) {
713 if (log.isDebugEnabled()) {
714 log.debug("Exception caught: " + e.getMessage(), e);
715 }
716 }
717
718
719
720 String lineId = this.getJavascriptTree() + "_" + this.getPath() + "_LineInter";
721
722
723 Map params = new HashMap();
724 params.put("tree", this);
725 params.put("PASTETYPE_SUB", new Integer(Tree.PASTETYPE_SUB));
726 params.put("DOCROOT", Tree.DOCROOT);
727 params.put("lineId", lineId);
728 params.put("permissionWrite", Boolean.valueOf(permissionWrite));
729 params.put("columns", this.getColumns());
730 params.put("menu", this.getMenu());
731 params.put("treeCssClass", "mgnlTreeDiv");
732 if (this.isBrowseMode()) {
733 params.put("treeCssClass", "mgnlTreeBrowseModeDiv mgnlTreeDiv");
734 }
735 return params;
736 }
737
738 public String getHtmlBranch() {
739 return StringUtils.EMPTY;
740 }
741
742 public String getHtmlChildren() {
743 StringBuffer html = new StringBuffer();
744 Content parentNode;
745 try {
746 parentNode = getHierarchyManager().getContent(this.getPathCurrent());
747
748 for (int i = 0; i < this.getItemTypes().size(); i++) {
749 String type = (String) this.getItemTypes().get(i);
750 if (hasSub(parentNode, type)) {
751 html.append(this.getHtmlChildrenOfOneType(parentNode, type));
752 }
753 }
754 }
755 catch (RepositoryException e) {
756 if (log.isDebugEnabled()) {
757 log.debug("Exception caught: " + e.getMessage(), e);
758 }
759 }
760 return html.toString();
761 }
762
763 public String getHtmlChildrenOfOneType(Content parentNode, String itemType) {
764 StringBuffer html = new StringBuffer();
765 try {
766 Iterator it = collectRenderedItems(parentNode, itemType);
767 while (it.hasNext()) {
768 Object maybeContent = it.next();
769 if (maybeContent instanceof Content) {
770 Content c = (Content) maybeContent;
771
772 if (strictTypes.contains(itemType) && !c.getItemType().getSystemName().equals(itemType)) {
773 continue;
774 }
775 }
776 getHtmlOfSingleItem(html, parentNode, itemType, maybeContent);
777 }
778 }
779 catch (RepositoryException e) {
780 if (log.isDebugEnabled()) {
781 log.debug("Exception caught: " + e.getMessage(), e);
782 }
783 }
784 return html.toString();
785 }
786
787 protected void getHtmlOfSingleItem(StringBuffer html, Content parentNode, String itemType, Object item) throws RepositoryException {
788 Content c = null;
789 NodeData d = null;
790 String handle;
791 String name;
792 boolean hasSub = false;
793 boolean showSub = false;
794 boolean isActivated = false;
795 boolean permissionWrite = false;
796 boolean permissionWriteParent = false;
797 if (itemType.equals(ITEM_TYPE_NODEDATA)) {
798 d = (NodeData) item;
799 handle = d.getHandle();
800 name = d.getName();
801
802 if (d.isGranted(info.magnolia.cms.security.Permission.WRITE) && d.isMultiValue() != NodeData.MULTIVALUE_TRUE) {
803 permissionWrite = true;
804 }
805 }
806 else {
807 c = (Content) item;
808
809 handle = c.getHandle();
810 if (this.getColumns().size() == 0) {
811 name = c.getName();
812 }
813 else {
814 this.getColumns(0).setWebsiteNode(c);
815 name = this.getColumns(0).getHtml();
816 }
817 if (c.isGranted(info.magnolia.cms.security.Permission.WRITE)) {
818 permissionWrite = true;
819 }
820 if (c.getAncestor(c.getLevel() - 1).isGranted(info.magnolia.cms.security.Permission.WRITE)) {
821 permissionWriteParent = true;
822 }
823 isActivated = c.getMetaData().getIsActivated();
824 for (int i = 0; i < this.getItemTypes().size(); i++) {
825 String type = (String) this.getItemTypes().get(i);
826
827 hasSub = hasSub(c, type);
828
829 if (hasSub) {
830 if (this.getPathOpen() != null
831 && (this.getPathOpen().indexOf(handle + "/") == 0 || this.getPathOpen().equals(handle))) {
832 showSub = true;
833 }
834 break;
835 }
836 }
837 }
838
839
840 if (!showNode(c, d, itemType)) {
841 return;
842 }
843
844 String icon = getIcon(c, d, itemType);
845
846 String idPre = this.javascriptTree + "_" + handle;
847 String jsHighlightNode = this.javascriptTree + ".nodeHighlight(this,'"
848 + handle
849 + "',"
850 + Boolean.toString(permissionWrite)
851 + ");";
852 String jsResetNode = this.javascriptTree + ".nodeReset(this,'" + handle + "');";
853 String jsSelectNode = this.javascriptTree + ".selectNode('"
854 + handle
855 + "',"
856 + Boolean.toString(permissionWrite)
857 + ",'"
858 + itemType
859 + "');";
860 String jsExpandNode;
861 if (this.getDrawShifter()) {
862 jsExpandNode = this.javascriptTree + ".expandNode('" + handle + "');";
863 }
864 else {
865 jsExpandNode = jsSelectNode;
866 }
867 String jsHighlightLine = this.javascriptTree + ".moveNodeHighlightLine('" + idPre + "_LineInter');";
868 String jsResetLine = this.javascriptTree + ".moveNodeResetLine('" + idPre + "_LineInter');";
869
870
871
872 if (permissionWriteParent) {
873 html.append("<div id=\"");
874 html.append(idPre);
875 html.append("_LineInter\" class=\"mgnlTreeLineInter mgnlLineEnabled\" onmouseover=\"");
876 html.append(jsHighlightLine);
877 html.append("\" onmouseout=\"");
878 html.append(jsResetLine);
879 html.append("\" onmousedown=\"");
880 html.append(this.javascriptTree);
881 html.append(".pasteNode('");
882 html.append(handle);
883 html.append("'," + Tree.PASTETYPE_ABOVE + ",true);\" ></div>");
884 }
885 else {
886 html.append("<div id=\"");
887 html.append(idPre);
888 html.append("_LineInter\" class=\"mgnlTreeLineInter mgnlLineDisabled\"></div>");
889 }
890
891 html.append("<div id=\"");
892 html.append(idPre);
893 html.append("_DivMain\" style=\"position:relative;top:0;left:0;width:100%;height:18px;\">");
894 html.append(" ");
895
896 html.append("<span id=\"");
897 html.append(idPre);
898 html.append("_Column0Outer\" class=\"mgnlTreeColumn ");
899 html.append(this.javascriptTree);
900 html.append("CssClassColumn0\" style=\"padding-left:");
901
902 html.append(getPaddingLeft(parentNode));
903 html.append("px;\">");
904 if (this.getDrawShifter()) {
905 String shifter = StringUtils.EMPTY;
906 if (hasSub) {
907 if (showSub) {
908 if (this.getShifterCollapse() != null) {
909 shifter = this.getShifterCollapse();
910 }
911 }
912 else {
913 if (this.getShifterExpand() != null) {
914 shifter = this.getShifterExpand();
915 }
916 }
917 }
918 else {
919 if (this.getShifterEmpty() != null) {
920 shifter = this.getShifterEmpty();
921 }
922 }
923 if (StringUtils.isNotEmpty(shifter)) {
924 html.append("<img id=\"");
925 html.append(idPre);
926 html.append("_Shifter\" onmousedown=\"");
927 html.append(this.javascriptTree);
928 html.append(".shifterDown('");
929 html.append(handle);
930 html.append("');\" onmouseout=\"");
931 html.append(this.javascriptTree);
932 html.append(".shifterOut();\" class=\"mgnlTreeShifter\" src=\"");
933 html.append(this.getRequest().getContextPath());
934 html.append(shifter);
935 html.append("\" />");
936 }
937 }
938 html.append("<span id=\"");
939 html.append(idPre);
940 html.append("_Name\" onmouseover=\"");
941 html.append(jsHighlightNode);
942 html.append("\" onmouseout=\"");
943 html.append(jsResetNode);
944 html.append("\" onmousedown=\"");
945 html.append(jsSelectNode);
946 html.append(this.javascriptTree);
947 html.append(".pasteNode('");
948 html.append(handle);
949 html.append("'," + Tree.PASTETYPE_SUB + ",");
950 html.append(permissionWrite);
951 html.append(");\">");
952 if (StringUtils.isNotEmpty(icon)) {
953 html.append("<img id=\"");
954 html.append(idPre);
955 html.append("_Icon\" class=\"mgnlTreeIcon\" src=\"");
956 html.append(this.getRequest().getContextPath());
957 html.append(icon);
958 html.append("\" onmousedown=\"");
959 html.append(jsExpandNode);
960 html.append("\"");
961 if (this.getIconOndblclick() != null) {
962 html.append(" ondblclick=\"");
963 html.append(this.getIconOndblclick());
964 html.append("\"");
965 }
966 html.append(" />");
967 }
968 String dblclick = StringUtils.EMPTY;
969 String htmlEdit = this.getColumns(0).getHtmlEdit();
970 if (permissionWrite && StringUtils.isNotEmpty(htmlEdit)) {
971 dblclick = " ondblclick=\"" + this.javascriptTree + ".editNodeData(this,'" + handle + "',0,'"+ StringUtils.replace(htmlEdit, "\"", """) + "');\"";
972 }
973 html.append("<span class=\"mgnlTreeText\" id=\"");
974 html.append(idPre);
975 html.append("_Column0Main\"");
976 html.append(dblclick);
977 html.append(">");
978 html.append(name);
979 html.append("</span></span></span>");
980
981
982 html.append(new Hidden(idPre + "_PermissionWrite", Boolean.toString(permissionWrite), false).getHtml());
983 html.append(new Hidden(idPre + "_ItemType", itemType, false).getHtml());
984 html.append(new Hidden(idPre + "_IsActivated", Boolean.toString(isActivated), false).getHtml());
985
986
987 onGetHtmlOfSingleItem(html, parentNode, itemType, item , idPre);
988
989 for (int i = 1; i < this.getColumns().size(); i++) {
990 String str = StringUtils.EMPTY;
991 TreeColumn tc = this.getColumns(i);
992 if (!itemType.equals(ITEM_TYPE_NODEDATA)) {
993
994 if (!tc.getIsNodeDataType() && !tc.getIsNodeDataValue()) {
995 tc.setWebsiteNode(c);
996 tc.setId(handle);
997 str = tc.getHtml();
998 }
999 }
1000 else {
1001 if (tc.getIsNodeDataType()) {
1002 str = NodeDataUtil.getTypeName(d);
1003 }
1004 else if (tc.getIsNodeDataValue()) {
1005 final String stringValue = NodeDataUtil.getValueString(d);
1006 str = StringEscapeUtils.escapeXml(stringValue);
1007 }
1008 if (StringUtils.isEmpty(str)) {
1009 str = TreeColumn.EMPTY;
1010 }
1011 tc.setName(name);
1012 }
1013 tc.setEvent("onmouseover", jsHighlightNode, true);
1014 tc.setEvent("onmouseout", jsResetNode, true);
1015 tc.setEvent("onmousedown", jsSelectNode, true);
1016 html.append("<span class=\"mgnlTreeColumn ");
1017 html.append(this.javascriptTree);
1018 html.append("CssClassColumn");
1019 html.append(i);
1020 html.append("\"><span id=\"");
1021 html.append(idPre);
1022 html.append("_Column");
1023 html.append(i);
1024 html.append("Main\"");
1025 html.append(tc.getHtmlCssClass());
1026 html.append(tc.getHtmlEvents());
1027 htmlEdit = tc.getHtmlEdit();
1028 if (permissionWrite && StringUtils.isNotEmpty(htmlEdit)) {
1029 html.append(" ondblclick=\"");
1030 html.append(this.javascriptTree);
1031 html.append(".editNodeData(this,'");
1032 html.append(handle);
1033 html.append("',");
1034 html.append(i);
1035 html.append(",'");
1036 html.append(StringUtils.replace(htmlEdit, "\"", """));
1037 html.append("');\"");
1038 html.append(",'");
1039
1040 }
1041 html.append(">");
1042 html.append(str);
1043 html.append("</span></span>");
1044 }
1045 html.append("</div>");
1046 String display = "none";
1047 if (showSub) {
1048 display = "block";
1049 }
1050 html.append("<div id=\"");
1051 html.append(idPre);
1052 html.append("_DivSub\" style=\"display:");
1053 html.append(display);
1054 html.append(";\">");
1055 if (hasSub) {
1056 if (showSub) {
1057 String pathRemaining = this.getPathOpen().substring(this.getPathCurrent().length());
1058 if (pathRemaining.length() > 0) {
1059
1060 String slash = "/";
1061 if (this.getPathCurrent().equals("/")) {
1062
1063 slash = StringUtils.EMPTY;
1064 }
1065 else {
1066 pathRemaining = pathRemaining.substring(1);
1067 }
1068 String nextChunk = StringUtils.substringBefore(pathRemaining, "/");
1069
1070 String pathNext = this.getPathCurrent() + slash + nextChunk;
1071 this.setPathCurrent(pathNext);
1072 html.append(this.getHtmlChildren());
1073 }
1074 }
1075 }
1076 html.append("</div>\n");
1077
1078 }
1079
1080 protected void onGetHtmlOfSingleItem(StringBuffer html, Content parentNode, String itemType, Object item, String idPre) {
1081 }
1082
1083 protected Iterator collectRenderedItems(Content parentNode, String itemType) {
1084 Iterator it;
1085 if (itemType.equalsIgnoreCase(ITEM_TYPE_NODEDATA)) {
1086 List nodeDatas = new ArrayList(parentNode.getNodeDataCollection());
1087
1088 Collections.sort(nodeDatas, new Comparator() {
1089
1090 public int compare(Object arg0, Object arg1) {
1091 return ((NodeData) arg0).getName().compareTo(((NodeData) arg1).getName());
1092 }
1093 });
1094 it = nodeDatas.iterator();
1095 }
1096 else {
1097 Collection nodes = parentNode.getChildren(itemType);
1098 Comparator comp = this.getSortComparator();
1099 if(comp != null){
1100 Collection sortedNodes = new TreeSet(comp);
1101 sortedNodes.addAll(nodes);
1102 nodes = sortedNodes;
1103 }
1104 it = nodes.iterator();
1105 }
1106 return it;
1107 }
1108
1109 protected int getPaddingLeft(Content parentNode) throws RepositoryException {
1110 int left = (parentNode.getLevel() - StringUtils.countMatches(getRootPath(), "/")) * this.getIndentionWidth();
1111 int paddingLeft = left + 8;
1112 if (paddingLeft < 8) {
1113 paddingLeft = 8;
1114 }
1115 return paddingLeft;
1116 }
1117
1118 protected boolean hasSub(Content c, String type) {
1119 int size;
1120 if (type.equalsIgnoreCase(ITEM_TYPE_NODEDATA)) {
1121 size = c.getNodeDataCollection().size();
1122 }
1123 else {
1124 size = c.getChildren(type).size();
1125 }
1126 return size > 0;
1127 }
1128
1129
1130
1131
1132
1133
1134
1135
1136 protected boolean showNode(Content node, NodeData nodedata, String itemType) {
1137 return true;
1138 }
1139
1140
1141
1142
1143 public void addMenuItem(ContextMenuItem item) {
1144 menu.addMenuItem(item);
1145 }
1146
1147
1148
1149
1150 public void addFunctionBarItem(FunctionBarItem item) {
1151 if (item != null) {
1152 item.setJavascriptMenuName(functionBar.getJavascriptName());
1153 }
1154 functionBar.addMenuItem(item);
1155 }
1156
1157
1158
1159
1160 public void addFunctionBarItemFromContextMenu(String itemName) {
1161 final ContextMenuItem menuItem = getMenu().getMenuItemByName(itemName);
1162 if (menuItem != null) {
1163 addFunctionBarItem(new FunctionBarItem(menuItem));
1164 }
1165 }
1166
1167
1168
1169
1170 public void addSeparator() {
1171 menu.addMenuItem(null);
1172 }
1173
1174 public ContextMenu getMenu() {
1175 return this.menu;
1176 }
1177
1178
1179
1180
1181 public FunctionBar getFunctionBar() {
1182 return this.functionBar;
1183 }
1184
1185 public void setMenu(ContextMenu menu) {
1186 this.menu = menu;
1187 }
1188
1189
1190
1191
1192 public void setFunctionBar(FunctionBar functionBar) {
1193 this.functionBar = functionBar;
1194 }
1195
1196
1197
1198
1199 public boolean isBrowseMode() {
1200 return browseMode;
1201 }
1202
1203
1204
1205
1206 public void setBrowseMode(boolean browseMode) {
1207 this.browseMode = browseMode;
1208 }
1209
1210
1211
1212
1213 public HierarchyManager getHierarchyManager() {
1214 return hm;
1215 }
1216
1217
1218
1219
1220 private void setHierarchyManager(HierarchyManager hm) {
1221 this.hm = hm;
1222 }
1223
1224
1225 public Comparator getSortComparator() {
1226 return sortComparator;
1227 }
1228
1229
1230 public void setSortComparator(Comparator sortComperator) {
1231 this.sortComparator = sortComperator;
1232 }
1233
1234 public String getRootPath() {
1235 return rootPath;
1236 }
1237
1238 public void setRootPath(String rootPath) {
1239 this.rootPath = rootPath;
1240 }
1241
1242
1243 }