View Javadoc
1   /**
2    * This file Copyright (c) 2012-2016 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.pages.app.editor;
35  
36  import info.magnolia.event.EventBus;
37  import info.magnolia.i18nsystem.SimpleTranslator;
38  import info.magnolia.pages.app.editor.event.ComponentMoveEvent;
39  import info.magnolia.pages.app.editor.event.NodeSelectedEvent;
40  import info.magnolia.pages.app.editor.parameters.PageEditorStatus;
41  import info.magnolia.ui.api.action.ActionExecutionException;
42  import info.magnolia.ui.api.action.ActionExecutor;
43  import info.magnolia.ui.api.app.SubAppContext;
44  import info.magnolia.ui.api.app.SubAppEventBus;
45  import info.magnolia.ui.api.message.Message;
46  import info.magnolia.ui.api.message.MessageType;
47  import info.magnolia.ui.api.overlay.AlertCallback;
48  import info.magnolia.ui.contentapp.detail.DetailLocation;
49  import info.magnolia.ui.vaadin.editor.PageEditorListener;
50  import info.magnolia.ui.vaadin.editor.PageEditorView;
51  import info.magnolia.ui.vaadin.gwt.client.shared.AbstractElement;
52  import info.magnolia.ui.vaadin.gwt.client.shared.ErrorType;
53  import info.magnolia.ui.vaadin.gwt.client.shared.PageEditorParameters;
54  import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
55  
56  import javax.inject.Inject;
57  import javax.inject.Named;
58  import javax.inject.Singleton;
59  
60  import org.slf4j.Logger;
61  import org.slf4j.LoggerFactory;
62  
63  import com.google.common.base.CaseFormat;
64  
65  /**
66   * Presenter for the server side {@link PageEditorView}.
67   * Serves multiple methods for actions triggered from the page editor.
68   */
69  @Singleton
70  public class PageEditorPresenter implements PageEditorListener {
71  
72      private static final Logger log = LoggerFactory.getLogger(PageEditorPresenter.class);
73      private static final String EXTERNAL_PAGE_CAPTION = "pages.edit.external.page.caption";
74  
75      private final ActionExecutor actionExecutor;
76      private final PageEditorView view;
77      private final EventBus subAppEventBus;
78      private final SubAppContext subAppContext;
79      private final SimpleTranslator i18n;
80      private final PageEditorStatus pageEditorStatus;
81  
82      private AbstractElement selectedElement;
83      private boolean moving = false;
84      private Listener listener;
85  
86      @Inject
87      public PageEditorPresenter(final ActionExecutor actionExecutor, PageEditorView view, final @Named(SubAppEventBus.NAME) EventBus subAppEventBus,
88              SubAppContext subAppContext, SimpleTranslator i18n, PageEditorStatus pageEditorStatus) {
89          this.actionExecutor = actionExecutor;
90          this.view = view;
91          this.subAppEventBus = subAppEventBus;
92          this.subAppContext = subAppContext;
93          this.i18n = i18n;
94          this.pageEditorStatus = pageEditorStatus;
95          registerHandlers();
96      }
97  
98      public PageEditorView start(DetailLocation location) {
99          view.setListener(this);
100         pageEditorStatus.updateStatusFromLocation(location);
101         loadPageEditor();
102         return view;
103     }
104 
105     public void reload(DetailLocation location) {
106         pageEditorStatus.updateStatusFromLocation(location);
107         loadPageEditor();
108     }
109 
110     private void registerHandlers() {
111         subAppEventBus.addHandler(ComponentMoveEvent.class, new ComponentMoveEvent.Handler() {
112             @Override
113             public void onMove(ComponentMoveEvent event) {
114                 moving = event.isStart();
115                 if (moving) {
116                     view.startMoveComponent();
117                 } else if (event.isServerSide()) {
118                     view.cancelMoveComponent();
119                 }
120                 listener.onMove();
121             }
122         });
123 
124     }
125 
126     @Override
127     public void onElementSelect(AbstractElement selectedElement) {
128         this.selectedElement = selectedElement;
129         subAppEventBus.fireEvent(new NodeSelectedEvent(selectedElement));
130     }
131 
132     @Override
133     public void onExternalPageSelect() {
134         this.selectedElement = null;
135         listener.updateCaptionForExternalPage(i18n.translate(EXTERNAL_PAGE_CAPTION));
136         listener.deactivateComponents();
137     }
138 
139     @Override
140     public void onError(ErrorType errorType, String... parameters) {
141         if (errorType == null) {
142             throw new IllegalArgumentException("ErrorType must be one of ErrorType.values().");
143         }
144 
145         String key = String.format("pages.templateErrorAlert.%s.message", CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, errorType.name()));
146         String message = i18n.translate(key, parameters);
147         subAppContext.openAlert(MessageStyleTypeEnum.WARNING, i18n.translate("pages.templateErrorAlert.title"), message, i18n.translate("button.ok"), new AlertCallback() {
148             @Override
149             public void onOk() {
150                 // Do nothing.
151             }
152         });
153     }
154 
155     /**
156      * Used for executing actions from 'client-side'. These might have a {@link AbstractElement} as part of the arguments, but don't have to.
157      * See {@link info.magnolia.ui.vaadin.gwt.client.rpc.PageEditorServerRpc} which receives the calls from 'client-side'.
158      *
159      * @see PagesEditorSubApp#prepareAndExecutePagesEditorAction(String) for 'server-side' action execution as comparison.
160      */
161     @Override
162     public void onAction(String actionName, Object... args) {
163         try {
164             actionExecutor.execute(actionName, args);
165         } catch (ActionExecutionException e) {
166             Message error = new Message(MessageType.ERROR, i18n.translate("pages.pageEditorPresenter.actionExecutionError.message"), e.getMessage());
167             log.error("An error occurred while executing action [{}]", actionName, e);
168             subAppContext.getAppContext().sendLocalMessage(error);
169         }
170     }
171 
172     public AbstractElement getSelectedElement() {
173         return selectedElement;
174     }
175 
176     public void loadPageEditor() {
177         PageEditorParameters pageEditorParameters = pageEditorStatus.getParameters();
178         view.load(pageEditorParameters);
179     }
180 
181     public void updateParameters() {
182         PageEditorParameters pageEditorParameters = pageEditorStatus.getParameters();
183         view.update(pageEditorParameters);
184     }
185 
186     public void refresh() {
187         view.refresh();
188     }
189 
190     public boolean isMoving() {
191         return moving;
192     }
193 
194     public void setListener(Listener listener) {
195         this.listener = listener;
196     }
197 
198     public PageEditorStatus getStatus() {
199         return pageEditorStatus;
200     }
201 
202     /**
203      * Listener interface to call {@link PageEditorPresenter}.
204      */
205     interface Listener {
206         void onMove();
207 
208         void updateCaptionForExternalPage(String title);
209 
210         void deactivateComponents();
211     }
212 }