Archive for the ‘rcp’ Category

Galileo ist da

Monday, July 6th, 2009

Am 23.6. hatten wir unser 2. eclipse DemoCamp in Leipzig. Der Anlass war das Simultanrelease von eclipse 3.5 Galileo, dass am 24.6. erschien. In der 7. Etage der Praxisklinik nahe von Leipzigs Stadtzentrum und mit großer Dachterrasse fanden sich ca. 30 Interessenten ein, um den 5 spannenden Vorträgen zu folgen.

img_0017

Die Vorträge waren recht verschieden und behandelten:

  • RIM – Informations Management eine RCP-Applikation mit der sehr effizient verschiedene Daten in einer lokalen Datenbasis durchsucbar abgelegt werden können
  • Textuelle DSLs entwickeln mit EMFText einem Werkzeug zur Entwicklung textueller Editoren
  • Dawn – collaborative, webbased GMF-Editing einer Diplomarbeit, in der die technische Realisierung eines verteilten GMF-Editors implementiert wird
  • Modular EMF/GMF customization with ObjectTeams/Java einem Werkzeug zur aspektorientierten Erweiterung bestehender eclipse Programme
  • flowR einem Modellierungs- und Softwareentwicklungsframework inklusive eingebauter Runtimeumgebung

Zu allen Vorträgen gab es zwischendurch oder danach verschiedenste Fragen, Ideen und Hinweise. Alle Beteiligten bewerteten das Democamp als positiv und wünschten weitere solcher Veranstaltungen, bei denen Wissen um Werkzeuge und Lösungen rundum eclipse besprochen werden.

Gegen 21:00 Uhr waren wir mit dem offiziellen Teil durch und liessen den Abend in Leipzigs Barfußgäßchen ausklingen.

img_0020

Schulen Sie noch oder modellieren Sie schon?

Monday, May 25th, 2009

Letzte Woche hielt ich eine Präsentation, bei der es mal wieder um die Evaluation des richtigen BPM-(Business-Process-Management)-Systems ging, bzw. synonym Workflowengine, Prozessengine…

Workflowstandardsprachen

Da wir dort selbst als Lösungsanbieter in Konkurrenz zu anderen Größen, die solche Systeme herstellen, auftraten, habe ich versucht die eigentlichen Probleme der generischen Lösungen herauszuarbeiten. Eine Recherche der vorhandenen Systeme und Sprachstandards ergab (nicht vollständig):
  • BPEL
  • jPDL
  • ARIS EPK
  • Microsoft Visio
  • UML Statecharts (eventuell mit Profilen)
  • SysML
  • xPDL
  • BPMN
  • Liste beliebig erweiterbar, um Sprachen und Werkzeuge mit denen Prozesse irgendwie gemalt werden können

Schon anhand der Anzahl wird sehr schnell klar, dass das eigentliche Kundenproblem damit wohl nicht wirklich ausreichend adressiert wird. Probleme sind der sehr technische Fokus der Sprachen oder andererseits der zu fachliche, der wiederum schlecht auf Technik abgebildet werden kann. Ein weiteres Problem ist, dass nur wenige Fachexperten eine dieser Sprachen kennen und beherrschen. Die Mitarbeiter müssen also immer geschult werden.

Die Lösung dieser beiden Probleme liegt meiner Meinung nach in einer kundenspezifischen Modellierungssprache, die in der gewohnten Sprache der Fachexperten die Prozesse, die beteiligten Systeme, die beteiligten Personen und Dokumente formal erfassen kann. Die gewohnte Sprache ist meist bereits aus vorhandenen Word-Texten oder Visio-Diagrammen ableitbar.

Mein Vorschlag war dort also die Erstellung eines kundenspezifischen Modelleditors (einer DSL) in der gewohnten Fachsprache mit den konkreten vorhandenen Backendsystemen. Unter der Haube generieren wir aus der kundenspezifischen Sprache z.B. jPDL um die Prozesse mit der OpenSource-Engine JBoss JBPM auszuführen. Außerdem generieren wir die technischen Adapter um die Backendsysteme anzusprechen, die Dokumention bspw. für das QM-Handbuch als PDF oder Office und auch Adapter für Test- und Simulationsfälle. Der Schulungsaufwand für die modellierenden Fachexperten entfällt also.

