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