Mittwoch, 28. November 2012

System Integration mit Xpert.Ivy: Intermediate Events über Dateien

Für die asynchrone Kommunikation zwischen Xpert.Ivy und externen Systemen innerhalb eines Prozesses stellt Xpert.Ivy Intermediate Events zur Verfügung.

Ein mögliches Szenario könnte wie im folgenden Bild sein. Eine Geschäftsapplikation sendet eine Meldung an Xpert.Ivy um einen Prozess zu starten. Im Laufe des Prozesses sendet Xpert.Ivy an ein Druckoutput System eine Anfrage zum Aufbereiten und Versenden eines Formulares. Anschliessend wartet der Prozess auf eine Meldung vom DMS System, dass das Formular zurückgesendet und archiviert wurde.




Und so könnte das in Xpert.Ivy aussehen:





Wie  ein Prozess Start über eine Datei funktionieren kann, habe ich in diesem Post beschrieben:
System Integration mit Xpert.Ivy: Event Start über Dateien

Intermediate Events

Jedem Intermediate Event muss in Xpert.Ivy eine eindeutige ID, genannt "Event ID", zugewiesen werden. Dies kann die Ivy Case ID sein, oder eine andere eindeutige ID.Wenn man die Case ID nimmt, muss man während dem Entwickeln mit dem Designer etwas aufpassen, da nach jedem Start der Engine wieder mit der Case ID "1" begonnen wird.

Im oben beschriebenen Szenario würde beim Print-Request bereits die gleiche Event-ID an das Druck-System übergeben. Dieses könnte die Event-ID als Strichcode auf ein Formular drucken, welcher dann wenn das Formular zurückkommt, vom Scanner bzw. Dokument Management System gelesen und wieder in die Event-ID umgewandelt wird. Diese wird dann vom DMS wieder an Xpert.Ivy zurückgegeben, wo so die Event-ID wieder einem bestimmten Prozess zugeordnet werden kann.

Hier das etwas überarbeitet Szenario.


Xpert.Ivy liefert die Klasse FileIntermediateEventBean aus, welche wir uns im folgenden etwas genauer ansehen.

FileIntermediateEventBean

Die Klasse FileIntermediateEventBean nimmt eine Datei im folgenden Format entgegegen:

Attribute1=Wert1,Attribute2=Wert2,...

Die Werte können über die Ivy Variable "result" im Output-Tab des Intermediate Events abgefragt werden.

Beispiel:


Mittwoch, 14. November 2012

Smalltalk versus Java

Als Entwickler im Umfeld von Geschäftsapplikationen mit Smalltalk und Java Erfahrung möchte ich hier einen kleinen Vergleich zwischen den beiden Sprachen bzw. Plattformen machen.

Die Geschichte von Smalltalk beginnt irgendwann in den 70er Jahren, wobei es erst in den 80er und 90er Jahren vermehrt Verbreitung fand, um dann mit dem Aufstieg von Java wieder Marktanteile zu verlieren. Heute sind Smalltalk-Projekte (zumindest in der Schweiz) ziemlich selten geworden.

Hier noch ein Zitat zu den Ursprüngen von Java:
Java. The elegant simplicity of C++. The blazing speed of Smalltalk.
http://c2.com/cgi/wiki?SmalltalkMinusMinus
Zum beginnen einige Gemeinsamkeiten von Smalltalk und Java, quer über Sprache und Plattform:
  • Beide sind Objekt-Orientiert
  • Beide haben eine grosse Klassenbibliothek z.Bsp. für Collections
  • Beide laufen in einer Virtual Machine und verwenden ein Garbage Collector
  • Viele Smalltalk VM's laufen wie die JVM auf mehreren Betriebssystemen
Und hier einige Unterschiede:
  • Smalltalk verwendet keine statische Typisierung
  • Smalltalk hat nur sechs Key-Wörter, alles andere wird über Klassen, Objekte, Methoden und Blöcke (entspricht in etwa den Closures in Java 8) abgebildet
  • Smalltalk verwendet sogenannte Images anstatt Dateien
  • In Smalltalk bilden Sprache, Runtime und IDE eine stärkere Einheit. Dafür gibt es nicht wirklich einen Hersteller übergreifenden Standard, ein Wechsel der IDE ist praktisch nicht möglich
In der täglichen Arbeit wirken sich diese Unterschiede mal weniger, mal mehr aus.

Statische versus Dynamische Typisierung

Als Nachteil von dynamischer Typisierung wird häufig angeführt, dass dadurch zur Laufzeit ein falsches Objekt verwendet werden könnte. In der praktischen Arbeit kommen solche Fehler aber extrem selten vor, wenn überhaupt. Viel häufiger tretten aber auch in Smalltalk folgende Probleme auf: Null Pointer Exceptions.

Umbenennen von Klassen oder Methoden geht in Java etwas einfacher (vorausgesetzt die ganzen Verweise liegen im Projekt oder Workspace vor), weil beim Compilieren Fehler auftreten. Dafür spart man in Smalltalk einiges an Zeit weil es keine merkbaren Compilierzeiten gibt.

Sprache und Klassenbibliothek

