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.internal.component;
21
22 import org.apache.myfaces.tobago.compat.InvokeOnComponent;
23 import org.apache.myfaces.tobago.component.Attributes;
24 import org.apache.myfaces.tobago.model.ExpandedState;
25 import org.apache.myfaces.tobago.model.Selectable;
26 import org.apache.myfaces.tobago.model.TreeDataModel;
27 import org.apache.myfaces.tobago.model.TreeNodeDataModel;
28 import org.apache.myfaces.tobago.model.TreePath;
29 import org.apache.myfaces.tobago.util.ComponentUtils;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import javax.faces.FacesException;
34 import javax.faces.component.ContextCallback;
35 import javax.faces.context.FacesContext;
36 import javax.faces.model.DataModel;
37 import javax.swing.tree.TreeNode;
38 import java.io.IOException;
39 import java.util.List;
40
41 public abstract class AbstractUIData extends javax.faces.component.UIData implements InvokeOnComponent {
42
43 private static final Logger LOG = LoggerFactory.getLogger(AbstractUIData.class);
44
45 public static final String SUFFIX_MARKED = "marked";
46 public static final String SUFFIX_EXPANDED = "expanded";
47
48
49
50
51 private boolean initialized;
52
53
54
55
56 private TreeDataModel dataModel;
57
58 public boolean isTreeModel() {
59 init();
60 return dataModel != null;
61 }
62
63 public TreeDataModel getTreeDataModel() {
64 if (isTreeModel()) {
65 return dataModel;
66 } else {
67 LOG.warn("Not a tree model");
68 return null;
69 }
70 }
71
72 @Override
73 protected DataModel getDataModel() {
74 init();
75
76 if (dataModel != null) {
77 return dataModel;
78 } else {
79 return super.getDataModel();
80 }
81 }
82
83 private void init() {
84 if (!initialized) {
85 Object value = getValue();
86 boolean showRoot = isShowRoot();
87 createTreeDataModel(value, showRoot);
88
89 initialized = true;
90 }
91 }
92
93
94
95
96 public Selectable getSelectableAsEnum() {
97 final Selectable selectable = Selectable.parse(ComponentUtils.getStringAttribute(this, Attributes.SELECTABLE));
98 return selectable != null ? selectable : Selectable.NONE;
99 }
100
101
102
103
104
105
106
107
108
109 protected void createTreeDataModel(Object value, boolean showRoot) {
110
111 if (value instanceof TreeNode) {
112 dataModel = new TreeNodeDataModel((TreeNode) value, showRoot, getExpandedState());
113 }
114 }
115
116 @Override
117 public void encodeBegin(FacesContext context) throws IOException {
118 init();
119 if (dataModel != null) {
120 dataModel.reset();
121 }
122 super.encodeBegin(context);
123 }
124
125 public abstract ExpandedState getExpandedState();
126
127
128
129
130
131 @Deprecated
132 public boolean hasRows() {
133 return getRows() != 0;
134 }
135
136 public boolean isRowVisible() {
137 init();
138 if (dataModel != null) {
139 return dataModel.isRowVisible();
140 } else {
141 return super.getDataModel().isRowAvailable();
142 }
143 }
144
145 public String getRowClientId() {
146 init();
147 return dataModel != null ? dataModel.getRowClientId() : null;
148 }
149
150 public String getRowParentClientId() {
151 init();
152 return dataModel != null ? dataModel.getRowParentClientId() : null;
153 }
154
155 public abstract boolean isShowRoot();
156
157 public boolean isShowRootJunction() {
158 return false;
159 }
160
161
162
163
164 public boolean isRowsUnlimited() {
165 return getRows() == 0;
166 }
167
168
169
170
171
172
173
174 public boolean isRendersRowContainer() {
175 return false;
176 }
177
178
179 public boolean invokeOnComponent(FacesContext facesContext, String clientId, ContextCallback callback)
180 throws FacesException {
181
182 int oldRowIndex = getRowIndex();
183 try {
184 String sheetId = getClientId(facesContext);
185 if (clientId.startsWith(sheetId)) {
186 String idRemainder = clientId.substring(sheetId.length());
187 if (LOG.isDebugEnabled()) {
188 LOG.debug("idRemainder = '" + idRemainder + "'");
189 }
190 if (idRemainder.matches("^:\\d+:.*")) {
191 idRemainder = idRemainder.substring(1);
192 int idx = idRemainder.indexOf(":");
193 try {
194 int rowIndex = Integer.parseInt(idRemainder.substring(0, idx));
195 if (LOG.isDebugEnabled()) {
196 LOG.debug("set rowIndex = '" + rowIndex + "'");
197 }
198 setRowIndex(rowIndex);
199 } catch (NumberFormatException e) {
200 LOG.warn("idRemainder = '" + idRemainder + "'", e);
201 }
202 } else {
203 if (LOG.isDebugEnabled()) {
204 LOG.debug("no match for '^:\\d+:.*'");
205 }
206 }
207 }
208
209 return ComponentUtils.invokeOnComponent(facesContext, this, clientId, callback);
210
211 } finally {
212
213 setRowIndex(oldRowIndex);
214 }
215 }
216
217
218
219
220 public TreePath getPath() {
221 if (isTreeModel()) {
222 return ((TreeDataModel) getDataModel()).getPath();
223 } else {
224 LOG.warn("Not a tree model");
225 return null;
226 }
227 }
228
229
230
231
232 public boolean isFolder() {
233 if (isTreeModel()) {
234 return ((TreeDataModel) getDataModel()).isFolder();
235 } else {
236 LOG.warn("Not a tree model");
237 return false;
238 }
239 }
240
241 public List<Integer> getRowIndicesOfChildren() {
242 if (isTreeModel()) {
243 return dataModel.getRowIndicesOfChildren();
244 } else {
245 LOG.warn("Not a tree model");
246 return null;
247 }
248 }
249 }