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.workflow;
017
018import java.util.List;
019import java.util.Map;
020import java.util.Optional;
021import java.util.function.Function;
022
023import org.apache.commons.lang3.StringUtils;
024
025import org.ametys.cms.repository.ModifiableContent;
026import org.ametys.cms.workflow.CreateContentFunction;
027import org.ametys.cms.workflow.EditContentFunction;
028import org.ametys.odf.ProgramItem;
029
030import com.opensymphony.workflow.WorkflowException;
031
032/**
033 * Abstract OSWorkflow function for creating a {@link ProgramItem} content
034 * Populate catalog and code metadata.
035 */
036public abstract class AbstractCreateODFProgramItemFunction extends AbstractCreateODFContentFunction
037{
038    @Override
039    protected void _populateAdditionalData(Map transientVars, ModifiableContent content) throws WorkflowException
040    {
041        super._populateAdditionalData(transientVars, content);
042        
043        if (content instanceof ProgramItem programItem)
044        {
045            /* Set the catalog */
046            
047            // Try to get the catalog from transient vars
048            _getValueFromTransientVars(transientVars, CONTENT_CATALOG_KEY)
049                // Use typed values from the EditContentFunction
050                .or(() -> _getValueFromContext(transientVars, EditContentFunction.VALUES_KEY, ProgramItem.CATALOG))
051                // Use raw values from the EditContentFunction
052                .or(() -> _getValueFromContext(transientVars, EditContentFunction.FORM_RAW_VALUES, EditContentFunction.FORM_ELEMENTS_PREFIX + ProgramItem.CATALOG))
053                // Used to get the catalog if the program item is created by java code, like for the csv import.
054                .or(() -> _getValueFromInitialValueSupplier(transientVars, List.of(ProgramItem.CATALOG)))
055                // Set the catalog if value is present
056                .ifPresent(programItem::setCatalog);
057
058            /* Set the code */
059            
060            // Used to get the code if the program item is created by java code, like for the csv import.
061            _getValueFromInitialValueSupplier(transientVars, List.of(ProgramItem.CODE))
062                // Set the code if value is present
063                .ifPresent(programItem::setCode);
064            
065            // Generate a code if empty
066            String code = programItem.getCode();
067            if (StringUtils.isEmpty(code))
068            {
069                programItem.setCode(org.ametys.core.util.StringUtils.generateKey().toUpperCase());
070            }
071        }
072    }
073    
074    private Optional<String> _getValueFromTransientVars(Map transientVars, String attributeName)
075    {
076        return Optional.ofNullable(transientVars.get(attributeName))
077            .map(String.class::cast)
078            .filter(StringUtils::isNotEmpty);
079    }
080    
081    private Optional<String> _getValueFromContext(Map transientVars, String parameter, String attributeName)
082    {
083        return Optional.ofNullable(getContextParameters(transientVars))
084            .map(params -> params.get(parameter))
085            .map(Map.class::cast)
086            .map(values -> values.get(attributeName))
087            .map(String.class::cast)
088            .filter(StringUtils::isNotEmpty);
089    }
090
091    @SuppressWarnings("unchecked")
092    private Optional<String> _getValueFromInitialValueSupplier(Map transientVars, List<String> attributePath)
093    {
094        return Optional.ofNullable(transientVars.get(CreateContentFunction.INITIAL_VALUE_SUPPLIER))
095            .map(Function.class::cast)
096            .map(function -> function.apply(attributePath))
097            .map(String.class::cast)
098            .filter(StringUtils::isNotEmpty);
099    }
100}