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.plugins.repository;
017
018import java.util.Collections;
019import java.util.HashMap;
020import java.util.HashSet;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.avalon.framework.configuration.Configuration;
025import org.apache.avalon.framework.configuration.ConfigurationException;
026
027import org.ametys.plugins.repository.jcr.JCRAmetysObjectFactory;
028import org.ametys.runtime.plugin.ExtensionPoint;
029import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint;
030
031/**
032 * {@link ExtensionPoint} hosting all {@link AmetysObjectFactory}.
033 */
034public class AmetysObjectFactoryExtensionPoint extends AbstractThreadSafeComponentExtensionPoint<AmetysObjectFactory>
035{
036    /** Avalon Role */
037    public static final String ROLE = AmetysObjectFactoryExtensionPoint.class.getName();
038    
039    private Map<String, AmetysObjectFactory> _schemes = new HashMap<>();
040    private Map<String, AmetysObjectFactory> _nodetypes = new HashMap<>();
041    private Map<String, Set<String>> _nodetypeDefinitions = new HashMap<>();
042    
043    @Override
044    public void initializeExtensions() throws Exception
045    {
046        super.initializeExtensions();
047        
048        for (String id : getExtensionsIds())
049        {
050            AmetysObjectFactory factory = getExtension(id);
051            _schemes.put(factory.getScheme(), factory);
052            
053            if (factory instanceof JCRAmetysObjectFactory)
054            {
055                JCRAmetysObjectFactory<?> jcrFactory = (JCRAmetysObjectFactory) factory;
056                
057                for (String nodetype : jcrFactory.getNodetypes())
058                {
059                    if (_nodetypes.containsKey(nodetype))
060                    {
061                        throw new IllegalArgumentException("Nodetype '" + nodetype + "' cannot be managed by more than one factory.");
062                    }
063                    
064                    _nodetypes.put(nodetype, factory);
065                }
066            }
067        }
068    }
069    
070    @Override
071    public void addExtension(String id, String pluginName, String pluginId, Configuration configuration) throws ConfigurationException
072    {
073        super.addExtension(id, pluginName, pluginId, configuration);
074        
075        String nodetypeDef = configuration.getChild("nodetype-definition", true).getValue(null);
076        String nodetypePlugin = configuration.getChild("nodetype-definition", true).getAttribute("plugin", pluginName);
077        
078        // Add the nodetype definition 
079        if (nodetypeDef != null)
080        {
081            Set<String> pluginDefs = null;
082            if (_nodetypeDefinitions.containsKey(nodetypePlugin))
083            {
084                pluginDefs = _nodetypeDefinitions.get(nodetypePlugin);
085            }
086            else
087            {
088                pluginDefs = new HashSet<>();
089                _nodetypeDefinitions.put(nodetypePlugin, pluginDefs);
090            }
091            
092            pluginDefs.add(nodetypeDef);
093        }
094    }
095    
096    /**
097     * Returns the declared nodetypes definitions.
098     * @return the declared nodetypes definitions.
099     */
100    public Map<String, Set<String>> getNodeTypeDefinitions()
101    {
102        return Collections.unmodifiableMap(_nodetypeDefinitions);
103    }
104    
105    /**
106     * Returns the {@link AmetysObjectFactory} corresponding to the given scheme.
107     * @param scheme the scheme.
108     * @return the {@link AmetysObjectFactory} or <code>null</code> if not found.
109     */
110    public AmetysObjectFactory getFactoryForScheme(String scheme)
111    {
112        return _schemes.get(scheme);
113    }
114    
115    /**
116     * Returns the {@link AmetysObjectFactory} corresponding to the given nodetype.
117     * @param nodetype the nodetype.
118     * @return the {@link AmetysObjectFactory} or <code>null</code> if not found.
119     */
120    public AmetysObjectFactory getFactoryForNodetype(String nodetype)
121    {
122        return _nodetypes.get(nodetype);
123    }
124}