View Javadoc

1   /**
2    * This file Copyright (c) 2003-2010 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.module.workflow.inbox;
35  
36  import info.magnolia.cms.core.Content;
37  import info.magnolia.cms.core.ItemType;
38  import info.magnolia.cms.gui.control.ContextMenu;
39  import info.magnolia.cms.gui.control.ContextMenuItem;
40  import info.magnolia.cms.gui.control.FunctionBar;
41  import info.magnolia.cms.gui.control.FunctionBarItem;
42  import info.magnolia.cms.gui.controlx.list.ListColumn;
43  import info.magnolia.cms.gui.controlx.list.ListControl;
44  import info.magnolia.cms.gui.controlx.list.ListModel;
45  import info.magnolia.cms.i18n.Messages;
46  import info.magnolia.cms.i18n.MessagesManager;
47  import info.magnolia.cms.util.AlertUtil;
48  import info.magnolia.cms.util.DateUtil;
49  import info.magnolia.freemarker.FreemarkerUtil;
50  import info.magnolia.context.MgnlContext;
51  import info.magnolia.module.admininterface.lists.AbstractList;
52  import info.magnolia.module.admininterface.lists.AdminListControlRenderer;
53  import info.magnolia.module.workflow.WorkflowConstants;
54  import info.magnolia.module.workflow.WorkflowUtil;
55  
56  import java.text.ParseException;
57  import java.text.SimpleDateFormat;
58  import java.util.Date;
59  
60  import javax.jcr.RepositoryException;
61  import javax.servlet.http.HttpServletRequest;
62  import javax.servlet.http.HttpServletResponse;
63  
64  import org.apache.commons.lang.ObjectUtils;
65  import org.apache.commons.lang.StringUtils;
66  import org.slf4j.Logger;
67  import org.slf4j.LoggerFactory;
68  
69  
70  /**
71   * The {@link info.magnolia.module.admininterface.lists.AbstractList} responsible for displaying a user's inbox, i.e current work items.
72   * @author Philipp Bracher
73   * @version $Revision:3416 $ ($Author:philipp $)
74   */
75  public class Inbox extends AbstractList {
76  
77      private static final Logger log = LoggerFactory.getLogger(Inbox.class);
78  
79      /**
80       * The id of the workitem on which we called the command.
81       */
82      private String flowItemId;
83  
84      /**
85       * The comment the user entered by proceeding or rejecting.
86       */
87      private String comment;
88  
89      /**
90       * Show all the values of the workitem if true.
91       */
92      private boolean debug = false;
93  
94      protected Messages msgs = MessagesManager.getMessages("info.magnolia.module.workflow.messages");
95  
96      public Inbox(String name, HttpServletRequest request, HttpServletResponse response) {
97          super(name, request, response);
98      }
99  
100     @Override
101     public ListModel getModel() {
102         return new InboxListModel(MgnlContext.getUser().getName());
103     }
104 
105     @Override
106     public String getSortBy() {
107         if(StringUtils.isEmpty(super.getSortBy())){
108             setSortBy("lastModified");
109         }
110         return super.getSortBy();
111     }
112 
113     /**
114      * Sets the select js code and defines the columns.
115      */
116     @Override
117     public void configureList(ListControl list) {
118 
119         // define the select action
120         list.setRenderer(new AdminListControlRenderer() {
121 
122             @Override
123             public String onSelect(ListControl list, Integer index) {
124 
125                 String customEditDialog = ObjectUtils.toString(list
126                         .getIteratorValue(WorkflowConstants.ATTRIBUTE_EDIT_DIALOG));
127 
128                 String editDialog = StringUtils.defaultIfEmpty(customEditDialog, WorkflowConstants.DEFAULT_EDIT_DIALOG);
129                 String repository = ObjectUtils.toString(list.getIteratorValue("repository"));
130                 String path = ObjectUtils.toString(list.getIteratorValue("path"));
131 
132                 StringBuffer js = new StringBuffer();
133                 js.append("mgnl.workflow.Inbox.current = ");
134                 js.append("{");
135                 js.append("id : '").append(list.getIteratorValue("id")).append("',");
136                 js.append("path : '").append(path).append("',");
137                 js.append("version : '").append(list.getIteratorValue("version")).append("',");
138                 js.append("repository : '").append(repository).append("',");
139                 js.append("workItemPath : '").append(list.getIteratorValue("workItemPath")).append("',");
140                 js.append("editDialog : '").append(editDialog).append("'");
141                 js.append("};");
142                 js.append("mgnl.workflow.Inbox.show = ").append(getShowJSFunction(repository, path)).append(";");
143                 js.append(super.onSelect(list, index));
144                 return js.toString();
145             }
146 
147             @Override
148             public String onDblClick(ListControl list, Integer index) {
149                 return "mgnl.workflow.Inbox.edit();";
150             }
151         });
152 
153         list.addSortableField("lastModified");
154         list.addGroupableField("repository");
155         list.addGroupableField("workflow");
156 
157         list.addColumn(new ListColumn() {
158 
159             {
160                 setName("icon");
161                 setLabel("");
162                 setWidth("30px");
163                 setSeparator(false);
164             }
165 
166             @Override
167             public Object getValue() {
168                 String path = "" + this.getListControl().getIteratorValue("path");
169                 String repository = "" + this.getListControl().getIteratorValue("repository");
170                 String uuid = "" + this.getListControl().getIteratorValue("uuid");
171                 String version = "" + this.getListControl().getIteratorValue("version");
172                 try {
173                     final Content content;
174                     // versioning disabled
175                     if (StringUtils.isEmpty(version)) {
176                         content = MgnlContext.getSystemContext().getHierarchyManager(repository).getContentByUUID(uuid);
177                     } else {
178                         content = MgnlContext.getSystemContext().getHierarchyManager(repository).getContentByUUID(uuid).getVersionedContent(version);
179                     }
180                     if (content.hasMixin(ItemType.DELETED_NODE_MIXIN)) {
181                         path = ItemType.DELETED_NODE_MIXIN;
182                     }
183                 } catch (RepositoryException e) {
184                     log.error("Failed to retrieve versioned node [path=" + path + ", uuid=" + uuid + ", version=" + version, e);
185                 }
186                 return "<img src=\""
187                 + MgnlContext.getContextPath()
188                 + "/"
189                 + getIcon(path, repository)
190                 + "\" alt=\"\" border=\"0\" />";
191             }
192         });
193         list.addColumn(new ListColumn("name", msgs.get("inbox.item"), "100", true));
194         list.addColumn(new ListColumn("repository", msgs.get("inbox.repository"), "100px", true));
195         list.addColumn(new ListColumn("workflow", msgs.get("inbox.workflow"), "100px", true));
196         list.addColumn(new ListColumn("comment", msgs.get("inbox.comment"), "200", true));
197         list.addColumn(new ListColumn() {
198 
199             {
200                 setName("lastModified");
201                 setLabel(msgs.get("inbox.date"));
202                 setWidth("150px");
203             }
204 
205             @Override
206             public Object getValue() {
207                 String str = (String) super.getValue();
208                 Date date = null;
209                 try {
210                     date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ").parse(str);
211                     return DateUtil.formatDateTime(date);
212 
213                 }
214                 catch (ParseException e) {
215                     return StringUtils.EMPTY;
216                 }
217             }
218         });
219 
220     }
221 
222     protected String getIcon(String path, String repository) {
223         return InboxHelper.getIcon(repository, path);
224     }
225 
226     protected String getShowJSFunction(String repository, String path) {
227         return InboxHelper.getShowJSFunction(repository, path);
228     }
229 
230     @Override
231     public void configureContextMenu(ContextMenu menu) {
232         ContextMenuItem edit = new ContextMenuItem("edit");
233         edit.setLabel(msgs.get("inbox.edit"));
234         edit.setOnclick("mgnl.workflow.Inbox.edit();");
235         edit.setIcon(MgnlContext.getContextPath() + "/.resources/icons/16/mail_write.gif");
236         edit.addJavascriptCondition("{test: function(){return mgnl.workflow.Inbox.current.id!=null}}");
237 
238         ContextMenuItem show = new ContextMenuItem("show");
239         show.setLabel(msgs.get("inbox.show"));
240         show.setOnclick("mgnl.workflow.Inbox.show();");
241         show.setIcon(MgnlContext.getContextPath() + "/.resources/icons/16/note_view.gif");
242         show.addJavascriptCondition("{test: function(){return mgnl.workflow.Inbox.current.id!=null}}");
243 
244         ContextMenuItem proceed = new ContextMenuItem("proceed");
245         proceed.setLabel(msgs.get("inbox.proceed"));
246         proceed.setOnclick("mgnl.workflow.Inbox.proceed();");
247         proceed.setIcon(MgnlContext.getContextPath() + "/.resources/icons/16/navigate_right2_green.gif");
248         proceed.addJavascriptCondition("{test: function(){return mgnl.workflow.Inbox.current.id!=null}}");
249 
250         ContextMenuItem reject = new ContextMenuItem("reject");
251         reject.setLabel(msgs.get("inbox.reject"));
252         reject.setOnclick("mgnl.workflow.Inbox.reject();");
253         reject.setIcon(MgnlContext.getContextPath() + "/.resources/icons/16/navigate_left2_red.gif");
254         reject.addJavascriptCondition("{test: function(){return mgnl.workflow.Inbox.current.id!=null}}");
255 
256         ContextMenuItem cancel = new ContextMenuItem("cancel");
257         cancel.setLabel(msgs.get("inbox.cancel"));
258         cancel.setOnclick("mgnl.workflow.Inbox.cancel();");
259         cancel.setIcon(MgnlContext.getContextPath() + "/.resources/icons/16/delete2.gif");
260         cancel.addJavascriptCondition("{test: function(){return mgnl.workflow.Inbox.current.id!=null}}");
261 
262         menu.addMenuItem(edit);
263         menu.addMenuItem(null);
264         menu.addMenuItem(show);
265         menu.addMenuItem(null);
266         menu.addMenuItem(proceed);
267         menu.addMenuItem(reject);
268         menu.addMenuItem(null);
269         menu.addMenuItem(cancel);
270     }
271 
272     /**
273      * Same as the context menu.
274      */
275     @Override
276     public void configureFunctionBar(FunctionBar bar) {
277         ContextMenu menu = this.getContextMenu();
278         bar.addMenuItem(new FunctionBarItem(menu.getMenuItemByName("edit")));
279         bar.addMenuItem(null);
280         bar.addMenuItem(new FunctionBarItem(menu.getMenuItemByName("show")));
281         bar.addMenuItem(null);
282         bar.addMenuItem(new FunctionBarItem(menu.getMenuItemByName("reject")));
283         bar.addMenuItem(new FunctionBarItem(menu.getMenuItemByName("proceed")));
284         bar.addMenuItem(null);
285         bar.addMenuItem(new FunctionBarItem(menu.getMenuItemByName("cancel")));
286     }
287 
288     /**
289      * Add some inbox specific stuff: mainly hidden fields.
290      */
291     @Override
292     public String onRender() {
293         return FreemarkerUtil.process(this);
294     }
295 
296     /**
297      * Proceed the item.
298      */
299     public String proceed() {
300         try {
301             WorkflowUtil.proceed(this.getFlowItemId(), WorkflowConstants.ACTION_PROCEED);
302         }
303         catch (Exception e) {
304             AlertUtil.setMessage("can't proceed:", e);
305         }
306         return this.show();
307     }
308 
309     /**
310      * Reject the item (adds a comment).
311      */
312     public String reject() {
313         try {
314             WorkflowUtil.proceed(this.getFlowItemId(), WorkflowConstants.ACTION_REJECT, this.getComment());
315         }
316         catch (Exception e) {
317             AlertUtil.setMessage("can't reject:", e);
318         }
319         return this.show();
320     }
321 
322     /**
323      * Stop the workflow.
324      */
325     public String cancel() {
326         try {
327             WorkflowUtil.proceed(this.getFlowItemId(), WorkflowConstants.ACTION_CANCEL);
328         }
329         catch (Exception e) {
330             AlertUtil.setMessage("can't cancel:", e);
331         }
332         return this.show();
333     }
334 
335     public String getFlowItemId() {
336         return this.flowItemId;
337     }
338 
339     public void setFlowItemId(String flowItemId) {
340         this.flowItemId = flowItemId;
341     }
342 
343     public String getComment() {
344         return this.comment;
345     }
346 
347     public void setComment(String comment) {
348         this.comment = comment;
349     }
350 
351     public boolean isDebug() {
352         return this.debug;
353     }
354 
355     public void setDebug(boolean debug) {
356         this.debug = debug;
357     }
358 
359 }