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.pages.app.detail;
35
36 import info.magnolia.i18nsystem.SimpleTranslator;
37 import info.magnolia.jcr.util.NodeTypes;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.objectfactory.Components;
40 import info.magnolia.pages.app.detail.context.MoveComponentContext;
41 import info.magnolia.pages.app.detail.context.NavigationContext;
42 import info.magnolia.pages.app.detail.context.PlatformContext;
43 import info.magnolia.ui.ValueContext;
44 import info.magnolia.ui.api.action.ActionExecutionException;
45 import info.magnolia.ui.api.action.ActionExecutor;
46 import info.magnolia.ui.api.app.SubAppContext;
47 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
48 import info.magnolia.ui.api.message.Message;
49 import info.magnolia.ui.api.message.MessageType;
50 import info.magnolia.ui.contentapp.detail.ContentDetailSubApp;
51 import info.magnolia.ui.datasource.jcr.JcrDatasource;
52 import info.magnolia.ui.editor.LocaleContext;
53 import info.magnolia.ui.framework.ioc.Destructible;
54 import info.magnolia.ui.observation.DatasourceObservation;
55 import info.magnolia.ui.vaadin.editor.PageEditorListener;
56 import info.magnolia.ui.vaadin.editor.PageEditorView;
57 import info.magnolia.ui.vaadin.gwt.client.shared.AbstractElement;
58 import info.magnolia.ui.vaadin.gwt.client.shared.ErrorType;
59
60 import java.util.stream.Stream;
61
62 import javax.inject.Inject;
63 import javax.jcr.Node;
64
65 import com.machinezoo.noexception.Exceptions;
66 import com.vaadin.shared.Registration;
67 import com.vaadin.ui.Notification;
68
69 import lombok.extern.slf4j.Slf4j;
70
71
72
73
74
75 @Slf4j
76 public class PageEditorPresenter implements PageEditorListener, Destructible {
77
78 private final ActionExecutor actionExecutor;
79 private final PageEditorView view;
80 private final SubAppContext subAppContext;
81 private final SimpleTranslator i18n;
82 private final PageEditorStatus pageEditorStatus;
83 private final ValueContext<Node> valueContext;
84 private final ContentDetailSubApp.LocationContext locationContext;
85 private final NavigationContext<String> navigationContext;
86 private final Registration observation;
87
88 @Inject
89 public PageEditorPresenter(final ActionExecutor actionExecutor,
90 I18NAuthoringSupport<Node> i18NAuthoringSupport,
91 PageEditorView view,
92 SubAppContext subAppContext,
93 SimpleTranslator i18n,
94 PageEditorStatus pageEditorStatus,
95 LocaleContext localeContext,
96 ContentDetailSubApp.LocationContext locationContext,
97 NavigationContext<String> navigationContext,
98 PlatformContext platformContext,
99 MoveComponentContext moveComponentContext,
100 ValueContext<Node> valueContext,
101 JcrDatasource jcrDatasource,
102 DatasourceObservation.Manual datasourceObservation) {
103 this.actionExecutor = actionExecutor;
104 this.subAppContext = subAppContext;
105 this.i18n = i18n;
106 this.pageEditorStatus = pageEditorStatus;
107 this.view = view;
108 this.valueContext = valueContext;
109 this.navigationContext = navigationContext;
110 this.locationContext = locationContext;
111
112 view.setListener(this);
113 view.asVaadinComponent().addAttachListener(event -> loadPageEditor());
114
115 locationContext.location().observe(detailLocation ->
116 detailLocation.ifPresent(location -> {
117 Exceptions.wrap().run(() -> {
118 Node relatedNode = jcrDatasource.getJCRSession().getNode(location.getNodePath());
119 pageEditorStatus.updateStatusFromLocation(location);
120 localeContext.populateFromI18NAuthoringSupport(relatedNode, i18NAuthoringSupport);
121 loadPageEditor();
122 });
123 }));
124
125 moveComponentContext.moving().observe(isMovingOptional -> isMovingOptional.ifPresent(isMoving -> {
126 if (isMoving) {
127 view.startMoveComponent();
128 } else if (moveComponentContext.serverSide().nullableValue()) {
129 view.cancelMoveComponent();
130 }
131 }));
132
133 valueContext.observe(nodes -> nodes.stream().findFirst()
134 .filter(Exceptions.wrap().predicate(n -> NodeUtil.isNodeType(n, NodeTypes.Page.NAME)))
135 .ifPresent(node -> localeContext.populateFromI18NAuthoringSupport(node, i18NAuthoringSupport)));
136
137 observation = datasourceObservation.register(() -> {
138 updateParameters();
139 view.refresh();
140 });
141
142 platformContext.platform().observe(platformType -> platformType.ifPresent(platform -> {
143 pageEditorStatus.setPlatformType(platform);
144 loadPageEditor();
145 }));
146 }
147
148
149
150
151
152
153 @Deprecated
154 public PageEditorPresenter(final ActionExecutor actionExecutor,
155 I18NAuthoringSupport<Node> i18NAuthoringSupport,
156 PageEditorView view,
157 SubAppContext subAppContext,
158 SimpleTranslator i18n,
159 PageEditorStatus pageEditorStatus,
160 LocaleContext localeContext,
161 ContentDetailSubApp.LocationContext locationContext,
162 NavigationContext<String> navigationContext,
163 MoveComponentContext moveComponentContext,
164 ValueContext<Node> valueContext,
165 JcrDatasource jcrDatasource,
166 DatasourceObservation.Manual datasourceObservation) {
167 this(actionExecutor, i18NAuthoringSupport, view,
168 subAppContext, i18n, pageEditorStatus,
169 localeContext, locationContext, navigationContext,
170 Components.getComponent(PlatformContext.class), moveComponentContext,
171 valueContext, jcrDatasource, datasourceObservation);
172 }
173
174 @Override
175 public void onElementSelect(AbstractElement selectedElement) {
176 pageEditorStatus.setSelectedElement(selectedElement);
177 updateParameters();
178 }
179
180 @Override
181 public void onExternalPageSelect() {
182 valueContext.clear();
183 }
184
185
186
187
188
189 @Override
190 public void onError(ErrorType errorType, String... parameters) {
191 String key = String.format("pages-app.templateErrorAlert.%s.message", errorType.name());
192 Notification.show(i18n.translate("pages-app.templateErrorAlert.title"), i18n.translate(key, (Object[]) parameters), Notification.Type.WARNING_MESSAGE);
193 }
194
195 @Override
196 public void onNavigation(String url) {
197 navigationContext.url().set(url);
198 locationContext.location().update(detailLocation -> {
199 valueContext.getSingle()
200 .filter(Exceptions.wrap().predicate(node -> NodeUtil.isNodeType(node, NodeTypes.Page.NAME)))
201 .ifPresent(Exceptions.wrap().consumer(node -> detailLocation.updateNodePath(node.getPath())));
202 }
203 );
204 }
205
206
207
208
209
210 @Override
211 public void onAction(String actionName, Object... args) {
212 Stream.of(args)
213 .filter(AbstractElement.class::isInstance)
214 .map(AbstractElement.class::cast)
215 .findFirst()
216 .ifPresent(pageEditorStatus::setSelectedElement);
217 try {
218 actionExecutor.execute(actionName, args);
219 } catch (ActionExecutionException e) {
220 Message error = new Message(MessageType.ERROR, i18n.translate("pages.pageEditorPresenter.actionExecutionError.message"), e.getMessage());
221 subAppContext.getAppContext().sendLocalMessage(error);
222 log.error("An error occurred while executing action [{}]", actionName, e);
223 }
224 }
225
226 private void loadPageEditor() {
227 view.load(pageEditorStatus.getParameters());
228 }
229
230 private void updateParameters() {
231 view.update(pageEditorStatus.getParameters());
232 }
233
234 @Override
235 public void destroy() {
236 observation.remove();
237 }
238 }