Was einem als Smalltalk Entwickler beim Einstieg in Java vermutlich als erstes auffällt, ist der grosse Aufwand den es zu Beginn braucht um nur einmal sämtliche Schlüsselwörter und Konstrukte der Java Sprache zu erlernen. Während sich ein Java Entwickler also noch mit der Sprache herumschlägt, kann sich ein Smalltalk Entwickler bereits in die Klassenbibliothekt einarbeiten. Bzw. er muss, da in Smalltalk nun mal sämtliche Konstrukte wie IF-Statements und Loops in Form von Klassen und Methoden vorliegen. Ansonsten finden sich praktisch alle Klassen in Smalltalk auch in Java wieder oder umgekehrt, hier als Beispiel ein Auszug aus den Collections-Klassen:

SmalltalkJava
DictionaryMap
IdentityDictionaryHashMap
CollectionList
OrderedCollectionArrayList
Array(primitive Arrays)
SetSet
IdentitySetHashSet
usw.


Tools und IDE

In Smalltalk findet der grösste Teil der Entwicklung im Class-Browser statt. Im Gegensatz zu Java IDEs wie Eclipse, wo Editierung und Browsing getrennt sind, bildet dies in Smalltalk immer eine Einheit. Die Klassen werden nicht primär in einzelnen Dateien gespeichert sondern in einem gemeinsamen Image. Dies macht die Entwicklung mit Smalltalk sehr effizient.

Im Gegensatz dazu ist es in keiner mir bekannten Smalltalk Umgebung möglich, verschiedene Arten von Resourcen oder gar Sprachen über die gleiche IDE zu editieren.

Class-Browser in VisualWorks - Browsen und Editieren gleichzeitig

Smalltalk oder ...?

Die Sprache Smalltalk ist einfacher als Java aber trotzdem sehr mächtig ist und wirkt dank der konsequenten Umsetzung der Konzepte immer noch modern. Im direkten Vergleich zu Smalltalk (oder auch C#) wirkt Java (die Sprache) für mich eher schwerfällig und veraltet. Alternative Sprachen bringen zwar einige der Vorteile dynamischer Sprachen auch auf die Java Plattform, die IDE Unterstützung scheint mir aber bei Smalltalk immer noch einiges komfortabler zu sein.

OO-Konzepte, Exception-Handling und die Klassenbibliotheken sind ein weiten Teilen vergleichbar.
Das grösste Problem im Smalltalk Umfeld ist die sehr kleine Community, die eher beschränkten Resourcen (Entwickler) seitens der Smalltalk Hersteller und dass es kein wirklicher Standard gibt und nur sehr wenige Hersteller übergreifende Frameworks. Diese Punkte dürften schlussendlich doch für Java sprechen.

Es ist zu hoffen, dass sich noch einige der Ideen und Konzepte von Smalltalk in die Java oder andere Plattformen retten können und dann vielleicht irgendwann zu Mainstream-Technologien werden. Ich bin aber ziemlich sicher, dass dies noch einige Jahr(zehnt)e dauern wird.

http://www.cincomsmalltalk.com
http://www.instantiations.com/
http://www.object-arts.com/

Donnerstag, 8. November 2012

ObjectStudio 8.4 ListView extensions

Some years ago I implemented some ListView extensions using WindowProc subclassing and primitives. While testing the new ObjectStudio Release 8.4.1 I found that registering our own WindowProc lead to crashes. I originally used the CHookWnd class, but because this class was marked obsolete by its author I had to find another way.

Using CWindowImpl I was now able to create a first working demo again.

Here is the primitive method which I use to register my own WindowProc for a ListView. It gets called from Smalltalk right after the ListView opens:

 BOOL LV_Init() {

     INIT_LOCAL_GVARS;
    OPTR oSelf;
    oSelf = PTOSn(0);

    // Get CPP handle of ListView form item
    OPTR oCppHandle = GetObjVar(oSelf,GetInstVarOffset(oSelf,SymbolHash((PSZ)_T("cppHandle"))));
    if (IsNil(oCppHandle)) return FALSE;

    // Check if handle is valid and get a reference to the MFC CListCtrl object
    if(ObjHandle(oCppHandle) == NULL) return FALSE;
    if(!AfxIsValidAddress((void*)ObjHandle(oCppHandle),sizeof(CListCtrl), true)) 
                 return FALSE;
    CListCtrl* m_pCtrl = (CListCtrl*)ObjHandle(oCppHandle);
    if(!m_pCtrl) return FALSE;


    HWND hwnd = m_pCtrl->GetSafeHwnd();
    if (hwnd == NULL) return FALSE;

   // New Code to Subclass the WindowProc instead of CHookWnd
    CMyListViewEx *myListViewEx = new CMyListViewEx();
    BOOL result = myListViewEx->SubclassWindow(hwnd);


    return result;
}

And this is the extension demo class, printing out middle mouse buttons down events to the transcript:

class CMyListViewEx : public CWindowImpl<CMyListViewEx,CListCtrl>
{
public:

    BEGIN_MSG_MAP(
CMyListViewEx)
        MESSAGE_HANDLER(WM_MBUTTONDOWN, OnMButtonDown)
    END_MSG_MAP()

    LRESULT OnMButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {

       INIT_LOCAL_GVARS;
       Out(_T("MBUTTONDOWN %i %i %i"), uMsg, wParam, lParam);

       bHandled = TRUE;
       return TRUE;
    }

   
CMyListViewEx(void);
    ~
CMyListViewEx(void);
   
    void OnFinalMessage(HWND hWnd) {
        UnsubclassWindow(TRUE);
        delete this;
    }
}


If we ever finish porting from ObjectStudio 7 to 8 I may contribute our extensions to the Cincom public Store repository.

See also: