/*******************************************************************************
 * Copyright (c) 2010, 2012 Oracle.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution. 
 * The Eclipse Public License is available at
 *     http://www.eclipse.org/legal/epl-v10.html
 * and the Apache License v2.0 is available at 
 *     http://www.opensource.org/licenses/apache2.0.php.
 * You may elect to redistribute this code under either of these licenses.
 *
 * Contributors:
 *     Bob Nettleton (Oracle) - Initial Reference Implementation
 ******************************************************************************/

package org.eclipse.gemini.naming;

import java.lang.reflect.Field;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.NamingManager;
import javax.naming.spi.ObjectFactory;
import javax.naming.spi.ObjectFactoryBuilder;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.jndi.JNDIConstants;
import org.osgi.service.jndi.JNDIContextManager;
import org.osgi.service.jndi.JNDIProviderAdmin;

/**
 * Activator implementation for the Gemini Naming Bundle.
 * 
 * This activator's main purpose is to register the JNDI Builder singleton
 * implementations that allow the Factory Manager to override the default JNDI
 * framework.
 * 
 * 
 */
public class Activator implements BundleActivator {

	private static final String					OSGI_URL_SCHEME					= "osgi";
	private static final String					RMI_URL_SCHEME					= "rmi";
	private static final String					RMI_URL_CONTEXT_FACTORY			= "com.sun.jndi.url.rmi.rmiURLContextFactory";
	
	private static Logger logger = Logger.getLogger(Activator.class.getName());

	private BundleContext						m_bundleContext					= null;
	private final List<ServiceRegistration>        m_listOfServiceRegistrations = new LinkedList<ServiceRegistration>();

	private CloseableProviderAdmin	m_providerAdminService;
	private ContextManagerServiceFactoryImpl m_contextManagerServiceFactory;
	
	/*
	 * Create the Factory Manager's builder implementation, and register it with
	 * the JNDI NamingManager.
	 * 
	 * @see
	 * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
	 * )
	 */
	public void start(BundleContext context) throws Exception {
		logger.info("Initializing Gemini Naming Factory Manager Bundle");
		
		m_bundleContext = context;

		// register static singletons with the JNDI framework
		logger.info("Installing Static Singletons");
		registerInitialContextFactoryBuilderSingleton();
		registerObjectFactoryBuilderSingleton();

		logger.info("Registering URL Context Factory for 'osgi' URL scheme");
		registerOSGiURLContextFactory();
		
		logger.info("Registering Default Runtime Builder for JRE-provided factories");
		registerDefaultRuntimeBuilder();
		
		logger.info("Registering ContextManager service");
		// register the JNDIContextManager service once all Factory
		// Manager initialization is complete
		registerContextManager();
		
		logger.info("Registering ProviderAdmin service");
		// register the JNDIProviderAdmin interface, used by OSGi-aware
		// context implementations to resolve JNDI references
		registerProviderAdmin();
	}
	

	/*
	 * Allow the Builder implementation to clean up any
	 * ServiceListener/ServiceTracker instances.
	 * 
	 * @see
	 * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		logger.info("Shutting down Gemini Naming Factory Manager Bundle");
		
		// close all known Contexts associated with the JNDIContextManager service
		m_contextManagerServiceFactory.closeAll();
		
		// close the JNDIProviderAdmin service
		m_providerAdminService.close();

		// unregister all the JNDI services registered by this Activator
		Iterator<ServiceRegistration> iterator = m_listOfServiceRegistrations.iterator();
		while(iterator.hasNext()) {
			ServiceRegistration serviceRegistration = 
				(ServiceRegistration)iterator.next();
			serviceRegistration.unregister();
		}
		
		unregisterSingletons();
	}


	/**
	 * Registers the InitialContextFactoryBuilder static singleton
	 * @throws NamingException on any error that occurs during the setting
	 *         of the builder.  
	 */
	private static void registerInitialContextFactoryBuilderSingleton() throws NamingException {
		try {
			NamingManager.setInitialContextFactoryBuilder(new TraditionalInitialContextFactoryBuilder());
		}
		catch (IllegalStateException illegalStateException) {
			logger.log(Level.SEVERE, 
			           "Gemini Naming Implementation cannot set the InitialContextFactoryBuilder - another builder was already installed",
			           illegalStateException);
			NamingException namingException = 
				new NamingException("Error occurred while attempting to set the IntialContextFactoryBuilder.");
			namingException.setRootCause(illegalStateException);
			throw namingException;
		} 
		catch(SecurityException securityException) {
			logger.log(Level.SEVERE, 
					   "Gemini Naming Implementation did not have the proper security permissions to install the InitialContextFactoryBuilder",
					   securityException);
			NamingException namingException = 
				new NamingException("Error occurred while attempting to set the IntialContextFactoryBuilder.");
			namingException.setRootCause(securityException);
			throw namingException;
		}
	}
	
	
	/**
	 * Registers the ObjectFactoryBuilder static singleton
	 * @throws NamingException on any error that occurs during the setting
	 *         of the builder.  
	 */
	private static void registerObjectFactoryBuilderSingleton() throws NamingException {
		try {
			NamingManager.setObjectFactoryBuilder(new TraditionalObjectFactoryBuilder());
		}
		catch (IllegalStateException illegalStateException) {
			logger.log(Level.SEVERE, 
			           "Gemini Naming Implementation cannot set the ObjectFactoryBuilder - another builder was already installed",
			           illegalStateException);
			NamingException namingException = 
				new NamingException("Error occurred while attempting to set the ObjectFactoryBuilder.");
			namingException.setRootCause(illegalStateException);
			throw namingException;
		} 
		catch(SecurityException securityException) {
			logger.log(Level.SEVERE, 
					   "Gemini Naming Implementation did not have the proper security permissions to install the ObjectFactoryBuilder",
					   securityException);
			NamingException namingException = 
				new NamingException("Error occurred while attempting to set the ObjectFactoryBuilder.");
			namingException.setRootCause(securityException);
			throw namingException;
		}
	}
		