Was wir als Werkzeugbauer itemis tun können, ist

  • die Erstellung des Editors auf Basis eclipse RCP
  • die Erstellung der Generatoren
  • die Installation/Betreuung der Engine bspw. JBoss JBPM.

Und wie mir einer der Fachexperten nach dem Meeting bestätigte ist das ein Weg, der Ihm sehr gut gefällt und den die Engine-Herstellerkonkurrenz nicht bieten kann. Vor allem auch die Möglichkeit, Dinge in der eigenen Sprache modellieren zu können, die es in den Standardsprachen erstmal nicht gibt.

Auftakt zur Vortragsreihe Leipzig

Thursday, February 26th, 2009

Am letzten Dienstag war es nun endlich soweit. Am Standort Leipzig sind wir mit der Vortragsreihe gestartet. Was sich an anderen Standorten bereits zu einer verlässlichen Institution etabliert hat, wollen wir mit dem Leipziger Team hier fortsetzen.

Das Auftaktthema bildete Eclipse RAP: Rich Clients im Web, bei dem wir gemeinsam mit unserem Partner und Kunden IBYKUS AG von den gemachten Erfahrungen beim Einsatz dieses AJAX Frameworks berichtet haben. Mit rund 20 Teilnehmern empfinde ich den Auftakt als gelungen.

Für alle Interessierten, die nicht an der Veranstaltung teilnehmen konnten hier die Vortragsunterlagen:

Das nächste Event ist für Mitte/Ende April geplant. Aller Voraussicht nach wird es sich dann um das Thema OSGi drehen.

Co-operation: Eclipse JAAS + Eclipse RAP

Monday, January 5th, 2009

Java Authentication and Authorization Service, kurz JAAS, ist in der Java-Welt das Standardvorgehen zur Authentifizierung und Autorisierung in Java-Anwendungen. Das Eclipse JAAS – noch ein Incubator Projekt – will die Lücke zwischen JAAS Standard und Eclipse PDE schliessen.

Zur Authentifizierung bietet Eclipse JAAS verschiedene Extensionpoints, die es ermöglichen, die Bestandteile von JAAS in der plugin.xml vorzunehmen. Bestandteil dieses Beitrags ist aber zunächst die Authentifizierung in einer Eclipse RAP Anwendung mittels JAAS.

org.eclipse.equinox.security.loginModule

Der loginModule Extensionpoint ermöglicht die Registrierung eines JAAS LoginModule.

<extension id="myLoginModule"
           name="My Login Module"
           point="org.eclipse.equinox.security.loginModule">
   <loginModule
       class="org.foo.bar.MyLoginModule"
       description="My Login Module">
   </loginModule>
</extension>

<extension id="unixLoginModule"
           name="Unix Login Module"
           point="org.eclipse.equinox.security.loginModule">
   <loginModule
       <!-- part of standard jdk -->
       class="com.sun.security.auth.module.UnixLoginModule"
       description="Unix Login Module">
   </loginModule>
</extension>

org.eclipse.equinox.security.callbackHandlerMapping

Mit diesem Extensionpoint wird das Mapping zwischen eine JAAS Loginkonfiguration und einem konkreten CallbackHandler definitiert.

<extension point="org.eclipse.equinox.security.callbackHandlerMapping">
  <callbackHandlerMapping
     callbackHandlerId="org.foo.bar.basicAuthDialog"
     configName="MyLogin">
  </callbackHandlerMapping>
</extension>

org.eclipse.equinox.security.loginConfigurationProvider

<extension id="myLoginConfigurationProvider"
        point="org.eclipse.equinox.security.loginConfigurationProvider">
      <loginConfigurationProvider
          class="org.foo.bar.MyLoginConfigProvider"/>
</extension>

org.eclipse.equinox.security.callbackHandler

Der CallbackHandler ermöglicht Nutzerinteraktionen, zb. zur Eingabe des Logins und Passworts im Dialog oder auf der Kommandozeile.

<extension id="basicAuthDialog"
           name="Basic Authentication Dialog"
           point="org.eclipse.equinox.security.callbackHandler">
   <callbackHandler
      class="org.foo.bar.BasicAuthHandler">
   </callbackHandler>
</extension>

Im Eclipse RAP Projekt können die meisten Ansätze aus RCP übernommen werden. Das CVS (dev.eclipse.org) liefert auch eine RCP-Beispielanwendung mit, die als Basis für das RAP-Projekt dienen kann.

