/*******************************************************************************
 * Copyright (c) 2001, 2007 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.common;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.util.ResourceLocator;
import org.eclipse.jst.jsf.context.symbol.source.AbstractContextSymbolFactory;
import org.eclipse.jst.jsf.context.symbol.source.ISymbolSourceProvider;
import org.eclipse.jst.jsf.context.symbol.source.ISymbolSourceProviderFactory;
import org.osgi.framework.Bundle;

/**
 * This is the central singleton for the My edit plugin.
 * <!-- begin-user-doc -->
 * This class is not API.
 * <!-- end-user-doc -->
 * @generated
 */
public final class JSFCommonPlugin extends EMFPlugin {

	/**
	 * Plugin id
	 */
	public static final String PLUGIN_ID = "org.eclipse.jst.jsf.common"; //$NON-NLS-1$

	/**
	 * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
	 * @generated
	 */
    public static final String copyright = "Copyright 2006 Oracle"; //$NON-NLS-1$

    private static List<ISymbolSourceProviderFactory>  registeredSymbolSourceProviders;
    private static Map<String,AbstractContextSymbolFactory>   registeredSymbolFactories;
    
    private final static String     FACTORY_ATTRIBUTE_NAME = "factory"; //$NON-NLS-1$
    private final static String     FACTORY_ATTRIBUTE_ID_NAME = "factoryId";  //$NON-NLS-1$
    private final static String     SYMBOL_SOURCE_ID = "symbolSourceId";  //$NON-NLS-1$
    private final static String     CONTEXT_SYMBOL_FACTORY =  "contextSymbolFactory"; //$NON-NLS-1$
	/**
	 * Keep track of the singleton.
	 * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
	 * @generated
	 */
    public static final JSFCommonPlugin INSTANCE = new JSFCommonPlugin();

	/**
	 * Keep track of the singleton.
	 * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
	 * @generated
	 */
    private static Implementation plugin;

	/**
	 * Create the instance.
	 * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
	 * @generated
	 */
    public JSFCommonPlugin() {
		super
		  (new ResourceLocator [] {
		   });
	}

	/**
	 * Returns the singleton instance of the Eclipse plugin.
	 * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
	 * @return the singleton instance.
	 * @generated
	 */
    public ResourceLocator getPluginResourceLocator() {
		return plugin;
	}

	/**
	 * Returns the singleton instance of the Eclipse plugin.
	 * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
	 * @return the singleton instance.
	 * @generated
	 */
    public static Implementation getPlugin() {
		return plugin;
	}

