001/* 002 * Copyright 2014 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.script; 017 018import java.io.File; 019import java.io.IOException; 020import java.io.InputStream; 021import java.util.ArrayList; 022import java.util.Collections; 023import java.util.List; 024import java.util.Map; 025 026import org.apache.avalon.framework.component.Component; 027import org.apache.avalon.framework.configuration.Configuration; 028import org.apache.avalon.framework.configuration.ConfigurationException; 029import org.apache.avalon.framework.configuration.DefaultConfiguration; 030import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 031import org.apache.avalon.framework.context.ContextException; 032import org.apache.avalon.framework.context.Contextualizable; 033import org.apache.avalon.framework.logger.AbstractLogEnabled; 034import org.apache.avalon.framework.service.ServiceException; 035import org.apache.avalon.framework.service.ServiceManager; 036import org.apache.avalon.framework.service.Serviceable; 037import org.apache.cocoon.Constants; 038import org.apache.cocoon.environment.Context; 039import org.apache.commons.lang.StringUtils; 040import org.apache.excalibur.source.Source; 041import org.apache.excalibur.source.SourceResolver; 042import org.xml.sax.SAXException; 043 044import org.ametys.core.ui.Callable; 045import org.ametys.core.util.I18nUtils; 046import org.ametys.runtime.i18n.I18nizableText; 047 048/** 049 * Script manager. 050 * Can be used to retrieves global script functions and help text defined in various configuration files 051 */ 052public class ScriptManager extends AbstractLogEnabled implements Component, Contextualizable, Serviceable 053{ 054 /** The Avalon role */ 055 public static final String ROLE = ScriptManager.class.getName(); 056 057 /** The list of script configuration */ 058 protected static List<Configuration> _scriptConfigurations; 059 060 /** Cocoon context */ 061 protected Context _context; 062 063 /** i18n utils */ 064 protected I18nUtils _i18nUtils; 065 066 /** Source resolver */ 067 private SourceResolver _sourceResolver; 068 069 @Override 070 public void contextualize(org.apache.avalon.framework.context.Context context) throws ContextException 071 { 072 _context = (Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); 073 } 074 075 public void service(ServiceManager manager) throws ServiceException 076 { 077 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 078 _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 079 } 080 081 /** 082 * Initialize the static script files if needed. 083 * Returns list of configurations for these files. 084 * @return list of configurations 085 * @throws ConfigurationException If the configuration is wrong 086 * @throws SAXException If an error occurred 087 * @throws IOException If an error occurred 088 */ 089 protected List<Configuration> _getScriptConfigurations() throws ConfigurationException, SAXException, IOException 090 { 091 if (_scriptConfigurations == null) 092 { 093 _scriptConfigurations = new ArrayList<>(2); 094 095 Source pluginScriptsSource = _sourceResolver.resolveURI("plugin:cms://script/scripts.xml"); 096 097 try (InputStream is = pluginScriptsSource.getInputStream()) 098 { 099 Configuration pluginScriptsCfg = new DefaultConfigurationBuilder().build(is); 100 _scriptConfigurations.add(pluginScriptsCfg); 101 } 102 103 File webInfScriptsFile = new File(_context.getRealPath("/WEB-INF/param/scripts.xml")); 104 Configuration webInfScriptsCfg = webInfScriptsFile.exists() ? (DefaultConfiguration) new DefaultConfigurationBuilder().buildFromFile(webInfScriptsFile) : new DefaultConfiguration("scripts"); 105 _scriptConfigurations.add(webInfScriptsCfg); 106 } 107 108 return _scriptConfigurations; 109 } 110 111 /** 112 * Retrieves the configured scripts 113 * @return a String containing all the configured scripts 114 * @throws IOException If an error occurred 115 * @throws SAXException If an error occurred 116 * @throws ConfigurationException If the configuration is wrong 117 */ 118 public String getGlobalScripts() throws ConfigurationException, SAXException, IOException 119 { 120 List<Configuration> scriptConfigurations = _getScriptConfigurations(); 121 StringBuilder sb = new StringBuilder(); 122 123 for (Configuration scriptCfg : scriptConfigurations) 124 { 125 sb.append(scriptCfg.getChild("script").getValue(StringUtils.EMPTY)); 126 } 127 128 return sb.toString(); 129 } 130 131 /** 132 * Retrieves and concatenates the script descriptions 133 * @return a String containing the concatenated description 134 * @throws IOException If an error occurred 135 * @throws SAXException If an error occurred 136 * @throws ConfigurationException If the configuration is wrong 137 */ 138 @Callable 139 public Map<String, Object> getScriptHtmlDescription() throws ConfigurationException, SAXException, IOException 140 { 141 List<Configuration> scriptConfigurations = _getScriptConfigurations(); 142 StringBuilder sb = new StringBuilder(); 143 144 // Base description 145 sb.append(_i18nUtils.translate(new I18nizableText("plugin.cms", "UITOOL_SCRIPT_SEARCH_HELP_BASE_DESCRIPTION"))).append("<br/><br/>"); 146 147 // Description from files 148 for (Configuration scriptCfg : scriptConfigurations) 149 { 150 I18nizableText i18nDesc = _parseI18nizableText(scriptCfg, "cms", "description"); 151 String desc = _i18nUtils.translate(i18nDesc); 152 153 if (StringUtils.isNotEmpty(desc)) 154 { 155 sb.append(desc).append("<br/><br/>"); 156 } 157 } 158 159 return Collections.singletonMap("description", (Object) sb.toString()); 160 } 161 162 /** 163 * Parses an i18n text. 164 * @param config the configuration to use. 165 * @param pluginName the current plugin name. 166 * @param name the child name. 167 * @return the i18n text. 168 */ 169 protected I18nizableText _parseI18nizableText(Configuration config, String pluginName, String name) 170 { 171 return I18nizableText.parseI18nizableText(config.getChild(name), "plugin." + pluginName, ""); 172 } 173}