JPA ist eine Programmbibliothek, die Ihnen den Zugriff auf laufende Anwendungen des
Betriebssystems ermöglicht. Eine Anwendung ist dabei ein Prozess, welcher System-Ressourcen
belegt. Zu den System-Ressourcen gehören vom Prozess eingerichtete Threads (Programmfäden).
Ein spezieller Thread ist der so genannte Benutzeroberflächen-Thread,
der wiederum erzeugt und kontrolliert die Fenster
und Steuerelemente der Benutzerschnittstelle.
Weitere Betriebssystem-Ressourcen sind Programmmodule.
Ein hervorzuhebendes Leistungsmerkmal der JPA-API ist der Eingriff in Benutzeroberflächen von
Fremdanwendungen. Wie von Geisterhand werden Anwendungen bedient, indem Tastatureingaben
und Mausereignisse für Fenster und Steuerelemente simuliert werden. Die Bedienung von
Anwendungen wird mit der JPA-API automatisiert. Komplexe sich wiederholende Benutzereingaben
werden programmgesteuert durchgeführt. Bildhaft ausgedrückt ist die JPA-API ein Software-Roboter,
der Arbeitsschritte bei bestehenden Software-Systemen mit Benutzeroberfläche
hilft zu vereinfachen oder gar zu erweitern. Sich wiederholende Maus- und Tastatureingaben können
auf ein Minimum reduziert werden, indem die JPA-API diese für Sie durchführt.
Neue Funktionalitäten können bestehenden Anwendungen hinzugefügt werden, ohne Details über
deren Programmierung wissen zu müssen.
Es gibt eine Vielzahl von Anwendungsfällen der JPA-API. Mehr dazu siehe
Anwendungsfälle.
|
|
|
|
Beim Architektur-Entwurf der JPA-API wurde Wert darauf gelegt, die Schnittstelle
auf Prozesse, Threads, Fenster, Steuerelemente und Programmmodule unabhängig
vom Betriebssystem zu gestalten. Die Schnittstelle der JPA-API dient als gemeinsamer
Nenner zu den gängigen Betriebssystemen mit Benutzeroberfläche.
Implementierungen der JPA-API sind grundsätzlich ohne große Änderungen
der Schnittstellen für andere Betriebssysteme als Mircosoft Windows durchführbar.
Ein großer Vorteil dieses neutralen Entwurfs ist, dass der Integrator der
JPA-API keine speziellen Programmierkenntnisse für das Betriebssystem, auf welchem
die JPA-API zum Einsatz kommt, benötigt.
Dennoch werden betriebssystemspezifische Erweiterungen durch erweiterte Klassen/Schnittstellen
bereitgestellt. Die Schnittstelle AppProcess repräsentiert beispielsweise eine
gestartete Anwendung. Von AppProcess abgeleitet ist die Schnittstelle AppProcess_win32.
AppProcess_win32 stellt betriebssystemspezifische Funktionalitäten bereit.
Ähnlich verhält es sich mit der Schnittstelle AppWindow. Über die erweiterte Schnittstelle AppWindow_win32,
welche ein Win32-Fenster darstellt, kann mittels der Methode getWindowHandle die HWND
eines Fensters abgefragt werden. Die HWND ist ein Handle (Nummer, Integerwert), welches ein Fenster unter Microsoft Windows
eindeutig identifiziert.
Es folgt stichpunktartig eine Liste von Features der JPA-API:
-
Starten von Anwendungen
-
Ermitteln aller laufenden Prozesse auf dem Rechner
-
Ermitteln der Threads, welche in einem Prozess ausgeführt werden.
-
Abfrage der Toplevel-Fenster (Rahmen- und Dialogfenster) einer Anwendung
-
Zugriff und Manipulation von Benutzeroberflächen
-
Abfangen von Ereignissen innerhalb einer Benutzeroberfläche
-
Zugriff auf Steuerelemente wie Schaltflächen, Listen, Kombinationslisten,
Benennungen und Texteingabefelder
-
Abfrage von in den Speicher geladenen Programmmodulen (Ausführbare Datei und
Funktionsbibliotheken)
-
Laden von Programmbibliotheken (unter Windows DLLs) und Aufrufen von Funktionen
aus der Bibliothek
Eine zentrale Rolle in der JPA-API spielen die Klasse AutomationManager und
die Schnittstelle ApplicationController.
AutomationManager ist eine Klasse, welche das Entwurfsmuster Singleton realisiert.
Singleton ermöglicht die Abfrage einer einzigen Instanz der Klasse AutomationManager
über die Methode getInstance von jeder beliebigen Codestelle aus.
Der ApplicationController ist ein Interface (Schnittstelle), welches sich vom
AutomationManager abfragen lässt. Der ApplicationController ist stellvertretend für
das Betriebssystem (bzw. den Rechner). Der ApplicationController ermöglicht das
Starten von Anwendungen und die Abfrage von allen laufenden Prozessen auf einem Rechner.
Desweiteren werden betriebssystemspezifische Erweiterungen von einem spezialisierten
Interface zur Verfügung gestellt. Unter Microsoft Windows trägt das Interface
den Namen ApplicationController_win32 und stellt DDE (Dynamic Data Exchange) zur Interprozesskommunikation
und einen Zugriff auf die Windows-Registry (Konfigurationsdatenbank) bereit.
Grundsätzlich muss zur Einbindung der JPA-API in Ihr Programm der ApplicationController abgefragt werden.
Der lokale ApplicationController bezieht sich auf den Rechner, wo Ihr Programm von der
JVM ausgeführt wird.
Es folgt der einleitende Programmcodeabschnitt:
import softhema.system.automation.*;
import softhema.system.automation.win32.*;
.
.
.
AutomationManager manager = AutomationManager.getInstance();
ApplicationController controller = manager.getApplicationControllerLocal();
//Specialized for windows:
ApplicationController_win32 controller_win32 = (ApplicationController_win32) controller;
Über den ApplicationController kann man sich nun ein Array mit den
gerade laufenden Prozessen geben lassen:
AppProcess[] processes = controller.getAppProcesses();
Eine wichtige Aufgabe von ApplicationController ist das Starten einer Anwendung:
AppProcess process = controller.exec("calc.exe");
Zurück bekommt man ein Objekt, welches die neu gestartete Anwendung repräsentiert.
Von dem Prozess-Objekt kann man nun das Hauptfenster abfragen. Da das Hauptfenster nicht
sofort nach dem Start der Anwendung erzeugt wird, sondern verzögert, sollte man
eine kurze Wartezeit einbauen. Es folgt der Quellcodeabschnitt:
Thread.sleep(1000);
AppWindowTopLevel windowMain = process.getWindowMain();
Das zurückgelieferte Objekt repräsentiert das Rahmenfenster der Anwendung.
|
|
|
Ein spezieller Anwendungsbereich eröffnet sich durch den entfernten Zugriff auf Rechner.
Dies wird durch eine RMI Client/Server-Architektur realisiert.
Der Server, genannt Remote-Application-Controller, muss dazu auf dem Hostrechner gestartet
werden. Mehr dazu unter Start des Remote-Application-Controllers.
Über die IP-Addresse des Hostrechners kann man nun
mittels einer Internet/Intranet-Verbindung
den Remote-Application-Controller ansprechen. Der Rechner von dem die Verbindung
aufgebaut wird, wird als RMI-Client bezeichnet.
Bei dem RMI-Client handelt es sich um ein ganz normales Java-Programm, welches
die JPA-API einbindet und auf die Betriebssystem-Objekte des ApplicationController zugreift.
Programmtechnisch kann derselbe Quellcode wiederverwendet werden, wie beim
lokalen ApplicationController.
Unterscheiden tut sich nur die Quellcodezeile zur Abfrage des ApplicationController
zu vorherigen Quellcodebeispielen:
ApplicationController controller = manager.getApplicationControllerRemote( "hostname or ip-address" );
Beim Aufruf der Methode getApplicationControllerRemote muss die IP-Adresse oder der Hostname des Rechners
angegeben werden, auf welchem der Remote-Application-Controller gestartet wurde.
Bevor der Remote-Application-Controller über das Internet/Intranet verfügbar ist,
muss dieser noch Online geschaltet werden.
|
|
|
|
Die Core-API von Java stellt bereits eine Möglichkeit zum Starten von
externen Anwendungen bereit. Dies geschieht über die Methode exec(...)
der Klasse Runtime.
|
|
|
|
Die gleiche Funktionalität wird über die Methode exec(...) der Klasse
ApplicationController der JPA-API bereitgestellt.
Zusätzlich wurde exec um einige Parameter erweitert.
Jetzt ist es möglich auf das Erscheinungsbild des Hauptfensters nach
dem Starten der Anwendung Einfluss zu nehmen.
Die gewünschte Position und der Anzeigestatus (maximiert, normal und minimiert)
des Hauptfensters kann angegeben werden.
Allerdings ist anzumerken, dass einige Anwendungen manche Optionen ignorieren
und diese deshalb ohne Wirkung sind.
Die Kernfunktionalität der JPA-API ist es Ihnen den Zugriff auf die Benutzeroberfläche
des neugestarteten Prozesses zu ermöglichen.
Dazu wurde die JPA-API als objekt-orientierte Klassenbibliothek entworfen.
Jedes Betriebssystem-Objekt wird durch spezialisierte Java-Klassen repräsentiert.
Im folgenden werden die Zusammenhänge näher erläutert.
|
|
|
|
In einem Prozess arbeiten ein oder mehrere Threads den Programmcode ab.
Threads sind als leichtgewichtige Prozesse anzusehen.
Alle Threads eines Prozesses teilen sich den gleichen virtuellen
Arbeitsspeicher und haben Zugriff auf die Ressourcen des Programms.
Nach dem Start eines Prozesses wird zunächst ein
sogenannter Hauptthread (main thread) in der main()-Funtion mit
der Ausführung des Programms beginnen. Handelt es sich
um eine Anwendung mit einer Benutzeroberfläche, dann
wird zumeist der Hauptthread für das Erzeugen von Dialogen
und Fenstern zuständig sein.
Während der Ausführung eines Prozesses werden Module
in den Speicher geladen.
Das obige Bild zeigt nun die Abhängigkeiten zwischen diesen
Betriebssystem-Objekten. Ein Prozess hat ein oder mehrere Threads.
Beim ersten Thread handelt es sich um den Hauptthread. Ein Thread
wiederum kann Fenster einer Benutzeroberfläche besitzen.
Falls Ereignisse in den Fenstern auftreten, wird der Thread entsprechend
reagieren.
Unter UML-Klassendiagramm der JPA-API werden einige
wichtige Klassen und deren Beziehungen zueinander aufgezeigt.
|
|