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.config.registry.DefinitionProvider;
37 import info.magnolia.context.WebContext;
38 import info.magnolia.jcr.util.NodeTypes;
39 import info.magnolia.jcr.util.NodeUtil;
40 import info.magnolia.jcr.util.PropertyUtil;
41 import info.magnolia.link.LinkUtil;
42 import info.magnolia.objectfactory.Components;
43 import info.magnolia.rendering.spa.renderer.SpaRenderableDefinition;
44 import info.magnolia.rendering.template.TemplateDefinition;
45 import info.magnolia.rendering.template.registry.TemplateDefinitionRegistry;
46 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
47 import info.magnolia.ui.contentapp.detail.ContentDetailSubApp;
48 import info.magnolia.ui.datasource.jcr.JcrDatasource;
49 import info.magnolia.ui.ValueContext;
50 import info.magnolia.ui.vaadin.editor.gwt.shared.PlatformType;
51 import info.magnolia.ui.vaadin.gwt.client.shared.AbstractElement;
52 import info.magnolia.ui.vaadin.gwt.client.shared.AreaElement;
53 import info.magnolia.ui.vaadin.gwt.client.shared.ComponentElement;
54 import info.magnolia.ui.vaadin.gwt.client.shared.PageEditorParameters;
55
56 import java.util.ArrayList;
57 import java.util.Arrays;
58 import java.util.List;
59 import java.util.Locale;
60 import java.util.Map;
61 import java.util.Optional;
62
63 import javax.inject.Inject;
64 import javax.inject.Provider;
65 import javax.jcr.Node;
66 import javax.jcr.Session;
67
68 import org.apache.commons.lang3.StringUtils;
69
70 import com.machinezoo.noexception.Exceptions;
71
72 import lombok.Data;
73
74
75
76
77 @Data
78 public class PageEditorStatus {
79
80 private static final String VERSION_PARAMETER = "mgnlVersion";
81 private static final String PREVIEW_PARAMETER = "mgnlPreview";
82 private static final String CHANNEL_PARAMETER = "mgnlChannel";
83 private static final String AVAILABLE_COMPONENTS_DIVIDER = ",";
84 private Locale locale;
85 private String version;
86 private String nodePath;
87 private String viewType;
88 private PlatformType platformType = PlatformType.DESKTOP;
89 private AbstractElement selectedElement;
90 private Map<String, String> i18nKeys;
91
92 private final I18NAuthoringSupport<Node> i18NAuthoringSupport;
93 private final JcrDatasource datasource;
94 private final Provider<WebContext> webContextProvider;
95 private final ValueContext<Node> valueContext;
96 private final TemplateDefinitionRegistry templateDefinitionRegistry;
97
98 @Inject
99 public PageEditorStatus(I18NAuthoringSupport<Node> i18NAuthoringSupport, JcrDatasource datasource, Provider<WebContext> webContextProvider, ValueContext<Node> valueContext, TemplateDefinitionRegistry templateDefinitionRegistry) {
100 this.i18NAuthoringSupport = i18NAuthoringSupport;
101 this.datasource = datasource;
102 this.webContextProvider = webContextProvider;
103 this.valueContext = valueContext;
104 this.templateDefinitionRegistry = templateDefinitionRegistry;
105 }
106
107
108
109
110 @Deprecated
111 public PageEditorStatus(I18NAuthoringSupport<Node> i18NAuthoringSupport, JcrDatasource datasource, Provider<WebContext> webContextProvider, ValueContext<Node> valueContext) {
112 this(i18NAuthoringSupport, datasource, webContextProvider, valueContext, Components.getComponent(TemplateDefinitionRegistry.class));
113 }
114
115 public List<String> getAvailableTemplates() {
116 return Optional.ofNullable(selectedElement)
117 .map(element -> {
118 if (element instanceof AreaElement) {
119 return ((AreaElement) element).getAvailableComponents();
120 } else if (element instanceof ComponentElement) {
121 return ((ComponentElement) element).getAvailableTemplates();
122 } else {
123 return null;
124 }
125 })
126 .map(availableComponents -> availableComponents.split(AVAILABLE_COMPONENTS_DIVIDER))
127 .map(Arrays::asList)
128 .orElseGet(ArrayList::new);
129 }
130
131 public void setSelectedElement(AbstractElement selectedElement) {
132 this.selectedElement = selectedElement;
133 Exceptions.wrap().run(() -> {
134 final Session jcrSession = datasource.getJCRSession();
135 Node node = null;
136 if (selectedElement instanceof AreaElement) {
137 AreaElement area = (AreaElement) selectedElement;
138 if (area.isOptional() && !area.isCreated()) {
139 node = NodeUtil.createPath(jcrSession.getRootNode(), area.getPath(), NodeTypes.Area.NAME);
140 }
141 }
142 if (node == null && jcrSession.nodeExists(selectedElement.getPath())) {
143 node = jcrSession.getNode(selectedElement.getPath());
144 }
145 valueContext.set(node);
146 });
147 }
148
149 void updateStatusFromLocation(ContentDetailSubApp.DetailLocation location) {
150 this.nodePath = location.getNodePath();
151 this.version = location.getVersion();
152 this.viewType = location.getViewType();
153 }
154
155 public PageEditorParameters getParameters() {
156 PageEditorParameters parameters = new PageEditorParameters();
157 parameters.setContextPath(webContextProvider.get().getContextPath());
158 parameters.setNodePath(nodePath);
159 parameters.setPlatformType(platformType);
160 parameters.setPreview(isPreview());
161 parameters.setI18nKeys(i18nKeys);
162 parameters.setSelectedElement(selectedElement);
163 parameters.setUrl(createUri());
164 return parameters;
165 }
166
167 public String getPageTitle() {
168 return Exceptions.wrap().get(() -> {
169 final Session session = datasource.getJCRSession();
170 if (session.nodeExists(nodePath)) {
171 Node node = session.getNode(nodePath);
172 if (!NodeUtil.isNodeType(node, NodeTypes.Page.NAME)) {
173 node = NodeUtil.getNearestAncestorOfType(node, NodeTypes.Page.NAME);
174 }
175 return PropertyUtil.getString(node, "title", (node != null ? node.getName() : ""));
176 } else {
177 return null;
178 }
179 });
180 }
181
182 private String createUri() {
183 return Exceptions.wrap().get(() -> {
184 final Session session = datasource.getJCRSession();
185 if (session.nodeExists(nodePath)) {
186 Node node = session.getNode(nodePath);
187 TemplateDefinition definition = getTemplateDefinition(node);
188 String url = getExternalSpaUrl(definition).orElse(i18NAuthoringSupport.createI18NURI(node, locale));
189 StringBuffer uri = new StringBuffer(url);
190 LinkUtil.addParameter(uri, PREVIEW_PARAMETER, Boolean.toString(isPreview()));
191 LinkUtil.addParameter(uri, CHANNEL_PARAMETER, platformType.getId());
192 if (StringUtils.isNotEmpty(version)) {
193 LinkUtil.addParameter(uri, VERSION_PARAMETER, version);
194 }
195 return uri.toString();
196 } else {
197 return null;
198 }
199 });
200 }
201
202 private Optional<String> getExternalSpaUrl(TemplateDefinition definition) {
203 if (definition instanceof SpaRenderableDefinition) {
204 return Optional.ofNullable(((SpaRenderableDefinition) definition).getUrl());
205 } else {
206 return Optional.empty();
207 }
208 }
209
210 private TemplateDefinition getTemplateDefinition(Node node) {
211 return Exceptions.wrap().get(() -> {
212 if (node.hasProperty(NodeTypes.Renderable.TEMPLATE)) {
213 String templateId = node.getProperty(NodeTypes.Renderable.TEMPLATE).getString();
214 DefinitionProvider<TemplateDefinition> definition = templateDefinitionRegistry.getProvider(templateId);
215 return definition.get();
216 }
217 return null;
218 });
219 }
220
221 private boolean isPreview() {
222 return "view".equals(viewType) || "version".equals(viewType);
223 }
224
225 void setPlatformType(PlatformType platformType) {
226 this.platformType = platformType;
227 }
228 }