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   **************************************************************************/
18  package org.exoplatform.ecm.webui.component.explorer.rightclick.manager;
19  
20  import java.util.Arrays;
21  import java.util.List;
22  import java.util.regex.Matcher;
23  
24  import javax.jcr.AccessDeniedException;
25  import javax.jcr.Node;
26  import javax.jcr.PathNotFoundException;
27  import javax.jcr.Session;
28  import javax.jcr.lock.Lock;
29  import javax.jcr.lock.LockException;
30  
31  import org.exoplatform.ecm.webui.component.explorer.UIJCRExplorer;
32  import org.exoplatform.ecm.webui.component.explorer.UIWorkingArea;
33  import org.exoplatform.ecm.webui.component.explorer.control.filter.CanSetPropertyFilter;
34  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsCheckedOutFilter;
35  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotHoldsLockFilter;
36  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotInTrashFilter;
37  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotSimpleLockedFilter;
38  import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotTrashHomeNodeFilter;
39  import org.exoplatform.ecm.webui.component.explorer.control.listener.UIWorkingAreaActionListener;
40  import org.exoplatform.ecm.webui.utils.JCRExceptionManager;
41  import org.exoplatform.ecm.utils.lock.LockUtil;
42  import org.exoplatform.ecm.webui.utils.PermissionUtil;
43  import org.exoplatform.ecm.webui.utils.Utils;
44  import org.exoplatform.services.cms.lock.LockService;
45  import org.exoplatform.services.log.ExoLogger;
46  import org.exoplatform.services.log.Log;
47  import org.exoplatform.services.organization.MembershipType;
48  import org.exoplatform.services.organization.OrganizationService;
49  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
50  import org.exoplatform.web.application.ApplicationMessage;
51  import org.exoplatform.webui.config.annotation.ComponentConfig;
52  import org.exoplatform.webui.config.annotation.EventConfig;
53  import org.exoplatform.webui.core.UIApplication;
54  import org.exoplatform.webui.core.UIComponent;
55  import org.exoplatform.webui.event.Event;
56  import org.exoplatform.webui.ext.filter.UIExtensionFilter;
57  import org.exoplatform.webui.ext.filter.UIExtensionFilters;
58  import org.exoplatform.webui.ext.manager.UIAbstractManager;
59  import org.exoplatform.webui.ext.manager.UIAbstractManagerComponent;
60  
61  /**
62   * Created by The eXo Platform SARL
63   * Author : Hoang Van Hung
64   *          hunghvit@gmail.com
65   * Aug 6, 2009
66   */
67  
68  @ComponentConfig(
69      events = {
70        @EventConfig(listeners = LockManageComponent.LockActionListener.class)
71      }
72  )
73  
74  public class LockManageComponent extends UIAbstractManagerComponent {
75  
76    private static final List<UIExtensionFilter> FILTERS
77        = Arrays.asList(new UIExtensionFilter[]{new IsNotInTrashFilter(),
78                                                new IsNotHoldsLockFilter(),
79                                                new IsNotSimpleLockedFilter(),
80                                                new CanSetPropertyFilter(),
81                                                new IsCheckedOutFilter(),
82                                                new IsNotTrashHomeNodeFilter() });
83  
84    private static final Log LOG  = ExoLogger.getLogger(LockManageComponent.class.getName());
85  
86    @UIExtensionFilters
87    public List<UIExtensionFilter> getFilters() {
88      return FILTERS;
89    }
90  
91  
92    private static void processMultiLock(String[] nodePaths, Event<?> event, UIJCRExplorer uiExplorer) throws Exception {
93      for(int i=0; i< nodePaths.length; i++) {
94        processLock(nodePaths[i], event, uiExplorer);
95      }
96      uiExplorer.updateAjax(event);
97    }
98  
99    private static void processLock(String nodePath, Event<?> event,  UIJCRExplorer uiExplorer) throws Exception {
100     UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
101     Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(nodePath);
102     String wsName = null;
103     if (matcher.find()) {
104       wsName = matcher.group(1);
105       nodePath = matcher.group(2);
106     } else {
107       throw new IllegalArgumentException("The ObjectId is invalid '"+ nodePath + "'");
108     }
109     Session session = uiExplorer.getSessionByWorkspace(wsName);
110     Node node;
111     try {
112       // Use the method getNodeByPath because it is link aware
113       node = uiExplorer.getNodeByPath(nodePath, session);
114       // Reset the path to manage the links that potentially create virtual path
115       nodePath = node.getPath();
116       // Reset the session to manage the links that potentially change of workspace
117       session = node.getSession();
118       // Reset the workspace name to manage the links that potentially change of workspace
119       wsName = session.getWorkspace().getName();
120     } catch(PathNotFoundException path) {
121       uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception",
122           null,ApplicationMessage.WARNING));
123       
124       return;
125     } catch (Exception e) {
126       JCRExceptionManager.process(uiApp, e);
127       return;
128     }
129     
130     try {
131       if (!PermissionUtil.canSetProperty(node))
132         throw new AccessDeniedException("access denied, can't lock node:" + node.getPath());
133       
134       if(node.canAddMixin(Utils.MIX_LOCKABLE)){
135         node.addMixin(Utils.MIX_LOCKABLE);
136         node.save();
137       }
138       Lock lock = node.lock(false, false);
139       LockUtil.keepLock(lock);
140       LockService lockService = uiExplorer.getApplicationComponent(LockService.class);
141       List<String> settingLockList = lockService.getAllGroupsOrUsersForLock();
142       OrganizationService service = WCMCoreUtils.getService(OrganizationService.class);
143       List<MembershipType> memberships = (List<MembershipType>) service.getMembershipTypeHandler().findMembershipTypes();
144       for (String settingLock : settingLockList) {
145         LockUtil.keepLock(lock, settingLock);
146         if (!settingLock.startsWith("*"))
147           continue;
148         String lockTokenString = settingLock;
149         for (MembershipType membership : memberships) {
150           lockTokenString = settingLock.replace("*", membership.getName());
151           LockUtil.keepLock(lock, lockTokenString);
152         }
153       }
154       session.save();
155     } catch(LockException le) {
156       ApplicationMessage appMessage = 
157         new ApplicationMessage("UIPopupMenu.msg.cant-lock", 
158                                new String[] {node.getPath()}, ApplicationMessage.ERROR);
159       appMessage.setArgsLocalized(false);
160       uiApp.addMessage(appMessage);
161       
162       uiExplorer.updateAjax(event);
163       return;
164     } catch (AccessDeniedException adEx) {
165       ApplicationMessage appMessage = 
166         new ApplicationMessage("UIPopupMenu.msg.can-not-lock-node", 
167                                new String[] {node.getPath()}, ApplicationMessage.ERROR);
168       appMessage.setArgsLocalized(false);
169       uiApp.addMessage(appMessage);
170       
171       uiExplorer.updateAjax(event);
172       return;
173     }
174     catch (Exception e) {
175       if (LOG.isErrorEnabled()) {
176         LOG.error("an unexpected error occurs while locking the node", e);
177       }
178       JCRExceptionManager.process(uiApp, e);
179       
180       uiExplorer.updateAjax(event);
181     }
182   }
183 
184   public static void lockManage(Event<? extends UIComponent> event, UIJCRExplorer uiExplorer) throws Exception {
185     String nodePath = event.getRequestContext().getRequestParameter(OBJECTID);
186     if(nodePath.indexOf(";") > -1) {
187       processMultiLock(nodePath.split(";"), event, uiExplorer);
188     } else {
189       processLock(nodePath, event, uiExplorer);
190     }
191   }
192 
193   public static class LockActionListener extends UIWorkingAreaActionListener<LockManageComponent> {
194     public void processEvent(Event<LockManageComponent> event) throws Exception {
195       UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
196       lockManage(event, uiExplorer);
197     }
198   }
199 
200   @Override
201   public Class<? extends UIAbstractManager> getUIAbstractManagerClass() {
202     return null;
203   }
204 
205 }