001/*
002 *  Copyright 2010 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.cms.workflow;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Map;
021
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.commons.collections.ListUtils;
025
026import org.ametys.cms.repository.WorkflowAwareContent;
027import org.ametys.core.user.User;
028import org.ametys.core.user.UserIdentity;
029import org.ametys.core.user.UserManager;
030import org.ametys.plugins.repository.AmetysRepositoryException;
031import org.ametys.plugins.repository.lock.LockHelper;
032import org.ametys.plugins.repository.lock.LockableAmetysObject;
033import org.ametys.plugins.workflow.EnhancedCondition;
034import org.ametys.runtime.i18n.I18nizableText;
035
036import com.opensymphony.module.propertyset.PropertySet;
037import com.opensymphony.workflow.WorkflowException;
038
039/**
040 * OSWorkflow condition for testing the lock state of a content.<p>
041 * Check if the content is locked and if it is the case, the condition
042 * passes only if the lock owner is the current caller.
043 */
044public class LockCondition extends AbstractContentWorkflowComponent implements EnhancedCondition
045{
046    /** The user manager */
047    protected UserManager _userManager;
048
049    @Override
050    public void service(ServiceManager manager) throws ServiceException
051    {
052        super.service(manager);
053        _userManager = (UserManager) manager.lookup(UserManager.ROLE);
054    }
055    
056    public boolean passesCondition(Map transientVars, Map args, PropertySet ps) throws WorkflowException
057    {
058        WorkflowAwareContent content = getContent(transientVars);
059        
060        try
061        {
062            if (content instanceof LockableAmetysObject)
063            {
064                // Récupérer le content
065                LockableAmetysObject lockableContent = (LockableAmetysObject) content;
066        
067                // Vérifier si le contenu n'est pas verrouillé
068                if (lockableContent.isLocked())
069                {
070                    boolean sameUser = LockHelper.isLockOwner(lockableContent, getUser(transientVars));
071                    
072                    if (!sameUser)
073                    {
074                        List<String> conditionFailures = getConditionFailures(transientVars);
075                        if (conditionFailures != null)
076                        {
077                            conditionFailures.add(String.format("Lock condition failed : content: %s is locked by user: %s", lockableContent, lockableContent.getLockOwner()));
078                        }
079                        
080                        List<String> i18nParams = new ArrayList<>();
081                        i18nParams.add(_contentHelper.getTitle(content));
082                        UserIdentity lockOwnerIdentity = lockableContent.getLockOwner();
083                        User lockOwner = _userManager.getUser(lockOwnerIdentity.getPopulationId(), lockOwnerIdentity.getLogin());
084                        i18nParams.add(lockOwner != null ? lockOwner.getFullName() : "");
085                        i18nParams.add(lockOwnerIdentity.getLogin());
086                        
087                        addWorkflowError(transientVars, new I18nizableText("plugin.cms", "WORKFLOW_CONTENT_LOCK_CONDITION_FAILED", i18nParams));
088                        
089                        if (_logger.isDebugEnabled())
090                        {
091                            _logger.debug(String.format("Content: %s is locked by user: %s, failing condition", lockableContent, lockableContent.getLockOwner()));
092                        }
093                    } 
094                    else if (_logger.isDebugEnabled())
095                    {
096                        _logger.debug(String.format("Content: %s is locked by current user, passing condition", lockableContent));
097                    }
098                    
099                    return sameUser;
100                }
101                else
102                {
103                    // Le contenu n'est pas verrouillé
104                    // FIXME faut-il le vérrouiller ?, si oui il faut faire une pre-function
105                    return true;
106                }
107            }
108            
109            // The content is not lockable: continue.
110            return true;
111        }
112        catch (AmetysRepositoryException e)
113        {
114            _logger.error("Unable to check the lock state of the content from the repository", e);
115            getConditionFailures(transientVars).add(String.format("Lock condition failed"));
116            return false;
117        }
118    }
119
120    @Override
121    public List<ConditionArgument> getArguments()
122    {
123        return ListUtils.EMPTY_LIST;
124    }
125
126    @Override
127    public I18nizableText getDescription(Map<String, String> argumentsValues)
128    {
129        return new I18nizableText("plugin.cms", "PLUGINS_CMS_LOCKABLE_CONDITION_DESCRIPTION");
130    }
131}