/*******************************************************************************
 * 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 Logger logger = Logger.getLogger(Activator.class.getName());

	private BundleContext						m_bundleContext					= null;
	private final List                          m_listOfServiceRegistrations = new LinkedList();

	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 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 serviceProperties = new Hashtable();
		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);
	}
	
	
	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);
	}

}