On Fri, Nov 16, 2012 at 1:17 PM, Donald Whytock <[email protected]> wrote:
> Sorry, my project site was recently hacked.  I'll have to find my
> archives.  Ping me in a week if I haven't responded, please.

Okay...here's some hastily-thrown-together, untested code samples that
might nevertheless tell you what I mean.  It's a very barebones
example.

WaitForStart and NotifyOnStart are general-purpose interfaces to set
up multiple bundles to wait for a single bundle to activate them.  An
implemented WaitForStart accepts an OSGI ServiceReference to a
NotifyOnStart service that should be called when it's time for things
to start; the interface is structured so that the NotifyOnStart
implementation doesn't care what the WaitForStart's start condition
is, and the WaitForStart doesn't care what the NotifyOnStart will do
once started.

StartBundle implements WaitForStart and registers itself as a service
that other bundles can find.  It also implements BundleListener and
registers itself to receive BundleEvents.  When the desired bundle is
started, StartBundle will set a flag and call notifyOnStart() for each
active NotifyOnStart reference it has on file.  When a bundle calls
StartBundle's waitForStart(), StartBundle will either call the
supplied notifyOnStart() if the flag is set, or else store the
NotifyOnStart in a list to be called when the desired bundle is
started.

SampleApp implements NotifyOnStart and registers itself as a service
that can be passed to other bundles.  It also implements
ServiceListener and registers itself to receive ServiceEvents related
to instances of WaitForStart.  When a WaitForStart service is
registered, SampleApp fetches the WaitForStart service and calls
waitForStart(), passing its own ServiceReference.

Note that this example is specifically made for multiple bundles
waiting on a single event, and isolating the nature of that event from
them into a single coordinating bundle.  You can also just implement
BundleListener on some single bundle that sets up all your routes for
you.  Just wanted to provide the flexibility.

---------------------------

package org.mypackage.waitforstart.service;

import org.osgi.framework.ServiceReference;

public interface WaitForStart
  {
  public void waitForStart(ServiceReference<NotifyOnStart> startListener);
  }

------------------------

package org.mypackage.waitforstart.service;

public interface NotifyOnStart
  {
  public void notifyOnStart();
  }

----------------------

package org.mypackage.startbundle;

import org.mypackage.waitforstart.service.WaitForStart;
import org.mypackage.waitforstart.service.NotifyOnStart;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.ServiceReference;

import java.util.ArrayList;

public class StartBundle implements BundleActivator, BundleListener,
WaitForStart
  {
  ArrayList<ServiceReference<NotifyOnStart>> notifyList = new
ArrayList<ServiceReference<NotifyOnStart>>();
  String BUNDLENAME = "bundle-name";
  BundleContext context = null;
  boolean started = false;

  public void start(BundleContext context)
    {
    this.context = context;
    context.addBundleListener(this);
    context.registerService(WaitForStart.class.getName(), this, null);
    }

  public void waitForStart(ServiceReference<NotifyOnStart> notifyonstart)
    {
    if (started)
      {
      NotifyOnStart notifier = context.getService(notifyonstart);
      if (notifier != null)
        notifier.notifyOnStart();
      }
    else
      notifyList.add(notifyonstart);
    }

  public void bundleChanged(BundleEvent event)
    {
    NotifyOnStart notifier = null;

    if (event.getBundle().getSymbolicName().equals(BUNDLENAME))
      if (event.getType() == BundleEvent.STARTED)
        {
        started = true;

        for (ServiceReference reference: notifyList)
          {
          notifier = (NotifyOnStart) context.getService(reference);
          if (notifier != null)
            notifier.notifyOnStart();
          }
        }
    }

  public void stop(BundleContext context)
    {
    }
  }

-----------------------------

package org.mypackage.sampleapp;

import org.mypackage.waitforstart.service.NotifyOnStart;
import org.mypackage.waitforstart.service.WaitForStart;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;

public class SampleApp implements BundleActivator, NotifyOnStart,
ServiceListener
  {
  ServiceRegistration registration = null;
  BundleContext context = null;
  ServiceReference<NotifyOnStart> reference = null;
  boolean started = false;

  public void start(BundleContext context)
    {
    this.context = context;

    registration =
context.registerService(NotifyOnStart.class.getName(), this, null);
    reference = registration.getReference();

    context.addServiceListener(this, "(" + Constants.OBJECTCLASS + "="
+ WaitForStart.class.getName() + ")");
    }

  public void serviceChanged(ServiceEvent event)
    {
    if (event.getType() == ServiceEvent.REGISTERED)
      context.getService(event.getServiceReference()).waitForStart(reference);
    }

  public void notifyOnStart()
    {
    if (!started)
      /* start routes here */

    started = true;
    }

  public void stop(BundleContext context)
    {
    registration.unregister();
    }
  }

Reply via email to