1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.view;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.log4j.Logger;
20 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
21 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
22 import org.kuali.rice.krad.service.DataObjectMetaDataService;
23 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
24 import org.kuali.rice.krad.uif.UifConstants;
25 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
26 import org.kuali.rice.krad.uif.util.ViewModelUtils;
27 import org.kuali.rice.krad.web.form.UifFormBase;
28
29 import javax.servlet.http.HttpServletRequest;
30 import java.io.Serializable;
31 import java.io.UnsupportedEncodingException;
32 import java.net.URLDecoder;
33 import java.net.URLEncoder;
34 import java.util.ArrayList;
35 import java.util.Enumeration;
36 import java.util.List;
37
38
39
40
41
42
43
44 @BeanTag(name="history")
45 public class History implements Serializable {
46 private static final long serialVersionUID = -8279297694371557335L;
47 private static final Logger LOG = Logger.getLogger(History.class);
48
49 public static final String ENTRY_TOKEN = "$^$";
50 public static final String VAR_TOKEN = "^$^";
51
52 private boolean appendHomewardPath;
53 private boolean appendPassedHistory;
54
55 private HistoryEntry current;
56
57 private List<HistoryEntry> homewardPath;
58 private List<HistoryEntry> historyEntries;
59
60 public History() {
61 historyEntries = new ArrayList<HistoryEntry>();
62 }
63
64
65
66
67
68
69
70
71
72
73
74 public List<HistoryEntry> getGeneratedBreadcrumbs() {
75 List<HistoryEntry> breadcrumbs = new ArrayList<HistoryEntry>();
76 for (int i = 0; i < historyEntries.size(); i++) {
77 if (i == 0) {
78 breadcrumbs.add(copyEntry(historyEntries.get(i)));
79 } else {
80 HistoryEntry breadcrumb = copyEntry(historyEntries.get(i));
81
82 String historyParam = "";
83 for (int j = 0; j < i; j++) {
84 historyParam = historyParam + ENTRY_TOKEN + historyEntries.get(j).toParam();
85 }
86 historyParam = historyParam.replaceFirst("\\" + ENTRY_TOKEN, "");
87
88 try {
89 historyParam = URLEncoder.encode(historyParam, "UTF-8");
90 } catch (Exception e) {
91 throw new RuntimeException("Error encoding history param", e);
92 }
93
94 if (StringUtils.isEmpty(breadcrumb.getUrl())) {
95 continue;
96 }
97
98 String url = breadcrumb.getUrl();
99 if (url.contains("?")) {
100 url += "&";
101 } else {
102 url += "?";
103 }
104
105 url += UifConstants.UrlParams.HISTORY
106 + "="
107 + historyParam
108 + "&"
109 + UifConstants.UrlParams.LAST_FORM_KEY
110 + "="
111 + current.getFormKey();
112
113 breadcrumb.setUrl(url);
114 breadcrumbs.add(breadcrumb);
115 }
116 }
117
118 return breadcrumbs;
119 }
120
121
122
123
124 public HistoryEntry getGeneratedCurrentBreadcrumb() {
125 if (current == null) {
126 return new HistoryEntry();
127 }
128
129 HistoryEntry breadcrumb = copyEntry(current);
130 String historyParam = "";
131 for (int j = 0; j < historyEntries.size(); j++) {
132 historyParam = historyParam + ENTRY_TOKEN + historyEntries.get(j).toParam();
133 }
134 historyParam = historyParam.replaceFirst("\\" + ENTRY_TOKEN, "");
135
136 try {
137 historyParam = URLEncoder.encode(historyParam, "UTF-8");
138 } catch (Exception e) {
139 throw new RuntimeException("Error encoding history param", e);
140 }
141
142 String url = "";
143 if (breadcrumb.getUrl().contains("?")) {
144 url = breadcrumb.getUrl() + "&" + UifConstants.UrlParams.HISTORY + "=" + historyParam;
145 } else {
146 url = breadcrumb.getUrl() + "?" + UifConstants.UrlParams.HISTORY + "=" + historyParam;
147 }
148 breadcrumb.setUrl(url);
149
150 return breadcrumb;
151 }
152
153
154
155
156
157
158
159 private HistoryEntry copyEntry(HistoryEntry e) {
160 return new HistoryEntry(e.getViewId(), e.getPageId(), e.getTitle(), e.getUrl(), e.getFormKey());
161 }
162
163
164
165
166
167
168
169
170
171
172
173 public void pushToHistory(String viewId, String pageId, String title, String url, String formKey) {
174 HistoryEntry entry = new HistoryEntry(viewId, pageId, title, url, formKey);
175 historyEntries.add(entry);
176 }
177
178
179
180
181
182
183
184
185
186 public void buildCurrentEntryFromRequest(UifFormBase form, HttpServletRequest request) {
187 boolean showHomeValue = false;
188 boolean pageIdValue = false;
189 boolean formKeyValue = false;
190
191 String queryString = "";
192 String url = request.getRequestURL().toString();
193
194
195 Enumeration<String> params = request.getParameterNames();
196 while (params.hasMoreElements()) {
197 String key = params.nextElement();
198 if (!key.equals(UifConstants.UrlParams.HISTORY)) {
199 for (String value : request.getParameterValues(key)) {
200 try {
201 queryString = queryString + "&" + key + "=" + URLEncoder.encode(value, "UTF-8");
202 } catch (UnsupportedEncodingException e) {
203 throw new RuntimeException("Unable to encode parameter value", e);
204 }
205 }
206 }
207
208 if (key.equals(UifConstants.UrlParams.PAGE_ID)) {
209 pageIdValue = true;
210 } else if (key.equals(UifConstants.UrlParams.SHOW_HOME)) {
211 showHomeValue = true;
212 } else if (key.equals(UifConstants.UrlParams.FORM_KEY)) {
213 formKeyValue = true;
214 }
215 }
216
217
218 if (StringUtils.isNotBlank(form.getFormKey()) && !formKeyValue) {
219 try {
220 queryString = queryString + "&" + UifConstants.UrlParams.FORM_KEY + "=" + URLEncoder.encode(
221 form.getFormKey(), "UTF-8");
222 } catch (UnsupportedEncodingException e) {
223 throw new RuntimeException("Unable to encode form key", e);
224 }
225 }
226
227 if (StringUtils.isNotBlank(form.getPageId()) && !pageIdValue) {
228 queryString = queryString + "&" + UifConstants.UrlParams.PAGE_ID + "=" + form.getPageId();
229 }
230
231 if (!showHomeValue) {
232 queryString = queryString + "&" + UifConstants.UrlParams.SHOW_HOME + "=false";
233 }
234
235 queryString = queryString.replaceFirst("&", "");
236
237 if (StringUtils.isNotEmpty(queryString)) {
238 url = url + "?" + queryString;
239 }
240
241 this.setCurrent(form.getViewId(), form.getPageId(), buildViewTitle(form), url, form.getFormKey());
242 }
243
244
245
246
247
248
249
250
251
252 public void buildHistoryFromParameterString(String parameterString) {
253 if (StringUtils.isNotEmpty(parameterString)) {
254 try {
255 parameterString = URLDecoder.decode(parameterString, "UTF-8");
256 } catch (UnsupportedEncodingException e) {
257 throw new RuntimeException("Unable to get history from parameter string", e);
258 }
259
260 historyEntries = new ArrayList<HistoryEntry>();
261 if (appendPassedHistory) {
262 String[] historyTokens = StringUtils.splitByWholeSeparator(parameterString, ENTRY_TOKEN);
263 for (String token : historyTokens) {
264 String[] params = StringUtils.splitByWholeSeparator(token, VAR_TOKEN);
265 pushToHistory(params[0], params[1], params[2], params[3], params[4]);
266 }
267 }
268 }
269
270 if (appendHomewardPath) {
271 historyEntries.addAll(homewardPath);
272 }
273 }
274
275
276
277
278
279
280
281
282 public String getHistoryParameterString() {
283 String history = "";
284
285 for (HistoryEntry entry : historyEntries) {
286 if (StringUtils.isNotBlank(history)) {
287 history = history + ENTRY_TOKEN;
288 }
289 history = history + entry.toParam();
290 }
291
292 if (current != null) {
293 if (StringUtils.isNotBlank(history)) {
294 history = history + ENTRY_TOKEN;
295 }
296 history = history + current.toParam();
297 }
298
299 try {
300 history = URLEncoder.encode(history, "UTF-8");
301 } catch (Exception e) {
302 throw new RuntimeException("Error encoding history param", e);
303 }
304
305 return history;
306 }
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 protected String buildViewTitle(UifFormBase form) {
323 View view = form.getView();
324 String title = view.getHeaderText();
325
326
327
328 String viewLabelPropertyName = view.getBreadcrumbTitlePropertyName();
329
330
331 if (StringUtils.isBlank(viewLabelPropertyName)) {
332 Class<?> dataObjectClass;
333 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
334 dataObjectClass = ObjectPropertyUtils.getPropertyType(form, view.getDefaultBindingObjectPath());
335 } else {
336 dataObjectClass = view.getFormClass();
337 }
338
339 DataObjectMetaDataService mds = KRADServiceLocatorWeb.getDataObjectMetaDataService();
340 if (dataObjectClass != null) {
341 viewLabelPropertyName = mds.getTitleAttribute(dataObjectClass);
342 }
343 }
344
345 String viewLabelPropertyPath = "";
346 if (StringUtils.isNotBlank(viewLabelPropertyName)) {
347
348 if (!viewLabelPropertyName.startsWith(UifConstants.NO_BIND_ADJUST_PREFIX)) {
349 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
350 viewLabelPropertyPath = view.getDefaultBindingObjectPath() + "." + viewLabelPropertyName;
351 }
352 } else {
353 viewLabelPropertyPath = StringUtils.removeStart(viewLabelPropertyName,
354 UifConstants.NO_BIND_ADJUST_PREFIX);
355 }
356 } else {
357
358 Class<?> dataObjectClass;
359 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
360 dataObjectClass = ViewModelUtils.getObjectClassForMetadata(view, form,
361 view.getDefaultBindingObjectPath());
362 } else {
363 dataObjectClass = view.getFormClass();
364 }
365
366 DataObjectMetaDataService mds = KRADServiceLocatorWeb.getDataObjectMetaDataService();
367 if (dataObjectClass != null) {
368 String titleAttribute = mds.getTitleAttribute(dataObjectClass);
369 if (StringUtils.isNotBlank(titleAttribute)) {
370 viewLabelPropertyPath = view.getDefaultBindingObjectPath() + "." + titleAttribute;
371 }
372 }
373 }
374
375 Object viewLabelPropertyValue = null;
376 if (StringUtils.isNotBlank(viewLabelPropertyPath) && ObjectPropertyUtils.isReadableProperty(form,
377 viewLabelPropertyPath)) {
378 viewLabelPropertyValue = ObjectPropertyUtils.getPropertyValue(form, viewLabelPropertyPath);
379 }
380
381 String titleAppend = "";
382 if (viewLabelPropertyValue != null) {
383 titleAppend = viewLabelPropertyValue.toString();
384 }
385
386 if (StringUtils.isNotBlank(titleAppend) && view.getBreadcrumbTitleDisplayOption() != null) {
387 if (view.getBreadcrumbTitleDisplayOption().equalsIgnoreCase(UifConstants.TitleAppendTypes.DASH)) {
388 title = title + " - " + titleAppend;
389 } else if (view.getBreadcrumbTitleDisplayOption().equalsIgnoreCase(
390 UifConstants.TitleAppendTypes.PARENTHESIS)) {
391 title = title + "(" + titleAppend + ")";
392 } else if (view.getBreadcrumbTitleDisplayOption().equalsIgnoreCase(UifConstants.TitleAppendTypes.REPLACE)) {
393 title = titleAppend;
394 }
395
396 }
397
398 return title;
399 }
400
401
402
403
404
405
406
407 @BeanTagAttribute(name="homewardPath",type= BeanTagAttribute.AttributeType.LISTBEAN)
408 public List<HistoryEntry> getHomewardPath() {
409 return this.homewardPath;
410 }
411
412
413
414
415 public void setHomewardPath(List<HistoryEntry> homewardPath) {
416 this.homewardPath = homewardPath;
417 }
418
419
420
421
422
423
424
425
426
427 @BeanTagAttribute(name="historyEntries",type= BeanTagAttribute.AttributeType.LISTBEAN)
428 public List<HistoryEntry> getHistoryEntries() {
429 return this.historyEntries;
430 }
431
432
433
434
435 public void setHistoryEntries(List<HistoryEntry> history) {
436 this.historyEntries = history;
437 }
438
439
440
441
442
443
444
445
446
447 @BeanTagAttribute(name="current",type= BeanTagAttribute.AttributeType.SINGLEBEAN)
448 public HistoryEntry getCurrent() {
449 return this.current;
450 }
451
452
453
454
455
456
457
458
459
460
461 private void setCurrent(String viewId, String pageId, String title, String url, String formKey) {
462 HistoryEntry entry = new HistoryEntry(viewId, pageId, title, url, formKey);
463 current = entry;
464 }
465
466
467
468
469 public void setCurrent(HistoryEntry current) {
470 this.current = current;
471 }
472
473
474
475
476
477
478
479
480 public void setAppendHomewardPath(boolean appendHomewardPath) {
481 this.appendHomewardPath = appendHomewardPath;
482 }
483
484
485
486
487 @BeanTagAttribute(name="appendHomewardPath")
488 public boolean isAppendHomewardPath() {
489 return appendHomewardPath;
490 }
491
492
493
494
495
496
497
498
499 public void setAppendPassedHistory(boolean appendPassedHistory) {
500 this.appendPassedHistory = appendPassedHistory;
501 }
502
503
504
505
506 @BeanTagAttribute(name="appendPassedHistory")
507 public boolean isAppendPassedHistory() {
508 return appendPassedHistory;
509 }
510
511 }