/** * Copyright (c) 2002-2011 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.neo4j.kernel.impl.osgi; import java.util.Collection; import java.util.LinkedList; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.BundleListener; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; /** * An OSGi-friendly extension loader, the OSGiExtensionLoader uses normal OSGi * service discovery to find published services. * * For Bundles that aren't OSGi-prepared Bundles (but rather plain old jar * files) this extension loader will read the <code>META-INF/services</code> * specifications and publish those services through the OSGi service discovery. */ public class OSGiExtensionLoader implements BundleListener { private final BundleContext bc; @SuppressWarnings( "unchecked" ) private final ConcurrentMap<Long, BundleServiceProvider> providers = new ConcurrentHashMap(); OSGiExtensionLoader( BundleContext bc ) { this.bc = bc; } public <T> Iterable<T> loadExtensionsOfType( Class<T> type ) { try { System.out.println( "Kernel: attempting to load extensions of type " + type.getName() ); ServiceReference[] services = bc.getServiceReferences( type.getName(), null ); if ( services != null ) { Collection<T> serviceCollection = new LinkedList<T>(); for ( ServiceReference sr : services ) { @SuppressWarnings( "unchecked" ) T service = (T) bc.getService( sr ); serviceCollection.add( service ); } return serviceCollection; } else { return null; } } catch ( InvalidSyntaxException e ) { System.out.println( "Failed to load extensions of type: " + type ); e.printStackTrace(); } return null; } public void bundleChanged( BundleEvent event ) { switch ( event.getType() ) { case BundleEvent.STARTING: case BundleEvent.STARTED: started( event.getBundle() ); break; case BundleEvent.STOPPING: stopping( event.getBundle() ); break; } } void started( Bundle bundle ) { providers.putIfAbsent( bundle.getBundleId(), new BundleServiceProvider( bundle ) ); } void stopping( Bundle bundle ) { providers.remove( bundle.getBundleId() ); } private class BundleServiceProvider { private final Bundle bundle; BundleServiceProvider( Bundle bundle ) { this.bundle = bundle; } } }