View Javadoc
1   /**
2    * This file Copyright (c) 2014-2018 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.ui.admincentral.shellapp.pulse.task.action;
35  
36  import info.magnolia.task.Task;
37  import info.magnolia.task.TasksManager;
38  import info.magnolia.ui.admincentral.shellapp.pulse.task.DefaultTaskDetailPresenter;
39  import info.magnolia.ui.api.action.AbstractAction;
40  import info.magnolia.ui.api.action.ActionDefinition;
41  import info.magnolia.ui.api.action.ActionExecutionException;
42  import info.magnolia.ui.api.shell.Shell;
43  import info.magnolia.ui.contentapp.browser.context.ValueContext;
44  import info.magnolia.ui.framework.datasource.components.SelectedItems;
45  import info.magnolia.ui.framework.ioc.AdmincentralFlavour;
46  import info.magnolia.ui.framework.ioc.BeanStore;
47  import info.magnolia.ui.framework.ioc.CurrentUiContextReference;
48  import info.magnolia.ui.framework.ioc.SessionStore;
49  
50  import org.slf4j.Logger;
51  import org.slf4j.LoggerFactory;
52  
53  /**
54   * Abstract action for a task action.
55   *
56   * @param <D> {@link info.magnolia.ui.api.action.ActionDefinition}.
57   */
58  public abstract class AbstractTaskAction<D extends ActionDefinition> extends AbstractAction<D> {
59      protected static final Logger log = LoggerFactory.getLogger(AbstractTaskAction.class);
60  
61      protected static final String DECISION = "decision";
62      protected static final String ACTOR_ID = "actorId";
63  
64      private Task task;
65      private TasksManager tasksManager;
66      private DefaultTaskDetailPresenter taskPresenter;
67      private Shell shell;
68  
69      private final ValueContext<Task> valueContext;
70  
71      protected AbstractTaskAction(D definition, Task task, TasksManager tasksManager, Shell shell, ValueContext<Task> valueContext) {
72          super(definition);
73          this.task = task;
74          this.tasksManager = tasksManager;
75          this.shell = shell;
76          this.valueContext = valueContext;
77      }
78  
79      /**
80       * @deprecated since 6.0. Use {@link #AbstractTaskAction(info.magnolia.ui.api.action.ActionDefinition, info.magnolia.task.Task, info.magnolia.task.TasksManager, info.magnolia.ui.api.shell.Shell, info.magnolia.ui.contentapp.browser.context.ValueContext)} instead.
81       */
82      @Deprecated
83      public AbstractTaskAction(D definition, Task task, TasksManager tasksManager, DefaultTaskDetailPresenter taskPresenter, Shell shell) {
84          super(definition);
85          this.task = task;
86          this.tasksManager = tasksManager;
87          this.taskPresenter = taskPresenter;
88          this.shell = shell;
89          if (!AdmincentralFlavour.get().isM5()) {
90              this.valueContext = accessViewBeanStore().get(ValueContext.class);
91          } else {
92              this.valueContext = null;
93          }
94      }
95  
96      @Override
97      public final void execute() throws ActionExecutionException {
98          log.debug("About to execute Task [{}]", task);
99          try {
100             canExecuteTask(task);
101             executeTask(tasksManager, task);
102             updateView();
103         } catch (Exception ex) {
104             log.error("An error occurred while trying to execute task [{}]", task, ex);
105             shell.showError("Error: " + ex.getMessage(), ex);
106         }
107     }
108 
109     /**
110      * Subclasses need to implement this method to actually execute the task.
111      */
112     protected abstract void executeTask(TasksManager tasksManager, Task task);
113 
114     /**
115      * Subclasses can override this method to check if the current task can actually be executed, e.g. by checking the current Task status.
116      * Default implementation does nothing.
117      *
118      * @throws IllegalStateException if a task status doesn't allow this action to be executed (e.g. trying to complete a task which is not in progress). In general, subclasses can throw this exception for any reason
119      * they deem should cause the current task execution to be aborted.
120      * @See {@link Task.Status}
121      *
122      * @deprecated since 5.4, use availability rules to check the allowed statuses.
123      * @see {@link info.magnolia.ui.admincentral.shellapp.pulse.task.action.availability.TaskAvailabilityRule}
124      */
125     @Deprecated
126     protected void canExecuteTask(Task task) throws IllegalStateException {
127         // no-op
128     }
129 
130     /**
131      * Subclasses can use the shell e.g. to display success notifications.
132      */
133     protected Shell getShell() {
134         return shell;
135     }
136 
137     /**
138      * Subclasses can use the TaskPresenter to interact back with it and its parent presenter, i.e. PulsePresenter.
139      */
140     protected DefaultTaskDetailPresenter getTaskPresenter() {
141         return taskPresenter;
142     }
143 
144     private BeanStore accessViewBeanStore() {
145         return SessionStore.access().getBeanStore(CurrentUiContextReference.get().getUiContextReference());
146     }
147 
148     protected void updateView() {
149         if (valueContext != null) {
150             valueContext.current().set(SelectedItems.of(tasksManager.getTaskById(task.getId())));
151         }
152     }
153 }