Saturday, February 16, 2013

Edcom Nachlese 2013

Bin heuer das erste mal auf der Edcom Nachlese in München. Freue mich schon von den Neuheiten von der Lotusphere Connect 2013 zu hören. Leider kommt Ed Brill, der als Referent angekündigt war, verständlicherweise nicht mehr, aber ich denke es wird trotzdem eine sehr interessante Veranstaltung.

Vor allem freue ich mich auch schon auf einen Meinungsaustausch bezüglich des neuen Notesrelease, das ich persönlich eher zweispältig sehe. Siehe auch meine diversen Blogposts zum Thema Notes 9.

Notes 9 Volltextsuche kleine Änderung große Usability Verbesserung
Notes 9 Suche in Ansichten wurde vereinheitlicht und verbessert. 
Neues Feature Database Maintenance in Domino 9
Coole neue notes.ini Variable in Domino 9 für Copy style compact
Notes 9 SE erste Eindrücke aus Sicht des Plugin Entwicklers 
Erste Eindrücke vom Browserplugin und iNotes 
Notes 9 als Anwender; erster Blick Hui, zweiter Blick leider Pfui. 
Notes 9 Verbesserung beim e-mail typeahead 

Lotusscript Code aus Java plugin aufrufen

In bestehenden Notesanwendungen steckt jede Menge Lotusscript Code der über viele Jahre aufwendig entwickelt wurde, deshalb möchte man bei der Entwicklung von Plugins nicht das Rad neu erfinden, sondern bestehenden Code auch aus Eclipse plugins aufrufen. Wie dies geht möchte ich heute gerne zeigen:

Als erstes muss man die Notes API (com.ibm.notes.java.api und com.ibm.java.ui) dem Plugin als Abhängigkeit hinzufügen.

Als Beispiel habe ich eine scriptlibrary mit einer Funktion getUmsatz mit den Parametern Kundennummer und Jahr hergenommen. In der Funktion der Scriptlibrary werden aufwendige Datenbankzugriffe und Berechnungen durchgeführt, die wir in java nicht nachprogrammieren wollen.

Da man von Java nicht direkt auf die Library zugreifen kann, braucht man als erstes einen kleinen Agent der als Brücke zwischen dem Plugin und der Scriptlibrary fungiert.



Option Public
Option Declare
Use "UmsatzScriptLibrary"
Sub Initialize
 Dim ses As New NotesSession
 Dim context As NotesDocument
 Set context=ses.Documentcontext
 Call context.Replaceitemvalue("umsatz", getUmsatz(context.Getitemvalue("kundenNummer")(0), context.getItemValue("jahr")(0)))
 Print context.Getitemvalue("umsatz")(0)
 context.save True,false
End Sub


Der Agent macht nichts anderes, als dass er ein in Memory Dokument über den Dokumentcontext holt. Die Aufrufparameter für die getUmsatz Funktion ausliest und das Ergebnis der Funktion in der Variable Umsatz speichert. Natürlich konnte man den Agent auch dahingehend erweitern, dass in dem in Memory Dokument auch ein Parameter für die auzurufende Funktion mitgegeben wird und er dann die richtige Funktion aus der Scriptlibrary aufruft.

Wichtig bei dem Agent ist, dass man das Ziel auf "None" setzt. Sonst funktioniert der Zugriff auf das übergebene Dokument nicht zuverlässig.


Der Javateil ist etwas aufwendiger:


public static void berechneKundenUmsatz(String kundenNummer, int jahr) {
  try {
   // Starte den Zugriff auf den Workspace und erstelle ein
   // NotesAgentDataobjekt mit unserem Brückenagent.
   NotesUIWorkspace ws = new NotesUIWorkspace();
   NotesAgentData data = new NotesAgentData(new NotesDatabaseData("",
     "test.nsf"), "agent");
   // Füge die Aufrufparameter für die Scriptlibrary dem data Objekt
   // hinzu. Diese werden später im documentcontext als Items
   // verfügbar.
   data.addItem("kundenNummer", kundenNummer);
   data.addItem("jahr", new Integer(jahr).toString());
   // Erstelle ein Callback Objekt. die Methode done dieses Objekts
   // wird nach Ausführung des Brücken Agent aufgerufen.
   NotesDocumentDataCallback callBack = new NotesDocumentDataCallback() {
    @Override
    public void done(final NotesDocumentDataEvent event) {
     // Erstelle einen Notessessionjob in dem wir auf das
     // zurückgegebene Dokument zugreifen können.
     NotesSessionJob job = new NotesSessionJob(
       "verarbeite Ergebnis") {
      @Override
      protected IStatus runInNotesThread(Session session,
        IProgressMonitor arg1) throws NotesException {
       // Lade das Dokument, dass der Agent mit dem
       // Ergebnis befüllt hat.
       Document doc = event.getDocumentData()
         .open(session);
       // Speichere das Resultat in einer Finalen Variable,
       // dass wir es im UIThread weiterverwenden können.
       final double result = doc
         .getItemValueDouble("umsatz");
       // Mache irgendetwas im UI mit dem Resultat. In
       // unserem Beispiel eine Dialogbox anzeigen.
       Display.getDefault().asyncExec(new Runnable() {
        @Override
        public void run() {
         MessageBox box = new MessageBox(PlatformUI
           .getWorkbench()
           .getActiveWorkbenchWindow()
           .getShell());
         box.setMessage("Das Ergebnis ist: "
           + result);
         box.open();
        }
       });
       return Status.OK_STATUS;
      }
     };
     // starte den Notesjob
     job.schedule();
    }
   };
   // Führe den Agent mit dem data und callback Objekt aus. Der letzte
   // Parameter bedeutet, das der UIContext keine Rolle spielt. Das
   // heißt es ist egal auf welches Dokument im UI derzeit geöffnet
   // ist.
   ws.runAgent(data, callBack, false);
  } catch (NotesException e) {
   e.printStackTrace();
  }

 }
