001/*
002 *  Copyright 2011 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.odf.orgunit.actions;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import org.apache.avalon.framework.parameters.Parameters;
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.cocoon.environment.Redirector;
025import org.apache.commons.lang.StringUtils;
026
027import org.ametys.cms.ObservationConstants;
028import org.ametys.cms.workflow.AbstractContentWorkflowComponent;
029import org.ametys.cms.workflow.InitializeContentWorkflowAction;
030import org.ametys.core.observation.Event;
031import org.ametys.core.observation.ObservationManager;
032import org.ametys.core.user.CurrentUserProvider;
033import org.ametys.odf.orgunit.OrgUnit;
034import org.ametys.odf.orgunit.RootOrgUnitProvider;
035import org.ametys.odf.workflow.AbstractCreateODFContentFunction;
036import org.ametys.plugins.repository.AmetysObjectResolver;
037import org.ametys.plugins.repository.jcr.DefaultAmetysObject;
038import org.ametys.plugins.repository.version.VersionableAmetysObject;
039import org.ametys.plugins.workflow.AbstractWorkflowComponent;
040import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow;
041
042import com.opensymphony.workflow.InvalidInputException;
043import com.opensymphony.workflow.WorkflowException;
044import com.opensymphony.workflow.spi.Step;
045
046/**
047 * Action for creating a new org unit
048 */
049public class AddOrgUnitAction extends InitializeContentWorkflowAction
050{
051    /** Constant for parent identifier */
052    public static final String CONTENT_PARENT_ID = AbstractCreateODFContentFunction.class.getName() + "$parentId";
053    
054    /** Ametys object resolver available to subclasses. */
055    protected AmetysObjectResolver _resolver;
056    /** Observation manager available to subclasses. */
057    protected ObservationManager _observationManager;
058    private RootOrgUnitProvider _rootOUProvider;
059    private CurrentUserProvider _currentUserProvider;
060    
061    @Override
062    public void service(ServiceManager smanager) throws ServiceException
063    {
064        super.service(smanager);
065        _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE);
066        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
067        _rootOUProvider = (RootOrgUnitProvider) smanager.lookup(RootOrgUnitProvider.ROLE);
068        _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE);
069    }
070    
071    @Override
072    protected Map _act(Redirector redirector, Map objectModel, String source, Parameters parameters, int actionId, Map inputs) throws InvalidInputException, WorkflowException
073    {
074        Map result = super._act(redirector, objectModel, source, parameters, actionId, inputs);
075        
076        @SuppressWarnings("unchecked")
077        Map<String, Object> workflowResult = (Map<String, Object>) inputs.get(AbstractWorkflowComponent.RESULT_MAP_KEY);
078        String contentId = (String) workflowResult.get("contentId");
079        
080        String parentId = (String) _getParameters(objectModel).get(CONTENT_PARENT_ID);
081        
082        if (StringUtils.isNotEmpty(parentId))
083        {
084            DefaultAmetysObject parent = _resolver.resolveById(parentId);
085            if (parent instanceof OrgUnit)
086            {
087                OrgUnit ou = (OrgUnit) parent;
088                ou.addSubOrgUnit(contentId);
089                
090                applyChangesToParent (ou);
091            }
092        }
093        else
094        {
095            // Attach new OrgUnit to root OrgUnit
096            OrgUnit rootOU = _rootOUProvider.getRoot();
097            if (rootOU != null && !rootOU.getId().equals(contentId))
098            {
099                rootOU.addSubOrgUnit(contentId);
100
101                applyChangesToParent (rootOU);
102            }
103        }
104        
105        return result;
106    }
107    
108    /**
109     * Apply changes to parent {@link OrgUnit}
110     * @param ou The parent orgunit
111     * @throws WorkflowException if failed to apply changes to parent
112     */
113    protected void applyChangesToParent(OrgUnit ou) throws WorkflowException
114    {
115        // Save changes
116        ou.saveChanges();
117        // Create new version
118        ((VersionableAmetysObject) ou).checkpoint();
119        
120        // Notify listeners
121        Map<String, Object> eventParams = new HashMap<>();
122        eventParams.put(ObservationConstants.ARGS_CONTENT, ou);
123        eventParams.put(ObservationConstants.ARGS_CONTENT_ID, ou.getId());
124        _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_MODIFIED, _currentUserProvider.getUser(), eventParams));
125       
126        // Do workflow action
127        Map<String, Object> inputs = new HashMap<>();
128        inputs.put(AbstractWorkflowComponent.RESULT_MAP_KEY, new HashMap<String, Object>());
129        inputs.put(AbstractContentWorkflowComponent.CONTENT_KEY, ou);
130        
131        AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(ou);
132        workflow.doAction(ou.getWorkflowId(), 22, inputs);
133        
134        Step currentStep = (Step) workflow.getCurrentSteps(ou.getWorkflowId()).iterator().next();
135        ou.setCurrentStepId(currentStep.getStepId());
136        ou.saveChanges();
137    }
138
139}