001/* 002 * Copyright 2018 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.extensions; 017 018import java.util.Collections; 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.avalon.framework.service.Serviceable; 025import org.apache.commons.lang3.StringUtils; 026 027import org.ametys.plugins.workflow.EnhancedFunction; 028import org.ametys.plugins.workflow.EnhancedFunctionExtensionPoint; 029import org.ametys.plugins.workflow.component.WorkflowArgument; 030import org.ametys.plugins.workflow.support.WorkflowElementDefinitionHelper; 031import org.ametys.runtime.i18n.I18nizableText; 032import org.ametys.runtime.model.StaticEnumerator; 033import org.ametys.runtime.plugin.ExtensionPoint; 034import org.ametys.runtime.plugin.component.AbstractLogEnabled; 035 036import com.opensymphony.module.propertyset.PropertySet; 037import com.opensymphony.workflow.FunctionProvider; 038import com.opensymphony.workflow.WorkflowException; 039 040/** 041 * Workflow function that will call each function registered on the extension point given as an argument 042 */ 043public class ExtensibleFunction extends AbstractLogEnabled implements EnhancedFunction, Serviceable 044{ 045 /** The rights key. */ 046 protected static final String EXTENSION_POINT_ROLE_ARGS_KEY = "extension-point"; 047 /** The service manager */ 048 protected ServiceManager _manager; 049 /** The enhanced function extension point */ 050 protected EnhancedFunctionExtensionPoint _enhancedFunctionEP; 051 052 public void service(ServiceManager manager) throws ServiceException 053 { 054 _manager = manager; 055 _enhancedFunctionEP = (EnhancedFunctionExtensionPoint) manager.lookup(EnhancedFunctionExtensionPoint.ROLE); 056 } 057 058 059 public void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException 060 { 061 ExtensionPoint<String> functionsExtensionPoint = _getFunctionsExtensionPoint(args); 062 for (String functionId : functionsExtensionPoint.getExtensionsIds()) 063 { 064 getLogger().debug("{} is delegating to extension {} of point {}", ExtensibleFunction.class.getName(), functionId); 065 String functionProviderRole = functionsExtensionPoint.getExtension(functionId); 066 FunctionProvider functionProvider = _getFunctionProvider(functionId, functionProviderRole); 067 functionProvider.execute(transientVars, Collections.emptyMap(), ps); // We do not transmit 'args', since those args are for this function, not for the extended functions that thus cannot use args 068 } 069 070 } 071 072 /** 073 * Get the function provider denoted 074 * @param functionId The id of the extension that gave the role 075 * @param functionProviderRole The role of the component to find 076 * @return The workflow function 077 * @throws WorkflowException If the role cannot be found 078 */ 079 protected FunctionProvider _getFunctionProvider(String functionId, String functionProviderRole) throws WorkflowException 080 { 081 EnhancedFunction extension = _enhancedFunctionEP.getExtension(functionProviderRole); 082 if (extension == null) 083 { 084 throw new WorkflowException("Cannot find workflow function with id '" + functionProviderRole + "' configured as an extension with id '" + functionId + "'"); 085 } 086 return extension; 087 } 088 089 090 /** 091 * Get the function extension point given in args 092 * @param args The workflow arguments 093 * @return The extension point 094 * @throws WorkflowException If the extension point is not configured or does not exist 095 */ 096 @SuppressWarnings("unchecked") 097 protected ExtensionPoint<String> _getFunctionsExtensionPoint(Map args) throws WorkflowException 098 { 099 String extensionPoint = (String) args.get(EXTENSION_POINT_ROLE_ARGS_KEY); 100 if (StringUtils.isBlank(extensionPoint)) 101 { 102 throw new WorkflowException("Cannot use the workflow function '" + ExtensibleFunction.class.getName() + "' without the argument '" + EXTENSION_POINT_ROLE_ARGS_KEY + "' describing the role of the extension point of function components to use"); 103 } 104 105 try 106 { 107 return (ExtensionPoint<String>) _manager.lookup(extensionPoint); 108 } 109 catch (ServiceException e) 110 { 111 throw new WorkflowException("The workflow function '" + ExtensibleFunction.class.getName() + "' has the argument '" + EXTENSION_POINT_ROLE_ARGS_KEY + "' valued to '" + extensionPoint + "', that does not denote a String extension point", e); 112 } 113 } 114 115 @Override 116 public FunctionType getFunctionExecType() 117 { 118 return FunctionType.POST; 119 } 120 121 @SuppressWarnings("unchecked") 122 @Override 123 public List<WorkflowArgument> getArguments() 124 { 125 WorkflowArgument extensionPoint = WorkflowElementDefinitionHelper.getElementDefinition( 126 EXTENSION_POINT_ROLE_ARGS_KEY, 127 new I18nizableText("plugin.cms", "PLUGINS_CMS_EXTENSIBLE_FUNCTION_ARGUMENT_EXTENSION_POINT_LABEL"), 128 new I18nizableText("plugin.cms", "PLUGINS_CMS_EXTENSIBLE_FUNCTION_ARGUMENT_EXTENSION_POINT_DESC"), 129 true, 130 false 131 ); 132 StaticEnumerator<String> extensionPointsStaticEnumerator = new StaticEnumerator<>(); 133 extensionPointsStaticEnumerator.add(new I18nizableText("plugin.cms", "PLUGINS_CMS_EXTENSIBLE_FUNCTION_POST_CONTENT_EDITION_LABEL"), "org.ametys.cms.workflow.extensions.PostContentEditionFunctionsExtensionPoint"); 134 extensionPointsStaticEnumerator.add(new I18nizableText("plugin.cms", "PLUGINS_CMS_EXTENSIBLE_FUNCTION_POST_CONTENT_VALIDATION_LABEL"), "org.ametys.cms.workflow.extensions.PostContentValidationFunctionsExtensionPoint"); 135 extensionPoint.setEnumerator(extensionPointsStaticEnumerator); 136 extensionPoint.setDefaultValue("org.ametys.cms.workflow.extensions.PostContentEditionFunctionsExtensionPoint"); 137 return List.of(extensionPoint); 138 } 139 140 @Override 141 public I18nizableText getLabel() 142 { 143 return new I18nizableText("plugin.cms", "PLUGINS_CMS_EXTENSIBLE_FUNCTION_LABEL"); 144 } 145 146 @Override 147 public I18nizableText getFullLabel(Map<String, String> args) 148 { 149 return (PostContentEditionFunctionsExtensionPoint.class.getName().equals(args.get(EXTENSION_POINT_ROLE_ARGS_KEY))) 150 ? new I18nizableText("plugin.cms", "PLUGINS_CMS_EXTENSIBLE_FUNCTION_EDITION_DESCRIPTION") 151 : new I18nizableText("plugin.cms", "PLUGINS_CMS_EXTENSIBLE_FUNCTION_VALIDATION_DESCRIPTION"); 152 } 153}