KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > riotfamily > riot > list > ui > ListSession


1 /* ***** BEGIN LICENSE BLOCK *****
2     * Version: MPL 1.1
3     * The contents of this file are subject to the Mozilla Public License Version
4     * 1.1 (the "License"); you may not use this file except in compliance with
5     * the License. You may obtain a copy of the License at
6     * http://www.mozilla.org/MPL/
7     *
8     * Software distributed under the License is distributed on an "AS IS" basis,
9     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10     * for the specific language governing rights and limitations under the
11     * License.
12     *
13     * The Original Code is Riot.
14     *
15     * The Initial Developer of the Original Code is
16     * Neteye GmbH.
17     * Portions created by the Initial Developer are Copyright (C) 2006
18     * the Initial Developer. All Rights Reserved.
19     *
20     * Contributor(s):
21     * Felix Gnass [fgnass at neteye dot de]
22     *
23     * ***** END LICENSE BLOCK ***** */

24 package org.riotfamily.riot.list.ui;
25
26 import java.io.PrintWriter JavaDoc;
27 import java.io.StringWriter JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Collection JavaDoc;
30 import java.util.Collections JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35
36 import javax.servlet.http.HttpServletRequest JavaDoc;
37 import javax.servlet.http.HttpServletResponse JavaDoc;
38
39 import org.riotfamily.common.beans.PropertyUtils;
40 import org.riotfamily.common.beans.ProtectedBeanWrapper;
41 import org.riotfamily.common.i18n.MessageResolver;
42 import org.riotfamily.common.util.FormatUtils;
43 import org.riotfamily.common.util.ResourceUtils;
44 import org.riotfamily.forms.Element;
45 import org.riotfamily.forms.Form;
46 import org.riotfamily.forms.controller.FormContextFactory;
47 import org.riotfamily.forms.element.TextField;
48 import org.riotfamily.forms.factory.FormRepository;
49 import org.riotfamily.forms.request.SimpleFormRequest;
50 import org.riotfamily.riot.dao.SortableDao;
51 import org.riotfamily.riot.editor.EditorDefinition;
52 import org.riotfamily.riot.editor.EditorDefinitionUtils;
53 import org.riotfamily.riot.editor.ListDefinition;
54 import org.riotfamily.riot.editor.TreeDefinition;
55 import org.riotfamily.riot.list.ColumnConfig;
56 import org.riotfamily.riot.list.ListConfig;
57 import org.riotfamily.riot.list.command.Command;
58 import org.riotfamily.riot.list.command.CommandResult;
59 import org.riotfamily.riot.list.command.CommandState;
60 import org.riotfamily.riot.list.command.core.ChooseCommand;
61 import org.riotfamily.riot.list.command.core.DescendCommand;
62 import org.riotfamily.riot.list.command.result.ConfirmResult;
63 import org.riotfamily.riot.list.support.ListParamsImpl;
64 import org.riotfamily.riot.list.ui.render.RenderContext;
65 import org.riotfamily.riot.security.AccessController;
66 import org.springframework.transaction.PlatformTransactionManager;
67 import org.springframework.transaction.TransactionDefinition;
68 import org.springframework.transaction.TransactionStatus;
69 import org.springframework.transaction.support.DefaultTransactionDefinition;
70
71 /**
72     * @author Felix Gnass [fgnass at neteye dot de]
73     * @since 6.4
74     */

