/* * Copyright 2008 Alin Dreghiciu. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. * * See the License for the specific language governing permissions and * limitations under the License. */ package org.ops4j.pax.url.commons.handler; import org.ops4j.lang.NullArgumentException; import org.ops4j.pax.swissbox.property.BundleContextPropertyResolver; import org.ops4j.util.property.PropertyResolver; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.url.AbstractURLStreamHandlerService; import org.osgi.service.url.URLConstants; import org.osgi.service.url.URLStreamHandlerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URL; import java.net.URLConnection; import java.util.Arrays; import java.util.Dictionary; import java.util.Hashtable; /** * Bundle activator for protocol handlers. * * @author Alin Dreghiciu * @since 0.1.0, January 13, 2007 */ public class HandlerActivator<T> implements BundleActivator { /** * Logger. */ private static final Logger LOG = LoggerFactory.getLogger( HandlerActivator.class ); /** * Array of handled protocols. */ private final String[] m_protocols; /** * Service PID. */ private final String m_pid; /** * Protocol specific connection factory. */ private final ConnectionFactory<T> m_connectionFactory; /** * Bundle context in use. */ private BundleContext m_bundleContext; /** * Property resolver to be used on resolving properties. */ private PropertyResolver m_propertyResolver; /** * Protocol handler specific configuration. */ private T m_configuration; /** * Handler service registration. Usef for cleanup. */ private ServiceRegistration m_handlerReg; /** * Managed service registration. Used for cleanup. */ private ServiceRegistration m_managedServiceReg; /** * Creates a protocol handler. * * @param protocols array of handled protocols. Cannot be null. * @param pid service pid. Cannot be null. * @param connectionFactory protocol specific connection factory. Cannot be null * * @throws NullArgumentException if any of the paramters is null */ public HandlerActivator( final String[] protocols, final String pid, final ConnectionFactory<T> connectionFactory ) { NullArgumentException.validateNotNull( protocols, "Protocols" ); NullArgumentException.validateNotNull( pid, "PID" ); NullArgumentException.validateNotNull( connectionFactory, "Connection factory" ); m_protocols = protocols; m_pid = pid; m_connectionFactory = connectionFactory; } /** * Registers Handler as a wrap: protocol stream handler service and as a configuration managed service if * possible. * * @param bundleContext the bundle context. * * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start( final BundleContext bundleContext ) { NullArgumentException.validateNotNull( bundleContext, "Bundle context" ); m_bundleContext = bundleContext; m_propertyResolver = new BundleContextPropertyResolver(bundleContext); m_configuration = m_connectionFactory.createConfiguration(m_propertyResolver); registerHandler(); registerManagedService(); LOG.debug( "Handler for protocols " + Arrays.deepToString( m_protocols ) + " started" ); } /** * Performs cleanup:<br/> * * Unregister handler;<br/> * * Unregister managed service;<br/> * * Release bundle context. * * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop( final BundleContext bundleContext ) { NullArgumentException.validateNotNull( bundleContext, "Bundle context" ); if ( m_handlerReg != null ) { m_handlerReg.unregister(); m_handlerReg = null; } if ( m_managedServiceReg != null ) { m_managedServiceReg.unregister(); m_managedServiceReg = null; } m_bundleContext = null; LOG.debug( "Handler for protocols " + Arrays.deepToString( m_protocols ) + " stopped" ); } /** * Register the handler service. */ private void registerHandler() { final Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put( URLConstants.URL_HANDLER_PROTOCOL, m_protocols ); m_handlerReg = m_bundleContext.registerService( URLStreamHandlerService.class.getName(), new Handler(), props ); } /** * Registers a managed service to listen on configuration updates. */ private void registerManagedService() { try { m_managedServiceReg = OptionalConfigAdminHelper.registerManagedService(m_pid, m_bundleContext, this); } catch ( Throwable ignore ) { setResolver( new BundleContextPropertyResolver( m_bundleContext ) ); m_managedServiceReg = null; } } /** * Getter. * * @return property resolver */ synchronized PropertyResolver getResolver() { return m_propertyResolver; } /** * Setter. * * @param propertyResolver property resolver */ synchronized void setResolver( final PropertyResolver propertyResolver ) { m_propertyResolver = propertyResolver; m_configuration = m_connectionFactory.createConfiguration( propertyResolver ); } /** * OSGi URLStreamHandlerService implementation that handles wrap protocol. * * @author Alin Dreghiciu * @since 0.1.0, January 13, 2008 */ private class Handler extends AbstractURLStreamHandlerService { /** * @see org.osgi.service.url.URLStreamHandlerService#openConnection(java.net.URL) */ @Override public URLConnection openConnection( final URL url ) throws IOException { return m_connectionFactory.createConnection( m_bundleContext, url, m_configuration ); } } }