001/* 002 * Copyright 2010 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.web.site; 017 018import java.util.Collections; 019import java.util.LinkedHashMap; 020import java.util.Map; 021import java.util.Set; 022import java.util.regex.Pattern; 023 024import org.apache.avalon.framework.configuration.Configuration; 025import org.apache.avalon.framework.configuration.ConfigurationException; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028 029import org.ametys.runtime.model.Enumerator; 030import org.ametys.runtime.model.disableconditions.DisableConditions; 031import org.ametys.runtime.parameter.Validator; 032import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint; 033import org.ametys.runtime.plugin.component.ThreadSafeComponentManager; 034import org.ametys.web.data.type.ModelItemTypeExtensionPoint; 035 036/** 037 * Extension point holding all {@link SiteParameterWrapper} definitions. 038 */ 039public class SiteConfigurationExtensionPoint extends AbstractThreadSafeComponentExtensionPoint<SiteParameterWrapper> 040{ 041 /** Avalon Role */ 042 public static final String ROLE = SiteConfigurationExtensionPoint.class.getName(); 043 044 private static final Pattern __PARAM_NAME_PATTERN = Pattern.compile("[a-z][a-z0-9-_]*", Pattern.CASE_INSENSITIVE); 045 046 /** Parameter's wrappers map, indexed by parameter ID. */ 047 private Map<String, SiteParameterWrapper> _parameterWrappers; 048 049 /** ComponentManager for {@link DisableConditions}. */ 050 private ThreadSafeComponentManager<DisableConditions> _disableConditionsManager; 051 052 /** ComponentManager for {@link Validator}s. */ 053 private ThreadSafeComponentManager<Validator> _validatorManager; 054 055 /** ComponentManager for {@link Enumerator}s. */ 056 private ThreadSafeComponentManager<Enumerator> _enumeratorManager; 057 058 /** Parser of parameter's wrappers */ 059 private SiteParameterWrapperParser _parameterWrapperParser; 060 061 /** Site parameter parser. */ 062 private SiteParameterParser _parameterParser; 063 064 private ModelItemTypeExtensionPoint _siteParameterTypeEP; 065 066 067 @Override 068 public void initialize() throws Exception 069 { 070 super.initialize(); 071 072 _parameterWrappers = new LinkedHashMap<>(); 073 074 _disableConditionsManager = new ThreadSafeComponentManager<>(); 075 _disableConditionsManager.setLogger(getLogger()); 076 _disableConditionsManager.contextualize(_context); 077 _disableConditionsManager.service(_cocoonManager); 078 079 _validatorManager = new ThreadSafeComponentManager<>(); 080 _validatorManager.setLogger(getLogger()); 081 _validatorManager.contextualize(_context); 082 _validatorManager.service(_cocoonManager); 083 084 _enumeratorManager = new ThreadSafeComponentManager<>(); 085 _enumeratorManager.setLogger(getLogger()); 086 _enumeratorManager.contextualize(_context); 087 _enumeratorManager.service(_cocoonManager); 088 089 _parameterParser = new SiteParameterParser(_siteParameterTypeEP, _disableConditionsManager, _enumeratorManager, _validatorManager); 090 _parameterWrapperParser = new SiteParameterWrapperParser(_parameterParser); 091 } 092 093 @Override 094 public void service(ServiceManager manager) throws ServiceException 095 { 096 super.service(manager); 097 _siteParameterTypeEP = (ModelItemTypeExtensionPoint) manager.lookup(ModelItemTypeExtensionPoint.ROLE_SITE_PARAM); 098 } 099 100 /** 101 * Dispose the manager before restarting it 102 */ 103 @Override 104 public void dispose() 105 { 106 _parameterWrapperParser = null; 107 _parameterParser = null; 108 109 _parameterWrappers = null; 110 _disableConditionsManager.dispose(); 111 _disableConditionsManager = null; 112 _validatorManager.dispose(); 113 _validatorManager = null; 114 _enumeratorManager.dispose(); 115 _enumeratorManager = null; 116 117 super.dispose(); 118 } 119 120 @Override 121 public boolean hasExtension(String id) 122 { 123 return _parameterWrappers.containsKey(id); 124 } 125 126 @Override 127 public void addExtension(String id, String pluginName, String featureName, Configuration configuration) throws ConfigurationException 128 { 129 if (getLogger().isDebugEnabled()) 130 { 131 getLogger().debug("Adding site parameters from feature " + pluginName + "/" + featureName); 132 } 133 134 Configuration[] parameterConfigurations = configuration.getChildren("param"); 135 for (Configuration parameterConfiguration : parameterConfigurations) 136 { 137 _addParameter(pluginName, featureName, parameterConfiguration); 138 } 139 } 140 141 /** 142 * Declare a site parameter. 143 * @param pluginName The name of the plugin declaring the extension. 144 * @param featureName the name of the feature 145 * @param configuration The parameter configuration. 146 * @throws ConfigurationException if configuration is not complete. 147 */ 148 protected void _addParameter(String pluginName, String featureName, Configuration configuration) throws ConfigurationException 149 { 150 SiteParameterWrapper parameter = _parameterWrapperParser.parse(_cocoonManager, pluginName, configuration); 151 152 String name = parameter.getDefinition().getName(); 153 154 if (!__PARAM_NAME_PATTERN.matcher(name).matches()) 155 { 156 throw new ConfigurationException("The feature " + pluginName + "/" + featureName + " declared an invalid site parameter name '" + name + "'. This value is not permited: only [a-zA-Z][a-zA-Z0-9-_]* are allowed.", configuration); 157 } 158 159 if (_parameterWrappers.containsKey(name)) 160 { 161 throw new ConfigurationException("In feature " + pluginName + "/" + featureName + " the parameter '" + name + "' is already declared. Parameter ids must be unique.", configuration); 162 } 163 164 _parameterWrappers.put(name, parameter); 165 166 if (getLogger().isDebugEnabled()) 167 { 168 getLogger().debug("Site parameter added: " + name); 169 } 170 } 171 172 @Override 173 public SiteParameterWrapper getExtension(String id) 174 { 175 if (hasExtension(id)) 176 { 177 return _parameterWrappers.get(id); 178 } 179 else 180 { 181 throw new IllegalArgumentException("There is no site parameter named '" + id + "'."); 182 } 183 } 184 185 @Override 186 public Set<String> getExtensionsIds() 187 { 188 return Collections.unmodifiableSet(_parameterWrappers.keySet()); 189 } 190 191 @Override 192 public void initializeExtensions() throws Exception 193 { 194 super.initializeExtensions(); 195 _parameterParser.lookupComponents(); 196 } 197}