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.core.schedule.SchedulableParameterTypeExtensionPoint; 035import org.ametys.core.user.UserManager; 036import org.ametys.runtime.i18n.I18nizableText; 037import org.ametys.runtime.model.ElementDefinition; 038import org.ametys.runtime.model.ElementDefinitionParser; 039import org.ametys.runtime.model.Enumerator; 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, ElementDefinition> _parameters; 095 /** The Schedulable Extension Point */ 096 protected SchedulableParameterTypeExtensionPoint _schedulableParameterTypeExtensionPoint; 097 /** The user manager */ 098 protected UserManager _userManager; 099 100 @Override 101 public void setPluginInfo(String pluginName, String featureName, String id) 102 { 103 _pluginName = pluginName; 104 _id = id; 105 } 106 107 @Override 108 public void contextualize(Context context) throws ContextException 109 { 110 _context = context; 111 } 112 113 @Override 114 public void service(ServiceManager manager) throws ServiceException 115 { 116 _smanager = manager; 117 _schedulableParameterTypeExtensionPoint = (SchedulableParameterTypeExtensionPoint) _smanager.lookup(SchedulableParameterTypeExtensionPoint.ROLE); 118 _userManager = (UserManager) manager.lookup(UserManager.ROLE); 119 } 120 121 @Override 122 public void configure(Configuration configuration) throws ConfigurationException 123 { 124 _label = I18nizableText.parseI18nizableText(configuration.getChild("label"), "plugin." + _pluginName); 125 _description = I18nizableText.parseI18nizableText(configuration.getChild("description"), "plugin." + _pluginName); 126 _iconGlyph = configuration.getChild("icon-glyph").getValue(""); 127 _iconSmall = configuration.getChild("icon-small").getValue(""); 128 _iconMedium = configuration.getChild("icon-medium").getValue(""); 129 _iconLarge = configuration.getChild("icon-large").getValue(""); 130 _private = configuration.getChild("private").getValueAsBoolean(false); 131 _acceptConcurrentExecution = configuration.getChild("acceptConcurrentExecution").getValueAsBoolean(true); 132 _configureParameters(configuration.getChild("parameters")); 133 } 134 135 private void _configureParameters(Configuration paramConfigs) throws ConfigurationException 136 { 137 _parameters = new LinkedHashMap<>(); 138 139 ThreadSafeComponentManager<Validator> validatorManager = new ThreadSafeComponentManager<>(); 140 validatorManager.setLogger(getLogger()); 141 validatorManager.contextualize(_context); 142 validatorManager.service(_smanager); 143 144 ThreadSafeComponentManager<Enumerator> enumeratorManager = new ThreadSafeComponentManager<>(); 145 enumeratorManager.setLogger(getLogger()); 146 enumeratorManager.contextualize(_context); 147 enumeratorManager.service(_smanager); 148 149 SchedulableParameterParser paramParser = new SchedulableParameterParser(_schedulableParameterTypeExtensionPoint, enumeratorManager, validatorManager); 150 for (Configuration paramConf : paramConfigs.getChildren("param")) 151 { 152 ElementDefinition definition = paramParser.parse(_smanager, _pluginName, paramConf, null, null); 153 String id = definition.getName(); 154 155 if (_parameters.containsKey(id)) 156 { 157 throw new ConfigurationException("The parameter '" + id + "' is already declared. IDs must be unique.", paramConf); 158 } 159 160 _parameters.put(id, definition); 161 } 162 163 try 164 { 165 paramParser.lookupComponents(); 166 } 167 catch (Exception e) 168 { 169 throw new ConfigurationException("Unable to lookup parameter local components", paramConfigs, e); 170 } 171 } 172 173 @Override 174 public abstract void execute(JobExecutionContext context) throws Exception; 175 176 @Override 177 public String getId() 178 { 179 return _id; 180 } 181 182 @Override 183 public I18nizableText getLabel() 184 { 185 return _label; 186 } 187 188 @Override 189 public I18nizableText getDescription() 190 { 191 return _description; 192 } 193 194 @Override 195 public String getIconGlyph() 196 { 197 return _iconGlyph; 198 } 199 200 @Override 201 public String getIconSmall() 202 { 203 return _iconSmall; 204 } 205 206 @Override 207 public String getIconMedium() 208 { 209 return _iconMedium; 210 } 211 212 @Override 213 public String getIconLarge() 214 { 215 return _iconLarge; 216 } 217 218 @Override 219 public boolean isPrivate() 220 { 221 return _private; 222 } 223 224 @Override 225 public boolean acceptConcurrentExecution() 226 { 227 return _acceptConcurrentExecution; 228 } 229 230 @Override 231 public Map<String, ElementDefinition> getParameters() 232 { 233 return _parameters; 234 } 235 236 /** 237 * Class for parsing parameters of a {@link Schedulable} 238 */ 239 public class SchedulableParameterParser extends ElementDefinitionParser 240 { 241 /** 242 * Constructor 243 * @param schedulableParameterTypeExtensionPoint the extension point to use to get available element types 244 * @param enumeratorManager The manager for enumeration 245 * @param validatorManager The manager for validation 246 */ 247 public SchedulableParameterParser(SchedulableParameterTypeExtensionPoint schedulableParameterTypeExtensionPoint, ThreadSafeComponentManager<Enumerator> enumeratorManager, ThreadSafeComponentManager<Validator> validatorManager) 248 { 249 super(schedulableParameterTypeExtensionPoint, enumeratorManager, validatorManager); 250 } 251 252 @Override 253 protected String _getNameConfigurationAttribute() 254 { 255 return "id"; 256 } 257 } 258}