home  |  suche  |  kontakt/johner  |  institut 
studierende  |  tech-docs  |  mindmailer 

Beispiel

Das Initiates file downloadvollständige Beispiel einschließlich der Apache Felix Dateien, liegt auch als Eclipse-Projekt vor.

ITelefonbuch - Das Interface des Services

package telefonbuch.serviceinterface;

public interface ITelefonbuch {
  public Adresse getAdresse(int telefonnummer);
}

Adresse - das Objekt, das über vom Interface zurückgegeben wird

package telefonbuch.serviceinterface;

public class Adresse {
  private int telefonnr;
  private String name;
  private String strasse;
  
  public Adresse(){}
  
  public Adresse(int telefonnr, String name, String strasse) {
    this.telefonnr = telefonnr;
    this.name = name;
    this.strasse = strasse;
  }

  public int getTelefonnr() {
    return telefonnr;
  }

  public void setTelefonnr(int telefonnr) {
    this.telefonnr = telefonnr;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getStrasse() {
    return strasse;
  }

  public void setStrasse(String strasse) {
    this.strasse = strasse;
  }
  
  public String toString(){
    return "Adresse: Telefonnr " + telefonnr + ", Name: " + name + ", Strasse: " + strasse; 
  }
}

Telefonbuch1 - eine Implementierung des Interfaces

package telefonbuch.service1;

import java.util.HashMap;
import java.util.Map;

import telefonbuch.serviceinterface.Adresse;
import telefonbuch.serviceinterface.ITelefonbuch;

public class Telefonbuch1 implements ITelefonbuch {
  private Map<Integer, Adresse> adressen;
  
  public Telefonbuch1(){
    adressen = new HashMap<Integer, Adresse>();
    adressen.put(1new Adresse(1"HTWG""Brauneggerstr. 1"));
    adressen.put(2new Adresse(2"Mensa""Brauneggerstr. 2"));
  }

  @Override
  public Adresse getAdresse(int telefonnummer) {
    return adressen.get(telefonnummer);
  }

}

TelefonbuchActivator1 - die Klasse, über die...

... das OSGI Framework mit dem Bundle kommuniziert.

package telefonbuch.service1;

import java.util.Properties;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

import telefonbuch.serviceinterface.ITelefonbuch;

public class TelefonbuchActivator1 implements BundleActivator {

  public void start(BundleContext context) {
    Properties props = new Properties();
    System.out.println("Füge Nummer-1 hinzu V e");
    props.put("Nummer""Nummer-1");
    
    context.registerService(ITelefonbuch.class.getName(),new Telefonbuch1(), props);
  }

  public void stop(BundleContext context) {
  }
}

manifesttelefonbuch.mf - das Manifest des Providers

Bundle-Name: Telefonbuch 1
Bundle-Description: Unser erstes Telefonbuch
Bundle-Vendor: HTWG Konstanz
Bundle-Version: 1.0.1
Bundle-Activator: telefonbuch.service1.TelefonbuchActivator1
Export-Package: telefonbuch.serviceinterface
Import-Package: org.osgi.framework

 

Das Package org.osgi.framework wird immer importiert. Unser Bundle stellt das Package telefonbuch.serviceinterface nach außen zur Verfügung, weshalb es exportiert wird. Auf die darin befindlichen Klassen (ITelefonbuch und Adresse) können andere Bundles zugreifen. Die anderen Klassen des Bundles (z.B. Telefonbuch1) sind für die anderen Bundles nicht erreichbar.

TelefonbuchClient - die Klasse, die...

... als Client fungiert und gleichzeitig den Activator des Clients darstellt. Der Activator könnte auch als eigene Klasse vorliegen.

Dieser Client kann nicht nur die im Interface spezifizierte Funktionalität des Providers aufrufen, sondern bemerkt dank des Listeners auch, wenn sich die Version des Provider-Bundles ändert (neue Version oder zusätzliche Implementierung) oder das Provider-Bundle nicht mehr zur Verfügung steht. 

package telefonbuch.client;

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

import telefonbuch.serviceinterface.ITelefonbuch;

public class TelefonbuchClient implements BundleActivator, ServiceListener {

  public void start(BundleContext contextthrows Exception {
    //den synchronized-Block brauchen wir nur, wenn wir mit Listener arbeiten.
    synchronized (this) { 
      // TODO besser als ServiceListener wäre ServiceTracker
      context.addServiceListener(this, "(&(objectClass=" + ITelefonbuch.class.getName() ")(Nummer=*))");

      ServiceReference[] refs = context.getServiceReferences(ITelefonbuch.class.getName()"(Nummer=*)");
      if (refs != null) {
        ITelefonbuch telefonbuch = (ITelefonbuchcontext.getService(refs[0]);
        System.out.println("Adresse zu Telefonnr. 1: " + telefonbuch.getAdresse(1).getStrasse());
        context.ungetService(refs[0]);
      else {
        System.out.println("Konnte Telefonbuch nicht finden...");
      }
    }
  }

  public void stop(BundleContext context) {
    // brauchen wir nicht
  }

  
  //Diese Methode brauchen wir nur, wenn wir mit Listener arbeiten 
  public synchronized void serviceChanged(ServiceEvent event) {
    String[] objectClass = (String[]) event.getServiceReference().getProperty("objectClass");
    System.out.println("Object class: " + objectClass[0])// = telefonbuch.serviceinterface.ITelefonbuch

    if (event.getType() == ServiceEvent.REGISTERED) {
      System.out.println("Service registiert");
    else if (event.getType() == ServiceEvent.UNREGISTERING) {
      System.out.println("Service unregistiert");
    else if (event.getType() == ServiceEvent.MODIFIED) {
      System.out.println("Service aktualisiert");
    else {
      System.out.println("Service sonstiges");
    }
  }
}

telefonbuchclientmanifest.mf

Manifest-Version: 1.0
Built-By: Christian Johner
Bundle-Name: Telefonbuch Client
Bundle-Description: Bundle, das das Telefonbuch nutzt
Bundle-Vendor: HTWG
Bundle-Version: 1.0.0
Bundle-Activator: telefonbuch.client.TelefonbuchClient
Import-Package: org.osgi.framework, telefonbuch.serviceinterface

 

Der Client importiert das Interface, genauer gesagt das Package, das das Interface (ITelefonbuch) enthält. Auf das Client-Bundle selbst soll kein anderes Bundle zugreifen, weshalb es kein Export-Package gibt.