View Javadoc
1   /**
2    * This file Copyright (c) 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.task.app.view.detail;
35  
36  import info.magnolia.context.Context;
37  import info.magnolia.i18nsystem.I18nizer;
38  import info.magnolia.icons.MagnoliaIcons;
39  import info.magnolia.registry.RegistrationException;
40  import info.magnolia.task.Task;
41  import info.magnolia.task.app.actions.ArchiveTasksAction;
42  import info.magnolia.task.definition.TaskDefinition;
43  import info.magnolia.task.definition.registry.TaskDefinitionRegistry;
44  import info.magnolia.ui.admincentral.shellapp.pulse.item.definition.ItemViewDefinition;
45  import info.magnolia.ui.admincentral.shellapp.pulse.item.registry.ItemViewDefinitionRegistry;
46  import info.magnolia.ui.api.app.SubAppContext;
47  import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
48  import info.magnolia.ui.api.location.Location;
49  import info.magnolia.ui.contentapp.browser.actions.ActionbarPresenter;
50  import info.magnolia.ui.contentapp.browser.actions.ActionbarView;
51  import info.magnolia.ui.contentapp.browser.context.ValueContext;
52  import info.magnolia.ui.contentapp.detail.ContentDetailSubApp;
53  import info.magnolia.ui.form.LocaleContext;
54  import info.magnolia.ui.form.definition.DefinitionConverter;
55  import info.magnolia.ui.framework.ViewDefinition;
56  import info.magnolia.ui.framework.app.BaseSubApp;
57  import info.magnolia.ui.framework.databinding.ItemProviderStrategy;
58  import info.magnolia.ui.framework.databinding.view.FormView;
59  import info.magnolia.ui.framework.datasource.definition.DatasourceDefinition;
60  
61  import java.text.MessageFormat;
62  import java.util.Locale;
63  import java.util.Optional;
64  
65  import javax.inject.Inject;
66  
67  import org.apache.commons.lang3.BooleanUtils;
68  import org.apache.commons.lang3.StringUtils;
69  import org.slf4j.Logger;
70  import org.slf4j.LoggerFactory;
71  
72  import lombok.SneakyThrows;
73  
74  /**
75   * TaskDetailSubApp.
76   */
77  public class TaskDetailSubApp extends BaseSubApp<TaskFormView> {
78  
79      private static final Logger log = LoggerFactory.getLogger(ArchiveTasksAction.class);
80  
81      private final TaskDetailDescriptor subAppDescriptor;
82      private final I18NAuthoringSupport i18NAuthoringSupport;
83      private final ItemViewDefinitionRegistry itemViewDefinitionRegistry;
84      private final I18nizer i18nizer;
85      private final TaskDefinitionRegistry taskDefinitionRegistry;
86      private ContentDetailSubApp.LocationContext locationContext;
87      private ItemProviderStrategy<Task> itemProviderStrategy;
88      private ValueContext<Task> valueContext;
89      private DatasourceDefinition datasourceDefinition;
90  
91      @Inject
92      protected TaskDetailSubApp(SubAppContext subAppContext,
93                                 I18NAuthoringSupport i18NAuthoringSupport,
94                                 ItemViewDefinitionRegistry itemViewDefinitionRegistry,
95                                 I18nizer i18nizer,
96                                 TaskDefinitionRegistry taskDefinitionRegistry,
97                                 DatasourceDefinition datasourceDefinition,
98                                 TaskDetailDescriptor detailDescriptor,
99                                 ValueContext<Task> valueContext) {
100         super(subAppContext, new TaskFormView());
101         this.itemViewDefinitionRegistry = itemViewDefinitionRegistry;
102         this.i18nizer = i18nizer;
103         this.taskDefinitionRegistry = taskDefinitionRegistry;
104         this.subAppDescriptor = detailDescriptor;
105         this.i18NAuthoringSupport = i18NAuthoringSupport;
106         this.datasourceDefinition = datasourceDefinition;
107         this.valueContext = valueContext;
108     }
109 
110     @Override
111     @SneakyThrows(RegistrationException.class)
112     public TaskFormView start(Location location) {
113         super.start(location);
114 
115         final TaskFormView view = getView();
116 
117         final LocaleContext localeContext = bindContext(LocaleContext.class);
118         final Locale currentLocale = getSubAppContext().getAuthoringLocale() != null ?
119                 getSubAppContext().getAuthoringLocale() :
120                 i18NAuthoringSupport.getDefaultLocale();
121         localeContext.current().set(currentLocale);
122 
123         this.locationContext = bindContext(ContentDetailSubApp.LocationContext.class);
124         this.locationContext.location().set(ContentDetailSubApp.DetailLocation.wrap(location));
125         this.itemProviderStrategy = create(subAppDescriptor.getItemProvider(), datasourceDefinition);
126 
127         bindInstance(ItemProviderStrategy.class, itemProviderStrategy);
128 
129         Optional<Task> itemProvider = itemProviderStrategy.read();
130         if (itemProvider.isPresent()) {
131             Task task = itemProvider.get();
132             TaskDefinition taskDefinition = taskDefinitionRegistry.get(task.getName());
133 
134             String itemView = taskDefinition.getTaskView();
135             if (StringUtils.isEmpty(itemView)) {
136                 String workspace = (String) task.getContent().get("repository");
137                 String taskView = taskDefinition.getViewMapping().get(workspace);
138                 itemView = StringUtils.isNotBlank(taskView) ? taskView : taskDefinition.getViewMapping().get("default");
139             }
140 
141             ItemViewDefinition itemViewDefinition = itemViewDefinitionRegistry.get(itemView);
142             itemViewDefinition = i18nizer.decorate(itemViewDefinition);
143 
144             valueContext.set(task);
145 
146             final FormView<Task> form = (FormView<Task>) create(DefinitionConverter.FORM.convert(itemViewDefinition.getForm()));
147 
148             updateViewAndSubAppDescriptorIcons(taskDefinition, task);
149             view.setSizeFull();
150             view.addStyleName("detail");
151             view.setMargin(false);
152             view.setSpacing(false);
153             subAppDescriptor.setActions(itemViewDefinition.getActions());
154             ActionbarPresenter actionbarPresenter = create(ActionbarPresenter.class, subAppDescriptor.getActions(), itemViewDefinition.getActionbar());
155             @SuppressWarnings("unchecked") ActionbarView actionbar = (ActionbarView) create(
156                     ViewDefinition.builder()
157                             .withImplementationClass(ActionbarView.class)
158                             .withName("actionbar")
159                             .build(), itemViewDefinition.getActionbar(), actionbarPresenter);
160 
161             view.setActionBar(actionbar);
162             view.setContent(form.asVaadinComponent());
163 
164             locationContext.location().observeNullable(l -> itemProviderStrategy.read().ifPresent(taskItem -> {
165                 form.populate(taskItem);
166                 valueContext.set(taskItem);
167                 try {
168                     TaskDefinition taskDef = taskDefinitionRegistry.get(taskItem.getName());
169                     updateViewAndSubAppDescriptorIcons(taskDef, taskItem);
170                 } catch (RegistrationException e) {
171                     log.debug("No task definition registered for name: {}", taskItem.getName());
172                 }
173             }));
174             localeContext.current().observeNullable(locale -> view.setContent(form.getLayout(locale)));
175         }
176 
177         return view;
178     }
179 
180     @Override
181     public void locationChanged(Location location) {
182         super.locationChanged(location);
183         this.locationContext.location().set(ContentDetailSubApp.DetailLocation.wrap(location));
184     }
185 
186     @Override
187     public void stop() {
188         getView().destroy();
189     }
190 
191     private String taskTitle(TaskDefinition definition, Task task) {
192         String title = definition.getTitle();
193         if ("publish".equals(task.getName())) {
194             title = title + " {1} {2}";
195         } else {
196             return title;
197         }
198 
199         String workspace = (String) task.getContent().get(Context.ATTRIBUTE_REPOSITORY);
200         String path = (String) task.getContent().get(Context.ATTRIBUTE_PATH);
201         boolean isDeletion = BooleanUtils.toBooleanDefaultIfNull((Boolean) task.getContent().get("isDeletion"), false);
202         title = MessageFormat.format(title, BooleanUtils.toInteger(isDeletion), workspace, path);
203 
204         return title;
205     }
206 
207     private MagnoliaIcons taskIcon(Task task) {
208         if ("publish".equals(task.getName())) {
209             if (BooleanUtils.toBooleanDefaultIfNull((Boolean) task.getContent().get("isDeletion"), false)) {
210                 return MagnoliaIcons.UNPUBLISH;
211             }
212             return BooleanUtils.toBooleanDefaultIfNull((Boolean) task.getContent().get("recursive"), false) ? MagnoliaIcons.PUBLISH_INCL_SUB : MagnoliaIcons.PUBLISH;
213         }
214 
215         return MagnoliaIcons.WORK_ITEM;
216     }
217 
218     private void updateViewAndSubAppDescriptorIcons(TaskDefinition taskDefinition, Task taskItem) {
219         String title = taskTitle(taskDefinition, taskItem);
220         MagnoliaIcons newIcon = taskIcon(taskItem);
221         getView().setCaption(title);
222         getView().setIcon(newIcon);
223         subAppDescriptor.setLabel(title);
224         subAppDescriptor.setIcon(newIcon.getCssClass());
225     }
226 }