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.admin.unlock;
18  
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.List;
23  import java.util.Set;
24  
25  import javax.jcr.AccessDeniedException;
26  import javax.jcr.Node;
27  import javax.jcr.NodeIterator;
28  import javax.jcr.PathNotFoundException;
29  import javax.jcr.Session;
30  import javax.jcr.lock.LockException;
31  import javax.jcr.query.Query;
32  import javax.jcr.query.QueryManager;
33  import javax.jcr.query.QueryResult;
34  import javax.jcr.version.VersionException;
35  
36  import org.apache.commons.lang.StringUtils;
37  import org.exoplatform.commons.utils.PageList;
38  import org.exoplatform.ecm.jcr.model.Preference;
39  import org.exoplatform.ecm.utils.lock.LockUtil;
40  import org.exoplatform.ecm.webui.comparator.NodeOwnerComparator;
41  import org.exoplatform.ecm.webui.comparator.NodeTitleComparator;
42  import org.exoplatform.ecm.webui.core.UIPagingGridDecorator;
43  import org.exoplatform.ecm.webui.utils.JCRExceptionManager;
44  import org.exoplatform.ecm.webui.utils.Utils;
45  import org.exoplatform.portal.config.UserACL;
46  import org.exoplatform.services.cms.lock.LockService;
47  import org.exoplatform.services.jcr.RepositoryService;
48  import org.exoplatform.services.jcr.config.RepositoryEntry;
49  import org.exoplatform.services.jcr.config.WorkspaceEntry;
50  import org.exoplatform.services.jcr.core.ManageableRepository;
51  import org.exoplatform.services.security.ConversationState;
52  import org.exoplatform.services.security.MembershipEntry;
53  import org.exoplatform.services.wcm.core.NodeLocation;
54  import org.exoplatform.services.wcm.core.NodetypeConstant;
55  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
56  import org.exoplatform.web.application.ApplicationMessage;
57  import org.exoplatform.webui.application.WebuiRequestContext;
58  import org.exoplatform.webui.config.annotation.ComponentConfig;
59  import org.exoplatform.webui.config.annotation.EventConfig;
60  import org.exoplatform.webui.core.UIApplication;
61  import org.exoplatform.webui.event.Event;
62  import org.exoplatform.webui.event.EventListener;
63  
64  /**
65   * Created by The eXo Platform SARL
66   * Author : Dang Van Minh
67   *          minh.dang@exoplatform.com
68   * Dec 29, 2006
69   * 11:30:17 AM
70   */
71  @ComponentConfig(
72                   template = "app:/groovy/webui/component/admin/unlock/UILockNodeList.gtmpl",
73                   events = {
74                       @EventConfig(listeners = UILockNodeList.UnLockActionListener.class),
75                       @EventConfig(listeners = UILockNodeList.SortActionListener.class)
76                   }
77      )
78  public class UILockNodeList extends UIPagingGridDecorator {
79    final static public String[] ACTIONS = {};
80    final static public String ST_EDIT = "EditUnLockForm";
81    private Preference preferences_;
82  
83    private static final String LOCK_QUERY = "select * from mix:lockable where jcr:lockOwner IS NOT NULL " +
84        "order by exo:dateCreated DESC";
85    private String typeSort_ = NodetypeConstant.SORT_BY_NODETYPE;
86    private String sortOrder_ = Preference.BLUE_UP_ARROW;
87    private String order_ = Preference.ASCENDING_ORDER;
88  
89    public static final String SORT_BY_NODENAME = "Alphabetic" ;
90    public static final String SORT_BY_NODEOWNER= "Owner" ;
91  
92  
93    public String getTypeSort() { return typeSort_; }
94  
95    public void setTypeSort(String typeSort) {
96      typeSort_ = typeSort;
97    }
98  
99    public String getSortOrder() { return sortOrder_; }
100 
101   public void setSortOrder(String sortOrder) {
102     sortOrder_ = sortOrder;
103   }
104 
105   public String getOrder() { return order_; }
106 
107   public void setOrder(String order) {
108     order_ = order;
109   }
110 
111   public void setPreferences(Preference preference) {this.preferences_ = preference; }
112 
113   public UILockNodeList() throws Exception {
114     getUIPageIterator().setId("LockNodeListIterator");
115 
116   }
117 
118   public String[] getActions() { return ACTIONS ; }
119 
120   public void refresh(int currentPage) throws Exception {
121     if (!getUIPageIterator().isJustPaginated()) {
122       PageList pageList = new UILockedNodePageList(LOCK_QUERY, getUIPageIterator().getItemsPerPage(), currentPage);
123       getUIPageIterator().setPageList(pageList);
124     }
125     if (currentPage > getUIPageIterator().getAvailablePage())
126       getUIPageIterator().setCurrentPage(getUIPageIterator().getAvailablePage());
127     else
128       getUIPageIterator().setCurrentPage(currentPage);
129     getUIPageIterator().setJustPaginated(false);
130   }
131 
132   public List getLockedNodeList() throws Exception {
133     return sort(NodeLocation.getNodeListByLocationList(getUIPageIterator().getCurrentPageData()));
134   }
135 
136   public List<Node> getAllLockedNodes() throws Exception {
137     RepositoryService repositoryService = getApplicationComponent(RepositoryService.class);
138 
139     ManageableRepository manageRepository = repositoryService.getCurrentRepository();
140     RepositoryEntry repo = manageRepository.getConfiguration();
141 
142     List<Node> listLockedNodes = new ArrayList<Node>();
143     QueryManager queryManager = null;
144     Session session = null;
145     String queryStatement = LOCK_QUERY;
146     Query query = null;
147     QueryResult queryResult = null;
148 
149     for(WorkspaceEntry ws : repo.getWorkspaceEntries()) {
150       session = WCMCoreUtils.getSystemSessionProvider().getSession(ws.getName(), manageRepository);
151       queryManager = session.getWorkspace().getQueryManager();
152       query = queryManager.createQuery(queryStatement, Query.SQL);
153       queryResult = query.execute();
154       for(NodeIterator iter = queryResult.getNodes(); iter.hasNext();) {
155         Node itemNode = iter.nextNode();
156         if (!Utils.isInTrash(itemNode) && itemNode.isLocked()) {
157           listLockedNodes.add(itemNode);
158         }
159       }
160     }
161     return listLockedNodes;
162   }
163 
164   private List<Node> sort(List<Node> childrenList) {
165     if (SORT_BY_NODENAME.equals(this.getTypeSort()))
166       Collections.sort(childrenList, new NodeTitleComparator(this.getOrder())) ;
167     else if(SORT_BY_NODEOWNER.equals(this.getTypeSort()))
168       Collections.sort(childrenList, new NodeOwnerComparator(this.getOrder())) ;
169     return childrenList;
170 
171   }
172 
173   static public class SortActionListener extends EventListener<UILockNodeList> {
174     public void execute(Event<UILockNodeList> event) throws Exception {
175       UILockNodeList uicomp = event.getSource();
176       UIUnLockManager uiUnLockManager = event.getSource().getParent();
177       UIApplication uiApp = uiUnLockManager.getAncestorOfType(UIApplication.class);
178 
179 
180       try {
181         String sortParam = event.getRequestContext().getRequestParameter(OBJECTID) ;
182         String[] array = sortParam.split(";");
183         String order = Preference.ASCENDING_ORDER.equals(array[0].trim()) || !array[1].trim().equals(uicomp.getTypeSort()) ?
184                                                                                                                             Preference.BLUE_DOWN_ARROW : Preference.BLUE_UP_ARROW;
185 
186         String prefOrder = Preference.ASCENDING_ORDER.equals(array[0].trim()) || !array[1].trim().equals(uicomp.getTypeSort())?
187                                                                                                                                Preference.ASCENDING_ORDER : Preference.DESCENDING_ORDER;
188         uicomp.setSortOrder(order);
189         uicomp.setTypeSort(array[1]);
190         uicomp.setOrder(prefOrder);
191         uiUnLockManager.refresh();
192         event.getRequestContext().addUIComponentToUpdateByAjax(uiUnLockManager);
193       } catch (Exception e) {
194         JCRExceptionManager.process(uiApp, e);
195         return;
196       }
197     }
198   }
199 
200   static public class UnLockActionListener extends EventListener<UILockNodeList> {
201     private List<String> getCurrentUserMemberships() throws Exception {
202 
203       List<String> groupList = new ArrayList<String> ();
204       
205       Collection<MembershipEntry> memberships =
206           ConversationState.getCurrent().getIdentity().getMemberships();
207       for(MembershipEntry entry: memberships){
208         groupList.add(entry.getMembershipType() + ":" + entry.getGroup());
209       }
210       
211       return groupList;
212     }
213 
214     public void execute(Event<UILockNodeList> event) throws Exception {
215       WebuiRequestContext rContext = event.getRequestContext();
216       UIUnLockManager uiUnLockManager = event.getSource().getParent();
217       UIApplication uiApp = uiUnLockManager.getAncestorOfType(UIApplication.class);
218       String nodePath = rContext.getRequestParameter(OBJECTID);
219       RepositoryService repositoryService = uiUnLockManager.getApplicationComponent(RepositoryService.class);
220       ManageableRepository manageRepository = repositoryService.getCurrentRepository();
221       Session session = null;
222       Node lockedNode = null;
223       UserACL userACLService = WCMCoreUtils.getService(UserACL.class);
224       String remoteUser = rContext.getRemoteUser();
225       boolean isAuthenticated = remoteUser.equals(userACLService.getSuperUser());
226       if (!isAuthenticated) {
227         LockService lockService = WCMCoreUtils.getService(LockService.class);
228         List<String> authorizedMemberships = lockService.getAllGroupsOrUsersForLock();
229         List<String> loginedUserMemberShips = getCurrentUserMemberships();
230         Set<String> loginedUserGroups = ConversationState.getCurrent().getIdentity().getGroups();
231         for (String authorizedMembership: authorizedMemberships) {
232           if ((authorizedMembership.startsWith("*") &&
233               loginedUserGroups.contains(StringUtils.substringAfter(authorizedMembership, ":")))
234               || loginedUserMemberShips.contains(authorizedMembership)) {
235             isAuthenticated=true;
236             break;
237           }
238         }
239       }
240 
241       RepositoryEntry repo = repositoryService.getCurrentRepository().getConfiguration();
242       for(WorkspaceEntry ws : repo.getWorkspaceEntries()) {
243         if (isAuthenticated) {
244           session = WCMCoreUtils.getSystemSessionProvider().getSession(ws.getName(), manageRepository);
245         }else {
246           session = WCMCoreUtils.getSystemSessionProvider().getSession(ws.getName(), manageRepository);
247         }
248         try {
249           lockedNode = (Node) session.getItem(nodePath);
250           if ((lockedNode != null) && !Utils.isInTrash(lockedNode)) break;
251         } catch (PathNotFoundException e) {
252           continue;
253         } catch (AccessDeniedException accessDeniedException) {
254           continue;
255         }
256       }
257 
258       if (lockedNode == null) {
259         Object[] args = { nodePath };
260         ApplicationMessage msg = new ApplicationMessage("UILockNodeList.msg.access-denied-exception",
261                                                         args,
262                                                         ApplicationMessage.WARNING);
263         msg.setArgsLocalized(false);
264         uiApp.addMessage(msg);
265         uiUnLockManager.refresh();
266         event.getRequestContext().addUIComponentToUpdateByAjax(uiUnLockManager);
267         return;
268       }
269 
270       if (isAuthenticated ) {
271         session = WCMCoreUtils.getSystemSessionProvider()
272             .getSession(lockedNode.getSession().getWorkspace().getName(),
273                         (ManageableRepository) lockedNode.getSession()
274                         .getRepository());
275         lockedNode = (Node)session.getItem(lockedNode.getPath());
276       }
277 
278       try {
279         if(lockedNode.holdsLock()) {
280           String lockToken = LockUtil.getLockToken(lockedNode);
281           if(lockToken != null) {
282             session.addLockToken(lockToken);
283           }
284           lockedNode.unlock();
285           lockedNode.removeMixin(Utils.MIX_LOCKABLE);
286           lockedNode.getSession().save();
287           LockUtil.removeLock(lockedNode);
288         }
289       } catch(LockException le) {
290         uiApp.addMessage(new ApplicationMessage("UILockNodeList.msg.can-not-unlock-node", null, ApplicationMessage.WARNING));
291         event.getRequestContext().addUIComponentToUpdateByAjax(uiUnLockManager);
292         return;
293       } catch(VersionException versionException) {
294         Object[] args = {lockedNode.getName()};
295         uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.can-not-unlock-node-is-checked-in", args,
296                                                 ApplicationMessage.WARNING));
297 
298         event.getRequestContext().addUIComponentToUpdateByAjax(uiUnLockManager);
299         return;
300       } catch (Exception e) {
301         JCRExceptionManager.process(uiApp, e);
302 
303       }
304       uiUnLockManager.refresh();
305       uiUnLockManager.getChild(UILockNodeList.class).setRendered(true);
306       uiUnLockManager.getChild(UILockHolderContainer.class).setRendered(false);
307     }
308   }
309 }