| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.felix.webconsole.plugins.event.internal; |
| |
| |
| import java.util.Dictionary; |
| import java.util.Hashtable; |
| |
| import org.osgi.framework.*; |
| import org.osgi.service.event.EventAdmin; |
| |
| /** |
| * This class handles all optional stuff. |
| * It listens for specific services and activates/deactivates |
| * features. |
| */ |
| public class OptionalFeaturesHandler |
| implements ServiceListener |
| { |
| private static final String EVENT_ADMIN_CLASS_NAME = "org.osgi.service.event.EventAdmin"; //$NON-NLS-1$ |
| private static final String CONFIGURATION_ADMIN_CLASS_NAME = "org.osgi.service.cm.ConfigurationAdmin"; //$NON-NLS-1$ |
| private static final String EVENT_HANDLER_CLASS_NAME = "org.osgi.service.event.EventHandler"; //$NON-NLS-1$ |
| |
| private static final String FILTER = "(|(" + Constants.OBJECTCLASS + "=" + EVENT_ADMIN_CLASS_NAME + ")" |
| +"(" + Constants.OBJECTCLASS + "=" + CONFIGURATION_ADMIN_CLASS_NAME + "))"; |
| |
| /** Event admin service id */ |
| //private Long eventAdminServiceId; |
| private ServiceReference eventAdminServiceRef; |
| |
| /** Registration for the event handler. */ |
| private ServiceRegistration eventHandlerRegistration; |
| |
| /** Configuration admin service id */ |
| private Long configAdminServiceId; |
| |
| /** Registration for the configuration listener. */ |
| private ServiceRegistration configListenerRegistration; |
| |
| /** Bundle context. */ |
| private final BundleContext bundleContext; |
| |
| /** The plugin */ |
| private final PluginServlet plugin; |
| |
| public OptionalFeaturesHandler(final PluginServlet plugin, final BundleContext context) |
| { |
| this.plugin = plugin; |
| this.bundleContext = context; |
| // check if event admin is already available |
| final ServiceReference ref = this.bundleContext.getServiceReference(EVENT_ADMIN_CLASS_NAME); |
| if ( ref != null ) |
| { |
| bindEventAdmin(ref); |
| } |
| |
| // check if config admin is already available |
| this.configAdminServiceId = null; |
| final ServiceReference cfaRef = this.bundleContext.getServiceReference(CONFIGURATION_ADMIN_CLASS_NAME); |
| if ( cfaRef != null ) |
| { |
| final Long id = (Long)cfaRef.getProperty(Constants.SERVICE_ID); |
| bindConfigAdmin(id); |
| } |
| |
| // listen for event and config admin from now on |
| try { |
| context.addServiceListener(this, FILTER); |
| } catch (InvalidSyntaxException ise) { |
| // this should never happen as this is a constant, so we ignore it |
| } |
| } |
| |
| /** |
| * @see javax.servlet.GenericServlet#destroy() |
| */ |
| public void destroy() |
| { |
| this.bundleContext.removeServiceListener(this); |
| this.unbindEventAdmin(this.eventAdminServiceRef); |
| this.unbindConfigAdmin(this.configAdminServiceId); |
| } |
| |
| /** |
| * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent) |
| */ |
| public void serviceChanged(final ServiceEvent event) |
| { |
| final ServiceReference ref = event.getServiceReference(); |
| final String[] objectClasses = (String[])ref.getProperty(Constants.OBJECTCLASS); |
| if ( objectClasses != null) |
| { |
| for(int i=0; i<objectClasses.length; i++) |
| { |
| if ( objectClasses[i].equals(EVENT_ADMIN_CLASS_NAME) ) |
| { |
| if ( event.getType() == ServiceEvent.REGISTERED ) |
| { |
| new Thread() |
| { |
| public void run() |
| { |
| try { |
| Thread.sleep(500); |
| } catch (InterruptedException ignore) {} |
| bindEventAdmin(ref); |
| } |
| }.start(); |
| } |
| else if ( event.getType() == ServiceEvent.UNREGISTERING ) |
| { |
| new Thread() |
| { |
| public void run() |
| { |
| try { |
| Thread.sleep(500); |
| } catch (InterruptedException ignore) {} |
| unbindEventAdmin(ref); |
| } |
| }.start(); |
| } |
| } |
| else if ( objectClasses[i].equals(CONFIGURATION_ADMIN_CLASS_NAME) ) |
| { |
| final Long id = (Long)event.getServiceReference().getProperty(Constants.SERVICE_ID); |
| if ( event.getType() == ServiceEvent.REGISTERED ) |
| { |
| new Thread() |
| { |
| public void run() |
| { |
| try { |
| Thread.sleep(500); |
| } catch (InterruptedException ignore) {} |
| bindConfigAdmin(id); |
| } |
| }.start(); |
| } |
| else if ( event.getType() == ServiceEvent.UNREGISTERING ) |
| { |
| new Thread() |
| { |
| public void run() |
| { |
| try { |
| Thread.sleep(500); |
| } catch (InterruptedException ignore) {} |
| unbindConfigAdmin(id); |
| } |
| }.start(); |
| } |
| } |
| } |
| } |
| } |
| |
| synchronized void bindEventAdmin(ServiceReference ref) |
| { |
| if ( this.eventAdminServiceRef != null) |
| { |
| this.unbindEventAdmin(this.eventAdminServiceRef); |
| } |
| this.eventAdminServiceRef = ref; |
| final Dictionary props = new Hashtable(); |
| props.put( Constants.SERVICE_DESCRIPTION, "Event handler for the Apache Felix Web Console" ); |
| props.put( Constants.SERVICE_VENDOR, "The Apache Software Foundation" ); |
| props.put( "event.topics", "*"); //$NON-NLS-1$ //$NON-NLS-2$ |
| this.plugin.setEventAdmin((EventAdmin) bundleContext.getService(ref)); |
| |
| this.eventHandlerRegistration = this.bundleContext.registerService(EVENT_HANDLER_CLASS_NAME, |
| new EventHandler(this.plugin.getCollector()), props); |
| } |
| |
| synchronized void unbindEventAdmin(ServiceReference ref) |
| { |
| if ( this.eventAdminServiceRef != null && this.eventAdminServiceRef.equals(ref) ) |
| { |
| bundleContext.ungetService(ref); |
| this.eventAdminServiceRef = null; |
| this.plugin.setEventAdmin(null); |
| if ( this.eventHandlerRegistration != null ) |
| { |
| this.eventHandlerRegistration.unregister(); |
| this.eventHandlerRegistration = null; |
| } |
| } |
| } |
| |
| synchronized void bindConfigAdmin(final Long id) |
| { |
| if ( this.configAdminServiceId != null ) |
| { |
| this.unbindConfigAdmin(this.configAdminServiceId); |
| } |
| this.plugin.setConfigAdminAvailable(true); |
| this.configAdminServiceId = id; |
| this.configListenerRegistration = ConfigurationListener.create(this.bundleContext, this.plugin); |
| } |
| |
| synchronized void unbindConfigAdmin(final Long id) |
| { |
| if ( this.configAdminServiceId != null && this.configAdminServiceId.equals(id) ) |
| { |
| this.configAdminServiceId = null; |
| this.plugin.setConfigAdminAvailable(false); |
| if ( this.configListenerRegistration != null ) |
| { |
| this.configListenerRegistration.unregister(); |
| this.configListenerRegistration = null; |
| } |
| } |
| } |
| } |