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.definition.ActionbarDefinition;
40 import info.magnolia.ui.api.action.ActionDefinition;
41 import info.magnolia.ui.api.action.ActionExecutionException;
42 import info.magnolia.ui.api.action.ActionExecutor;
43 import info.magnolia.ui.api.app.AppContext;
44 import info.magnolia.ui.api.availability.AvailabilityChecker;
45 import info.magnolia.ui.api.message.Message;
46 import info.magnolia.ui.api.message.MessageType;
47 import info.magnolia.ui.api.view.View;
48 import info.magnolia.ui.contentapp.browser.ActionExecutionService;
49 import info.magnolia.ui.contentapp.browser.actions.ActionbarPresenter;
50 import info.magnolia.ui.contentapp.browser.actions.ActionbarView;
51 import info.magnolia.ui.ValueContext;
52 import info.magnolia.ui.UIComponent;
53 import info.magnolia.ui.contentapp.browser.preview.NoOpPreviewProvider;
54 import info.magnolia.ui.mediaeditor.data.MediaState;
55 import info.magnolia.ui.mediaeditor.data.MediaStateImpl;
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, MediaEditorInternalEvent.Handler, MediaState.Listener {
77 private static final Logger log = LoggerFactory.getLogger(MediaEditorPresenterImpl.class);
78
79 private MediaEditorView view;
80 private MediaEditorDefinition definition;
81 private AppContext appContext;
82 private MediaState mediaState;
83 private EventBus eventBus;
84 private ActionExecutor actionExecutor;
85 private HandlerRegistration internalMediaEditorEventHandlerRegistration;
86 private Set<HandlerRegistration> completionHandlers = new HashSet<>();
87 private final SimpleTranslator i18n;
88 private ValueContext<MediaState> valueContext;
89 private AvailabilityChecker availabilityChecker;
90
91 public MediaEditorPresenterImpl(
92 MediaEditorDefinition definition,
93 EventBus eventBus,
94 MediaEditorView view,
95 AppContext appContext,
96 SimpleTranslator i18n,
97 AvailabilityChecker availabilityChecker) {
98 this.eventBus = eventBus;
99 this.view = view;
100 this.definition = definition;
101 this.appContext = appContext;
102 this.i18n = i18n;
103 this.internalMediaEditorEventHandlerRegistration = eventBus.addHandler(MediaEditorInternalEvent.class, this);
104 this.view.asVaadinComponent().addDetachListener(event -> mediaState.clearState());
105 this.availabilityChecker = availabilityChecker;
106 }
107
108 @Override
109 public void setActionExecutor(ActionExecutor actionExecutor) {
110 this.actionExecutor = actionExecutor;
111 }
112
113 @Override
114 public UIComponent start(final InputStream stream) {
115 try {
116 mediaState = new MediaStateImpl(IOUtils.toByteArray(stream), i18n);
117 mediaState.setListener(this);
118 valueContext = view.bindContext(ValueContext.class);
119 valueContext.set(mediaState);
120 Map<String, ActionDefinition> actions = definition.getActions();
121 ActionbarDefinition actionbarDefinition = definition.getActionBar();
122 final ActionbarPresenter<MediaState> actionbarPresenter = view.create(
123 ActionbarPresenter.class,
124 valueContext,
125 actions,
126 actionbarDefinition,
127 getActionExecutionService(),
128 availabilityChecker
129 );
130
131 final ActionbarView<MediaState> actionbar = view.create(
132 ActionbarView.class,
133 actionbarDefinition,
134 actionbarPresenter,
135 new NoOpPreviewProvider()
136 );
137
138 stream.close();
139 view.setActionBar(actionbar);
140 switchToDefaultMode();
141 return view;
142 } catch (IOException e) {
143 errorOccurred(i18n.translate("ui-mediaeditor.mediaeditorPresenter.errorWhileEditing") + " ", e);
144 log.error("Error occurred while editing media: " + e.getMessage(), e);
145 }
146 return null;
147 }
148
149 private ActionExecutionService getActionExecutionService() {
150 return new ActionExecutionService(actionExecutor, null) {
151 @Override
152 public void executeAction(String actionName, Object... parameters) {
153 doExecuteMediaEditorAction(actionName);
154 }
155 };
156 }
157
158 @Override
159 public View getView() {
160 return view;
161 }
162
163 @Override
164 public void onSubmit(MediaEditorInternalEvent event) {
165 mediaState.commitState();
166 complete(CompletionType.SUBMIT);
167 }
168
169 @Override
170 public void onCancelAll(MediaEditorInternalEvent event) {
171 mediaState.revertState();
172 complete(CompletionType.CANCEL);
173 }
174
175 @Override
176 public void onLastActionCancelled(MediaEditorInternalEvent e) {
177 switchToDefaultMode();
178 }
179
180 @Override
181 public void onLastActionApplied(MediaEditorInternalEvent e) {
182 switchToDefaultMode();
183 }
184
185 private void switchToDefaultMode() {
186 doExecuteMediaEditorAction(definition.getDefaultAction());
187 }
188
189 @Override
190 public HandlerRegistration addCompletionHandler(Handler handler) {
191 HandlerRegistration hr = eventBus.addHandler(MediaEditorCompletedEvent.class, handler);
192 completionHandlers.add(hr);
193 return hr;
194 }
195
196 @Override
197 public MediaEditorDefinition getDefinition() {
198 return definition;
199 }
200
201 private void complete(CompletionType completionType) {
202 InputStream is = new ByteArrayInputStream(mediaState.getState());
203 eventBus.fireEvent(new MediaEditorCompletedEvent(completionType, is));
204 clearEventHandlers();
205 }
206
207 private void clearEventHandlers() {
208 internalMediaEditorEventHandlerRegistration.removeHandler();
209 for (HandlerRegistration hr : completionHandlers) {
210 hr.removeHandler();
211 }
212 }
213
214 private void doExecuteMediaEditorAction(String actionName) {
215 try {
216 actionExecutor.execute(actionName, this, view, valueContext, eventBus);
217 } catch (ActionExecutionException e) {
218 errorOccurred(i18n.translate("ui-mediaeditor.mediaeditorPresenter.actionExecutionException") + " ", e);
219 log.warn("Unable to execute action [" + actionName + "]", e);
220 }
221 }
222
223 @Override
224 public void errorOccurred(String message, Throwable e) {
225 Message error = new Message(MessageType.ERROR, message, e.getMessage());
226 appContext.sendLocalMessage(error);
227 }
228
229 public byte[] getData() {
230 return mediaState.getState();
231 }
232 }