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.cms.search.model;
017
018import java.util.ArrayList;
019import java.util.Collections;
020import java.util.List;
021
022import org.apache.avalon.framework.component.ComponentException;
023import org.apache.avalon.framework.configuration.Configuration;
024import org.apache.avalon.framework.configuration.ConfigurationException;
025import org.apache.commons.lang3.StringUtils;
026
027import org.ametys.cms.data.type.ModelItemTypeExtensionPoint;
028import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint;
029
030/**
031 * Extension point handling {@link SystemProperty} objects.
032 */
033public class SystemPropertyExtensionPoint extends AbstractThreadSafeComponentExtensionPoint<SystemProperty>// implements Initializable
034{
035    /** The extension point role. */
036    public static final String ROLE = SystemPropertyExtensionPoint.class.getName();
037    
038    /** Collection of the displayable properties. */
039    protected List<String> _displayProps;
040    
041    @Override
042    public void addExtension(String id, String pluginName, String featureName, Configuration configuration) throws ConfigurationException
043    {
044        if (getLogger().isDebugEnabled())
045        {
046            getLogger().debug("Adding system properties from feature " + pluginName + "/" + featureName);
047        }
048        
049        try
050        {
051            for (Configuration propConf : configuration.getChildren("property"))
052            {
053                addSystemProperty(pluginName, featureName, propConf);
054            }
055        }
056        catch (ConfigurationException e)
057        {
058            if (getLogger().isWarnEnabled())
059            {
060                getLogger().warn("The feature '" + pluginName + "/" + featureName + "' declares a system property extension with an invalid configuration.", e);
061            }
062        }
063    }
064    
065    /**
066     * Declare a new system property.
067     * @param pluginName The name of the plugin declaring the extension
068     * @param featureName The feature name.
069     * @param configuration The configuration of the extension
070     * @throws ConfigurationException if configuration if not complete
071     */
072    @SuppressWarnings("unchecked")
073    protected void addSystemProperty(String pluginName, String featureName, Configuration configuration) throws ConfigurationException
074    {
075        String id = configuration.getAttribute("id", "");
076        if (StringUtils.isBlank(id))
077        {
078            throw new ConfigurationException("SystemProperty declaration is incorrect since no 'id' attribute is specified (or may be empty)", configuration);
079        }
080        
081        String className = configuration.getAttribute("class", "");
082        if (StringUtils.isBlank(className))
083        {
084            throw new ConfigurationException("SystemProperty declaration is incorrect since no 'class' attribute is specified (or may be empty)", configuration);
085        }
086        
087        try
088        {
089            Class<?> clazz = Class.forName(className);
090            if (!SystemProperty.class.isAssignableFrom(clazz))
091            {
092                throw new ConfigurationException("The system property declaration must be declared with a class implementing SystemProperty.");
093            }
094            
095            addComponent(pluginName, featureName, id, (Class<? extends SystemProperty>) clazz, configuration);
096        }
097        catch (ComponentException | ClassNotFoundException e)
098        {
099            throw new ConfigurationException("Unable to instanciate the SystemProperty of id '" + id + "'.", e);
100        }
101    }
102    
103    @Override
104    public void initializeExtensions() throws Exception
105    {
106        super.initializeExtensions();
107        
108        _displayProps = new ArrayList<>();
109        for (String id : getExtensionsIds())
110        {
111            SystemProperty prop = getExtension(id);
112            prop.init(ModelItemTypeExtensionPoint.ROLE_CONTENT_PROPERTY);
113            
114            if (prop.isDisplayable())
115            {
116                _displayProps.add(id);
117            }
118        }
119    }
120    
121    /**
122     * Get the IDs of the properties that can be displayed.
123     * @return The Collection of properties that can be displayed.
124     */
125    public List<String> getDisplayProperties()
126    {
127        return Collections.unmodifiableList(_displayProps);
128    }
129    
130    /**
131     * Tests if a property exists and is displayable.
132     * @param name The property name.
133     * @return <code>true</code> if the property exists and is displayable.
134     */
135    public boolean isDisplayable(String name)
136    {
137        return _displayProps.contains(name);
138    }
139}