/******************************************************************************* | |
* 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); | |
} | |
} |