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