blob: 7559f909ca5be3f8ecc80da727e914c8b0634429 [file] [log] [blame]
/*
* 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;
}
}
}
}