Das ist jetzt natürlich nur ein kleines Beispiel, bei dem der Aufwand vielleicht nicht dafür steht, aber in dem Lotusscript agent kann auch auf das UI zugegriffen werden. Das heißt der Agent kann Dialoge anzeigen und er kann auch mehrere Werte oder eine ganze Liste als Ergebnis zurückliefern. Damit kann man auch bei der Entwicklung von Plugins sehr leicht bestehenden Code wieder verwenden.

Wednesday, February 6, 2013

Experience Webseite der IBM wurde für Version 9 aktualisiert

Die IBM hat eine sehr schöne Webseite über die neuen Funktionen und die Vorteile von Notes 9 gegenüber anderen e-mail Systemen zusammengestellt.

Für weitere Infos zur neuen Version schauen Sie auch auf meine Übersicht über alle Postings zum Thema Notes/Domino 9 

Monday, February 4, 2013

Lösen von Notes Performanceproblemen mit dem NRPC Parser

Der Notes Client besitzt eine eingebaute Tracefunktion um die NRPC (Notes Remote Procedure Call) Kommunikation zwischen einem Client und dem Server zu tracen. Leider ist das Log, dass diese Tracefunktionalität zur Verfügung stellt, etwas unübersichtlich und kryptisch. Jedoch gibt es auf OpenNTF eine Datenbank mit der man die Analyse vereinfachen kann.

Hier die Schritte um eine Performanceanalyse mit der Datenbank durchzuführen:

Downloaden Sie den NRPC Parser von OpenNTF und signieren Sie die Datenbank mit einer Developer id, damit Sie keine Probleme mit der ECL haben.

Öffnen Sie die Parserdatenbank und klicken Sie auf die

 Schaltfläche. Damit werden in Ihrer notes.ini die Einträge
  • Client_Clock=1
  • Debug_Console=1
  • Debug_Outfile=c:\Program Files (x86)\IBM\Lotus\Notes\Data\RPC.txt
  • CONSOLE_LOG_ENABLED=1
gesetzt. Diese bewirken, dass in die Datei RPC.txt  nach dem Neustart des Clients jeder RPC protokolliert wird.

Jetzt muss der Notesclient neu gestart werden und man kann die Funktion in Notes durchführen mit der man ein Performanceproblem hat. z.B. eine Datenbank öffnen, oder ein Dokument aufmachen.

Danach sollte man die Notes.ini Einträge mit

wieder deaktivieren und den Notesclient neu starten.

Danach kann man mit der Schaltfläche
die erstellte Datei analysieren lassen und bekommt dann für jeden Aufruf einer Funktion auf dem Server eine Zeile in der genau  steht was gemacht wurde, wie lange dieser Aufruf gedauert hat und wieviele Daten vom Server gesendet und empfangen wurden.


Aufwendige Operationen sind rot markiert. Die Spalte Sent gibt die Datenmenge in Bytes an die der Server gesendet hat. Die Spalte Rec'd gibt an, wieviel Daten der Server vom Client empfangen hat.

Update 11.11.2013 Wie in den Kommentaren angeführt hat Andrew Magerman eine neue Version des NRPC Parser veröffentlicht, die jetzt auch mit aktuellen Version von Notes korrekt funktioniert. Die Angabe von Debug_ThreadID=0 die man in älteren Versionen des NRPC Parsers benötigte ist daher nicht mehr notwendig. Vielen Dank für dieses Update und das fantastische Tool.











Wednesday, January 30, 2013

Überschüssige Leerzeichen im Text entfernen mit Regular Expression

