blob: fb0bc928f48a5fc33b848fa3c61fdba92592cf98 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2015 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.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.SynchronousBundleListener;
class ContextManagerServiceFactoryImpl implements ServiceFactory {
// map of bundles to context managers (CloseableContextManager)
private Map m_mapOfManagers =
Collections.synchronizedMap(new HashMap());
/* BundleContext for the Gemini Naming Implementation Bundle */
private final BundleContext m_implBundleContext;
ContextManagerServiceFactoryImpl(BundleContext implBundleContext) {
m_implBundleContext = implBundleContext;
}
@Override
public Object getService(Bundle bundle, ServiceRegistration registration) {
CloseableContextManager contextManager =
createContextManager(bundle, m_implBundleContext);
m_mapOfManagers.put(bundle, contextManager);
bundle.getBundleContext().addBundleListener(new ContextManagerBundleListener());
return contextManager;
}
@Override
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
closeContextManager(bundle);
}
protected void closeAll() {
synchronized(m_mapOfManagers) {
Iterator iterator = m_mapOfManagers.entrySet().iterator();
while(iterator.hasNext()) {
Map.Entry currentMapEntry = (Map.Entry) iterator.next();
Object currentMapEntryValue = currentMapEntry.getValue();
if (currentMapEntryValue != null){
((CloseableContextManager)currentMapEntryValue).close();
iterator.remove();
}
}
}
}
private void closeContextManager(Bundle bundle) {
CloseableContextManager contextManager =
(CloseableContextManager)m_mapOfManagers.get(bundle);
if(contextManager != null) {
contextManager.close();
m_mapOfManagers.remove(bundle);
}
}
private class ContextManagerBundleListener implements SynchronousBundleListener {
@Override
public void bundleChanged(BundleEvent event) {
if(event.getType() == BundleEvent.STOPPED) {
if(m_mapOfManagers.containsKey(event.getBundle())) {
closeContextManager(event.getBundle());
}
}
}
}
/**
* Convenience factory method for creating a CloseableContextManager
* instance.
* @param bundle the Bundle associated with this context manager
* @return a CloseableContextManager that will handle requests for
* the given Bundle.
*/
private static CloseableContextManager createContextManager(Bundle bundle, BundleContext implBundleContext) {
return new SecurityAwareContextManagerImpl(new ContextManagerImpl(bundle, implBundleContext));
}
}