1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.lifecycle.initialize;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
20 import org.kuali.rice.krad.service.DataDictionaryService;
21 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
22 import org.kuali.rice.krad.uif.UifConstants;
23 import org.kuali.rice.krad.uif.UifPropertyPaths;
24 import org.kuali.rice.krad.uif.component.BindingInfo;
25 import org.kuali.rice.krad.uif.field.DataField;
26 import org.kuali.rice.krad.uif.field.InputField;
27 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
28 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTaskBase;
29 import org.kuali.rice.krad.uif.util.ComponentFactory;
30 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
31 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
32 import org.kuali.rice.krad.uif.view.View;
33 import org.kuali.rice.krad.util.KRADConstants;
34
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Map.Entry;
38
39
40
41
42
43
44 public class InitializeDataFieldFromDictionaryTask extends ViewLifecycleTaskBase<DataField> {
45
46
47
48
49
50
51 public InitializeDataFieldFromDictionaryTask() {
52 super(DataField.class);
53 }
54
55
56
57
58
59
60
61 @Override
62 protected void performLifecycleTask() {
63 DataField field = (DataField) getElementState().getElement();
64
65 AttributeDefinition attributeDefinition = null;
66
67 String dictionaryAttributeName = field.getDictionaryAttributeName();
68 String dictionaryObjectEntry = field.getDictionaryObjectEntry();
69
70 Map<String, String> propertyExpressions = field.getPropertyExpressions();
71
72 if (dictionaryAttributeName == null && propertyExpressions.containsKey(UifPropertyPaths.DICTIONARY_ATTR_NAME)) {
73 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
74 dictionaryAttributeName = propertyExpressions.get(UifPropertyPaths.DICTIONARY_ATTR_NAME);
75
76 if (dictionaryAttributeName.contains(UifConstants.DEFAULT_PATH_BIND_ADJUST_PREFIX)) {
77 dictionaryAttributeName = dictionaryAttributeName.replace(UifConstants.DEFAULT_PATH_BIND_ADJUST_PREFIX,
78 "");
79 } else if (dictionaryAttributeName.contains(UifConstants.LINE_PATH_BIND_ADJUST_PREFIX)) {
80
81
82
83
84 List<Object> collection = ObjectPropertyUtils.getPropertyValue(ViewLifecycle.getModel(),
85 field.getBindingInfo().getCollectionPath());
86
87 if (!collection.isEmpty()) {
88 dictionaryAttributeName = dictionaryAttributeName.replace(UifConstants.LINE_PATH_BIND_ADJUST_PREFIX,
89 field.getBindingInfo().getCollectionPath() + "[0].");
90 } else {
91 dictionaryAttributeName = null;
92 }
93 }
94
95 dictionaryAttributeName = (String) expressionEvaluator.evaluateExpression(field.getContext(),
96 dictionaryAttributeName);
97 }
98
99 if (!(dictionaryAttributeName == null && propertyExpressions.containsKey(UifPropertyPaths.DICTIONARY_ATTR_NAME))) {
100
101
102 if (StringUtils.isNotBlank(dictionaryObjectEntry) && StringUtils.isBlank(dictionaryAttributeName)) {
103 dictionaryAttributeName = field.getPropertyName();
104 }
105
106
107 if (StringUtils.isNotBlank(dictionaryAttributeName) && StringUtils.isNotBlank(dictionaryObjectEntry)) {
108 attributeDefinition = KRADServiceLocatorWeb.getDataDictionaryService().getAttributeDefinition(
109 dictionaryObjectEntry, dictionaryAttributeName);
110 }
111
112
113 if (attributeDefinition == null) {
114 BindingInfo fieldBindingInfo = field.getBindingInfo();
115 String collectionPath = fieldBindingInfo.getCollectionPath();
116
117 String propertyPath;
118 if (StringUtils.isNotBlank(collectionPath)) {
119 StringBuilder propertyPathBuilder = new StringBuilder();
120
121 String bindingObjectPath = fieldBindingInfo.getBindingObjectPath();
122 if (StringUtils.isNotBlank(bindingObjectPath)) {
123 propertyPathBuilder.append(bindingObjectPath).append('.');
124 }
125
126 propertyPathBuilder.append(collectionPath).append('.');
127
128 String bindByNamePrefix = fieldBindingInfo.getBindByNamePrefix();
129 if (StringUtils.isNotBlank(bindByNamePrefix)) {
130
131
132
133 if (!bindByNamePrefix.startsWith(collectionPath)) {
134 propertyPathBuilder.append(bindByNamePrefix).append('.');
135 }
136 }
137
138 propertyPathBuilder.append(fieldBindingInfo.getBindingName());
139 propertyPath = propertyPathBuilder.toString();
140 } else {
141 propertyPath = field.getBindingInfo().getBindingPath();
142 }
143
144 attributeDefinition = findNestedDictionaryAttribute(propertyPath);
145 }
146
147
148 if (attributeDefinition != null) {
149 field.copyFromAttributeDefinition(attributeDefinition);
150 }
151 }
152
153
154 if (field instanceof InputField) {
155 InputField inputField = (InputField) field;
156 if (inputField.getControl() == null) {
157 inputField.setControl(ComponentFactory.getTextControl());
158 }
159 }
160 }
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 private String getDictionaryEntryName(String dictionaryEntryPrefix) {
178 if (StringUtils.isEmpty(dictionaryEntryPrefix)) {
179 return dictionaryEntryPrefix;
180 }
181
182 Map<String, Class<?>> modelClasses = ViewLifecycle.getView().getObjectPathToConcreteClassMapping();
183 Class<?> dictionaryModelClass = modelClasses.get(dictionaryEntryPrefix);
184
185
186 if (dictionaryModelClass != null) {
187 return dictionaryModelClass.getName();
188 }
189
190
191
192 Class<?> modelClass = null;
193 String modelProperty = dictionaryEntryPrefix;
194
195 int bestMatchLength = 0;
196 int modelClassPathLength = dictionaryEntryPrefix.length();
197
198
199 synchronized (modelClasses) {
200
201
202 for (Entry<String, Class<?>> modelClassEntry : modelClasses.entrySet()) {
203 String path = modelClassEntry.getKey();
204 int pathlen = path.length();
205
206 if (dictionaryEntryPrefix.startsWith(path) && pathlen > bestMatchLength
207 && modelClassPathLength > pathlen && dictionaryEntryPrefix.charAt(pathlen) == '.') {
208 bestMatchLength = pathlen;
209 modelClass = modelClassEntry.getValue();
210 modelProperty = dictionaryEntryPrefix.substring(pathlen + 1);
211 }
212 }
213 }
214
215 if (modelClass != null) {
216
217 dictionaryModelClass = ObjectPropertyUtils.getPropertyType(modelClass, modelProperty);
218 }
219
220 if (dictionaryModelClass == null) {
221
222 dictionaryModelClass = ObjectPropertyUtils.getPropertyType(ViewLifecycle.getModel(), dictionaryEntryPrefix);
223 }
224
225 return dictionaryModelClass == null ? null : dictionaryModelClass.getName();
226 }
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245 protected AttributeDefinition findNestedDictionaryAttribute(String propertyPath) {
246 DataField field = (DataField) getElementState().getElement();
247
248 String fieldBindingPrefix = null;
249 String dictionaryAttributePath = propertyPath;
250
251 if (field.getBindingInfo().isBindToMap()) {
252 fieldBindingPrefix = "";
253 if (!field.getBindingInfo().isBindToForm() && StringUtils.isNotBlank(
254 field.getBindingInfo().getBindingObjectPath())) {
255 fieldBindingPrefix = field.getBindingInfo().getBindingObjectPath();
256 }
257 if (StringUtils.isNotBlank(field.getBindingInfo().getBindByNamePrefix())) {
258 if (StringUtils.isNotBlank(fieldBindingPrefix)) {
259 fieldBindingPrefix += "." + field.getBindingInfo().getBindByNamePrefix();
260 } else {
261 fieldBindingPrefix = field.getBindingInfo().getBindByNamePrefix();
262 }
263 }
264
265 dictionaryAttributePath = field.getBindingInfo().getBindingName();
266 }
267
268 if (StringUtils.isEmpty(dictionaryAttributePath)) {
269 return null;
270 }
271
272 if (StringUtils.startsWith(dictionaryAttributePath, KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX)) {
273 dictionaryAttributePath = StringUtils.substringAfter(dictionaryAttributePath, KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX);
274 }
275
276 DataDictionaryService ddService = KRADServiceLocatorWeb.getDataDictionaryService();
277
278 String dictionaryAttributeName = ObjectPropertyUtils.getCanonicalPath(dictionaryAttributePath);
279 String dictionaryEntryPrefix = fieldBindingPrefix;
280
281 AttributeDefinition attribute = null;
282 String dictionaryEntryName = null;
283
284 int i = dictionaryAttributeName.indexOf('.');
285 while (attribute == null && i != -1) {
286
287 if (dictionaryEntryPrefix != null) {
288 dictionaryEntryName = getDictionaryEntryName(dictionaryEntryPrefix);
289 dictionaryEntryPrefix += '.' + dictionaryAttributeName.substring(0, i);
290 } else {
291 dictionaryEntryName = null;
292 dictionaryEntryPrefix = dictionaryAttributeName.substring(0, i);
293 }
294
295 if (dictionaryEntryName != null) {
296 attribute = ddService.getAttributeDefinition(dictionaryEntryName, dictionaryAttributeName);
297 }
298
299 if (attribute == null) {
300 dictionaryAttributeName = dictionaryAttributeName.substring(i+1);
301 i = dictionaryAttributeName.indexOf('.');
302 }
303 }
304
305 if (attribute == null && dictionaryEntryPrefix != null) {
306 dictionaryEntryName = getDictionaryEntryName(dictionaryEntryPrefix);
307
308 if (dictionaryEntryName != null) {
309 attribute = ddService.getAttributeDefinition(dictionaryEntryName, dictionaryAttributeName);
310 }
311 }
312
313
314 if (attribute != null) {
315 field.setDictionaryObjectEntry(dictionaryEntryName);
316 field.setDictionaryAttributeName(dictionaryAttributeName);
317 }
318
319 return attribute;
320 }
321
322 }