	/**
	 * Unregisters the InitialContextFactoryBuilder static singleton
	 * and the ObjectFactoryBuilder static singleton.
	 */
	private static void unregisterSingletons() {
		Field[] fields = NamingManager.class.getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field: fields) {
				if (InitialContextFactoryBuilder.class.equals(field.getType()) 
						|| ObjectFactoryBuilder.class.equals(field.getType())){
					field.setAccessible(true);
					try {
						field.set(null, null);
					} catch (IllegalArgumentException e) {
						logger.log(Level.SEVERE,
								   "Unable to reset NamingManager static singleton " + field.getType(),
								   e);
					} catch (IllegalAccessException e) {
						logger.log(Level.SEVERE,
								   "Unable to reset NamingManager static singleton " + field.getType(),
								   e);
					}
				}
			}
		}
	}
	
	
	
	
	/**
	 * Registers the OSGi URL Context Factory.
	 * 
	 */
	private void registerOSGiURLContextFactory() {
		Hashtable<Object, Object> serviceProperties = new Hashtable<Object, Object>();
		serviceProperties.put(JNDIConstants.JNDI_URLSCHEME, OSGI_URL_SCHEME);

		ServiceRegistration serviceRegistration = 
			m_bundleContext.registerService(ObjectFactory.class.getName(), 
										    new OSGiURLContextFactoryServiceFactory(), 
										    serviceProperties);
		m_listOfServiceRegistrations.add(serviceRegistration);
	}
	
	
	/**
	 * Registers the InitialContextFactoryBuilder implementation that 
	 * is responsible for loading the JDK-defined providers that must be
	 * loaded from the boot classpath.  
	 * 
	 */
	private void registerDefaultRuntimeBuilder() {
		ServiceRegistration serviceRegistration = 
			m_bundleContext.registerService(InitialContextFactoryBuilder.class.getName(), 
					                        new DefaultRuntimeInitialContextFactoryBuilder(), 
					                        null);
		m_listOfServiceRegistrations.add(serviceRegistration);
		
		Hashtable<Object, Object> props = new Hashtable<Object, Object>();
        props.put(JNDIConstants.JNDI_URLSCHEME, RMI_URL_SCHEME);
		try {
			ServiceRegistration rmiRegistration = 
				m_bundleContext.registerService(ObjectFactory.class.getName(),
												ClassLoader.getSystemClassLoader().loadClass(RMI_URL_CONTEXT_FACTORY).newInstance(),
												props);
			m_listOfServiceRegistrations.add(rmiRegistration);
		}
		catch(ClassNotFoundException e) {
			logger.log(Level.SEVERE, RMI_URL_CONTEXT_FACTORY + " cannot be found through the system classloader.", e);
		}
		catch(InstantiationException e) {
			logger.log(Level.SEVERE, "Exception occurred while instantiating " + RMI_URL_CONTEXT_FACTORY, e);
		}
		catch(IllegalAccessException e) {
			logger.log(Level.SEVERE, "Exception occured while instantiating " + RMI_URL_CONTEXT_FACTORY, e);
		}
	}
	
	
	private void registerContextManager() {
		m_contextManagerServiceFactory = 
			new ContextManagerServiceFactoryImpl(m_bundleContext);
		ServiceRegistration serviceRegistration = 
			m_bundleContext.registerService(JNDIContextManager.class.getName(),
											m_contextManagerServiceFactory,
					                        null);
		m_listOfServiceRegistrations.add(serviceRegistration);
	}
	

	private void registerProviderAdmin() {
		m_providerAdminService = 
			new SecurityAwareProviderAdminImpl(new ProviderAdminImpl(m_bundleContext));
		
		
		ServiceRegistration serviceRegistration =  
			m_bundleContext.registerService(JNDIProviderAdmin.class.getName(),
					                        m_providerAdminService,
					                        null);
		m_listOfServiceRegistrations.add(serviceRegistration);
	}

}