001/* 002 * Copyright 2012 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.userpref; 017 018import java.util.Collection; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.Map; 022import java.util.regex.Pattern; 023 024import org.apache.avalon.framework.activity.Disposable; 025import org.apache.avalon.framework.configuration.Configurable; 026import org.apache.avalon.framework.configuration.Configuration; 027import org.apache.avalon.framework.configuration.ConfigurationException; 028import org.apache.avalon.framework.context.Context; 029import org.apache.avalon.framework.context.ContextException; 030import org.apache.avalon.framework.context.Contextualizable; 031import org.apache.avalon.framework.service.ServiceException; 032import org.apache.avalon.framework.service.ServiceManager; 033import org.apache.avalon.framework.service.Serviceable; 034import org.apache.commons.lang3.StringUtils; 035 036import org.ametys.core.userpref.UserPreference; 037import org.ametys.core.userpref.UserPreferenceProvider; 038import org.ametys.runtime.parameter.AbstractParameterParser; 039import org.ametys.runtime.parameter.Enumerator; 040import org.ametys.runtime.parameter.ParameterHelper; 041import org.ametys.runtime.parameter.ParameterHelper.ParameterType; 042import org.ametys.runtime.parameter.Validator; 043import org.ametys.runtime.plugin.component.AbstractLogEnabled; 044import org.ametys.runtime.plugin.component.PluginAware; 045import org.ametys.runtime.plugin.component.ThreadSafeComponentManager; 046 047/** 048 * Provides user preferences based on static configuration. 049 */ 050public class StaticUserPreferenceProvider extends AbstractLogEnabled implements UserPreferenceProvider, Contextualizable, Serviceable, Configurable, PluginAware, Disposable 051{ 052 053 /** The user preferences, indexed by Id*/ 054 protected Map<String, UserPreference> _preferences; 055 056 /** ComponentManager for {@link Validator}s. */ 057 protected ThreadSafeComponentManager<Validator> _validatorManager; 058 059 /** ComponentManager for {@link Enumerator}s. */ 060 protected ThreadSafeComponentManager<Enumerator> _enumeratorManager; 061 062 /** Avalon service manager */ 063 protected ServiceManager _serviceManager; 064 065 /** Avalon context */ 066 protected Context _context; 067 068 /** The plugin name. */ 069 protected String _pluginName; 070 071 @Override 072 public void setPluginInfo(String pluginName, String featureName, String id) 073 { 074 _pluginName = pluginName; 075 } 076 077 @Override 078 public void contextualize(Context context) throws ContextException 079 { 080 _context = context; 081 } 082 083 @Override 084 public void service(ServiceManager manager) throws ServiceException 085 { 086 _serviceManager = manager; 087 } 088 089 @Override 090 public void dispose() 091 { 092 _validatorManager.dispose(); 093 _validatorManager = null; 094 _enumeratorManager.dispose(); 095 _enumeratorManager = null; 096 } 097 098 @Override 099 public void configure(Configuration configuration) throws ConfigurationException 100 { 101 _validatorManager = new ThreadSafeComponentManager<>(); 102 _validatorManager.setLogger(getLogger()); 103 _validatorManager.contextualize(_context); 104 _validatorManager.service(_serviceManager); 105 106 _enumeratorManager = new ThreadSafeComponentManager<>(); 107 _enumeratorManager.setLogger(getLogger()); 108 _enumeratorManager.contextualize(_context); 109 _enumeratorManager.service(_serviceManager); 110 111 UserPreferenceParser prefParser = new UserPreferenceParser(_enumeratorManager, _validatorManager); 112 113 _preferences = new HashMap<>(); 114 115 Configuration[] prefConfigurations = configuration.getChildren("param"); 116 for (Configuration prefConfiguration : prefConfigurations) 117 { 118 configurePreference(prefParser, prefConfiguration); 119 } 120 121 try 122 { 123 prefParser.lookupComponents(); 124 } 125 catch (Exception e) 126 { 127 throw new ConfigurationException("Unable to lookup parameter local components", configuration, e); 128 } 129 } 130 131 /** 132 * Configure a user preference. 133 * @param prefParser the preference parser. 134 * @param configuration The preference configuration. 135 * @throws ConfigurationException if configuration is incomplete or invalid. 136 */ 137 protected void configurePreference(UserPreferenceParser prefParser, Configuration configuration) throws ConfigurationException 138 { 139 UserPreference preference = prefParser.parseParameter(_serviceManager, _pluginName, configuration); 140 String id = preference.getId(); 141 142 if (_preferences.containsKey(id)) 143 { 144 throw new ConfigurationException("The user preference '" + id + "' is already declared. Preference IDs must be unique.", configuration); 145 } 146 147 _preferences.put(id, preference); 148 149 if (getLogger().isDebugEnabled()) 150 { 151 getLogger().debug("User preference added: " + id); 152 } 153 } 154 155 @Override 156 public Collection<UserPreference> getPreferences(Map<String, String> context) 157 { 158 Collection<UserPreference> userPrefs = new HashSet<>(); 159 160 String currentWorkspace = context.get(UserPreferenceProvider.CONTEXT_VAR_WORKSPACE); 161 for (UserPreference userPref : _preferences.values()) 162 { 163 Pattern workspace = ((StaticUserPreference) userPref).getWorkspace(); 164 if (StringUtils.isBlank(currentWorkspace) || workspace == null || workspace.matcher(currentWorkspace).matches()) 165 { 166 userPrefs.add(userPref); 167 } 168 } 169 170 return userPrefs; 171 } 172 173 /** 174 * A user pref with additionnal static information such as workspace 175 */ 176 class StaticUserPreference extends UserPreference 177 { 178 protected Pattern _workspace; 179 180 public void setWorkspace(Pattern workspace) 181 { 182 _workspace = workspace; 183 } 184 185 /** 186 * Get the workspace associated to this userpreference if any 187 * @return A pattern or null 188 */ 189 public Pattern getWorkspace() 190 { 191 return _workspace; 192 } 193 } 194 195 /** 196 * Parser for UserPreference. 197 */ 198 class UserPreferenceParser extends AbstractParameterParser<UserPreference, ParameterType> 199 { 200 public UserPreferenceParser(ThreadSafeComponentManager<Enumerator> enumeratorManager, ThreadSafeComponentManager<Validator> validatorManager) 201 { 202 super(enumeratorManager, validatorManager); 203 } 204 205 @Override 206 protected UserPreference _createParameter(Configuration parameterConfig) throws ConfigurationException 207 { 208 return new StaticUserPreference(); 209 } 210 211 @Override 212 protected String _parseId(Configuration parameterConfig) throws ConfigurationException 213 { 214 return parameterConfig.getAttribute("id"); 215 } 216 217 @Override 218 protected ParameterType _parseType(Configuration parameterConfig) throws ConfigurationException 219 { 220 try 221 { 222 return ParameterType.valueOf(parameterConfig.getAttribute("type").toUpperCase()); 223 } 224 catch (IllegalArgumentException e) 225 { 226 throw new ConfigurationException("Invalid parameter type", parameterConfig, e); 227 } 228 } 229 230 @Override 231 protected Object _parseDefaultValue(Configuration parameterConfig, UserPreference preference) 232 { 233 String defaultValue = parameterConfig.getChild("default-value").getValue(null); 234 return ParameterHelper.castValue(defaultValue, preference.getType()); 235 } 236 237 /** 238 * Parse the workspace if any to create a pattern 239 * @param configuration The user pref configuration 240 * @return The pattern or null 241 * @throws ConfigurationException if the configuration is wrong 242 */ 243 protected Pattern _parseWorkspace(Configuration configuration) throws ConfigurationException 244 { 245 String value = configuration.getChild("workspace").getValue(null); 246 if (StringUtils.isNotBlank(value)) 247 { 248 return Pattern.compile(value); 249 } 250 else 251 { 252 return null; 253 } 254 } 255 256 @Override 257 protected void _additionalParsing(ServiceManager manager, String pluginName, Configuration preferenceConfig, String parameterId, UserPreference preference) throws ConfigurationException 258 { 259 super._additionalParsing(manager, pluginName, preferenceConfig, parameterId, preference); 260 261 boolean multiple = preferenceConfig.getAttributeAsBoolean("multiple", false); 262 int order = preferenceConfig.getChild("order").getValueAsInteger(1000); 263 String managerRole = preferenceConfig.getChild("manager-role").getValue(null); 264 boolean privateStatus = preferenceConfig.getAttributeAsBoolean("private", false); 265 Pattern workspace = _parseWorkspace(preferenceConfig); 266 267 preference.setId(parameterId); 268 preference.setDisplayGroup(_parseI18nizableText(preferenceConfig, pluginName, "group")); 269 preference.setMultiple(multiple); 270 preference.setManagerRole(managerRole); 271 preference.setOrder(order); 272 preference.setPrivate(privateStatus); 273 ((StaticUserPreference) preference).setWorkspace(workspace); 274 } 275 } 276 277}