View Javadoc
1   /*
2    * Copyright (C) 2003-2007 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.ecm.webui.component.explorer.control ;
18  
19  import java.util.Collection;
20  import java.util.Collections;
21  import java.util.List;
22  import java.util.regex.Matcher;
23  import java.util.regex.Pattern;
24  
25  import javax.jcr.AccessDeniedException;
26  import javax.jcr.Node;
27  import javax.jcr.RepositoryException;
28  import javax.jcr.Session;
29  import javax.jcr.query.InvalidQueryException;
30  import javax.jcr.query.Query;
31  
32  import org.apache.commons.lang.StringUtils;
33  import org.exoplatform.ecm.jcr.SimpleSearchValidator;
34  import org.exoplatform.ecm.utils.text.Text;
35  import org.exoplatform.ecm.webui.component.explorer.UIDocumentContainer;
36  import org.exoplatform.ecm.webui.component.explorer.UIDocumentInfo;
37  import org.exoplatform.ecm.webui.component.explorer.UIDocumentWorkspace;
38  import org.exoplatform.ecm.webui.component.explorer.UIDrivesArea;
39  import org.exoplatform.ecm.webui.component.explorer.UIJCRExplorer;
40  import org.exoplatform.ecm.webui.component.explorer.UIJCRExplorer.HistoryEntry;
41  import org.exoplatform.ecm.webui.component.explorer.UIWorkingArea;
42  import org.exoplatform.ecm.webui.component.explorer.search.UISearchResult;
43  import org.exoplatform.ecm.webui.component.explorer.sidebar.UISideBar;
44  import org.exoplatform.services.cms.link.LinkUtils;
45  import org.exoplatform.services.jcr.core.ManageableRepository;
46  import org.exoplatform.services.jcr.ext.common.SessionProvider;
47  import org.exoplatform.services.security.ConversationState;
48  import org.exoplatform.services.security.IdentityConstants;
49  import org.exoplatform.web.application.ApplicationMessage;
50  import org.exoplatform.webui.config.annotation.ComponentConfig;
51  import org.exoplatform.webui.config.annotation.EventConfig;
52  import org.exoplatform.webui.core.UIApplication;
53  import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
54  import org.exoplatform.webui.event.Event;
55  import org.exoplatform.webui.event.Event.Phase;
56  import org.exoplatform.webui.event.EventListener;
57  import org.exoplatform.webui.form.UIForm;
58  import org.exoplatform.webui.form.UIFormHiddenInput;
59  import org.exoplatform.webui.form.UIFormStringInput;
60  
61  /**
62   * Created by The eXo Platform SARL
63   * Author : Tran The Trong
64   *          trongtt@exoplatform.com
65   * Aug 2, 2006
66   */
67  @ComponentConfig(
68      lifecycle = UIFormLifecycle.class,
69      template =  "app:/groovy/webui/component/explorer/control/UIAddressBar.gtmpl",
70      events = {
71        @EventConfig(listeners = UIAddressBar.ChangeNodeActionListener.class, phase = Phase.DECODE),
72        @EventConfig(listeners = UIAddressBar.BackActionListener.class, phase = Phase.DECODE),
73        @EventConfig(listeners = UIAddressBar.HistoryActionListener.class, phase = Phase.DECODE),
74        @EventConfig(listeners = UIAddressBar.ChangeViewActionListener.class, phase = Phase.DECODE),
75        @EventConfig(listeners = UIAddressBar.SimpleSearchActionListener.class),
76        @EventConfig(listeners = UIAddressBar.RefreshSessionActionListener.class, phase = Phase.DECODE)
77      }
78  )
79  
80  public class UIAddressBar extends UIForm {
81  
82    public static final Pattern FILE_EXPLORER_URL_SYNTAX = Pattern.compile("([^:/]+):(.*)");
83  
84    public final static String  WS_NAME                  = "workspaceName";
85  
86    public final static String  FIELD_ADDRESS            = "address";
87  
88    public final static String  FIELD_ADDRESS_HIDDEN     = "address_hidden";
89  
90    public final static String  ACTION_TAXONOMY          = "exo:taxonomyAction";
91  
92    public final static String  EXO_TARGETPATH           = "exo:targetPath";
93  
94    public final static String  EXO_TARGETWORKSPACE      = "exo:targetWorkspace";
95  
96    private String              selectedViewName_;
97  
98    private String[]            arrView_                 = {};
99  
100   /** The Constant MESSAGE_NOT_SUPPORT_KEYWORD. */
101   private final static String MESSAGE_NOT_SUPPORT_KEYWORD = "UIAddressBar.msg.keyword-not-support";
102   final static private String FIELD_SIMPLE_SEARCH      = "simpleSearch";
103 
104   final static private  String ROOT_SQL_QUERY  = "select * from nt:base where (not jcr:primaryType like 'nt:resource') AND" +
105                                "((jcr:primaryType like 'exo:symlink' or jcr:primaryType like 'exo:taxonomyLink')" +
106                                " OR ( contains(*, '$1') or lower(exo:name) like '%$2%' or lower(exo:summary) like '%$3%' or lower(exo:commentContent) like '%$4%')) order by exo:title ASC";
107   final static private String SQL_QUERY = "select * from nt:base where (not jcr:primaryType like 'nt:resource') AND jcr:path like '$0/%' AND " +
108                                "( (jcr:primaryType like 'exo:symlink' or jcr:primaryType like 'exo:taxonomyLink')" +
109                                " OR ( contains(*, '$1') or lower(exo:name) like '%$2%' or lower(exo:summary) like '%$3%' or lower(exo:commentContent) like '%$4%')) order by exo:title ASC";
110 
111   public UIAddressBar() throws Exception {
112     addUIFormInput(new UIFormStringInput(FIELD_ADDRESS, FIELD_ADDRESS, null));
113     addUIFormInput(new UIFormStringInput(FIELD_SIMPLE_SEARCH,
114                                          FIELD_SIMPLE_SEARCH,
115                                          null).addValidator(SimpleSearchValidator.class));
116     addUIFormInput(new UIFormHiddenInput(FIELD_ADDRESS_HIDDEN, FIELD_ADDRESS_HIDDEN, null));
117   }
118 
119   public void setViewList(List<String> viewList) {
120     Collections.sort(viewList);
121     arrView_ = viewList.toArray(new String[viewList.size()]);
122   }
123 
124   public String[] getViewList() { return arrView_; }
125 
126   public void setSelectedViewName(String viewName) { selectedViewName_ = viewName; }
127 
128   public boolean isSelectedView(String viewName) {
129     if(selectedViewName_ != null && selectedViewName_.equals(viewName)) return true;
130     return false;
131   }
132 
133   public String getSelectedViewName() { return selectedViewName_; }
134 
135   public Collection<HistoryEntry> getFullHistory() {
136     UIJCRExplorer uiJCRExplorer = getAncestorOfType(UIJCRExplorer.class) ;
137     return uiJCRExplorer.getHistory() ;
138   }
139 
140   static public class BackActionListener extends EventListener<UIAddressBar> {
141     public void execute(Event<UIAddressBar> event) throws Exception {
142       UIAddressBar uiAddressBar = event.getSource() ;
143       UIJCRExplorer uiExplorer = uiAddressBar.getAncestorOfType(UIJCRExplorer.class) ;
144       UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class) ;
145       try {
146         UIWorkingArea uiWorkingArea = uiExplorer.getChild(UIWorkingArea.class);
147         UIDocumentWorkspace uiDocumentWorkspace = uiWorkingArea.getChild(UIDocumentWorkspace.class);
148 
149         if(!uiDocumentWorkspace.isRendered()) {
150           uiWorkingArea.getChild(UIDrivesArea.class).setRendered(false);
151           uiWorkingArea.getChild(UIDocumentWorkspace.class).setRendered(true);
152           uiDocumentWorkspace.setRenderedChild(UIDocumentContainer.class) ;
153         }
154         if(uiExplorer.isViewTag() && !uiExplorer.getCurrentNode().equals(uiExplorer.getRootNode())) {
155           uiExplorer.setSelectRootNode() ;
156           uiExplorer.setIsViewTag(true) ;
157         } else if(uiExplorer.isViewTag() && uiExplorer.getCurrentStateNode() != null) {
158           uiExplorer.setIsViewTag(false) ;
159           uiExplorer.setSelectNode(uiExplorer.getCurrentStatePath()) ;
160         } else {
161           String previousNodePath = uiExplorer.rewind() ;
162           String previousWs = uiExplorer.previousWsName();
163           uiExplorer.setBackNodePath(previousWs, previousNodePath);
164           if (uiExplorer.hasPaginator(previousNodePath, previousWs)) {
165             event.getRequestContext().addUIComponentToUpdateByAjax(uiExplorer);
166             return;
167           }
168         }
169         uiExplorer.updateAjax(event) ;
170       } catch (AccessDeniedException ade) {
171         uiApp.addMessage(new ApplicationMessage("UIAddressBar.msg.access-denied", null,
172                                                 ApplicationMessage.WARNING)) ;
173 
174         return ;
175       } catch (Exception e) {
176         uiApp.addMessage(new ApplicationMessage("UIJCRExplorer.msg.no-node-history",
177                                                 null, ApplicationMessage.WARNING)) ;
178 
179         return ;
180       }
181     }
182   }
183 
184   static public class ChangeNodeActionListener extends EventListener<UIAddressBar> {
185     public void execute(Event<UIAddressBar> event) throws Exception {
186       UIAddressBar uiAddress = event.getSource() ;
187       String path = Text.escapeIllegalJcrChars(uiAddress.getUIStringInput(FIELD_ADDRESS).getValue());
188       ((UIFormHiddenInput)uiAddress.getChildById(FIELD_ADDRESS_HIDDEN)).setValue(path);
189       if (path == null || path.trim().length() == 0) path = "/";
190       UIJCRExplorer uiExplorer = uiAddress.getAncestorOfType(UIJCRExplorer.class) ;
191       uiExplorer.setIsViewTag(false) ;
192       try {
193         String prefix = uiExplorer.getRootPath();
194         String nodePath = LinkUtils.evaluatePath(LinkUtils.createPath(prefix, path));
195         if (!nodePath.startsWith(prefix)) {
196           nodePath = prefix;
197         }
198         uiExplorer.setSelectNode(nodePath) ;
199         uiExplorer.setCurrentStatePath(nodePath) ;
200         UIWorkingArea uiWorkingArea = uiExplorer.getChild(UIWorkingArea.class);
201         UIDocumentWorkspace uiDocumentWorkspace = uiWorkingArea.getChild(UIDocumentWorkspace.class);
202         if(!uiDocumentWorkspace.isRendered()) {
203           uiDocumentWorkspace.setRendered(true);
204         } else {
205           uiDocumentWorkspace.setRenderedChild(UIDocumentContainer.class);
206         }
207       } catch(Exception e) {
208         UIApplication uiApp = uiAddress.getAncestorOfType(UIApplication.class) ;
209         uiApp.addMessage(new ApplicationMessage("UIAddressBar.msg.path-not-found", null,
210                                                 ApplicationMessage.WARNING)) ;
211 
212         return ;
213       }
214       uiExplorer.updateAjax(event) ;
215     }
216   }
217 
218   static public class HistoryActionListener extends EventListener<UIAddressBar> {
219     public void execute(Event<UIAddressBar> event) throws Exception {
220       UIAddressBar uiAddressBar = event.getSource() ;
221       String fullPath = event.getRequestContext().getRequestParameter(OBJECTID) ;
222       UIJCRExplorer uiExplorer = uiAddressBar.getAncestorOfType(UIJCRExplorer.class) ;
223       String workspace = null;
224       String path = null;
225       try{
226         Matcher matcher = FILE_EXPLORER_URL_SYNTAX.matcher(fullPath);
227         if (matcher.find()) {
228           workspace = matcher.group(1);
229           path = matcher.group(2);
230         }
231         uiExplorer.setSelectNode(workspace, path) ;
232         uiExplorer.refreshExplorer() ;
233       } catch (AccessDeniedException ade) {
234         UIApplication uiApp = uiAddressBar.getAncestorOfType(UIApplication.class) ;
235         uiApp.addMessage(new ApplicationMessage("UIAddressBar.msg.access-denied", null,
236                                                 ApplicationMessage.WARNING)) ;
237 
238         return ;
239       }
240     }
241   }
242 
243   static public class ChangeViewActionListener extends EventListener<UIAddressBar> {
244     public void execute(Event<UIAddressBar> event) throws Exception {
245       UIAddressBar uiAddressBar = event.getSource() ;
246       UIJCRExplorer uiExplorer = uiAddressBar.getAncestorOfType(UIJCRExplorer.class);
247       UIWorkingArea uiWorkingArea = uiExplorer.getChild(UIWorkingArea.class);
248       UIDocumentWorkspace uiDocumentWorkspace = uiWorkingArea.getChild(UIDocumentWorkspace.class);
249       if(!uiDocumentWorkspace.isRendered()) {
250         uiWorkingArea.getChild(UIDrivesArea.class).setRendered(false);
251         uiWorkingArea.getChild(UIDocumentWorkspace.class).setRendered(true);
252       }
253       String viewName = event.getRequestContext().getRequestParameter(OBJECTID);
254       uiAddressBar.setSelectedViewName(viewName);
255       UIActionBar uiActionBar = uiWorkingArea.getChild(UIActionBar.class);
256       uiActionBar.setTabOptions(viewName) ;
257       uiWorkingArea.getChild(UISideBar.class).initComponents();
258       uiExplorer.findFirstComponentOfType(UIDocumentInfo.class).getExpandedFolders().clear();
259       uiExplorer.updateAjax(event);
260     }
261   }
262 
263   static public class SimpleSearchActionListener extends EventListener<UIAddressBar> {
264     public void execute(Event<UIAddressBar> event) throws Exception {
265       UIAddressBar uiAddressBar = event.getSource();
266       UIApplication uiApp = uiAddressBar.getAncestorOfType(UIApplication.class);
267       UIJCRExplorer uiExplorer = uiAddressBar.getAncestorOfType(UIJCRExplorer.class);
268       String text = uiAddressBar.getUIStringInput(FIELD_SIMPLE_SEARCH).getValue();
269       Node currentNode = uiExplorer.getCurrentNode();
270       String queryStatement = null;
271       if("/".equals(currentNode.getPath())) {
272         queryStatement = ROOT_SQL_QUERY;
273       }else {
274         queryStatement = StringUtils.replace(SQL_QUERY,"$0",currentNode.getPath());
275       }
276       String escapedText = org.exoplatform.services.cms.impl.Utils.escapeIllegalCharacterInQuery(text);
277       queryStatement = StringUtils.replace(queryStatement,"$1", escapedText);
278       queryStatement = StringUtils.replace(queryStatement,"$2", escapedText.toLowerCase());
279       queryStatement = StringUtils.replace(queryStatement,"$3", escapedText.toLowerCase());
280       queryStatement = StringUtils.replace(queryStatement,"$4", escapedText.toLowerCase());
281       uiExplorer.removeChildById("ViewSearch");
282       UIWorkingArea uiWorkingArea = uiExplorer.getChild(UIWorkingArea.class);
283       UIDocumentWorkspace uiDocumentWorkspace = uiWorkingArea.getChild(UIDocumentWorkspace.class);
284       if(!uiDocumentWorkspace.isRendered()) {
285         uiWorkingArea.getChild(UIDrivesArea.class).setRendered(false);
286         uiWorkingArea.getChild(UIDocumentWorkspace.class).setRendered(true);
287       }
288       SessionProvider sessionProvider = new SessionProvider(ConversationState.getCurrent());
289       Session session = sessionProvider.getSession(currentNode.getSession().getWorkspace().getName(),
290           (ManageableRepository)currentNode.getSession().getRepository());
291       UISearchResult uiSearchResult = uiDocumentWorkspace.getChildById(UIDocumentWorkspace.SIMPLE_SEARCH_RESULT);
292       long startTime = System.currentTimeMillis();
293       uiSearchResult.setQuery(queryStatement, session.getWorkspace().getName(), Query.SQL,
294                               IdentityConstants.SYSTEM.equals(session.getUserID()), text);
295       try {
296         uiSearchResult.updateGrid();
297       } catch (InvalidQueryException invalidEx) {
298         uiApp.addMessage(new ApplicationMessage(MESSAGE_NOT_SUPPORT_KEYWORD, null, ApplicationMessage.WARNING));
299         return;
300       } catch (RepositoryException reEx) {
301         uiApp.addMessage(new ApplicationMessage(MESSAGE_NOT_SUPPORT_KEYWORD, null, ApplicationMessage.WARNING));
302         return;
303       }
304       long time = System.currentTimeMillis() - startTime;
305       uiSearchResult.setSearchTime(time);
306 
307       uiDocumentWorkspace.setRenderedChild(UISearchResult.class);
308       if(!uiDocumentWorkspace.isRendered()) {
309         event.getRequestContext().addUIComponentToUpdateByAjax(uiDocumentWorkspace);
310       }
311     }
312   }
313 
314   static public class RefreshSessionActionListener extends EventListener<UIAddressBar> {
315     public void execute(Event<UIAddressBar> event) throws Exception {
316       UIJCRExplorer uiJCRExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class) ;
317       uiJCRExplorer.getSession().refresh(false) ;
318       uiJCRExplorer.refreshExplorer() ;
319       UIWorkingArea uiWorkingArea = uiJCRExplorer.getChild(UIWorkingArea.class);
320       UIActionBar uiActionBar = uiWorkingArea.getChild(UIActionBar.class);
321       uiActionBar.setTabOptions(event.getSource().getSelectedViewName()) ;
322       UIApplication uiApp = uiJCRExplorer.getAncestorOfType(UIApplication.class) ;
323       String mess = "UIJCRExplorer.msg.refresh-session-success" ;
324       uiApp.addMessage(new ApplicationMessage(mess, null, ApplicationMessage.INFO)) ;
325     }
326   }
327   
328   public static String UppercaseFirstLetters(String str) 
329   {
330     boolean prevWasWhiteSp = true;
331     char[] chars = str.toCharArray();
332     for (int i = 0; i < chars.length; i++) {
333       if (Character.isLetter(chars[i])) {
334         if (prevWasWhiteSp) {
335           chars[i] = Character.toUpperCase(chars[i]);    
336         }
337         prevWasWhiteSp = false;
338       } else {
339         prevWasWhiteSp = Character.isWhitespace(chars[i]);
340       }
341     }
342     return new String(chars);
343   }
344 
345 }