    /**
     * @param e
     * @param msg
     */
    public static void log(final Exception e, final String msg) {
        final ILog log = getPlugin().getLog();

        log.log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, msg, e));
    }

    /**
     * Logs using the default ILog implementation provided by getLog().
     * 
     * @param severity Severity (IStatus constant) of log entry
     * @param message Human-readable message describing log entry
     * @param ex Throwable instance (can be null)
     */
    public static void log(int severity, String message, Throwable ex) {
        getPlugin().getLog().log(new Status(severity, PLUGIN_ID, IStatus.OK, message, ex));
    }

    /**
     * Logs using the default ILog implementation provided by getLog().
     * 
     * @param severity Severity (IStatus constant) of log entry
     * @param message Human-readable message describing log entry
     */
    public static void log(int severity, String message) {
        log(severity, message, null);
    }
    /**
     * @return all registered symbol source providers
     */
    public static ISymbolSourceProvider[]  getSymbolSourceProvider()
    {
        return registeredSymbolSourceProviders.toArray(new ISymbolSourceProvider[0]);
    }
    
    /**
     * @return all registered symbol source providers
     */
    public synchronized static List<ISymbolSourceProviderFactory> getSymbolSourceProviders()
    {
        if (registeredSymbolSourceProviders == null)
        {
            registerProviders();
            if (registeredSymbolSourceProviders == null)
            {
                throw new AssertionError("registerProviders failed"); //$NON-NLS-1$
            }
        }
        return Collections.unmodifiableList(registeredSymbolSourceProviders);
    }
    
    private static void registerProviders()
    {
        final IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(plugin.getBundle().getSymbolicName(), Implementation.SYMBOL_SOURCE_EXT_ID);
        final IExtension[] extensions = point.getExtensions();
        registeredSymbolSourceProviders = new ArrayList<ISymbolSourceProviderFactory>(extensions.length);

        for (int i = 0; i < extensions.length; i++)
        {
            final IExtension extension = extensions[i];
            final IConfigurationElement[] elements = 
                extension.getConfigurationElements();
            final String bundleId = extension.getContributor().getName();
            
            for (int j = 0; j < elements.length; j++)
            {
                final IConfigurationElement element = elements[j];
                if (SYMBOL_SOURCE_ID.equals(element.getName())
                        && element.getAttribute(FACTORY_ATTRIBUTE_NAME) != null)
                {
                    String factoryClassName = element.getAttribute(FACTORY_ATTRIBUTE_NAME);
                    final Bundle bundle = Platform.getBundle(bundleId);
                    
                    if (bundle != null)
                    {
                        try
                        {
                            Class factoryClass = bundle.loadClass(factoryClassName);
                            
                            ISymbolSourceProviderFactory factory = 
                                (ISymbolSourceProviderFactory) factoryClass.newInstance();

                            registeredSymbolSourceProviders.add(factory);
                        }
                        catch (Exception e)
                        {
                            plugin.log(new Status(IStatus.ERROR, plugin.getBundle().getSymbolicName(), 0, "Error loading symbol provider extension point",e)); //$NON-NLS-1$
                        }
                    }
                }
            }
        }
    }

    /**
     * @return the list of registed symbol factories
     */
    public synchronized static Map<String, AbstractContextSymbolFactory> getSymbolFactories()
    {
        if (registeredSymbolFactories == null)
        {
            registerSymbolFactories();
            if (registeredSymbolFactories == null)
            {
                throw new AssertionError("registerProviders failed"); //$NON-NLS-1$
            }
        }
        return Collections.unmodifiableMap(registeredSymbolFactories);
    }
    
    private static void registerSymbolFactories()
    {
        final IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(plugin.getBundle().getSymbolicName(), Implementation.SYMBOL_FACTORY_EXT_ID);
        final IExtension[] extensions = point.getExtensions();
        registeredSymbolFactories = new HashMap<String, AbstractContextSymbolFactory>(extensions.length);

        for (int i = 0; i < extensions.length; i++)
        {
            final IExtension extension = extensions[i];
            final IConfigurationElement[] elements = 
                extension.getConfigurationElements();
            final String bundleId = extension.getContributor().getName();
            
            for (int j = 0; j < elements.length; j++)
            {
                final IConfigurationElement element = elements[j];
                if (CONTEXT_SYMBOL_FACTORY.equals(element.getName())
                        && element.getAttribute(FACTORY_ATTRIBUTE_NAME) != null)
                {
                    final String factoryClassName = element.getAttribute(FACTORY_ATTRIBUTE_NAME);
                    final String factoryId = element.getAttribute(FACTORY_ATTRIBUTE_ID_NAME);
                    final Bundle bundle = Platform.getBundle(bundleId);
                    
                    if (bundle != null)
                    {
                        try {
                            Class factoryClass = bundle.loadClass(factoryClassName);
                        
                            AbstractContextSymbolFactory factory = 
                                (AbstractContextSymbolFactory) factoryClass.newInstance();
                            registeredSymbolFactories.put(factoryId, factory);
                        } catch (InstantiationException e) {
                            plugin.log(new Status(IStatus.ERROR, plugin.getBundle().getSymbolicName(), 0, "Error loading symbol factory extension point",e)); //$NON-NLS-1$
                        } catch (IllegalAccessException e) {
                            plugin.log(new Status(IStatus.ERROR, plugin.getBundle().getSymbolicName(), 0, "Error loading symbol factory extension point",e)); //$NON-NLS-1$
                        } catch (ClassNotFoundException e) {
                            plugin.log(new Status(IStatus.ERROR, plugin.getBundle().getSymbolicName(), 0, "Error loading symbol factory extension point",e)); //$NON-NLS-1$
                        }
                    }
                }
            }
        }
    }
    
    /**
     * Logs an exception in this plugin to the error log
     * 
     * @param t
     */
    public static void log(Throwable t)
    {
        ILog log = getPlugin().getLog();
        IStatus status = new Status(IStatus.ERROR, getPlugin().getSymbolicName(), 0,  "Caught exception", t); //$NON-NLS-1$
        log.log(status);
    }

	/**
	 * The actual implementation of the Eclipse <b>Plugin</b>.
	 * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
	 * @generated
	 */
    public static class Implementation extends EclipsePlugin 
    {
        /**
         * Name of the symbolSourceProvider ext point
         */
        public static final  String   SYMBOL_SOURCE_EXT_ID = "symbolSourceProvider"; //$NON-NLS-1$
        /**
         * Local identifier for the symbol factory extension point
         */
        public static final  String   SYMBOL_FACTORY_EXT_ID = "contextSymbolFactory"; //$NON-NLS-1$
		/**
		 * Creates an instance.
		 * <!-- begin-user-doc -->
         * <!-- end-user-doc -->
		 * @generated
		 */
        public Implementation() {
			super();

			// Remember the static instance.
			//
			plugin = this;
		}
	}
    
	
	/**
	 * Utility method returning class from class name using classloader from specified bundle
	 * @param className
	 * @param bundleId
	 * @return Class
	 */
	public static Class<?> loadClass(String className, String bundleId) {
		Class<?> aClass = null;
		try {
			if (bundleId != null){
				Bundle bundle = Platform.getBundle(bundleId);
				if (bundle != null){
					aClass = bundle.loadClass(className);
				}
			}
		} catch (ClassNotFoundException e) {
			log(e);
		}
		return aClass;
	}
}
