1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
21
22 import org.apache.myfaces.tobago.component.UITreeNode;
23 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
24 import org.apache.myfaces.tobago.internal.component.AbstractUITree;
25 import org.apache.myfaces.tobago.model.ExpandedState;
26 import org.apache.myfaces.tobago.model.MarkedState;
27 import org.apache.myfaces.tobago.model.Selectable;
28 import org.apache.myfaces.tobago.model.TreePath;
29 import org.apache.myfaces.tobago.renderkit.LayoutComponentRendererBase;
30 import org.apache.myfaces.tobago.renderkit.css.Classes;
31 import org.apache.myfaces.tobago.renderkit.css.Style;
32 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
33 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
34 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
35 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
36 import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
37 import org.apache.myfaces.tobago.renderkit.util.RenderUtils;
38 import org.apache.myfaces.tobago.util.ComponentUtils;
39 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 import javax.faces.component.UIComponent;
44 import javax.faces.context.FacesContext;
45 import java.io.IOException;
46
47 public class TreeRenderer extends LayoutComponentRendererBase {
48
49 private static final Logger LOG = LoggerFactory.getLogger(TreeRenderer.class);
50
51 @Override
52 public void decode(FacesContext facesContext, UIComponent component) {
53 final AbstractUITree tree = (AbstractUITree) component;
54 RenderUtils.decodedStateOfTreeData(facesContext, tree);
55 }
56
57 @Override
58 public boolean getRendersChildren() {
59 return true;
60 }
61
62 @Override
63 public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
64
65 }
66
67 @Override
68 public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
69
70 AbstractUITree tree = (AbstractUITree) component;
71
72 String clientId = tree.getClientId(facesContext);
73 UIComponent root = ComponentUtils.findDescendant(tree, UITreeNode.class);
74 if (root == null) {
75 LOG.error("Can't find the tree root. This may occur while updating a tree from Tobago 1.0 to 1.5. "
76 + "Please refer the documentation to see how to use tree tags.");
77 return;
78 }
79
80 TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
81
82 writer.startElement(HtmlElements.DIV, tree);
83 writer.writeClassAttribute(Classes.create(tree));
84 Style style = new Style(facesContext, tree);
85 writer.writeStyleAttribute(style);
86 writer.writeIdAttribute(clientId);
87 HtmlRendererUtils.writeDataAttributes(facesContext, writer, tree);
88
89 final Selectable selectable = tree.getSelectableAsEnum();
90 if (selectable.isSupportedByTree()) {
91 writer.writeAttribute(DataAttributes.SELECTABLE, selectable.getValue(), false);
92 }
93
94 MarkedState markedState = tree.getMarkedState();
95 String markedValue = "";
96
97 ExpandedState expandedState = tree.getExpandedState();
98 StringBuilder expandedValue = new StringBuilder(",");
99
100 final int last = tree.isRowsUnlimited() ? Integer.MAX_VALUE : tree.getFirst() + tree.getRows();
101 for (int rowIndex = tree.getFirst(); rowIndex < last; rowIndex++) {
102 tree.setRowIndex(rowIndex);
103 if (!tree.isRowAvailable()) {
104 break;
105 }
106
107 final TreePath path = tree.getPath();
108
109 if (markedState.isMarked(path)) {
110 markedValue += rowIndex;
111 }
112
113 if (tree.isFolder() && expandedState.isExpanded(path)) {
114 expandedValue.append(rowIndex);
115 expandedValue.append(",");
116 }
117
118 for (UIComponent child : tree.getChildren()) {
119 RenderUtils.prepareRendererAll(facesContext, child);
120 RenderUtils.encode(facesContext, child);
121 }
122 }
123 tree.setRowIndex(-1);
124
125 writer.startElement(HtmlElements.INPUT, tree);
126 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
127 final String markedId = clientId + ComponentUtils.SUB_SEPARATOR + AbstractUITree.SUFFIX_MARKED;
128 writer.writeNameAttribute(markedId);
129 writer.writeIdAttribute(markedId);
130 writer.writeClassAttribute(Classes.create(tree, AbstractUITree.SUFFIX_MARKED));
131 writer.writeAttribute(HtmlAttributes.VALUE, markedValue, false);
132 writer.endElement(HtmlElements.INPUT);
133
134 writer.startElement(HtmlElements.INPUT, tree);
135 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
136 final String expandedId = clientId + ComponentUtils.SUB_SEPARATOR + AbstractUIData.SUFFIX_EXPANDED;
137 writer.writeNameAttribute(expandedId);
138 writer.writeIdAttribute(expandedId);
139 writer.writeClassAttribute(Classes.create(tree, AbstractUIData.SUFFIX_EXPANDED));
140 writer.writeAttribute(HtmlAttributes.VALUE, expandedValue.toString(), false);
141 writer.endElement(HtmlElements.INPUT);
142
143 writer.endElement(HtmlElements.DIV);
144 }
145
146 @Override
147 public boolean getPrepareRendersChildren() {
148 return true;
149 }
150 }