View Javadoc
1   /*
2    * Copyright (C) 2003-2009 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.wiki.webui;
18  
19  import java.util.HashMap;
20  import java.util.ResourceBundle;
21  
22  import javax.portlet.PortletMode;
23  import javax.portlet.PortletPreferences;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.exoplatform.container.ExoContainerContext;
27  import org.exoplatform.services.security.ConversationState;
28  import org.exoplatform.webui.application.WebuiApplication;
29  import org.exoplatform.webui.application.WebuiRequestContext;
30  import org.exoplatform.webui.application.portlet.PortletRequestContext;
31  import org.exoplatform.webui.config.annotation.ComponentConfig;
32  import org.exoplatform.webui.config.annotation.EventConfig;
33  import org.exoplatform.webui.core.UIComponent;
34  import org.exoplatform.webui.core.UIPopupContainer;
35  import org.exoplatform.webui.core.UIPopupWindow;
36  import org.exoplatform.webui.core.UIPortletApplication;
37  import org.exoplatform.webui.core.lifecycle.UIApplicationLifecycle;
38  import org.exoplatform.webui.event.Event;
39  import org.exoplatform.webui.event.EventListener;
40  import org.exoplatform.wiki.WikiPortletPreference;
41  import org.exoplatform.wiki.commons.Utils;
42  import org.exoplatform.wiki.commons.WikiConstants;
43  import org.exoplatform.wiki.mow.api.Page;
44  import org.exoplatform.wiki.mow.api.Wiki;
45  import org.exoplatform.wiki.resolver.TitleResolver;
46  import org.exoplatform.wiki.mow.api.PermissionType;
47  import org.exoplatform.wiki.service.WikiContext;
48  import org.exoplatform.wiki.service.WikiPageParams;
49  import org.exoplatform.wiki.service.WikiService;
50  import org.exoplatform.wiki.tree.utils.TreeUtils;
51  import org.exoplatform.wiki.webui.UIWikiPermissionForm.Scope;
52  import org.exoplatform.wiki.webui.control.UIAttachmentContainer;
53  import org.exoplatform.wiki.webui.control.action.AddPageActionComponent;
54  
55  @ComponentConfig(
56    lifecycle = UIApplicationLifecycle.class,
57    template = "app:/templates/wiki/webui/UIWikiPortlet.gtmpl",
58    events = {
59      @EventConfig(listeners = UIWikiPortlet.ViewPageActionListener.class),
60      @EventConfig(listeners = UIWikiPortlet.ChangeModeActionListener.class),
61      @EventConfig(listeners = UIWikiPortlet.RedirectActionListener.class)
62    }
63  )
64  public class UIWikiPortlet extends UIPortletApplication {
65    
66    private WikiMode              mode                       = WikiMode.VIEW;
67  
68    private EditMode              editmode                   = EditMode.ALL;
69    
70    private EditorMode editorMode_ = EditorMode.RICHTEXT;
71  
72    private String                sectionIndex               = "";
73  
74    private WikiMode              previousMode;
75  
76    private WikiPortletPreference portletPreferences         = new WikiPortletPreference();
77  
78    public static String          VIEW_PAGE_ACTION           = "ViewPage";
79  
80    public static String          CHANGE_MODE_ACTION         = "ChangeMode";
81  
82    public static String          REDIRECT_ACTION            = "Redirect";
83  
84    public static String          WIKI_PORTLET_ACTION_PREFIX = "UIWikiPortlet_";
85  
86    private String                redirectURL                = "";
87    
88    private ResourceBundle resourceBundle;
89  
90    private WikiService wikiService;
91  
92    private PortletMode portletMode;
93  
94    public static enum PopupLevel {
95      L1,
96      L2
97    }
98  
99    
100   public UIWikiPortlet() throws Exception {
101     super();
102     try {
103       wikiService = ExoContainerContext.getCurrentContainer().getComponentInstanceOfType(WikiService.class);
104       addChild(UIWikiEmptyAjaxBlock.class, null, null);
105       addChild(UIWikiPortletPreferences.class, null, null);
106       addChild(UIWikiUpperArea.class, null, null);
107       addChild(UIWikiMiddleArea.class, null, null);
108       addChild(UIWikiMaskWorkspace.class, null, "UIWikiMaskWorkspace");
109       UIPopupContainer uiPopupContainer = addChild(UIPopupContainer.class, null, "UIWikiPopupContainer" + PopupLevel.L1);
110       uiPopupContainer.getChild(UIPopupWindow.class).setId("UIWikiPopupWindow" + PopupLevel.L1);
111       uiPopupContainer = uiPopupContainer.addChild(UIPopupContainer.class, null, "UIWikiPopupContainer" + PopupLevel.L2);
112       uiPopupContainer.getChild(UIPopupWindow.class).setId("UIWikiPopupWindow" + PopupLevel.L2);
113       loadPreferences();
114     } catch (Exception e) {
115       log.error("An exception happens when init WikiPortlet", e);
116     }
117   }
118 
119   public WikiPortletPreference getPortletPreferences() {
120     return portletPreferences;
121   }
122 
123   public void setPortletPreferences(WikiPortletPreference portletPreferences) {
124     this.portletPreferences = portletPreferences;
125   }
126   
127   public ResourceBundle getResourceBundle() {
128     if (resourceBundle == null) {
129       WebuiRequestContext context = WebuiRequestContext.getCurrentInstance();
130       resourceBundle = context.getApplicationResourceBundle();
131     }
132     return resourceBundle;
133   }
134 
135   public void processRender(WebuiApplication app, WebuiRequestContext context) throws Exception {
136     PortletRequestContext portletReqContext = (PortletRequestContext) context;
137     redirectURL = this.url(this.REDIRECT_ACTION);
138     loadPreferences();
139     portletMode = portletReqContext.getApplicationMode();
140     if (portletMode == PortletMode.VIEW) {
141       if (mode.equals(WikiMode.PORTLETPREFERENCES)) {        
142         changeMode(WikiMode.VIEW);
143       }
144       getChild(UIWikiUpperArea.class).getChild(UIWikiApplicationControlArea.class)
145                                      .getChild(UIWikiBreadCrumb.class)
146                                      .setRendered(portletPreferences.isShowBreadcrumb());     
147       String requestURL = Utils.getCurrentRequestURL();
148 
149       WikiPageParams wikiPageParams = Utils.getCurrentWikiPageParams();
150       Wiki wiki = Utils.getCurrentWiki();
151       if(wiki == null) {
152         wiki = wikiService.createWiki(wikiPageParams.getType(), wikiPageParams.getOwner());
153       }
154 
155       if (!context.useAjax()) {
156         UIWikiPermissionForm wikiPermissionForm = this.findComponentById("UIWikiPagePermissionForm");
157         if (wikiPermissionForm != null) {
158           this.getPopupContainer(wikiPermissionForm.getPopupLevel()).deActivate();
159         }
160       }
161 
162       Page page = Utils.getCurrentWikiPage();
163       
164       if (page == null) {
165         changeMode(WikiMode.PAGE_NOT_FOUND);
166         super.processRender(app, context);
167         return;
168       } else {
169         if (mode.equals(WikiMode.PAGE_NOT_FOUND)) {
170           changeMode(WikiMode.VIEW);
171         }
172 
173         if((WikiMode.EDITPAGE.equals(this.getWikiMode()) || WikiMode.ADDPAGE.equals(this.getWikiMode()))
174                 && !wikiService.hasPermissionOnPage(page, PermissionType.EDITPAGE, ConversationState.getCurrent().getIdentity())) {
175           changeMode(WikiMode.VIEW);
176         }
177       }
178       
179       // Check if page url is null then create url for it
180       if (StringUtils.isEmpty(page.getUrl())) {
181         page.setUrl(Utils.getURLFromParams(new WikiPageParams(wiki.getType(), wiki.getOwner(), page.getName())));
182       }
183       
184       if (WikiContext.ADDPAGE.equalsIgnoreCase(wikiPageParams.getParameter(WikiContext.ACTION))) {
185         AddPageActionComponent addPageComponent = this.findFirstComponentOfType(AddPageActionComponent.class);
186         if (addPageComponent != null) {
187           Event<UIComponent> xEvent = addPageComponent.createEvent(AddPageActionComponent.ACTION, Event.Phase.PROCESS, context);
188           if (xEvent != null) {
189             xEvent.broadcast();
190           }
191         }
192       }else if (org.exoplatform.wiki.utils.Utils.COMPARE_REVISION.equalsIgnoreCase(wikiPageParams.getParameter(WikiContext.ACTION))) {
193         //UIWikiPageInfoArea.COMPARE_REVISION
194         UIWikiPageInfoArea pageInfoArea = this.findFirstComponentOfType(UIWikiPageInfoArea.class);
195         if (pageInfoArea != null) {
196           Event<UIComponent> xEvent = pageInfoArea.createEvent(org.exoplatform.wiki.utils.Utils.COMPARE_REVISION, Event.Phase.PROCESS, context);
197           if (xEvent != null) {
198             xEvent.broadcast();
199           }
200         }
201       }
202       try {
203         // TODO: ignore request URL of resources
204         context.setAttribute("wikiPage", page);
205         ((UIWikiPageTitleControlArea) findComponentById(UIWikiPageControlArea.TITLE_CONTROL)).getUIFormInputInfo()
206                                                                                              .setValue(page.getTitle());      
207       } catch (Exception e) {
208         context.setAttribute("wikiPage", null);
209         UIWikiPageContentArea wikiPageContentArea = findFirstComponentOfType(UIWikiPageContentArea.class);
210         if (wikiPageContentArea != null) {
211           UIWikiContentDisplay contentDisplay = wikiPageContentArea.getChildById(UIWikiPageContentArea.VIEW_DISPLAY);
212           contentDisplay.setHtmlOutput(("Exceptions occur when rendering content!"));
213         }
214         if (log.isWarnEnabled()) {
215           log.warn("An exception happens when resolving URL: " + requestURL, e);
216         }
217       }
218 
219       // Check to close wikiPagePermissionForm
220       if (!WikiMode.VIEW.equals(this.getWikiMode())) {
221         UIWikiPermissionForm wikiPermissionForm = this.findComponentById("UIWikiPagePermissionForm");
222         if (wikiPermissionForm != null && Scope.PAGE.equals(wikiPermissionForm.getScope())) {
223           this.getPopupContainer(wikiPermissionForm.getPopupLevel()).deActivate();
224         }
225       }
226       
227       super.processRender(app, context);
228 
229       if (getWikiMode() == WikiMode.HELP) {
230         changeMode(previousMode);
231       }
232     } else if (portletMode == PortletMode.EDIT) {
233       changeMode(WikiMode.PORTLETPREFERENCES);
234       super.processRender(app, context);
235     } else {
236       super.processRender(app, context);
237     }
238   }
239   
240   public UIPopupContainer getPopupContainer(PopupLevel level) {
241     UIPopupContainer popupContainer = getChildById("UIWikiPopupContainer" + PopupLevel.L1);
242     if (level == PopupLevel.L2) {
243       popupContainer = popupContainer.getChildById("UIWikiPopupContainer" + PopupLevel.L2);
244     }
245     return popupContainer;
246   }
247   
248   public WikiMode getWikiMode() {
249     return mode;
250   }
251   
252   public EditMode getEditMode() {
253     return editmode;
254   }
255   
256   /**
257    * gets the mode of wiki editor
258    * @return the editor mode
259    */
260   public EditorMode getEditorMode() {
261     return editorMode_;
262   }
263   
264   public String getSectionIndex() {
265     return sectionIndex;
266   }
267 
268   public void setSectionIndex(String sectionIndex) {
269     this.sectionIndex = sectionIndex;
270   }
271 
272   public String getRedirectURL() {
273     return redirectURL;
274   }
275 
276   public void setRedirectURL(String redirectURL) {
277     this.redirectURL = redirectURL;
278   }
279 
280   public void changeMode(WikiMode newMode) {
281     if (newMode== WikiMode.HELP)
282         this.previousMode = mode;
283     if (newMode.equals(WikiMode.VIEW)) {
284       findFirstComponentOfType(UIWikiPageTitleControlArea.class).toInfoMode();
285       UIWikiBottomArea bottomArea = findFirstComponentOfType(UIWikiBottomArea.class).setRendered(true);
286       bottomArea.getChild(UIAttachmentContainer.class).setRendered(false);
287       bottomArea.getChild(UIWikiPageVersionsList.class).setRendered(false);
288     }
289     if (newMode.equals(WikiMode.EDITPAGE)||newMode.equals(WikiMode.ADDPAGE)) {
290       findFirstComponentOfType(UIAttachmentContainer.class).setRendered(true);
291       
292       findFirstComponentOfType(UIWikiSidePanelArea.class).setRendered(EditorMode.SOURCE.equals(editorMode_));
293       findFirstComponentOfType(UIWikiBottomArea.class).setRendered(EditorMode.SOURCE.equals(editorMode_));
294       findFirstComponentOfType(UIWikiPageEditForm.class).getUIFormTextAreaInput(UIWikiPageEditForm.FIELD_CONTENT)
295                                                         .setRendered(EditorMode.SOURCE.equals(editorMode_));
296       findFirstComponentOfType(UIWikiRichTextArea.class).setRendered(EditorMode.RICHTEXT.equals(editorMode_));
297     }
298     mode = newMode;
299   }
300   
301   public void changeEditMode(EditMode newEditMode) {
302     editmode = newEditMode;
303   }
304   
305   /**
306    * changes the mode of wiki editor
307    * @param newMode the new mode
308    */
309   public void changeEditorMode(EditorMode newMode) {
310     editorMode_ = newMode;
311   }
312 
313   private void loadPreferences() {
314     PortletRequestContext pcontext = (PortletRequestContext) WebuiRequestContext.getCurrentInstance();
315     PortletPreferences portletPref = pcontext.getRequest().getPreferences();
316     try {
317       portletPreferences.setShowBreadcrumb(Boolean.parseBoolean(portletPref.getValue(WikiPortletPreference.SHOW_BREADCRUMB, "true")));
318       portletPreferences.setShowNavigationTree(Boolean.parseBoolean(portletPref.getValue(WikiPortletPreference.SHOW_NAVIGATIONTREE, "true")));
319     } catch (Exception e) {
320       log.error("Fail to load wiki portlet's preference: ", e);
321     }
322   }
323   
324   public HashMap<String, Object> getUIExtContext() throws Exception {
325     HashMap<String, Object> context = new HashMap<String, Object>();
326     WikiPageParams params = Utils.getCurrentWikiPageParams();
327     context.put(WikiConstants.WIKI_MODE, this.mode);
328     context.put(WikiConstants.CURRENT_PAGE, params.getPageName());
329     context.put(WikiConstants.CURRENT_WIKI_OWNER, params.getOwner());
330     context.put(WikiConstants.CURRENT_WIKI_TYPE, params.getType());
331     UIWikiPageArea wikiPageArea = this.findFirstComponentOfType(UIWikiPageArea.class);
332     UIWikiPageEditForm wikiPageEditForm = wikiPageArea.findFirstComponentOfType(UIWikiPageEditForm.class);
333     UIWikiRichTextArea wikiRichTextArea = wikiPageEditForm.findFirstComponentOfType(UIWikiRichTextArea.class);
334     context.put(WikiConstants.IS_MARKUP, Boolean.valueOf(!wikiRichTextArea.isRendered()));
335     return context;
336   }
337   
338   protected boolean isKeepSessionAlive() {
339     return (this.mode == WikiMode.EDITPAGE) || (this.mode == WikiMode.EDITTEMPLATE) 
340       || (this.mode == WikiMode.ADDPAGE) || (this.mode == WikiMode.ADDTEMPLATE);
341   }
342  
343   public static class ViewPageActionListener extends EventListener<UIWikiPortlet> {
344     @Override
345     public void execute(Event<UIWikiPortlet> event) throws Exception {
346       UIWikiPortlet wikiPortlet = event.getSource();
347       WikiMode currentMode = wikiPortlet.getWikiMode();
348       if (currentMode.equals(WikiMode.VIEW)) {
349         event.getRequestContext()
350              .addUIComponentToUpdateByAjax(wikiPortlet.findFirstComponentOfType(UIWikiEmptyAjaxBlock.class));
351       } else {
352         event.getSource().changeMode(WikiMode.VIEW);
353       }
354 
355     }
356   }
357   
358   public static class ChangeModeActionListener extends EventListener<UIWikiPortlet> {
359     @Override
360     public void execute(Event<UIWikiPortlet> event) throws Exception {
361       UIWikiPortlet wikiPortlet = event.getSource();
362       String mode = event.getRequestContext().getRequestParameter("mode");
363       String currentModeName = (mode.equals("")) ? WikiMode.VIEW.toString() : mode;
364       WikiMode currentMode = Utils.getModeFromAction(currentModeName);
365       if (!wikiPortlet.mode.equals(currentMode)) {
366         if (currentMode == null)
367           currentMode = WikiMode.VIEW;
368         event.getSource().changeMode(currentMode);
369       }
370       event.getRequestContext()
371            .addUIComponentToUpdateByAjax(wikiPortlet.findFirstComponentOfType(UIWikiEmptyAjaxBlock.class));
372     }
373   }
374   
375   public static class RedirectActionListener extends EventListener<UIWikiPortlet> {
376     @Override
377     public void execute(Event<UIWikiPortlet> event) throws Exception {      
378       String value = event.getRequestContext().getRequestParameter(OBJECTID);
379       value = TitleResolver.getId(value, false);
380       WikiPageParams params = TreeUtils.getPageParamsFromPath(value);
381       Utils.redirect(params, WikiMode.VIEW);
382     }
383   }
384   
385 }