| home | suche | kontakt/johner | institut | hinweise studierende | tech-docs | blog | mindmailer |
![]() |
Beispiel
Das
vollstä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(1, new Adresse(1, "HTWG", "Brauneggerstr. 1"));
adressen.put(2, new 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 context) throws 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 = (ITelefonbuch) context.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.