public class BasicAuthHandler extends AbstractLoginDialog {
 
  private String username;
  private char[] password;
 
  protected Control createDialogArea(Composite parent) {
    // implement user interface
  }
 
  public void internalHandle() {
    Callback[] callbacks = getCallbacks();
    for (int i = 0; i &lt; callbacks.length; i++) {
      if (callbacks[i] instanceof NameCallback) {
        ((NameCallback) callbacks[i]).setName(username);
      } else if (callbacks[i] instanceof PasswordCallback) {
        ((PasswordCallback) callbacks[i]).setPassword(password);
      }
    }
  }
}

Die wichtigsten Ausschnitte des abstrakten Logindialogs mit Implementierung des CallbackHandler Interface:

public abstract class AbstractLoginDialog extends TitleAreaDialog
  implements CallbackHandler {
 
  Callback[] callbackArray;
 
  protected final Callback[] getCallbacks() {
    return this.callbackArray;
  }
 
  public abstract void internalHandle();
 
  public void handle(final Callback[] callbacks) throws IOException {
    this.callbackArray = callbacks;
    final Display display = Display.getDefault();
    display.syncExec(new Runnable() {
      public void run() {
        isCancelled = false;
        setBlockOnOpen(false);
        open();
 
        final Button okButton = getButton(IDialogConstants.OK_ID);
        okButton.setText("Login");
        okButton.addSelectionListener(new SelectionListener() {
 
          public void widgetSelected(final SelectionEvent event) {
            processCallbacks = true;
          }
 
          public void widgetDefaultSelected(final SelectionEvent event) {
            // nothing to do
          }
        });
 
        final Button cancel = getButton(IDialogConstants.CANCEL_ID);
        cancel.addSelectionListener(new SelectionListener() {
 
          public void widgetSelected(final SelectionEvent event) {
            isCancelled = true;
            processCallbacks = true;
          }
 
          public void widgetDefaultSelected(final SelectionEvent event) {
            // nothing to do
          }
        });
      }
    });
 
    try {
      ModalContext.setAllowReadAndDispatch(true);
      ModalContext.run(new IRunnableWithProgress() {
 
      public void run(final IProgressMonitor monitor) {
        // Wait here until OK or cancel is pressed, then let it rip.
        // The event listener is responsible for closing the dialog
        // (in the loginSucceeded event).
        while (!processCallbacks) {
          try {
            Thread.sleep(100);
          } catch (final Exception e) {
            // do nothing
          }
        }
        processCallbacks = false;
        // Call the adapter to handle the callbacks
        if (!isCancelled()) {
          internalHandle();
 
        }
      }, true, new NullProgressMonitor(), Display.getDefault());
    } catch (final Exception e) {
      final IOException ioe = new IOException();
      ioe.initCause(e);
      throw ioe;
    }
  }
  ...
}

Beispielanwendung

Eine Beispielanwendung, die vor dem Laden und Starten der Workbench ein Login sicher stellt, könnte zb. so aussehen:

package org.foo.bar;
 
public class Application implements IEntryPoint {
 
  public int createUI() {
    Display display = PlatformUI.createDisplay();
    if (login(display)) {
      WorkbenchAdvisor advisor = new ApplicationWorkbenchAdvisor();
      return PlatformUI.createAndRunWorkbench(display, advisor);
    }
    return 0;
  }
 
  private boolean login(final Display display) {
    String configName = "MyLogin";
    URL configUrl = Activator.getDefault().getBundle()
                     .getEntry("data/jaas_config.txt");
    ILoginContext secureContext = LoginContextFactory
                     .createContext(configName, configUrl);
 
    Subject s = null;
    do {
      try {
        s = secureContext.getSubject();
      } catch (LoginException e) {
        // handle login exception
      }
    } while (s == null);
    return true;
  }
}

Und schliesslich die zugehörige JAAS Loginkonfiguration in data/jaas_config.txt.

MyLogin {
    org.eclipse.equinox.security.auth.module.ExtensionLoginModule required
        extensionId="org.foo.bar.unixLoginModule";

    org.eclipse.equinox.security.auth.module.ExtensionLoginModule required
        extensionId="org.foo.bar.myLoginModule"
};