001/*
002 *  Copyright 2017 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.workflow.copy;
017
018import java.util.Map;
019import java.util.Optional;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023
024import org.ametys.cms.content.CopyContentComponent;
025import org.ametys.cms.repository.Content;
026import org.ametys.cms.repository.ModifiableContent;
027import org.ametys.cms.repository.ModifiableWorkflowAwareContent;
028import org.ametys.cms.workflow.copy.CreateContentByCopyFunction;
029import org.ametys.odf.ODFHelper;
030import org.ametys.plugins.repository.ModifiableTraversableAmetysObject;
031import org.ametys.plugins.repository.collection.AmetysObjectCollection;
032import org.ametys.plugins.repository.data.holder.values.SynchronizableValue;
033
034import com.opensymphony.workflow.WorkflowException;
035
036/**
037 * OSWorkflow function to create a odf content by copy of another
038 */
039public abstract class AbstractCreateODFContentByCopyFunction extends CreateContentByCopyFunction
040{
041    /** Key for the parent of the target content */
042    public static final String PARENT_KEY = AbstractCreateProgramItemByCopyFunction.class.getName() + "$parentId";
043    
044    /** ODF helper */
045    protected ODFHelper _odfHelper;
046    
047    @Override
048    public void service(ServiceManager manager) throws ServiceException
049    {
050        super.service(manager);
051        _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE);
052        
053        // Override component for copy
054        _copyContentComponent = (CopyContentComponent) manager.lookup(org.ametys.odf.content.CopyContentComponent.ROLE);
055    }
056    
057    @Override
058    protected AmetysObjectCollection< ? , ModifiableWorkflowAwareContent> _getContentRoot(Map transientVars) throws WorkflowException
059    {
060        return _odfHelper.getRootContent(true);
061    }
062    
063    @Override
064    protected ModifiableWorkflowAwareContent _createContent(Map transientVars, Map args, String desiredContentName, ModifiableTraversableAmetysObject contentsNode)
065    {
066        String baseName = desiredContentName;
067        String prefix = _getContentNamePrefix();
068        if (!baseName.startsWith(prefix))
069        {
070            baseName = prefix + baseName;
071        }
072
073        return super._createContent(transientVars, args, baseName, contentsNode);
074    }
075
076    @Override
077    protected void processValues(Map transientVars, ModifiableContent targetContent, Map<String, Object> values) throws WorkflowException
078    {
079        super.processValues(transientVars, targetContent, values);
080        
081        // Add the parent content if exists and compatible
082        Content parent = _getParent(transientVars);
083        
084        if (parent != null && _isCompatibleParent(parent))
085        {
086            values.put(_getParentAttributeName(parent), _buildParentSynchronizableValue(parent));
087        }
088    }
089    
090    /**
091     * Get the parent content if exists.
092     * @param transientVars The transient vars
093     * @return the parent content (may be not compatible at this stage)
094     */
095    protected Content _getParent(Map transientVars)
096    {
097        return Optional.of(PARENT_KEY)
098            .map(transientVars::get)
099            .map(String.class::cast)
100            .map(_resolver::<Content>resolveById)
101            .orElse(null);
102    }
103    
104    /**
105     * Check if the parent is compatible
106     * @param parent The parent
107     * @return <code>true</code> if the parent is compatible
108     */
109    protected abstract boolean _isCompatibleParent(Content parent);
110    
111    /**
112     * Get the parent attribute name.
113     * @param parent The parent
114     * @return the parent attribute name
115     */
116    protected abstract String _getParentAttributeName(Content parent);
117    
118    /**
119     * Get the parent attribute synchronizable value.
120     * @param parent The parent
121     * @return a synchronizable value
122     */
123    protected abstract SynchronizableValue _buildParentSynchronizableValue(Content parent);
124    
125    /**
126     * Get the prefix for content name
127     * @return the prefix
128     */
129    protected abstract String _getContentNamePrefix ();
130}