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