View Javadoc
1   /*
2    * Copyright (C) 2003-2008 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.wcm.webui.scv;
18  
19  import org.apache.commons.lang.StringUtils;
20  import org.exoplatform.ecm.utils.lock.LockUtil;
21  import org.exoplatform.portal.application.PortalRequestContext;
22  import org.exoplatform.portal.mop.SiteType;
23  import org.exoplatform.portal.webui.application.UIPortlet;
24  import org.exoplatform.portal.webui.util.Util;
25  import org.exoplatform.services.cms.templates.TemplateService;
26  import org.exoplatform.services.ecm.publication.PublicationService;
27  import org.exoplatform.services.jcr.core.ManageableRepository;
28  import org.exoplatform.services.jcr.util.Text;
29  import org.exoplatform.services.log.ExoLogger;
30  import org.exoplatform.services.log.Log;
31  import org.exoplatform.services.wcm.publication.WCMComposer;
32  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
33  import org.exoplatform.wcm.webui.Utils;
34  import org.exoplatform.wcm.webui.reader.ContentReader;
35  import org.exoplatform.web.url.navigation.NavigationResource;
36  import org.exoplatform.web.url.navigation.NodeURL;
37  import org.exoplatform.webui.application.WebuiRequestContext;
38  import org.exoplatform.webui.application.portlet.PortletRequestContext;
39  import org.exoplatform.webui.config.annotation.ComponentConfig;
40  import org.exoplatform.webui.config.annotation.EventConfig;
41  import org.exoplatform.webui.core.UIContainer;
42  import org.exoplatform.webui.core.lifecycle.Lifecycle;
43  import org.exoplatform.webui.event.Event;
44  import org.exoplatform.webui.event.EventListener;
45  
46  import javax.jcr.Node;
47  import javax.jcr.RepositoryException;
48  import javax.jcr.ValueFormatException;
49  import javax.portlet.PortletPreferences;
50  import java.io.UnsupportedEncodingException;
51  import java.net.URLDecoder;
52  import java.text.SimpleDateFormat;
53  import java.util.*;
54  
55  /**
56   * Author : Do Ngoc Anh *
57   * Email: anh.do@exoplatform.com *
58   * May 14, 2008
59   */
60  @ComponentConfig(
61      lifecycle=Lifecycle.class,
62      template="app:/groovy/SingleContentViewer/UIPresentationContainer.gtmpl",
63      events = {
64          @EventConfig(listeners=UIPresentationContainer.PreferencesActionListener.class),
65          @EventConfig(listeners=UIPresentationContainer.FastPublishActionListener.class)
66      }
67  )
68  public class UIPresentationContainer extends UIContainer{
69    public final static String PARAMETER_REGX       = "(.*)/(.*)";
70    private static final Log         LOG            = ExoLogger.getLogger(UIPresentationContainer.class.getName());
71  
72    private boolean isPrint = false;
73    private PortletPreferences portletPreferences;
74    private String contentParameter = null;
75    /**
76     * Instantiates a new uI presentation container.
77     *
78     * @throws Exception the exception
79     */
80    public UIPresentationContainer() throws Exception{
81      PortletRequestContext portletRequestContext = WebuiRequestContext.getCurrentInstance();
82      addChild(UIPresentation.class, null, UIPresentation.class.getSimpleName() + portletRequestContext.getWindowId());
83  
84      portletPreferences = portletRequestContext.getRequest().getPreferences();
85    }
86  
87    /**
88     * Gets the bar info show.
89     *
90     * @return the value for info bar setting
91     *
92     * @throws Exception the exception
93     */
94    public boolean isShowInfoBar() throws Exception {
95      if (UIPortlet.getCurrentUIPortlet().getShowInfoBar())
96        return true;
97      return false;
98    }
99  
100   /**
101    * Gets the title.
102    *
103    * @param node the node
104    *
105    * @return the title
106    *
107    * @throws Exception the exception
108    */
109   public String getTitle(Node node) throws Exception {
110     String title = null;
111     if (node.hasProperty("exo:title")) {
112       title = node.getProperty("exo:title").getValue().getString().trim();
113     }
114     if (title == null || title.equals("")) {
115       if (node.hasNode("jcr:content")) {
116         Node content = node.getNode("jcr:content");
117         if (content.hasProperty("dc:title")) {
118           try {
119             title = content.getProperty("dc:title").getValues()[0].getString().trim();
120           } catch (ValueFormatException e) {
121             title = null;
122           }
123           catch (IllegalStateException e) {
124             title = null;
125           }
126           catch (RepositoryException e) {
127             title = null;
128           }
129         }
130       }
131     }
132     if (title == null || title.equals("")) {
133       title = Utils.getRealNode(node).getName();
134     }
135     return ContentReader.getXSSCompatibilityContent(title);
136   }
137 
138   public boolean isPrinting() {
139     return this.isPrint;
140   }
141 
142   public boolean isShowTitle() {
143     return Boolean.parseBoolean(portletPreferences.getValue(UISingleContentViewerPortlet.SHOW_TITLE, "false"));
144   }
145   public boolean isShowDate() {
146     return Boolean.parseBoolean(portletPreferences.getValue(UISingleContentViewerPortlet.SHOW_DATE, "false"));
147   }
148   public boolean isShowOptionBar() {
149     return Boolean.parseBoolean(portletPreferences.getValue(UISingleContentViewerPortlet.SHOW_OPTIONBAR, "false"));
150   }
151 
152   public boolean isContextual() {
153     return Boolean.parseBoolean(portletPreferences.getValue(UISingleContentViewerPortlet.CONTEXTUAL_MODE, "false"));
154   }
155 
156   public String getCurrentState() throws Exception {
157     UIPresentation presentation = getChild(UIPresentation.class);
158     Node node = presentation.getOriginalNode();
159     PublicationService publicationService = WCMCoreUtils.getService(PublicationService.class);
160     if(node == null || !publicationService.isNodeEnrolledInLifecycle(node)) return StringUtils.EMPTY;
161     return publicationService.getCurrentState(node);
162   }
163 
164   /**
165    * Gets the created date.
166    *
167    * @param node the node
168    *
169    * @return the created date
170    *
171    * @throws Exception the exception
172    */
173   public String getCreatedDate(Node node) throws Exception {
174     if (node.hasProperty("exo:dateCreated")) {
175       Calendar calendar = node.getProperty("exo:dateCreated").getValue().getDate();
176       return new SimpleDateFormat("dd.MM.yyyy '|' hh'h'mm").format(calendar.getTime());
177     }
178     return null;
179   }
180 
181   /**
182    * Gets the node.
183    *
184    * @return the node
185    */
186   public Node getNodeView() {
187     UIPresentation presentation = getChild(UIPresentation.class);
188     try {
189       Node viewNode;
190     //Check for the saved parameter
191     viewNode = getParameterizedNode();
192     if (viewNode!= null) {
193       if (viewNode.isNodeType("nt:frozenNode")) {
194             try {
195               String nodeUUID = viewNode.getProperty("jcr:frozenUuid").getString();
196               presentation.setOriginalNode(viewNode.getSession().getNodeByUUID(nodeUUID));
197               presentation.setNode(viewNode);
198             } catch (Exception ex) {
199               return viewNode;
200             }
201       }
202       return viewNode;
203     }
204     PortletRequestContext portletRequestContext = WebuiRequestContext.getCurrentInstance();
205     portletPreferences = portletRequestContext.getRequest().getPreferences();
206     String repository = portletPreferences.getValue(UISingleContentViewerPortlet.REPOSITORY, null);
207     String workspace = portletPreferences.getValue(UISingleContentViewerPortlet.WORKSPACE, null);
208     String nodeIdentifier = portletPreferences.getValue(UISingleContentViewerPortlet.IDENTIFIER, null);
209     String sharedCache = portletPreferences.getValue(UISingleContentViewerPortlet.ENABLE_CACHE, "true");
210     sharedCache = "true".equals(sharedCache) ? WCMComposer.VISIBILITY_PUBLIC:WCMComposer.VISIBILITY_USER;
211     viewNode = Utils.getRealNode(repository, workspace, nodeIdentifier, false, sharedCache);
212     if (viewNode!=null) {
213         boolean isDocumentType = false;
214         if (viewNode.isNodeType("nt:frozenNode")) isDocumentType = true;
215         // check node is a document node
216         TemplateService templateService = getApplicationComponent(TemplateService.class);
217         List<String> documentTypes = templateService.getDocumentTemplates();
218         for (String documentType : documentTypes) {
219           if (viewNode.isNodeType(documentType)) {
220             isDocumentType = true;
221             break;
222           }
223         }
224         if (!isDocumentType) return null;
225         if (viewNode != null && viewNode.isNodeType("nt:frozenNode")) {
226           String nodeUUID = viewNode.getProperty("jcr:frozenUuid").getString();
227           presentation.setOriginalNode(viewNode.getSession().getNodeByUUID(nodeUUID));
228           presentation.setNode(viewNode);
229         } else {
230           presentation.setOriginalNode(viewNode);
231           presentation.setNode(viewNode);
232         }
233     }
234       return viewNode;
235     } catch (Exception e) {
236       return null;
237     }
238   }
239   /**
240    * Gets the node.
241    *
242    * @return the node
243    *
244    * @throws Exception the exception
245    */
246   public Node getParameterizedNode() throws Exception {
247     PortletRequestContext portletRequestContext = WebuiRequestContext.getCurrentInstance();
248     PortletPreferences preferences = portletRequestContext.getRequest().getPreferences();
249     String sharedCache = preferences.getValue(UISingleContentViewerPortlet.ENABLE_CACHE, "false");
250     sharedCache = "true".equals(sharedCache) ? WCMComposer.VISIBILITY_PUBLIC:WCMComposer.VISIBILITY_USER;
251 
252     PortalRequestContext preq = Util.getPortalRequestContext();
253     if (!preq.useAjax()) {
254       contentParameter = getRequestParameters();
255     }
256 
257     if (contentParameter == null) return null;
258     UIPresentation presentation = getChild(UIPresentation.class);
259     Node nodeView = Utils.getViewableNodeByComposer(null, null, contentParameter, null, sharedCache);
260     if (nodeView!=null) {
261       boolean isDocumentType = false;
262       if (nodeView.isNodeType("nt:frozenNode")) isDocumentType = true;
263       // check node is a document node
264       if (!isDocumentType) {
265         TemplateService templateService = getApplicationComponent(TemplateService.class);
266         List<String> documentTypes = templateService.getDocumentTemplates();
267         for (String documentType : documentTypes) {
268           if (nodeView.isNodeType(documentType)) {
269             isDocumentType = true;
270             break;
271           }
272         }
273       }
274       if (!isDocumentType) return null;
275       if (nodeView != null && nodeView.isNodeType("nt:frozenNode")) {
276         String nodeUUID = nodeView.getProperty("jcr:frozenUuid").getString();
277         presentation.setOriginalNode(nodeView.getSession().getNodeByUUID(nodeUUID));
278         presentation.setNode(nodeView);
279       } else {
280         presentation.setOriginalNode(nodeView);
281         presentation.setNode(nodeView);
282       }
283       isPrint = Boolean.parseBoolean(Util.getPortalRequestContext().getRequestParameter("isPrint"));
284     }
285     return nodeView;
286   }
287 
288   /**
289    * Gets the request parameters.
290    *
291    * @return the request parameters
292    */
293   private String getRequestParameters() throws Exception {
294     String parameters = null;
295     if (!Boolean.parseBoolean(portletPreferences.getValue(UISingleContentViewerPortlet.CONTEXTUAL_MODE, "false"))) {
296       return null;
297     }
298     try {
299       parameters = URLDecoder.decode(StringUtils.substringAfter(Util.getPortalRequestContext()
300                                                                     .getNodePath(),
301                                                                 Util.getUIPortal()
302                                                                     .getSelectedUserNode()
303                                                                     .getURI()
304                                                                     + "/"), "UTF-8");
305     } catch (UnsupportedEncodingException e) {
306       return null;
307     }
308     String parameterName = portletPreferences.getValue(UISingleContentViewerPortlet.PARAMETER, "");
309     if (!parameters.matches(PARAMETER_REGX)) {
310       String path = Util.getPortalRequestContext().getRequestParameter(parameterName);
311       if (path == null){
312         return null;
313       }
314       parameters = Text.unescape(Util.getPortalRequestContext().getRequestParameter(parameterName));
315       return parameters.substring(1);
316     }
317     return Text.unescape(parameters);
318   }
319 
320   /**
321    * Get the print's page URL
322    *
323    * @return <code>true</code> if the Quick Print is shown. Otherwise, <code>false</code>
324    */
325   public String getPrintUrl(Node node) throws RepositoryException{
326     String printParameterName;
327     Node tempNode = node;
328     if (tempNode==null) {
329       tempNode = getNodeView();
330     }
331     String strPath = tempNode.getPath();
332     String repository = ((ManageableRepository)tempNode.getSession().getRepository()).getConfiguration().getName();
333     String workspace = tempNode.getSession().getWorkspace().getName();
334     String printPageUrl = portletPreferences.getValue(UISingleContentViewerPortlet.PRINT_PAGE, "");
335     printParameterName = portletPreferences.getValue(UISingleContentViewerPortlet.PRINT_PARAMETER, "");
336 
337     String paramName = "/" + repository + "/" + workspace + strPath;
338     NodeURL nodeURL = Util.getPortalRequestContext().createURL(NodeURL.TYPE);
339     NavigationResource resource = new NavigationResource(SiteType.PORTAL,
340                                                          Util.getPortalRequestContext()
341                                                              .getPortalOwner(), printPageUrl);
342     nodeURL.setResource(resource);
343     nodeURL.setQueryParameterValue(printParameterName, paramName);
344     nodeURL.setQueryParameterValue("isPrint", "true");
345     nodeURL.setQueryParameterValue("noadminbar", "true");
346     return nodeURL.toString();
347   }
348 
349   /**
350    * Get the quick edit url
351    *
352    * @param node
353    * @return
354    */
355   public String getQuickEditLink(Node node){
356     Node tempNode = node;
357     if (tempNode==null) {
358       tempNode = getNodeView();
359     }
360     return Utils.getEditLink(tempNode, true, false);
361   }
362 
363   public Node getOriginalNode() {
364     UIPresentation presentation = getChild(UIPresentation.class);
365     if (presentation == null)
366       return null;
367     try {
368       return presentation.getOriginalNode();
369     } catch (Exception e) {
370       return null;
371     }
372   }
373 
374   public boolean isViewMode() {
375     return Utils.getCurrentMode().equals(WCMComposer.MODE_LIVE);
376   }
377 
378   public String getInlineEditingMsg() {
379     StringBuffer sb = new StringBuffer();
380     sb.append("new Array(");
381     sb.append("'")
382       .append(Text.escapeIllegalJcrChars(getResourceBundle("UIPresentationContainer.msg.internal-server-error")))
383       .append("', '")
384       .append(Text.escapeIllegalJcrChars(getResourceBundle("UIPresentationContainer.msg.empty-title-error")))
385       .append("')");
386     return sb.toString();
387   }
388 
389   private String getResourceBundle(String key) {
390     try {
391       ResourceBundle rs = WebuiRequestContext.getCurrentInstance().getApplicationResourceBundle();
392       return rs.getString(key);
393     } catch(MissingResourceException e) {
394       return key;
395     }
396   }
397 
398 
399   /**
400    * The listener interface for receiving preferencesAction events.
401    * The class that is interested in processing a preferencesAction
402    * event implements this interface, and the object created
403    * with that class is registered with a component using the
404    * component's <code>addPreferencesActionListener</code> method. When
405    * the preferencesAction event occurs, that object's appropriate
406    * method is invoked.
407    */
408   public static class PreferencesActionListener extends EventListener<UIPresentationContainer>{
409     /* (non-Javadoc)
410      * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event)
411      */
412     public void execute(Event<UIPresentationContainer> event) throws Exception {
413       UIPresentationContainer presentationContainer = event.getSource();
414       UISCVPreferences pcvConfigForm = presentationContainer.createUIComponent(UISCVPreferences.class, null, null);
415       Utils.createPopupWindow(presentationContainer, pcvConfigForm, UISingleContentViewerPortlet.UIPreferencesPopupID, 600);
416     }
417   }
418 
419   public static class FastPublishActionListener extends EventListener<UIPresentationContainer> {
420 
421     /*
422      * (non-Javadoc)
423      * @see
424      * org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui
425      * .event.Event)
426      */
427     public void execute(Event<UIPresentationContainer> event) throws Exception {
428       UIPresentationContainer uiContainer = event.getSource();
429       PublicationService publicationService = WCMCoreUtils.getService(PublicationService.class);
430       Node node = uiContainer.getNodeView();
431       if (node.isLocked()) {
432         node.getSession().addLockToken(LockUtil.getLockToken(node));
433       }
434       HashMap<String, String> context = new HashMap<String, String>();
435       publicationService.changeState(node, "published", context);
436       event.getRequestContext().getJavascriptManager().getRequireJS().addScripts("location.reload(true);");
437     }
438 
439   }
440 
441   public String getInlineEditingField(Node orgNode, String propertyName, String defaultValue, String inputType,
442       String idGenerator, String cssClass, boolean isGenericProperty, String... arguments) throws Exception {
443     return org.exoplatform.ecm.webui.utils.Utils.getInlineEditingField(orgNode, propertyName, defaultValue,
444                                                         inputType, idGenerator, cssClass, isGenericProperty, arguments);
445   }
446   public String getInlineEditingField(Node orgNode, String propertyName) throws Exception{
447     return org.exoplatform.ecm.webui.utils.Utils.getInlineEditingField(orgNode, propertyName);
448   }
449 }