/*
* Copyright (C) 2003-2007 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.ecm.webui.component.admin.unlock;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.jcr.AccessDeniedException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.Session;
import javax.jcr.lock.LockException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.version.VersionException;
import org.apache.commons.lang.StringUtils;
import org.exoplatform.commons.utils.PageList;
import org.exoplatform.ecm.jcr.model.Preference;
import org.exoplatform.ecm.utils.lock.LockUtil;
import org.exoplatform.ecm.webui.comparator.NodeOwnerComparator;
import org.exoplatform.ecm.webui.comparator.NodeTitleComparator;
import org.exoplatform.ecm.webui.core.UIPagingGridDecorator;
import org.exoplatform.ecm.webui.utils.JCRExceptionManager;
import org.exoplatform.ecm.webui.utils.Utils;
import org.exoplatform.portal.config.UserACL;
import org.exoplatform.services.cms.lock.LockService;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.MembershipEntry;
import org.exoplatform.services.wcm.core.NodeLocation;
import org.exoplatform.services.wcm.core.NodetypeConstant;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;
import org.exoplatform.web.application.ApplicationMessage;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIApplication;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.EventListener;
/**
* Created by The eXo Platform SARL
* Author : Dang Van Minh
* minh.dang@exoplatform.com
* Dec 29, 2006
* 11:30:17 AM
*/
@ComponentConfig(
template = "app:/groovy/webui/component/admin/unlock/UILockNodeList.gtmpl",
events = {
@EventConfig(listeners = UILockNodeList.UnLockActionListener.class),
@EventConfig(listeners = UILockNodeList.SortActionListener.class)
}
)
public class UILockNodeList extends UIPagingGridDecorator {
final static public String[] ACTIONS = {};
final static public String ST_EDIT = "EditUnLockForm";
private Preference preferences_;
private static final String LOCK_QUERY = "select * from mix:lockable where jcr:lockOwner IS NOT NULL " +
"order by exo:dateCreated DESC";
private String typeSort_ = NodetypeConstant.SORT_BY_NODETYPE;
private String sortOrder_ = Preference.BLUE_UP_ARROW;
private String order_ = Preference.ASCENDING_ORDER;
public static final String SORT_BY_NODENAME = "Alphabetic" ;
public static final String SORT_BY_NODEOWNER= "Owner" ;
public String getTypeSort() { return typeSort_; }
public void setTypeSort(String typeSort) {
typeSort_ = typeSort;
}
public String getSortOrder() { return sortOrder_; }
public void setSortOrder(String sortOrder) {
sortOrder_ = sortOrder;
}
public String getOrder() { return order_; }
public void setOrder(String order) {
order_ = order;
}
public void setPreferences(Preference preference) {this.preferences_ = preference; }
public UILockNodeList() throws Exception {
getUIPageIterator().setId("LockNodeListIterator");
}
public String[] getActions() { return ACTIONS ; }
public void refresh(int currentPage) throws Exception {
if (!getUIPageIterator().isJustPaginated()) {
PageList pageList = new UILockedNodePageList(LOCK_QUERY, getUIPageIterator().getItemsPerPage(), currentPage);
getUIPageIterator().setPageList(pageList);
}
if (currentPage > getUIPageIterator().getAvailablePage())
getUIPageIterator().setCurrentPage(getUIPageIterator().getAvailablePage());
else
getUIPageIterator().setCurrentPage(currentPage);
getUIPageIterator().setJustPaginated(false);
}
public List getLockedNodeList() throws Exception {
return sort(NodeLocation.getNodeListByLocationList(getUIPageIterator().getCurrentPageData()));
}
public List<Node> getAllLockedNodes() throws Exception {
RepositoryService repositoryService = getApplicationComponent(RepositoryService.class);
ManageableRepository manageRepository = repositoryService.getCurrentRepository();
RepositoryEntry repo = manageRepository.getConfiguration();
List<Node> listLockedNodes = new ArrayList<Node>();
QueryManager queryManager = null;
Session session = null;
String queryStatement = LOCK_QUERY;
Query query = null;
QueryResult queryResult = null;
for(WorkspaceEntry ws : repo.getWorkspaceEntries()) {
session = WCMCoreUtils.getSystemSessionProvider().getSession(ws.getName(), manageRepository);
queryManager = session.getWorkspace().getQueryManager();
query = queryManager.createQuery(queryStatement, Query.SQL);
queryResult = query.execute();
for(NodeIterator iter = queryResult.getNodes(); iter.hasNext();) {
Node itemNode = iter.nextNode();
if (!Utils.isInTrash(itemNode) && itemNode.isLocked()) {
listLockedNodes.add(itemNode);
}
}
}
return listLockedNodes;
}
private List<Node> sort(List<Node> childrenList) {
if (SORT_BY_NODENAME.equals(this.getTypeSort()))
Collections.sort(childrenList, new NodeTitleComparator(this.getOrder())) ;
else if(SORT_BY_NODEOWNER.equals(this.getTypeSort()))
Collections.sort(childrenList, new NodeOwnerComparator(this.getOrder())) ;
return childrenList;
}
static public class SortActionListener extends EventListener<UILockNodeList> {
public void execute(Event<UILockNodeList> event) throws Exception {
UILockNodeList uicomp = event.getSource();
UIUnLockManager uiUnLockManager = event.getSource().getParent();
UIApplication uiApp = uiUnLockManager.getAncestorOfType(UIApplication.class);
try {
String sortParam = event.getRequestContext().getRequestParameter(OBJECTID) ;
String[] array = sortParam.split(";");
String order = Preference.ASCENDING_ORDER.equals(array[0].trim()) || !array[1].trim().equals(uicomp.getTypeSort()) ?
Preference.BLUE_DOWN_ARROW : Preference.BLUE_UP_ARROW;
String prefOrder = Preference.ASCENDING_ORDER.equals(array[0].trim()) || !array[1].trim().equals(uicomp.getTypeSort())?
Preference.ASCENDING_ORDER : Preference.DESCENDING_ORDER;
uicomp.setSortOrder(order);
uicomp.setTypeSort(array[1]);
uicomp.setOrder(prefOrder);
uiUnLockManager.refresh();
event.getRequestContext().addUIComponentToUpdateByAjax(uiUnLockManager);
} catch (Exception e) {
JCRExceptionManager.process(uiApp, e);
return;
}
}
}
static public class UnLockActionListener extends EventListener<UILockNodeList> {
private List<String> getCurrentUserMemberships() throws Exception {
List<String> groupList = new ArrayList<String> ();
Collection<MembershipEntry> memberships =
ConversationState.getCurrent().getIdentity().getMemberships();
for(MembershipEntry entry: memberships){
groupList.add(entry.getMembershipType() + ":" + entry.getGroup());
}
return groupList;
}
public void execute(Event<UILockNodeList> event) throws Exception {
WebuiRequestContext rContext = event.getRequestContext();
UIUnLockManager uiUnLockManager = event.getSource().getParent();
UIApplication uiApp = uiUnLockManager.getAncestorOfType(UIApplication.class);
String nodePath = rContext.getRequestParameter(OBJECTID);
RepositoryService repositoryService = uiUnLockManager.getApplicationComponent(RepositoryService.class);
ManageableRepository manageRepository = repositoryService.getCurrentRepository();
Session session = null;
Node lockedNode = null;
UserACL userACLService = WCMCoreUtils.getService(UserACL.class);
String remoteUser = rContext.getRemoteUser();
boolean isAuthenticated = remoteUser.equals(userACLService.getSuperUser());
if (!isAuthenticated) {
LockService lockService = WCMCoreUtils.getService(LockService.class);
List<String> authorizedMemberships = lockService.getAllGroupsOrUsersForLock();
List<String> loginedUserMemberShips = getCurrentUserMemberships();
Set<String> loginedUserGroups = ConversationState.getCurrent().getIdentity().getGroups();
for (String authorizedMembership: authorizedMemberships) {
if ((authorizedMembership.startsWith("*") &&
loginedUserGroups.contains(StringUtils.substringAfter(authorizedMembership, ":")))
|| loginedUserMemberShips.contains(authorizedMembership)) {
isAuthenticated=true;
break;
}
}
}
RepositoryEntry repo = repositoryService.getCurrentRepository().getConfiguration();
for(WorkspaceEntry ws : repo.getWorkspaceEntries()) {
if (isAuthenticated) {
session = WCMCoreUtils.getSystemSessionProvider().getSession(ws.getName(), manageRepository);
}else {
session = WCMCoreUtils.getUserSessionProvider().getSession(ws.getName(), manageRepository);
}
try {
lockedNode = (Node) session.getItem(nodePath);
if ((lockedNode != null) && !Utils.isInTrash(lockedNode)) break;
} catch (PathNotFoundException e) {
continue;
} catch (AccessDeniedException accessDeniedException) {
continue;
}
}
if (lockedNode == null) {
Object[] args = { nodePath };
ApplicationMessage msg = new ApplicationMessage("UILockNodeList.msg.access-denied-exception",
args,
ApplicationMessage.WARNING);
msg.setArgsLocalized(false);
uiApp.addMessage(msg);
uiUnLockManager.refresh();
event.getRequestContext().addUIComponentToUpdateByAjax(uiUnLockManager);
return;
}
if (isAuthenticated ) {
session = WCMCoreUtils.getSystemSessionProvider()
.getSession(lockedNode.getSession().getWorkspace().getName(),
(ManageableRepository) lockedNode.getSession()
.getRepository());
lockedNode = (Node)session.getItem(lockedNode.getPath());
}
try {
if(lockedNode.holdsLock()) {
String lockToken = LockUtil.getLockToken(lockedNode);
if(lockToken != null) {
session.addLockToken(lockToken);
}
lockedNode.unlock();
lockedNode.removeMixin(Utils.MIX_LOCKABLE);
lockedNode.getSession().save();
LockUtil.removeLock(lockedNode);
}
} catch(LockException le) {
uiApp.addMessage(new ApplicationMessage("UILockNodeList.msg.can-not-unlock-node", null, ApplicationMessage.WARNING));
event.getRequestContext().addUIComponentToUpdateByAjax(uiUnLockManager);
return;
} catch(VersionException versionException) {
Object[] args = {lockedNode.getName()};
uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.can-not-unlock-node-is-checked-in", args,
ApplicationMessage.WARNING));
event.getRequestContext().addUIComponentToUpdateByAjax(uiUnLockManager);
return;
} catch (Exception e) {
JCRExceptionManager.process(uiApp, e);
}
uiUnLockManager.refresh();
uiUnLockManager.getChild(UILockNodeList.class).setRendered(true);
uiUnLockManager.getChild(UILockHolderContainer.class).setRendered(false);
}
}
}