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