75 public class ListSession implements RenderContext {
76
77     private static final DefaultTransactionDefinition TRANSACTION_DEFINITION =
78         new DefaultTransactionDefinition(
79         TransactionDefinition.PROPAGATION_REQUIRED);
80
81     private String JavaDoc key;
82
83     private ListDefinition listDefinition;
84
85     private String JavaDoc parentId;
86
87     private MessageResolver messageResolver;
88
89     private String JavaDoc contextPath;
90
91     private PlatformTransactionManager transactionManager;
92
93     private Form filterForm;
94
95     private TextField searchField;
96
97     private String JavaDoc filterFormHtml;
98
99     private String JavaDoc title;
100
101     private ListConfig listConfig;
102
103     private List JavaDoc listCommands;
104
105     private List JavaDoc itemCommands;
106
107     private String JavaDoc[] defaultCommandIds;
108
109     private ListParamsImpl params;
110
111     private boolean expired;
112
113     public ListSession(String JavaDoc key, ListDefinition listDefinition,
114             String JavaDoc parentId, MessageResolver messageResolver, String JavaDoc contextPath,
115             FormRepository formRepository,
116             FormContextFactory formContextFactory,
117             PlatformTransactionManager transactionManager) {
118
119         this.key = key;
120         this.listDefinition = listDefinition;
121         this.parentId = parentId;
122         this.messageResolver = messageResolver;
123         this.contextPath = contextPath;
124         this.transactionManager = transactionManager;
125         this.listConfig = listDefinition.getListConfig();
126
127         listCommands = listConfig.getCommands();
128         itemCommands = listConfig.getColumnCommands();
129         defaultCommandIds = listConfig.getDefaultCommandIds();
130         title = listDefinition.createReference(parentId, messageResolver).getLabel();
131         params = new ListParamsImpl();
132
133         String JavaDoc formId = listConfig.getFilterFormId();
134         if (formId != null) {
135             filterForm = formRepository.createForm(formId);
136         }
137
138         if (listConfig.getSearchProperties() != null) {
139             if (filterForm == null) {
140                 filterForm = new Form();
141                 filterForm.setBeanClass(HashMap JavaDoc.class);
142             }
143             searchField = new TextField();
144             searchField.setLabel("Search");
145             filterForm.addElement(searchField);
146         }
147
148         if (filterForm != null) {
149             filterForm.setFormContext(formContextFactory.createFormContext(
150                     messageResolver, contextPath, null));
151
152             filterForm.setTemplate(ResourceUtils.getPath(getClass(), "FilterForm.ftl"));
153
154             Iterator JavaDoc it = filterForm.getRegisteredElements().iterator();
155             while (it.hasNext()) {
156                 Element e = (Element) it.next();
157                 e.setRequired(false);
158             }
159
160             params.setFilteredProperties(filterForm.getEditorBinder()
161                     .getBoundProperties());
162
163             params.setFilter(filterForm.populateBackingObject());
164             updateFilterFormHtml();
165         }
166
167         params.setSearchProperties(listConfig.getSearchProperties());
168         params.setPageSize(listConfig.getPageSize());
169         params.setOrder(listConfig.getDefaultOrder());
170
171     }
172
173     public String JavaDoc getKey() {
174         return key;
175     }
176
177     public void setChooserTarget(EditorDefinition target) {
178         listCommands = Collections.EMPTY_LIST;
179         itemCommands = new ArrayList JavaDoc();
180
181         ListDefinition targetList = EditorDefinitionUtils
182                 .getParentListDefinition(target);
183
184         if (targetList != listDefinition
185                 || targetList instanceof TreeDefinition) {
186
187             ListDefinition nextList = targetList;
188             if (listDefinition != targetList) {
189                 nextList = EditorDefinitionUtils.getNextListDefinition(
190                         listDefinition, targetList);
191             }
192             if (nextList instanceof TreeDefinition) {
193                 TreeDefinition tree = (TreeDefinition) nextList;
194                 nextList = tree.getNodeListDefinition();
195             }
196             itemCommands.add(new DescendCommand(nextList, target));
197         }
198
199         if (listDefinition.getBeanClass().isAssignableFrom(
200                 target.getBeanClass())) {
201
202             itemCommands.add(new ChooseCommand(target));
203         }
204
205         defaultCommandIds = new String JavaDoc[] { DescendCommand.ID, ChooseCommand.ID };
206     }
207
208     public String JavaDoc getTitle() {
209         return title;
210     }
211
212     private void updateFilterFormHtml() {
213         StringWriter JavaDoc writer = new StringWriter JavaDoc();
214         filterForm.render(new PrintWriter JavaDoc(writer));
215         filterFormHtml = writer.toString();
216     }
217
218     public ListModel getItems(HttpServletRequest JavaDoc request) {
219         Object JavaDoc parent = EditorDefinitionUtils.loadParent(
220                 listDefinition, parentId);
221
222         int itemsTotal = listConfig.getDao().getListSize(parent, params);
223         int pageSize = params.getPageSize();
224         Collection JavaDoc beans = listConfig.getDao().list(parent, params);
225         if (itemsTotal < beans.size()) {
226             itemsTotal = beans.size();
227             pageSize = itemsTotal;
228         }
229
230         ListModel model = new ListModel(itemsTotal, pageSize, params.getPage());
231
232         ArrayList JavaDoc items = new ArrayList JavaDoc(beans.size());
233         int rowIndex = 0;
234         Iterator JavaDoc it = beans.iterator();
235         while (it.hasNext()) {
236             Object JavaDoc bean = it.next();
237             ListItem item = new ListItem();
238             item.setRowIndex(rowIndex++);
239             item.setLastOnPage(!it.hasNext());
240             item.setObjectId(EditorDefinitionUtils.getObjectId(listDefinition, bean));
241             item.setColumns(getColumns(bean));
242             item.setCommands(getCommandStates(itemCommands,
243                     item, bean, itemsTotal, request));
244
245             if (listConfig.getRowStyleProperty() != null) {
246                 item.setCssClass(FormatUtils.toCssClass(
247                         PropertyUtils.getPropertyAsString(bean,
248                         listConfig.getRowStyleProperty())));
249             }
250             item.setDefaultCommandIds(defaultCommandIds);
251             items.add(item);
252         }
253         model.setItems(items);
254         return model;
255     }
256
257     private List JavaDoc getColumns(Object JavaDoc bean) {
258         ArrayList JavaDoc result = new ArrayList JavaDoc();
259         Iterator JavaDoc it = listConfig.getColumnConfigs().iterator();
260         ProtectedBeanWrapper wrapper = new ProtectedBeanWrapper(bean);
261         while (it.hasNext()) {
262             ColumnConfig col = (ColumnConfig) it.next();
263             String JavaDoc propertyName = col.getProperty();
264             Object JavaDoc value;
265             if (propertyName != null) {
266                 value = wrapper.getPropertyValue(propertyName);
267             }
268             else {
269                 value = bean;
270             }
271             StringWriter JavaDoc writer = new StringWriter JavaDoc();
272             col.getRenderer().render(propertyName, value, this,
273                     new PrintWriter JavaDoc(writer));
274
275             result.add(writer.toString());
276         }
277         return result;
278     }
279
280     public ListModel getModel(HttpServletRequest JavaDoc request) {
281         ListModel model = getItems(request);
282
283         model.setEditorId(listDefinition.getId());
284         model.setParentId(parentId);
285         model.setItemCommandCount(itemCommands.size());
286         model.setListCommands(getListCommands(request));
287         model.setCssClass(listConfig.getId());
288
289         boolean sortableDao = listConfig.getDao() instanceof SortableDao;
290
291         ArrayList JavaDoc columns = new ArrayList JavaDoc();
292         Iterator JavaDoc it = listConfig.getColumnConfigs().iterator();
293         while (it.hasNext()) {
294             ColumnConfig config = (ColumnConfig) it.next();
295             ListColumn column = new ListColumn();
296             column.setProperty(config.getProperty());
297             column.setHeading(getHeading(config.getProperty(),
298                     config.getLookupLevel()));
299
300             column.setSortable(sortableDao && config.isSortable());
301             column.setCssClass(FormatUtils.toCssClass(config.getProperty()));
302             if (params.hasOrder() && params.getPrimaryOrder()
303                     .getProperty().equals(config.getProperty())) {
304
305                 column.setSorted(true);
306                 column.setAscending(params.getPrimaryOrder().isAscending());
307             }
308             columns.add(column);
309         }
310         model.setColumns(columns);
311         model.setFilterFormHtml(filterFormHtml);
312         return model;
313     }
314
315     private String JavaDoc getHeading(String JavaDoc property, int lookupLevel) {
316         return getHeading(getBeanClass(), property, lookupLevel);
317     }
318
319     private String JavaDoc getHeading(Class JavaDoc clazz, String JavaDoc property, int lookupLevel) {
320         if (property == null) {
321             return null;
322         }
323         if (clazz != null) {
324             String JavaDoc root = property;
325             int pos = property.indexOf('.');
326             if (pos > 0) {
327                 root = property.substring(0, pos);
328             }
329             if (lookupLevel > 1) {
330                 clazz = PropertyUtils.getPropertyType(clazz, root);
331                 if (pos > 0) {
332                     String JavaDoc nestedProperty = property.substring(pos + 1);
333                     return getHeading(clazz, nestedProperty, lookupLevel - 1);
334                 }
335                 else {
336                     return messageResolver.getClassLabel(null, clazz);
337                 }
338             }
339         }
340         return messageResolver.getPropertyLabel(
341                 getListId(), clazz, property);
342     }
343
344     public ListModel sort(String JavaDoc property, HttpServletRequest JavaDoc request) {
345         ColumnConfig col = listConfig.getColumnConfig(property);
346         params.orderBy(property, col.isAscending(), col.isCaseSensitive());
347         return getModel(request);
348     }
349
350     public String JavaDoc[] getSearchProperties() {
351         return listConfig.getSearchProperties();
352     }
353
354     public String JavaDoc getSearchQuery() {
355         return params.getSearch();
356     }
357
358     public String JavaDoc getFilterFormHtml() {
359         return filterFormHtml;
360     }
361
362     public ListModel filter(Map JavaDoc filter, HttpServletRequest JavaDoc request) {
363         if (filterForm != null) {
364             filterForm.processRequest(new SimpleFormRequest(filter));
365             params.setFilter(filterForm.populateBackingObject());
366             if (searchField != null) {
367                 params.setSearch(searchField.getText());
368             }
369             updateFilterFormHtml();
370         }
371         params.setPage(1);
372         ListModel result = getItems(request);
373         result.setFilterFormHtml(filterFormHtml);
374         return result;
375     }
376
377     public ListModel gotoPage(int page, HttpServletRequest JavaDoc request) {
378         params.setPage(page);
379         return getItems(request);
380     }
381
382     public boolean hasListCommands() {
383         return !listCommands.isEmpty();
384     }
385
386     public List JavaDoc getListCommands(HttpServletRequest JavaDoc request) {
387         //REVISIT: Should we pass the correct item count here?
388
return getCommandStates(listCommands, null, null, -1, request);
389     }
390
391     public List JavaDoc getFormCommands(String JavaDoc objectId, HttpServletRequest JavaDoc request) {
392         Object JavaDoc bean = null;
393         if (objectId != null) {
394             bean = listConfig.getDao().load(objectId);
395         }
396         return getCommandStates(listConfig.getFormCommands(),
397                 new ListItem(objectId), bean, 1, request);
398     }
399
400     private List JavaDoc getCommandStates(List JavaDoc commands, ListItem item, Object JavaDoc bean,
401             int itemsTotal, HttpServletRequest JavaDoc request) {
402
403         ArrayList JavaDoc result = new ArrayList JavaDoc();
404         CommandContextImpl context = new CommandContextImpl(this, request);
405         context.setBean(bean);
406         context.setItem(item);
407         context.setItemsTotal(itemsTotal);
408         Iterator JavaDoc it = commands.iterator();
409         while (it.hasNext()) {
410             Command command = (Command) it.next();
411             CommandState state = command.getState(context);
412             boolean granted = AccessController.isGranted(
413                     state.getAction(), bean);
414
415             state.setEnabled(state.isEnabled() && granted);
416             result.add(state);
417         }
418         return result;
419     }
420
421     public CommandResult execCommand(ListItem item, String JavaDoc commandId,
422             boolean confirmed, HttpServletRequest JavaDoc request,
423             HttpServletResponse JavaDoc response) {
424
425         Collection JavaDoc commands = item != null ? itemCommands : listCommands;
426         Command command = getCommand(commands, commandId);
427         Object JavaDoc bean = null;
428         CommandContextImpl context = new CommandContextImpl(this, request);
429         if (item != null) {
430             context.setItem(item);
431         }
432         else {
433             bean = EditorDefinitionUtils.loadParent(listDefinition, parentId);
434             context.setBean(bean);
435         }
436         String JavaDoc action = command.getState(context).getAction();
437         if (AccessController.isGranted(action, bean)) {
438             if (!confirmed) {
439                 String JavaDoc message = command.getConfirmationMessage(context);
440                 if (message != null) {
441                     return new ConfirmResult(item, commandId, message);
442                 }
443             }
444             TransactionStatus status = transactionManager.getTransaction(TRANSACTION_DEFINITION);
445             CommandResult result;
446             try {
447                 result = command.execute(context);
448             }
449             catch (RuntimeException JavaDoc e) {
450                 transactionManager.rollback(status);
451                 throw e;
452             }
453             transactionManager.commit(status);
454             return result;
455         }
456         else {
457             return null;
458         }
459     }
460     
461     private Command getCommand(Collection JavaDoc commands, String JavaDoc id) {
462         Iterator JavaDoc it = commands.iterator();
463         while (it.hasNext()) {
464             Command command = (Command) it.next();
465             if (id.equals(command.getId())) {
466                 return command;
467             }
468         }
469         throw new IllegalArgumentException JavaDoc("No such command: " + id);
470     }
471
472     public Object JavaDoc loadBean(String JavaDoc objectId) {
473         return listDefinition.getListConfig().getDao().load(objectId);
474     }
475
476     public ListDefinition getListDefinition() {
477         return listDefinition;
478     }
479
480     public String JavaDoc getListId() {
481         return listDefinition.getListId();
482     }
483
484     public ListParamsImpl getParams() {
485         return params;
486     }
487
488     public String JavaDoc getParentId() {
489         return parentId;
490     }
491
492     public Class JavaDoc getBeanClass() {
493         return listDefinition.getBeanClass();
494     }
495
496     public MessageResolver getMessageResolver() {
497         return messageResolver;
498     }
499
500     public String JavaDoc getContextPath() {
501         return contextPath;
502     }
503
504     void invalidate() {
505         expired = true;
506     }
507
508     public boolean isExpired() {
509         return expired;
510     }
511
512 }
513
Popular Tags