001/*
002 *  Copyright 2015 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.runtime.plugin;
017
018import java.util.Collection;
019import java.util.Collections;
020import java.util.HashMap;
021import java.util.Map;
022
023import org.apache.avalon.framework.configuration.Configuration;
024import org.apache.avalon.framework.configuration.ConfigurationException;
025
026import org.ametys.runtime.config.ConfigParameterInfo;
027
028/**
029 * Object representation of a plugin.xml
030 */
031public class Plugin
032{
033    /** Name for fake plugins, eg. declared on the fly */
034    public static final String DEFAULT_NAME = "_default";
035    
036    private String _pluginName;
037    private String _version;
038    private Configuration _configuration;
039    
040    private Map<String, ConfigParameterInfo> _configParameters = new HashMap<>();
041    private Map<String, ConfigParameterInfo> _paramCheckers = new HashMap<>();
042    private Map<String, Feature> _features = new HashMap<>();
043    private Map<String, ExtensionPointDefinition> _extensionPoints = new HashMap<>();
044    
045    Plugin(String pluginName)
046    {
047        _pluginName = pluginName;
048    }
049    
050    /**
051     * Returns this plugin's name.
052     * @return this plugin's name.
053     */
054    public String getName()
055    {
056        return _pluginName;
057    }
058    
059    /**
060     * Returns this plugin's version, or null if not specified.
061     * @return this plugin's version.
062     */
063    public String getVersion()
064    {
065        return _version;
066    }
067    
068    /**
069     * Returns the {@link Feature}s defined by this plugin.
070     * @return the {@link Feature}s defined by this plugin.
071     */
072    public Map<String, Feature> getFeatures()
073    {
074        return _features;
075    }
076    
077    /**
078     * Returns the ids of the extension points defined by this plugin.
079     * @return the ids of the extension points defined by this plugin.
080     */
081    public Collection<String> getExtensionPoints()
082    {
083        return Collections.unmodifiableSet(_extensionPoints.keySet());
084    }
085    
086    Configuration getConfiguration()
087    {
088        return _configuration;
089    }
090    
091    Map<String, ExtensionPointDefinition> getExtensionPointDefinitions()
092    {
093        return _extensionPoints;
094    }
095    
096    Map<String, ConfigParameterInfo> getConfigParameters()
097    {
098        return _configParameters;
099    }
100    
101    Map<String, ConfigParameterInfo> getParameterCheckers()
102    {
103        return _paramCheckers;
104    }
105    
106    void configure(Configuration configuration) throws ConfigurationException
107    {
108        _configuration = configuration;
109        
110        _version = configuration.getAttribute("version", null);
111        
112        Configuration configConfiguration = configuration.getChild("config");
113        
114        _configureConfigParameters(configConfiguration);
115        _configureParametersCheckers(configConfiguration);
116        
117        _configureFeatures();
118        _configureExtensionPoints();
119    }
120    
121    private void _configureConfigParameters(Configuration configConfiguration)
122    {
123        Configuration[] parameterConfigurations = configConfiguration.getChildren("param");
124        for (Configuration parameterConfiguration : parameterConfigurations)
125        {
126            // XML schema requires attributes id and enforces id uniqueness
127            String id = parameterConfiguration.getAttribute("id", null);
128            
129            // Add the new parameter to the list of declared parameters
130            _configParameters.put(id, new ConfigParameterInfo(id, _pluginName, parameterConfiguration));
131        }            
132    }
133    
134    private void _configureParametersCheckers(Configuration configConfiguration)
135    {
136        Configuration[] parameterConfigurations = configConfiguration.getChildren("param-checker");
137        for (Configuration parameterConfiguration : parameterConfigurations)
138        {
139            String id = parameterConfiguration.getAttribute("id", null);
140            
141            // Add the new parameter to the list of declared parameters
142            _paramCheckers.put(id, new ConfigParameterInfo(id, _pluginName, parameterConfiguration));
143        }            
144    }
145
146    private void _configureFeatures()
147    {
148        Configuration[] featuresConf = _configuration.getChildren("feature");
149        
150        for (Configuration conf : featuresConf)
151        {
152            // XML schema requires attributes name and enforces name uniqueness
153            String featureName = conf.getAttribute("name", null);
154            
155            Feature feature = new Feature(_pluginName, featureName);
156            feature.configure(conf);
157            _features.put(feature.getFeatureId(), feature);
158        }
159    }
160    
161    private void _configureExtensionPoints() throws ConfigurationException
162    {
163        Configuration[] extPointConfs = _configuration.getChild("extension-points").getChildren("extension-point");
164        
165        for (Configuration conf : extPointConfs)
166        {
167            // XML schema requires attributes class
168            String clazz = conf.getAttribute("class", null);
169            String id = conf.getAttribute("id", clazz);
170            boolean safe = conf.getAttributeAsBoolean("safe", false);
171            
172            if (_extensionPoints.containsKey(id))
173            {
174                throw new ConfigurationException("Extension point id should be unique: " + id, conf);
175            }
176            
177            _extensionPoints.put(id, new ExtensionPointDefinition(id, conf, _pluginName, safe));
178        }
179    }
180}