001/* 002 * Copyright 2016 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.plugins.core.impl.schedule; 017 018import java.util.LinkedHashMap; 019import java.util.Map; 020 021import org.apache.avalon.framework.component.Component; 022import org.apache.avalon.framework.configuration.Configurable; 023import org.apache.avalon.framework.configuration.Configuration; 024import org.apache.avalon.framework.configuration.ConfigurationException; 025import org.apache.avalon.framework.context.Context; 026import org.apache.avalon.framework.context.ContextException; 027import org.apache.avalon.framework.context.Contextualizable; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.avalon.framework.service.Serviceable; 031import org.quartz.JobExecutionContext; 032 033import org.ametys.core.schedule.Schedulable; 034import org.ametys.runtime.i18n.I18nizableText; 035import org.ametys.runtime.parameter.AbstractParameterParser; 036import org.ametys.runtime.parameter.Enumerator; 037import org.ametys.runtime.parameter.Parameter; 038import org.ametys.runtime.parameter.ParameterHelper; 039import org.ametys.runtime.parameter.ParameterHelper.ParameterType; 040import org.ametys.runtime.parameter.Validator; 041import org.ametys.runtime.plugin.component.AbstractLogEnabled; 042import org.ametys.runtime.plugin.component.PluginAware; 043import org.ametys.runtime.plugin.component.ThreadSafeComponentManager; 044 045/** 046 * Default static implementation of {@link Schedulable} 047 * For implementing the {@link Schedulable} interface (while being {@link Configurable}), extends this class and implements the {@link #execute(org.quartz.JobExecutionContext)} method 048 * <br> 049 * For instance: 050 * <pre> 051 * public class SayHelloSchedulable extends AbstractStaticSchedulable 052 * { 053 * public static final String FIRSTNAME_KEY = "firstName"; 054 * 055 * private static final String __JOBDATAMAP_FIRSTNAME_KEY = Scheduler.PARAM_VALUES_PREFIX + FIRSTNAME_KEY; 056 * 057 * public void execute(JobExecutionContext context) throws Exception 058 * { 059 * JobKey jobKey = context.getJobDetail().getKey(); 060 * JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); 061 * String name = jobDataMap.getString(__JOBDATAMAP_FIRSTNAME_KEY); 062 * System.out.println("[" + jobKey + "] " + new Date() + " - Hello " + name + "!"); 063 * } 064 * } 065 * </pre> 066 */ 067public abstract class AbstractStaticSchedulable extends AbstractLogEnabled implements Schedulable, Component, Configurable, PluginAware, Serviceable, Contextualizable 068{ 069 /** The name of the plugin that has declared this component */ 070 protected String _pluginName; 071 /** The id of this extension */ 072 protected String _id; 073 /** The service manager */ 074 protected ServiceManager _smanager; 075 /** The context */ 076 protected Context _context; 077 /** The label */ 078 protected I18nizableText _label; 079 /** The description */ 080 protected I18nizableText _description; 081 /** The icon glyph */ 082 protected String _iconGlyph; 083 /** The small icon */ 084 protected String _iconSmall; 085 /** The medium icon */ 086 protected String _iconMedium; 087 /** The large icon */ 088 protected String _iconLarge; 089 /** True if the schedulable is private */ 090 protected boolean _private; 091 /** True if two runnables of this schedulable can be executed concurrently */ 092 protected boolean _acceptConcurrentExecution; 093 /** The parameters */ 094 protected Map<String, Parameter<ParameterType>> _parameters; 095 096 @Override 097 public void setPluginInfo(String pluginName, String featureName, String id) 098 { 099 _pluginName = pluginName; 100 _id = id; 101 } 102 103 @Override 104 public void contextualize(Context context) throws ContextException 105 { 106 _context = context; 107 } 108 109 @Override 110 public void service(ServiceManager manager) throws ServiceException 111 { 112 _smanager = manager; 113 } 114 115 @Override 116 public void configure(Configuration configuration) throws ConfigurationException 117 { 118 _label = I18nizableText.parseI18nizableText(configuration.getChild("label"), "plugin." + _pluginName); 119 _description = I18nizableText.parseI18nizableText(configuration.getChild("description"), "plugin." + _pluginName); 120 _iconGlyph = configuration.getChild("icon-glyph").getValue(""); 121 _iconSmall = configuration.getChild("icon-small").getValue(""); 122 _iconMedium = configuration.getChild("icon-medium").getValue(""); 123 _iconLarge = configuration.getChild("icon-large").getValue(""); 124 _private = configuration.getChild("private").getValueAsBoolean(false); 125 _acceptConcurrentExecution = configuration.getChild("acceptConcurrentExecution").getValueAsBoolean(true); 126 _configureParameters(configuration.getChild("parameters")); 127 } 128 129 private void _configureParameters(Configuration paramConfigs) throws ConfigurationException 130 { 131 _parameters = new LinkedHashMap<>(); 132 133 ThreadSafeComponentManager<Validator> validatorManager = new ThreadSafeComponentManager<>(); 134 validatorManager.setLogger(getLogger()); 135 validatorManager.contextualize(_context); 136 validatorManager.service(_smanager); 137 138 ThreadSafeComponentManager<Enumerator> enumeratorManager = new ThreadSafeComponentManager<>(); 139 enumeratorManager.setLogger(getLogger()); 140 enumeratorManager.contextualize(_context); 141 enumeratorManager.service(_smanager); 142 143 SchedulableParameterParser paramParser = new SchedulableParameterParser(enumeratorManager, validatorManager); 144 for (Configuration paramConf : paramConfigs.getChildren("param")) 145 { 146 Parameter<ParameterType> parameter = paramParser.parseParameter(_smanager, _pluginName, paramConf); 147 String id = parameter.getId(); 148 149 if (_parameters.containsKey(id)) 150 { 151 throw new ConfigurationException("The parameter '" + id + "' is already declared. IDs must be unique.", paramConf); 152 } 153 154 _parameters.put(id, parameter); 155 } 156 157 try 158 { 159 paramParser.lookupComponents(); 160 } 161 catch (Exception e) 162 { 163 throw new ConfigurationException("Unable to lookup parameter local components", paramConfigs, e); 164 } 165 } 166 167 @Override 168 public abstract void execute(JobExecutionContext context) throws Exception; 169 170 @Override 171 public String getId() 172 { 173 return _id; 174 } 175 176 @Override 177 public I18nizableText getLabel() 178 { 179 return _label; 180 } 181 182 @Override 183 public I18nizableText getDescription() 184 { 185 return _description; 186 } 187 188 @Override 189 public String getIconGlyph() 190 { 191 return _iconGlyph; 192 } 193 194 @Override 195 public String getIconSmall() 196 { 197 return _iconSmall; 198 } 199 200 @Override 201 public String getIconMedium() 202 { 203 return _iconMedium; 204 } 205 206 @Override 207 public String getIconLarge() 208 { 209 return _iconLarge; 210 } 211 212 @Override 213 public boolean isPrivate() 214 { 215 return _private; 216 } 217 218 @Override 219 public boolean acceptConcurrentExecution() 220 { 221 return _acceptConcurrentExecution; 222 } 223 224 @Override 225 public Map<String, Parameter<ParameterType>> getParameters() 226 { 227 return _parameters; 228 } 229 230 /** 231 * Class for parsing parameters of a {@link Schedulable} 232 */ 233 public class SchedulableParameterParser extends AbstractParameterParser<Parameter<ParameterType>, ParameterType> 234 { 235 /** 236 * Constructor 237 * @param enumeratorManager The manager for enumeration 238 * @param validatorManager The manager for validation 239 */ 240 public SchedulableParameterParser(ThreadSafeComponentManager<Enumerator> enumeratorManager, ThreadSafeComponentManager<Validator> validatorManager) 241 { 242 super(enumeratorManager, validatorManager); 243 } 244 245 @Override 246 protected Parameter<ParameterType> _createParameter(Configuration parameterConfig) throws ConfigurationException 247 { 248 return new Parameter<>(); 249 } 250 251 @Override 252 protected String _parseId(Configuration parameterConfig) throws ConfigurationException 253 { 254 return parameterConfig.getAttribute("id"); 255 } 256 257 @Override 258 protected ParameterType _parseType(Configuration parameterConfig) throws ConfigurationException 259 { 260 try 261 { 262 return ParameterType.valueOf(parameterConfig.getAttribute("type").toUpperCase()); 263 } 264 catch (IllegalArgumentException e) 265 { 266 throw new ConfigurationException("Invalid parameter type", parameterConfig, e); 267 } 268 } 269 270 @Override 271 protected Object _parseDefaultValue(Configuration parameterConfig, Parameter<ParameterType> parameter) throws ConfigurationException 272 { 273 String defaultValue = parameterConfig.getChild("default-value").getValue(null); 274 return ParameterHelper.castValue(defaultValue, parameter.getType()); 275 } 276 277 @Override 278 protected void _additionalParsing(ServiceManager manager, String pluginName, Configuration parameterConfig, String parameterId, Parameter<ParameterType> parameter) 279 throws ConfigurationException 280 { 281 super._additionalParsing(manager, pluginName, parameterConfig, parameterId, parameter); 282 parameter.setId(parameterId); 283 } 284 } 285}