View Javadoc
1   /**
2    * This file Copyright (c) 2014-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.pages.app.editor.parameters;
35  
36  import info.magnolia.config.registry.DefinitionProvider;
37  import info.magnolia.context.MgnlContext;
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.repository.RepositoryConstants;
47  import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
48  import info.magnolia.ui.contentapp.detail.DetailLocation;
49  import info.magnolia.ui.contentapp.detail.DetailView;
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.PageEditorParameters;
53  import info.magnolia.ui.vaadin.gwt.client.shared.PageElement;
54  
55  import java.util.Locale;
56  import java.util.Map;
57  
58  import javax.inject.Inject;
59  import javax.jcr.Node;
60  import javax.jcr.RepositoryException;
61  import javax.jcr.Session;
62  
63  import org.apache.commons.lang3.StringUtils;
64  import org.slf4j.Logger;
65  import org.slf4j.LoggerFactory;
66  
67  import com.machinezoo.noexception.Exceptions;
68  
69  /**
70   * Default implementation of {@link PageEditorStatus}.
71   */
72  public class DefaultPageEditorStatus implements PageEditorStatus {
73  
74      private static final Logger log = LoggerFactory.getLogger(DefaultPageEditorStatus.class);
75  
76      private final I18NAuthoringSupport i18NAuthoringSupport;
77      private Locale locale;
78      private String version;
79      private String nodePath;
80      private DetailView.ViewType viewType;
81      private PlatformType platFormType = PlatformType.DESKTOP;
82      private AbstractElement selectedElement;
83      private Map<String, String> i18nKeys;
84      private final TemplateDefinitionRegistry templateDefinitionRegistry;
85  
86      @Inject
87      public DefaultPageEditorStatus(I18NAuthoringSupport i18NAuthoringSupport, TemplateDefinitionRegistry templateDefinitionRegistry) {
88          this.i18NAuthoringSupport = i18NAuthoringSupport;
89          this.templateDefinitionRegistry = templateDefinitionRegistry;
90      }
91  
92      /**
93       * @deprecated Since 6.2, uses {@link DefaultPageEditorStatus(I18NAuthoringSupport, TemplateDefinitionRegistry) instead.}
94       */
95      public DefaultPageEditorStatus(I18NAuthoringSupport i18NAuthoringSupport) {
96          this.i18NAuthoringSupport = i18NAuthoringSupport;
97          this.templateDefinitionRegistry = Components.getComponent(TemplateDefinitionRegistry.class);
98      }
99  
100     @Override
101     public void updateStatusFromLocation(DetailLocation location) {
102         this.nodePath = location.getNodePath();
103         this.version = location.getVersion();
104         this.viewType = location.getViewType();
105         this.selectedElement = null;
106     }
107 
108     @Override
109     public boolean isLocationChanged(DetailLocation location) {
110         DetailView.ViewType viewType = location.getViewType();
111         String path = location.getNodePath();
112 
113         if ((path.equals(nodePath) && DetailView.ViewType.VIEW.equals(viewType) == isPreview())
114                 && (location.getVersion() == null ? version == null : location.getVersion().equals(version))) {
115             return false;
116         }
117         return true;
118     }
119 
120     @Override
121     public String getNodePath() {
122         return nodePath;
123     }
124 
125     @Override
126     public PlatformType getPlatformType() {
127         return platFormType;
128     }
129 
130     @Override
131     public Locale getLocale() {
132         return locale;
133     }
134 
135     @Override
136     public String getVersion() {
137         return version;
138     }
139 
140     @Override
141     public boolean isPreview() {
142         return DetailView.ViewType.VIEW.equals(viewType);
143     }
144 
145     @Override
146     public AbstractElement getSelectedElement() {
147         return selectedElement;
148     }
149 
150     @Override
151     public void setNodePath(String nodePath) {
152         this.nodePath = nodePath;
153     }
154 
155     @Override
156     public void setPlatformType(PlatformType platform) {
157         this.platFormType = platform;
158     }
159 
160     @Override
161     public void setLocale(Locale locale) {
162         this.locale = locale;
163     }
164 
165     @Override
166     public void setSelectedElement(AbstractElement element) {
167         this.selectedElement = element;
168     }
169 
170     @Override
171     public void setI18nKeys(Map<String, String> i18nKeys) {
172         this.i18nKeys = i18nKeys;
173     }
174 
175     @Override
176     public PageEditorParameters getParameters() {
177         PageEditorParameters parameters = new PageEditorParameters();
178         parameters.setContextPath(MgnlContext.getContextPath());
179         parameters.setNodePath(nodePath);
180         parameters.setPlatformType(platFormType);
181         parameters.setPreview(isPreview());
182         parameters.setI18nKeys(i18nKeys);
183         parameters.setSpa(isSpa());
184 
185         // Ideally we would pass the PageElement as well, but that would need more changes on the client-side, as 'null'
186         // currently resolves to the PageElement.
187         AbstractElement element = selectedElement instanceof PageElement ? null : selectedElement;
188         parameters.setSelectedElement(element);
189 
190         String uri = createUri(nodePath, isPreview(), version, platFormType, locale);
191         parameters.setUrl(uri);
192         return parameters;
193     }
194 
195     private boolean isSpa() {
196         return Exceptions.wrap().get(() -> {
197             final Session session = MgnlContext.getJCRSession(RepositoryConstants.WEBSITE);
198             if (!session.nodeExists(nodePath)) {
199                 return false;
200             }
201 
202             Node node = session.getNode(nodePath);
203             if (!NodeUtil.isNodeType(node, NodeTypes.Page.NAME)) {
204                 node = NodeUtil.getNearestAncestorOfType(node, NodeTypes.Page.NAME);
205             }
206 
207             String templateId = PropertyUtil.getString(node, NodeTypes.Renderable.TEMPLATE);
208 
209             if (templateId == null) {
210                 return false;
211             }
212 
213             DefinitionProvider<TemplateDefinition> definitionProvider = templateDefinitionRegistry.getProvider(templateId);
214 
215             return definitionProvider.isValid() && definitionProvider.get() instanceof SpaRenderableDefinition;
216         });
217     }
218 
219 
220     protected String createUri(String nodePath, boolean isPreview, String version, PlatformType platformType, Locale locale) {
221         String uri = "";
222         try {
223             Node node = MgnlContext.getJCRSession(RepositoryConstants.WEBSITE).getNode(nodePath);
224             uri = i18NAuthoringSupport.createI18NURI(node, locale);
225             StringBuffer sb = new StringBuffer(uri);
226 
227 
228             LinkUtil.addParameter(sb, PREVIEW_PARAMETER, Boolean.toString(isPreview));
229 
230             LinkUtil.addParameter(sb, CHANNEL_PARAMETER, platformType.getId());
231 
232             if (StringUtils.isNotEmpty(version)) {
233                 LinkUtil.addParameter(sb, VERSION_PARAMETER, version);
234             }
235             uri = sb.toString();
236 
237         } catch (RepositoryException e) {
238             log.error("Could not get page node from location object.", e);
239         }
240         return uri;
241     }
242 }