Nehmen wir an, wir haben einen Code der wild mit String konkatinierung zusammengebaut wurde und Whitespace unterschiedlicher Länge enthält. z.B. "     Der            faule braune        Fuchs ". Mit folgenden kleinen Codeschnippsel kann man den überschüssigen Whitespace eliminieren.


text = text.replaceAll("\\s{2,}", " ").trim();

Ergibt "Der faule braune Fuchs".

Monday, January 14, 2013

Notes 9 Verbesserung beim e-mail typeahead

Das Typeahead bei e-mail Adressfeldern ist eine sehr praktische Sache, aber seit Einführung dieser Funktion stört mich die Tatsache, dass immer zuerst die lokalen Adressbücher vor den Serveradressbüchern durchsucht werden, obwohl davon auszugehen ist, dass die Serveradressbücher im Normalfall die viel akuraten Informationen enthalten. Mit Notes 9 wurde nun eine neue notes.ini Variable (TypeaheadShowServerFirst=1) eingeführt mit der man dieses Verhalten umkehren kann.

Ohne TypeaheadShowServerFirst=1



Mit TypeaheadShowServerFirst=1

Die Notes.ini Variable kann natürlich auch über eine Desktoppolicy gesetzt werden. Leider gibt es jedoch keine Benutzerschnittstelle für diese meiner Meinung nach extrem wichtige Einstellung.

Laut Doku in der Version 9 soll diese Variable auch in 8.5.3 funktionieren. In meinem 8.5.3 FP1 Client hat die Variable jedoch keine Funktion.


Für weitere Infos zur neuen Version schauen Sie auch auf meine Übersicht über alle Postings zum Thema Notes/Domino 9

Friday, January 11, 2013

Neuer Artikel im Wiki über Plugin und Feature Deployment

Die IBM hat eine sehr gute Beschreibung (Managing features in the IBM Lotus Notes 8.5.x Client) über die verschiedenen Möglichkeiten der Installation von Features und Plugins im Lotus Notes Domino Wiki veröffentlicht. Ich war am Anfang sehr skeptisch bezüglich der Wikis aber in letzter Zeit wird wirklich sehr guter Content seitens der IBM veröffentlicht. Hoffentlich hält der positive Trend an.

Thursday, January 10, 2013

Zugriff auf die Hard und Softwarekonfiguration über WMI mittels Lotus Script

Unter Windows gibt es mit dem Windows Management Instrumentation ein sehr mächtiges Werkzeug mit dem man auf diverse Hardware und Software Informationen in Windows zugreifen, bzw mit dem man auch administrative Dinge erledigen kann. Normalerweise verwendet man WMI aus einem vb oder aus einem Powershell script.

Heute möchte ich aber zeigen, dass man den selben Mechanismus auch bequem von Lotus script für die Beschaffung von diversen Infos verwenden kann. Als Beispiel möchte ich einen Agenten anführen, der z.B. die derzeitige Bildschirmauflösung ausliest. Eventuell will man ja in einem Notesscript je nach verwendeter Bildschirmauflösung verschiedene Framesets anzeigen.


Sub Initialize
 Dim objWMIService As Variant
 Dim colItems as Variant
 Dim strComputer As String
 strComputer="."
 Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
 Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_DesktopMonitor",,48) 
 Forall objItem In colItems 
  print "Monitor Höhe:" & objItem.ScreenHeight
  Print "Monitor Breite:" & objItem.ScreenWidth 
 End forall
End Sub


02-04  die verwendeten Variablen werden definiert.
05 Mit WMI kann man auch auf Remotecomputer zugreifen. Im Normalfall will man jedoch auf seinen eigenen Computer zugreifen, was man durch den Punkt erreichen kann.
06  Das WMI Service Objekte wird instantiert.
07 WMI stellt die Informationen in einer Datenbank ähnlichen Struktur zur Verfügung die mit einer an SQL angelehnten Syntax abgefragt werden kann. Ich komme dann noch später dazu wie man auf diese SQL Kommandos kommt.
08-11 Mittels einer Forall Schleife werden alle Sätze gelesen. Normalerweise sollte hier nur ein Satz zurückgegeben werden, ausser der Benutzer hat mehrere Monitore;-)

Obiges Gerüst kann man natürlich nicht nur für den obigen Zweck verwenden sondern mit den richtigen WMI SQL's kann man praktisch auf jede Info die in Windows gespeichert ist zugreifen. Um den Querystring zusammenzubauen kann man entweder die Doku in der MSDN durcharbeiten oder besser auf den genialen WMI Code Creator  zurückgreifen.


Mit dem kann man sich bequem die Informationen zusammenklicken und bekommt dann den Code in vbscript angezeigt. Mittels diesen Infos kann man dann oben angeführtes Lotus Script Beispiel überarbeiten und auf die gewünschten Infos zugreifen.


ad