/* * #%L * Alfresco Records Management Module * %% * Copyright (C) 2005 - 2016 Alfresco Software Limited * %% * This file is part of the Alfresco software. * - * If the software was purchased under a paid Alfresco license, the terms of * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: * - * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.repo.action.parameter; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.service.cmr.action.ParameterizedItem; import org.alfresco.service.cmr.action.ParameterizedItemDefinition; import org.alfresco.service.cmr.repository.NodeRef; /** * Parameter processor component * * @author Roy Wetherall * @since 2.1 */ public class ParameterProcessorComponent implements ParameterSubstitutionSuggester { /** regex used to parse parameters */ private static final String REG_EX_OLD = "\\$\\{([^\\$\\{]+)\\}"; private static final String REG_EX = "\\{([^\\{]+)\\}"; /** registry of parameter processors */ private Map<String, ParameterProcessor> processors = new HashMap<String, ParameterProcessor>(5); private List<ParameterSubstitutionSuggester> subtitutionSuggesterProcessors = new ArrayList<ParameterSubstitutionSuggester>(5); /** * Register parameter processor * * @param processor */ public void register(ParameterProcessor processor) { this.processors.put(processor.getName(), processor); if(processor instanceof ParameterSubstitutionSuggester) { this.subtitutionSuggesterProcessors.add((ParameterSubstitutionSuggester)processor); } } /** * * @param ruleItem * @param ruleItemDefinition * @param actionedUponNodeRef */ public void process(ParameterizedItem ruleItem, ParameterizedItemDefinition ruleItemDefinition, NodeRef actionedUponNodeRef) { for (Map.Entry<String, Serializable> entry : ruleItem.getParameterValues().entrySet()) { String parameterName = entry.getKey(); Object parameterValue = entry.getValue(); // only sub string property values if (parameterValue instanceof String) { // set the updated parameter value ruleItem.setParameterValue(parameterName, process((String)parameterValue, actionedUponNodeRef)); } } } /** * Process the value for substitution within the context of the provided node. * * @param value value * @param nodeRef node reference * @return String resulting value */ public String process(String value, NodeRef nodeRef) { return process(process(value, nodeRef, REG_EX_OLD), nodeRef, REG_EX); } public String process(String value, NodeRef nodeRef, String regExp) { // match the substitution pattern Pattern patt = Pattern.compile(regExp); Matcher m = patt.matcher(value); StringBuffer sb = new StringBuffer(value.length()); while (m.find()) { String text = m.group(1); // lookup parameter processor to use ParameterProcessor processor = lookupProcessor(text); if (processor == null) { throw new AlfrescoRuntimeException("A parameter processor has not been found for the substitution string " + text); } else { // process each substitution value text = processor.process(text, nodeRef); } // append new value m.appendReplacement(sb, Matcher.quoteReplacement(text)); } m.appendTail(sb); return sb.toString(); } /** * Return a list of substitution suggestions for the passed string fragment. * * @param subtitutionFragment Text fragment to search on. * @return A list of substitutions that match the substitution fragment. */ public List<String> getSubstitutionSuggestions(final String substitutionFragment) { List<String> suggestions = new ArrayList<String>(); for (ParameterSubstitutionSuggester suggestor : this.subtitutionSuggesterProcessors) { suggestions.addAll(suggestor.getSubstitutionSuggestions(substitutionFragment.toLowerCase())); } return suggestions; } /** * Look up parameter processor * * @param value * @return */ private ParameterProcessor lookupProcessor(String value) { ParameterProcessor result = null; if (value != null && !value.isEmpty()) { String[] values = value.split("\\.", 2); if (values.length != 0) { // get the processor from the registered map result = processors.get(values[0]); } } return result; } }