View Javadoc
1   /**
2    * This file Copyright (c) 2019 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.dialog.actions;
35  
36  import static java.util.stream.Collectors.toList;
37  
38  import info.magnolia.config.registry.Registry;
39  import info.magnolia.i18nsystem.I18nizer;
40  import info.magnolia.ui.CloseHandler;
41  import info.magnolia.ui.UIComponent;
42  import info.magnolia.ui.ValueContext;
43  import info.magnolia.ui.api.action.AbstractAction;
44  import info.magnolia.ui.api.action.ActionExecutionException;
45  import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
46  import info.magnolia.ui.dialog.ActionExecution;
47  import info.magnolia.ui.dialog.DialogBuilder;
48  import info.magnolia.ui.dialog.DialogDefinition;
49  import info.magnolia.ui.dialog.DialogDefinitionRegistry;
50  import info.magnolia.ui.dialog.EditorActionBar;
51  import info.magnolia.ui.dialog.FormDialogDefinition;
52  import info.magnolia.ui.editor.EditorView;
53  import info.magnolia.ui.editor.LocaleContext;
54  import info.magnolia.ui.field.LocaleSelector;
55  
56  import java.util.List;
57  
58  import javax.inject.Inject;
59  
60  import com.vaadin.ui.Window;
61  
62  /**
63   * Opens a dialog.
64   */
65  public class OpenDialogAction<T> extends AbstractAction<OpenDialogActionDefinition> {
66  
67      private final UIComponent parentView;
68      private final I18NAuthoringSupport<T> i18NAuthoringSupport;
69      private final DialogDefinitionRegistry dialogDefinitionRegistry;
70      private final LocaleContext localeContext;
71      private final ValueContext<T> valueContext;
72      private final I18nizer i18nizer;
73  
74      @Inject
75      public OpenDialogAction(OpenDialogActionDefinition definition,
76                              LocaleContext localeContext,
77                              ValueContext<T> valueContext,
78                              UIComponent parentView,
79                              I18NAuthoringSupport<T> i18NAuthoringSupport,
80                              DialogDefinitionRegistry dialogDefinitionRegistry,
81                              I18nizer i18nizer) {
82          super(definition);
83          this.localeContext = localeContext;
84          this.valueContext = valueContext;
85          this.parentView = parentView;
86          this.i18NAuthoringSupport = i18NAuthoringSupport;
87          this.dialogDefinitionRegistry = dialogDefinitionRegistry;
88          this.i18nizer = i18nizer;
89      }
90  
91      @Override
92      public void execute() throws ActionExecutionException {
93          try {
94              DialogDefinition dialogDefinition = getDialogDefinition(dialogDefinitionRegistry, i18nizer);
95              if (dialogDefinition instanceof FormDialogDefinition) {
96                  valueContext.getSingle().ifPresent(item -> {
97                      if (!localeContext.isPopulated()) {
98                          localeContext.populateFromI18NAuthoringSupport(item, i18NAuthoringSupport);
99                      }
100                 });
101 
102                 FormDialogDefinition<T> formDialogDefinition = (FormDialogDefinition) dialogDefinition;
103                 EditorView<T> form = parentView.create(formDialogDefinition.getForm());
104 
105                 if (getDefinition().isPopulate()) {
106                     populate(form);
107                 }
108 
109                 List<ActionExecution<T>> actionExecutions =
110                         ActionExecution.<T>fromDefinitions(dialogDefinition.getActions().values(), form.getComponentProvider())
111                                 .collect(toList());
112 
113                 Window dialog = new DialogBuilder()
114                         .withTitle(dialogDefinition.getLabel())
115                         .withContent(form.asVaadinComponent())
116                         .withShortcuts(actionExecutions)
117                         .light(dialogDefinition.isLight())
118                         .withFooter(configureFooter(formDialogDefinition, actionExecutions, form).layout())
119                         .buildAndOpen();
120 
121                 CloseHandler closeHandler = getCloseHandler(dialog);
122                 dialog.addCloseListener((Window.CloseListener) e -> closeHandler.close());
123                 form.bindInstance(CloseHandler.class, closeHandler);
124             }
125         } catch (Registry.InvalidDefinitionException | Registry.NoSuchDefinitionException e) {
126             throw new ActionExecutionException(e);
127         }
128     }
129 
130     protected void populate(EditorView<T> form) {
131         valueContext.getSingle().ifPresent(form::populate);
132     }
133 
134     protected EditorActionBar<T> configureFooter(FormDialogDefinition<T> dialogDefinition, List<ActionExecution<T>> actionExecutions, EditorView<T> form) {
135         EditorActionBar<T> editorActionBar = form.create(EditorActionBar.class);
136                 editorActionBar
137                 .withActions(actionExecutions)
138                 .withLayoutDefinition(dialogDefinition.getFooterLayout());
139 
140         if (dialogDefinition.getForm().hasI18NProperties()) {
141             LocaleSelector localeSelector = form.create(LocaleSelector.class);
142             editorActionBar = editorActionBar.withLabeledControl("localeSelector", localeSelector);
143         }
144         return editorActionBar;
145     }
146 
147     protected CloseHandler getCloseHandler(Window dialog) {
148         return dialog::close;
149     }
150 
151     protected DialogDefinition getDialogDefinition(DialogDefinitionRegistry dialogDefinitionRegistry, I18nizer i18nizer) {
152         return i18nizer.decorate(dialogDefinitionRegistry.getProvider(getDefinition().getDialogId()).get());
153     }
154 
155     protected ValueContext<T> getValueContext() {
156         return valueContext;
157     }
158 }