1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.mediaeditor;
35
36 import info.magnolia.event.EventBus;
37 import info.magnolia.event.HandlerRegistration;
38 import info.magnolia.i18nsystem.SimpleTranslator;
39 import info.magnolia.objectfactory.Components;
40 import info.magnolia.ui.actionbar.ActionbarPresenter;
41 import info.magnolia.ui.actionbar.ActionbarView;
42 import info.magnolia.ui.api.action.ActionDefinition;
43 import info.magnolia.ui.api.action.ActionExecutionException;
44 import info.magnolia.ui.api.action.ActionExecutor;
45 import info.magnolia.ui.api.app.AppContext;
46 import info.magnolia.ui.api.availability.AvailabilityDefinition;
47 import info.magnolia.ui.api.message.Message;
48 import info.magnolia.ui.api.message.MessageType;
49 import info.magnolia.ui.api.view.View;
50 import info.magnolia.ui.dialog.DialogPresenter;
51 import info.magnolia.ui.dialog.DialogView;
52 import info.magnolia.ui.dialog.definition.ConfiguredDialogDefinition;
53 import info.magnolia.ui.mediaeditor.action.availability.MediaEditorAvailabilityChecker;
54 import info.magnolia.ui.mediaeditor.data.EditHistoryTrackingProperty;
55 import info.magnolia.ui.mediaeditor.data.EditHistoryTrackingPropertyImpl;
56 import info.magnolia.ui.mediaeditor.definition.MediaEditorDefinition;
57 import info.magnolia.ui.mediaeditor.event.MediaEditorCompletedEvent;
58 import info.magnolia.ui.mediaeditor.event.MediaEditorCompletedEvent.CompletionType;
59 import info.magnolia.ui.mediaeditor.event.MediaEditorCompletedEvent.Handler;
60 import info.magnolia.ui.mediaeditor.event.MediaEditorInternalEvent;
61
62 import java.io.ByteArrayInputStream;
63 import java.io.IOException;
64 import java.io.InputStream;
65 import java.util.HashSet;
66 import java.util.Map;
67 import java.util.Set;
68
69 import org.apache.commons.io.IOUtils;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
72
73
74
75
76 public class MediaEditorPresenterImpl implements MediaEditorPresenter, ActionbarPresenter.Listener, MediaEditorInternalEvent.Handler, EditHistoryTrackingProperty.Listener {
77 private static final Logger log = LoggerFactory.getLogger(MediaEditorPresenterImpl.class);
78
79 private MediaEditorView view;
80 private ActionbarPresenter actionbarPresenter;
81 private MediaEditorDefinition definition;
82 private DialogPresenter dialogPresenter;
83 private AppContext appContext;
84 private EditHistoryTrackingProperty dataSource;
85 private EventBus eventBus;
86 private ActionExecutor actionExecutor;
87 private HandlerRegistration internalMediaEditorEventHandlerRegistration;
88 private Set<HandlerRegistration> completionHandlers = new HashSet<>();
89 private final SimpleTranslator i18n;
90 private final MediaEditorAvailabilityChecker mediaEditorAvailabilityChecker;
91
92 public MediaEditorPresenterImpl(
93 MediaEditorDefinition definition,
94 EventBus eventBus,
95 MediaEditorView view,
96 ActionbarPresenter actionbarPresenter,
97 DialogPresenter dialogPresenter,
98 AppContext appContext,
99 SimpleTranslator i18n,
100 MediaEditorAvailabilityChecker mediaEditorAvailabilityChecker) {
101 this.eventBus = eventBus;
102 this.view = view;
103 this.actionbarPresenter = actionbarPresenter;
104 this.definition = definition;
105 this.dialogPresenter = dialogPresenter;
106 this.appContext = appContext;
107 this.i18n = i18n;
108 this.mediaEditorAvailabilityChecker = mediaEditorAvailabilityChecker;
109 this.actionbarPresenter.setListener(this);
110 this.internalMediaEditorEventHandlerRegistration = eventBus.addHandler(MediaEditorInternalEvent.class, this);
111 this.view.asVaadinComponent().addDetachListener(event -> dataSource.purgeHistory());
112 }
113
114
115
116
117 @Deprecated
118 public MediaEditorPresenterImpl(
119 MediaEditorDefinition definition,
120 EventBus eventBus,
121 MediaEditorView view,
122 ActionbarPresenter actionbarPresenter,
123 DialogPresenter dialogPresenter,
124 AppContext appContext,
125 SimpleTranslator i18n) {
126 this(definition, eventBus, view, actionbarPresenter, dialogPresenter, appContext, i18n, Components.getComponent(MediaEditorAvailabilityChecker.class));
127 }
128
129 @Override
130 public void setActionExecutor(ActionExecutor actionExecutor) {
131 this.actionExecutor = actionExecutor;
132 }
133
134 @Override
135 public View start(final InputStream stream) {
136 try {
137 final ActionbarView actionbar = actionbarPresenter.start(definition.getActionBar(), definition.getActions());
138 updateActionbar();
139 final DialogView dialogView = dialogPresenter.start(new ConfiguredDialogDefinition(), appContext);
140 this.dataSource = new EditHistoryTrackingPropertyImpl(IOUtils.toByteArray(stream), i18n);
141 this.dataSource.setListener(this);
142 view.setActionBar(actionbar);
143 view.setDialog(dialogView);
144 switchToDefaultMode();
145 return view;
146 } catch (IOException e) {
147 errorOccurred(i18n.translate("ui-mediaeditor.mediaeditorPresenter.errorWhileEditing") + " ", e);
148 log.error("Error occurred while editing media: " + e.getMessage(), e);
149 } finally {
150 IOUtils.closeQuietly(stream);
151 }
152 return null;
153 }
154
155 @Override
156 public View getView() {
157 return view;
158 }
159
160 @Override
161 public void onSubmit(MediaEditorInternalEvent event) {
162 dataSource.commit();
163 complete(CompletionType.SUBMIT);
164 }
165
166 @Override
167 public void onCancelAll(MediaEditorInternalEvent event) {
168 dataSource.revert();
169 complete(CompletionType.CANCEL);
170 }
171
172 @Override
173 public void onLastActionCancelled(MediaEditorInternalEvent e) {
174 switchToDefaultMode();
175 }
176
177 @Override
178 public void onLastActionApplied(MediaEditorInternalEvent e) {
179 switchToDefaultMode();
180 }
181
182 private void switchToDefaultMode() {
183 doExecuteMediaEditorAction(definition.getDefaultAction());
184 }
185
186 @Override
187 public HandlerRegistration addCompletionHandler(Handler handler) {
188 HandlerRegistration hr = eventBus.addHandler(MediaEditorCompletedEvent.class, handler);
189 completionHandlers.add(hr);
190 return hr;
191 }
192
193 @Override
194 public void onActionbarItemClicked(String actionName) {
195 doExecuteMediaEditorAction(actionName);
196 }
197
198 @Override
199 public MediaEditorDefinition getDefinition() {
200 return definition;
201 }
202
203 private void complete(CompletionType completionType) {
204 InputStream is = new ByteArrayInputStream(dataSource.getValue());
205 eventBus.fireEvent(new MediaEditorCompletedEvent(completionType, is));
206 clearEventHandlers();
207 }
208
209 private void clearEventHandlers() {
210 internalMediaEditorEventHandlerRegistration.removeHandler();
211 for (HandlerRegistration hr : completionHandlers) {
212 hr.removeHandler();
213 }
214 }
215
216 private void doExecuteMediaEditorAction(String actionName) {
217 try {
218 actionExecutor.execute(actionName, this, view, dataSource);
219 } catch (ActionExecutionException e) {
220 errorOccurred(i18n.translate("ui-mediaeditor.mediaeditorPresenter.actionExecutionException") + " ", e);
221 log.warn("Unable to execute action [" + actionName + "]", e);
222 }
223 }
224
225 @Override
226 public void errorOccurred(String message, Throwable e) {
227 Message error = new Message(MessageType.ERROR, message, e.getMessage());
228 appContext.sendLocalMessage(error);
229 }
230
231 protected void updateActionbar() {
232 Map<String, ActionDefinition> actionsDefinition = definition.getActions();
233 for (Map.Entry<String, ActionDefinition> action : actionsDefinition.entrySet()) {
234 AvailabilityDefinition availabilityDefinition = action.getValue().getAvailability();
235 if (mediaEditorAvailabilityChecker.isAvailable(availabilityDefinition)) {
236 actionbarPresenter.enable(action.getKey());
237 } else {
238 actionbarPresenter.disable(action.getKey());
239 }
240 }
241 }
242 }