# Standardmodule

In dieser Dokumentation finden Sie eine detaillierte Modulbeschreibung der folgenden Standardmodule:

Die Standardmodule elo, tfer, addr, notify, exif, www sind in Javadoc der internen ELOas Schnittstelle unter http://www.forum.elo.com/javadoc/as/21/ (opens new window) beschrieben.

# cnt: ELO Counter Access

Das Standardmodul cnt stellt den Zugriff auf ELOam Counter-Variablen zur Verfügung.

# cnt: Verfügbare Funktionen

Counter anlegen: Die Funktion createCounter() erzeugt einen neuen Counter und initialisiert ihn mit einem Startwert. Falls der Counter bereits existiert, wird er zurückgesetzt.

createCounter: function (counterName, initialValue) {
    var counterInfo = new CounterInfo();
    counterInfo.setName(counterName);
    counterInfo.setValue(initialValue);
    var info = new Array(1);
    info[0] = counterInfo;
    ixConnect.ix().checkinCounters(info, LockC.NO);
},

Counterwert ermitteln: Die Funktion getCounterValue() ermittelt den aktuellen Wert des angegebenen Counters. Wenn der Parameter autoIncrement auf true gestellt wird, wird der Counterwert zusätzlich automatisch hochgezählt.

getCounterValue: function (counterName, autoIncrement) {
    var counterNames = new Array(1);
    counterNames[0] = counterName;
    var counterInfo = ixConnect.ix().checkoutCounters(counterNames,
                                                      autoIncrement,
                                                      LockC.NO);
    return counterInfo[0].getValue();
},

Tracking-Nummer aus Counter bilden: Wenn man eine fortlaufende und automatisch erkennbare Nummer benötigt, kann man diese Funktion getTrackId() verwenden. Sie liest den nächsten Counterwert und codiert eine Zahl mit einem Präfix und einer Prüfziffer. Der erzeugte String sieht dann so aus <Präfix><Fortlaufende Zahl>C<Prüfziffer> ("ELO1234C0")

getTrackId: function (counterName, prefix) {
    var tid = cnt.getCounterValue(counterName, true);
    return cnt.calcTrackId(tid, prefix)
},

Tracking-Nummer bilden: Wenn man eine fortlaufende und automatisch erkennbare Nummer benötigt, kann man diese Funktion calcTrackId() verwenden. Sie codiert eine Zahl mit einem Präfix und einer Prüfziffer. Der erzeugte String sieht dann so aus <Präfix><Fortlaufende Zahl>C<Prüfziffer> ("ELO1234C0")

calcTrackId: function (trackId, prefix) {
    var chk = 0;
    var tmp = trackId;
    while (tmp > 0) {
        chk = chk + (tmp % 10);
        tmp = Math.floor(tmp / 10);
    }
    return prefix + "" + trackId + "C" + (chk %10);
},

Tracking-Nummer im Text suchen: Die Funktion findTrackId() sucht in einem Text nach einer Tracking-Nummer. Das erwartete Präfix und die Länge der eigentlichen Zahl können über einen Parameter gesteuert werden. Falls die Zahl eine variable Länge besitzt, kann der Längenparameter auf 0 gestellt werden. Wenn im Text kein passender Treffer vorhanden ist, wird eine -1 zurückgeliefert. Andernfalls wird der Zahlenwert (und nicht die komplette Track-ID) geliefert.

findTrackId: function (text, prefix, length) {
    text = " " + text + " ";
    var pattern = "\\s" + prefix + "\\d+C\\d\\s";
    if (length > 0) {
        pattern = "\\s" + prefix + "\\d{" +
                  length + "}C\\d\\s";
    }
    var val = text.match(new RegExp(pattern, "g"));
    if (!val) {
        return -1;
    }
    for (var i = 0; i < val.length; i++) {
        var found = val[i];
        var number = found.substr(prefix.length + 1,
                                  found.length - prefix.length - 4);
        var checksum = found.substr(found.length - 2, 1);
        if (checkId(number, checksum)) {
            return number;
        }
    }
    return -1;
}

# db:DB Access

Das Standardmodul DB Access stellt einen einfachen Zugriff auf externe Datenbanken zur Verfügung. Im Standard werden ODBC-Datenbanken sowie Microsoft SQL und Oracle SQL unterstützt. Falls auf andere Datenbanken mit einem native JDBC driver zugegriffen werden soll, müssen die entsprechenden JAR Dateien in das LIB-Verzeichnis des Services kopiert werden und die Imports und Zugriffsparameter im Modul Imports hinterlegt werden. Die Reihenfolge der Datenbankdefinitionen in dem Imports-Modul bestimmt dann den Wert des Parameters Verbindungsnummer in den nachfolgenden Aufrufen.

# db: Verfügbare Funktionen

getColumn( Verbindungsnummer, SQL Abfrage );

Dieser Aufruf muss als Parameter eine SQL-Abfrage mitgeben, welche eine Spalte abfragt und als Ergebnis nur eine Zeile zurückliefert.

Beispiel:

"select USERNAME from CUSTOMERS where USERID = 12345"

Über die Verbindungsnummer wird bestimmt, welche Datenbankverbindung verwendet wird. Die Liste der verfügbaren Verbindungen ist im Modul Imports definiert.

Beispiel mit JavaScript-Code:

var cmd = "select USERNAME from CUSTOMERS where USERID = 12345"
var res=getColumn(1, cmd);
log.debug(res);

Beispiel im GUI Designer:

GUI-Designer

Abb.: GUI-Designer

Falls die Trefferliste mehrere Zeilen umfasst, wird nur der erste Wert geliefert. Alle weiteren werden ohne Fehlermeldung ignoriert.

getLine( Verbindungsnummer, SQL Abfrage );

Dieser Aufruf gibt als Ergebnis ein JavaScript-Objekt mit den Werten der ersten Zeile der SQL Abfrage zurück. Die Abfrage kann beliebig viele Spalten enthalten, auch ein *. Die Spaltennamen müssen aber eindeutig und zulässige JavaScript-Bezeichner sein. Achten Sie auf die Groß- und Kleinschreibung (case sensitive) bei den JavaScript-Bezeichnern.

Beispiel:

"select USERNAME, STREET, CITY from CUSTOMERS where USERID = 12345"

Über die Verbindungsnummer wird bestimmt, welche Datenbankverbindung verwendet wird. Die Liste der verfügbaren Verbindungen ist im Modul Imports definiert.

Beispiel mit JavaScript-Code:

var cmd = "SELECT objshort, objidate,
          objguid FROM [elo20].[dbo].objekte where objid = 22";
var res = getLine(1,cmd);
log.debug(res.objshort);
log.debug(res.objidate);
log.debug(res.objguid);

Falls die Trefferliste mehrere Zeilen umfasst, werden nur die Werte der ersten Zeile zurückgeliefert. Alle weiteren Zeilen werden ohne Fehlermeldung ignoriert.

getMultiLine(Verbindungsnummer, SQL Kommando, Maximale Anzahl Zeilen)

Dieses Kommando arbeitet ähnlich wie der Aufruf getLine. Allerdings wird nicht ein Objekt, sondern ein Array von Objekten zurückgegeben. Jede Zeile aus der Trefferliste erzeugt ein Eintrag in dem Array. Damit es bei großen Datenbanken und unglücklichen Abfragen nicht zu einem Speicherüberlauf kommt, kann man die maximale Anzahl von Zeilen begrenzen. Zusätzliche Treffer werden einfach ignoriert.

Beispiel:

    var obj = db.getMultiLine(1, "select objshort,
                              objid from [elo80].[dbo].objekte where objid <
                              100 order by objshort", 50);
    for (var lg = 0; lg < obj.length; lg++) {
        log.debug(obj[lg].objid + " : " + obj[lg].objshort);
    }
doUpdate(Verbindungsnummer, SQL Kommando)

Man kann die Aufrufe getLine oder getColumn nicht dafür "missbrauchen" um eine Veränderung in der Datenbank auszuführen. Dieses Kommandos verwenden intern den JDBC-Befehl executeQuery – und dieser lässt nur SELECT-Abfragen zu.

Zum Verändern eines Eintrags kann man den Aufruf doUpdate verwenden. Dieser übergibt das eingetragene SQL-Kommando an den JDBC-Befehl executeUpdate – damit kann man auch bestehende Einträge verändern oder neue Einträge einfügen.

Information

Da alle Parameter in Text Form übergeben werden müssen, muss man selbst darauf achten, dass eventuell vorkommende Anführungsstriche korrekt codiert werden. Andernfalls führt es mindestens zu Fehlermeldungen, im schlimmsten Fall zu einem SQL-Injection-Angriff auf den SQL-Server.

# Imports

Die Art und der Umfang der benötigten Importe sind abhängig von der Datenbank und müssen der Herstellerdokumentation entnommen werden. Die verwendeten JAR-Dateien müssen bei Bedarf in das LIB-Verzeichnis des ELOas Services kopiert werden.

Im Folgenden ein Beispiel für die notwendigen Importe der JDBC-ODBC-Bridge:

importPackage(Packages.sun.jdbc.odbc);

Im Modul Imports der Standard ELOas Libraries 12 wurde ein Standardsystem-Selektor eingeführt. Der Standardsystem-Selektor hat aus Performancegründen den Standardwert SordC.mbLean und wird bei der Verarbeitung der vorhandenen ELOas Regeln verwendet.

const EM_SYS_STDSEL = SordC.mbLean;

Außerdem wurde im Modul Imports ein System-Selektor namens EM_SYS_SELECTOR eingeführt. Der System-Selektor wird im Modul bt auf den Wert des eingestellten Standardsystem-Selektors gesetzt. Der System-Selektor kann im Event onStart der ELOas Regeln die weiteren Eigenschaften eines Eintrags außer ID und Name verwenden bzw. verarbeiten.

EM_SYS_SELECTOR=SordC.mbAll;

Analog dazu wurden die Workflow-Konstanten um einen Workflow-Selektor namens EM_WF_SELECTOR erweitert:

var EM_WF_SELECTOR = SordC.mbLean;

# Verbindungsparameter

Die Datenbankverbindungsparameter werden im Modul Imports hinterlegt. Dort gibt es eine Liste von Verbindungen, die dann später durch ihre Nummer (mit 0 beginnend) als Verbindungsnummer angesprochen werden können.

var EM_connections = [
    {
        driver: 'sun.jdbc.odbc.JdbcOdbcDriver',
        url: 'jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\\Temp\\EMDemo.mdb',
        user: '',
        password: '',
        initdone: false,
        classloaded: false,
        dbcn: null
    },
    {
        driver: 'com.microsoft.sqlserver.jdbc.SQLServerDriver',
        url: 'jdbc:sqlserver://srvt02:1433',
        user: 'elodb',
        password: 'elodb',
        initdone: false,
        classloaded: false,
        dbcn: null
    }
];

Für jede Verbindung müssen folgende Informationen hinterlegt werden:

driver JDBC Klassenname für die Datenbankverbindung. Diese Information erhalten Sie vom JDBC -Treiberhersteller oder vom Datenbankhersteller.
url Zugriffs-URL auf die Datenbank. Hier werden datenbankabhängige Verbindungsparameter hinterlegt, z. B. Dateipfade bei Access Datenbanken oder Servernamen und Ports bei SQL Datenbanken. Diese Verbindungsparameter sind Herstellerabhängig und müssen der jeweiligen Dokumentation entnommen werden.
user Login-Name für den Datenbankzugriff. Dieser Parameter wird nicht von allen Datenbanken verwendet (z. B. nicht von ungeschützten Access Datenbanken). In diesem Fall kann der Parameter leer bleiben.
password Passwort für die Datenbankanmeldung.
initdone Interne Variable für die "lazy initialization".
classloaded Interne Variable zur Kontrolle, ob die Klassendatei bereits geladen wurde.
dbcn Interne Variable zur Speicherung des Datenbank-Verbindungsobjekts.

# JavaScript-Code

Die Routine dbInit wird nur modulintern aufgerufen. Sie wird vor jedem Datenbankzugriff aufgerufen und prüft nach, ob schon eine Verbindung aufgebaut wurde und erstellt sie bei Bedarf.

function dbInit(connectId) {
    if (EM_connections[connectId].initdone == true) {
        return;
    }
log.debug("Now init JDBC driver");
var driverName = EM_connections[connectId].driver;
var dbUrl = EM_connections[connectId].url;
var dbUser = EM_connections[connectId].user;
var dbPassword = EM_connections[connectId].password;
try {
    if (!EM_connections[connectId].classloaded) {
        Class.forName(driverName).newInstance();
        log.debug("Register driver ODBC");
        DriverManager.registerDriver(new JdbcOdbcDriver());
        EM_connections[connectId].classloaded = true;
    }
    log.debug("Get Connection");
    EM_connections[connectId].dbcn = DriverManager.getConnection(dbUrl,
                                                                 dbUser,
                                                                 dbPassword);
    log.debug("Init done.");
}   catch (e) {
    log.debug("ODBC Exception: " + e);
}
EM_connections[connectId].initdone = true;
}

Die Funktion exitRuleset_DB_Access() wird automatisch nach der Beendung der Ruleset-Verarbeitung aufgerufen. Sie prüft nach, ob eine Verbindung existiert und schließt sie dann. Diese Kontrolle muss für alle konfigurierten Datenbanken erfolgen.

function exitRuleset_DB_Access() {
    log.debug("dbExit");
    for (i = 0; i < EM_connections.length; i++) {
        if (EM_connections[i].initdone) {
            if (EM_connections[i].dbcn) {
                try {
                    EM_connections[i].dbcn.close();
                    EM_connections[i].initdone = false;
                    log.debug("Connection closed: " + i);
                }   catch(e) {
                    log.info("Error closing database " + i + ": " + e);
                }
            }
        }
    }
}

Die Funktion getLine() liest eine Zeile aus der Datenbank mit beliebigen Spalten und packt die Ergebnisse in ein JavaScript-Objekt. Dieses Objekt enthält für jede Spalte eine Member-Variable mit dem Spaltennamen.

function getLine(connection, qry) {
    // Unterfunktion: erzeugt ein JavaScript Objekt mit
    // dem eingelesenen Datenbankinhalt
    function dbResult(connection, qry) {
        // Zuerst die Verbindung aufbauen
        dbInit(connection);
        // nun ein SQL Statement Objekt erzeugen
        var p = EM_connections[connection].dbcn.createStatement();
        // und die Abfrage ausführen
        var rss = p.executeQuery(qry);
        // rss enthält die Trefferliste, es wird nun die erste
        // Zeile eingelesen
        if (rss.next()) {
            // über die Metadaten wird die Zahl der Spalten ermittelt
            var metaData = rss.getMetaData();           
            var cnt = metaData.getColumnCount();
            // Zu jeder Spalte wird nun eine Member Variable erzeugt
            // Diese hat als Namen den SQL Spaltenname und als Wert
            // den gelesenen Datenbankinhalt.
            // Die erste Spalte ist zusätzlich immer unter dem Namen
            // first ansprechbar.
            for (i = 1; i <= cnt; i++) {
                var name = metaData.getColumnName(i);
                var value = rss.getString(i);
                this[name] = value;
                if (i == 1) {
                this.first = value;
                }
            }
        }
        // Abschließend wird die Trefferliste und das SQL
        // Statement geschlossen.
        rss.close();
        p.close();
    }
    // hier ist der eigentliche Funktionsstart. Es wird
    // ein JavaScript Objekt mit dem Datenbankinhalt
    // angefordert.
    var res = new dbResult(connection, qry);
    return res;
}
// Die Funktion getColumn ist eine spezielle Variante
// des getLine Aufrufs. Die SQL Abfrage darf nur eine
// Spalte als Ergebnis aufweisen. Falls es weitere
// Spalten gibt, werden diese, genauso wie zusätzliche
// Zeilen, ignoriert.
function getColumn(connection, qry) {
    var res = getLine(connection, qry);
    return res.first;
}

# dex: Document Export

Das Modul Document Export kann automatisiert Dokumente aus dem Repository in das Dateisystem exportieren. Dieser Export ist kein einmaliger Vorgang – wenn eine neue Dokumentenversion erzeugt wird, schreibt das Modul automatisch eine aktualisierte Datei. Weiterhin können bereits veröffentlichte Dateien wieder gelöscht werden. Die Dateien können aus Sicherheitsgründen nur in einem vorkonfigurierten Pfad liegen.

Zur Verwendung muss eine Ablagemaske definiert werden, welche den Dokumentenstatus und ein oder mehrere Ablageziele im Dateisystem enthält. Zusätzlich wird in der Maske die Dokumentennummer des letzten Exports gespeichert.

Statusfeld in der Maske

Abb.: Statusfeld in der Maske

Das Statusfeld bestimmt die durchzuführenden Aktionen. Mit Aktiv: Freigegeben wird die Datei zum Export angemeldet. Aktiv: zur Löschung vorgesehen bewirkt, dass die Datei im Dateisystem gelöscht wird und der Status auf Nicht mehr aktiv / Gelöscht gesetzt wird. Alle anderen Statuseinstellungen bewirken keine Aktion des ELOas und sind für interne Dokumente oder noch nicht freigegebene Dokumente gedacht. Da dieser Statuswert von der internen Verarbeitung abgefragt wird, ist es sinnvoll diese Zeile nur aus einer vorkonfigurierten Stichwortliste heraus zu füllen.

Die Felder Dateipfad 1..5 enthalten den Pfad und Dateiname des Dokuments im Dateisystem. Dabei handelt es sich um einen relativen Pfad, der Startanteil ist als dexRoot fest im JavaScript-Modul vorgegeben und kann dort angepasst werden. Dieser feste Anteil ist zur Sicherheit eingeplant, denn sonst können durch Fehleingaben der Benutzer beliebige Dateien überschrieben werden.

Das Feld Letzter Export enthält die Dokumentennummer der zuletzt exportierten Dateiversion. Wenn nach einer Bearbeitung eine neue Dateiversion erzeugt wurde, wird das durch das Modul erkannt und eine Kopie der Datei neu in das Dateisystem geschrieben. Anschließend wird dieses Feld aktualisiert.

Wenn bei der Bearbeitung ein Fehler aufgetreten ist, wird durch die Error Rule in dem Feld Letzter Export der Text "ERROR" hinterlegt. Man kann somit im ELO ein dynamisches Register erstellen, welches dieses Feld auf den Wert ERROR überprüft und somit immer eine aktuelle Liste aller nicht exportierbaren Dokumente anzeigt.

Beispiel für ein dynamisches Register, wenn die Maske die ID 22 besitzt:

!+ , objkeys where objmask = 22 and objid = parentid and okeyname ='PDEXPORT
        and okeydata ='ERROR'

# dex: Verfügbare Funktionen

Das Modul stellt nur eine Funktion zur Verfügung: processDoc. Diese bekommt als Parameter das Indexserver-SORD-Objekt und prüft anhand des Status, ob die Datei exportiert oder gelöscht werden soll und führt die entsprechende Aktion aus. Als Rückgabewert wird die neue Dokumenten-ID übergeben. Das aktuelle SORD-Objekt steht innerhalb einer Regelabarbeitung in der JavaScript-Variablen Sord zur Verfügung.

Beispiel im XML-Ruleset-Code:

<rule>
    <name>Regel 1</name>
    <condition>(PDEXPORT != Sord.getDoc()) &amp;&amp; (PDEXPORT != "ERROR") ||
               (PDSTATUS == "Aktiv: zur Löschung vorgesehen") </condition>
    <index>
    <name>PDEXPORT</name>
    <value>dex.processDoc(Sord)</value>
    </index>
</rule>

# dex: JavaScript-Code

Als Erstes wird der Basispfad docRoot für die Dokumentenablage bestimmt. Der Zielpfad wird immer aus dieser Einstellung und der Benutzereingabe in der Ablagemaske ermittelt. Prinzipiell wäre es möglich, diesen Basispfad leer zu lassen, sodass der Benutzer beliebige Pfade angeben kann. Diese Vorgehensweise würde aber ein großes Sicherheitsrisiko darstellen, da dann jeder Benutzer beliebige Dateien aus dem Zugriffsbereich des ELOas überschreiben kann.

var dexRoot = "c:\\temp\\";

Die Funktion processDoc wird von der Regeldefinition heraus aufgerufen. Hier wird der Status des Indexserver-SORD-Objekts geprüft und die benötigte Funktion aufgerufen.

function processDoc( Sord ) {
    log.debug("Status: " + PDSTATUS + ", Name: " + NAME);
    if (PDSTATUS == "Aktiv: zur Löschung vorgesehen") {
        return dex.deleteDoc(Sord);
    }   else if (PDSTATUS == "Aktiv: Freigegeben") {
        return dex.exportDoc(Sord);
    }
    return "";
}

Falls der Status auf "Löschen" eingestellt war, wird in der Funktion deleteDoc die Löschung der Dateien veranlasst und der Status auf "Gelöscht" umgestellt.

function deleteDoc(Sord) {
    dex.deleteFile(PDPATH1);
    dex.deleteFile(PDPATH2);
    dex.deleteFile(PDPATH3);
    dex.deleteFile(PDPATH4);
    dex.deleteFile(PDPATH5);
    PDSTATUS = "Nicht mehr aktiv / Gelöscht";
    return Sord.getDoc();
}

Die Funktion deleteFile führt die eigentliche Löschung durch. Sie prüft zuerst, ob ein Dateiname konfiguriert ist und ob die Datei vorhanden ist und entfernt diese dann aus dem Dateisystem.

function deleteFile(destPath) {
    if (destPath == "") {
        return;
    }
    var file = new File(docRoot + destPath);
    if (file.exists()) {
        log.debug("Delete expired version: " + docRoot + destPath);
        file["delete"]();
    }
}

Falls eine neue Dateiversion geschrieben werden soll, wird die interne Funktion exportDoc aufgerufen. Hier wird die Datei vom Dokumentenmanager abgeholt und in die Zielordner kopiert.

function exportDoc(Sord) {
    var editInfo = ixConnect.ix().checkoutDoc(Sord.getId(), null,
                                              EditInfoC.mbSordDoc, LockC.NO);
    var url = editInfo.document.docs[0].getUrl();
    dex.copyFile(url, PDPATH1);
    dex.copyFile(url, PDPATH2);
    dex.copyFile(url, PDPATH3);
    dex.copyFile(url, PDPATH4);
    dex.copyFile(url, PDPATH5);
    return Sord.getDoc();
}

Die Funktion copyFile führt den Kopiervorgang in den Zielordner aus. Es wird zuerst geprüft, ob ein Zieldateiname vorliegt und ob eine eventuell vorhandene Altversion gelöscht werden muss. Anschließend wird die neue Version vom Dokumentenmanager geholt und im Zielordner gespeichert.

function copyFile(url, destPath) {
    if (destPath == "") {
        return;
    }
    log.debug("Path: " + docRoot + destPath);
    var file = new File(docRoot + destPath);
    if (file.exists()) {
        log.debug("Delete old version.");
        file["delete"]();
    }
    ixConnect.download(url, file);
}

# ix: IndexServer Functions

Das Modul ix enthält eine Sammlung verschiedener Indexserver Funktionen, die häufiger mal in Skripten benötigt werden. Dabei handelt es sich im Wesentlichen aber nur um einfache Wrapper um den gleichartigen Indexserverbefehl und keine neue komplexe Funktionalität.

# ix: Verfügbare Funktionen

Löschen eines SORD-Eintrags: Der Funktion deleteSord() werden als Parameter die Objekt-IDs des zu löschenden SORD-Eintrags und des Parent-Eintrags mitgegeben.

deleteSord: function (parentId, objId) {
    log.info("Delete SORD: ParentId = " + parentId + ", ObjectId = " + objId);
    return ixConnect.ix().deleteSord(parentId, objId, LockC.NO, null);
},

Suchen eines Eintrags: Die Funktion lookupIndex() ermittelt die Objekt-ID eines Eintrags, welche über den Ablagepfad gefunden wird. Der Parameter archivePath muss mit einem Trennzeichen beginnen.

lookupIndex: function (archivePath) {
    log.info("Lookup Index: " + archivePath);
    var editInfo = ixConnect.ix().checkoutSord("ARCPATH:" + archivePath,
                                               EditInfoC.mbOnlyId, LockC.NO);
    if (editInfo) {
        return editInfo.getSord().getId();
    }   else {
        return 0;
    }
}

Suchen eines Eintrags: Die Funktion lookupIndexByLine() ermittelt die Objekt-ID eines Eintrags anhand einer Metadatenfeldsuche. Wenn der Parameter Mask-ID mit einem Leerstring übergeben wird, wird eine maskenübergreifende Suche durchgeführt. Der Gruppenname und der Suchbegriff müssen übergeben werden.

lookupIndexByLine : function(maskId, groupName, value) {
    var findInfo = new FindInfo();
    var findByIndex = new FindByIndex();
    if (maskId != "") {
        findByIndex.maskId = maskId;
    }
    var objKey = new ObjKey();
    var keyData = new Array(1);
    keyData[0] = value;
    objKey.setName(groupName);
    objKey.setData(keyData);
    var objKeys = new Array(1);
    objKeys[0] = objKey;
    findByIndex.setObjKeys(objKeys);
    findInfo.setFindByIndex(findByIndex);
    var findResult = ixConnect.ix().findFirstSords(findInfo, 1, SordC.mbMin);
    ixConnect.ix().findClose(findResult.getSearchId());
    if (findResult.sords.length == 0) {
        return 0;
    }
    return findResult.sords[0].id;
},

Lesen der Volltextinformation: Die Funktion getFulltext() liefert die aktuelle Volltextinformation zu einem Dokument. Der Volltext wird als String zurückgegeben.

Beachten Sie

Sie können nicht erkennen, ob kein Volltext vorliegt oder die Volltextbearbeitung vollständig abgeschlossen ist oder mit Fehler abgebrochen wurde. Es wird der Text zurückgeliefert, der zum Abfragezeitpunkt vorhanden ist (evtl. auch eben ein Leerstring – wenn keine Volltextinformation vorliegt).

getFulltext: function(objId) {
    var editInfo = ixConnect.ix().checkoutDoc(objId, null,
                                              EditInfoC.mbSordDoc, LockC.NO);
    var url = editInfo.document.docs[0].fulltextContent.url
    var ext = "." + editInfo.document.docs[0].fulltextContent.ext
    var name = fu.clearSpecialChars(editInfo.sord.name);
    var temp = File.createTempFile(name, ext);
    log.debug("Temp file: " + temp.getAbsolutePath());
    ixConnect.download(url, temp);
    var text = FileUtils.readFileToString(temp, "UTF-8");
    temp["delete"]();
    return text;
}

Erzeugen einer Ordnerliste: Die Funktion createSubPath() prüft nach, ob der angegebene Ordnerpfad im Repository vorhanden ist und legt die fehlenden Teile bei Bedarf automatisch an.

createSubPath: function (startId, destPath, folderMask) {
    log.debug("createPath: " + destPath);
    try {
        var editInfo = ixConnect.ix().checkoutSord("ARCPATH:" + destPath,
                                                   EditInfoC.mbOnlyId, LockC.NO);
        log.debug("Path found, GUID: " + editInfo.getSord().getGuid() +
                  " ID: " + editInfo.getSord().getId());
        return editInfo.getSord().getId();;
    }   catch (e) {
        log.debug("Path not found, create new: " + destPath +
                  ", use foldermask: " + folderMask);
    }
    items = destPath.split("¶");
    var sordList = new Array(items.length - 1);
    for (var i = 1; i < items.length; i++) {
    log.debug("Split " + i + " : " + items[i]);
    var sord = new Sord();
    sord.setMask(folderMask);
    sord.setName(items[i]);
    sordList[i - 1] = sord;
    }
    log.debug("now checkinSordPath");
    var ids = ixConnect.ix().checkinSordPath(startId, sordList,
            new SordZ(SordC.mbName | SordC.mbMask));
    log.debug("checkin done: id: " + ids[ids.length - 1]);
    return ids[ids.length - 1];
}

# wf: Workflow Utils

Das Modul wf enthält vereinfachte Zugriffe auf Workflow-Daten. Dabei gibt es zwei Gruppen von Funktionen.

Die High Level Funktionen changeNodeUser und readActiveWorkflow sind für den einfachen Zugriff aus einer laufenden WORKFLOW-Abarbeitung heraus zu verwenden und arbeiten mit dem aktuell aktiven Workflow. Sie sind leicht zu verwenden, führen aber nur eine einfache Funktion aus.

Die Low-Level-Funktionen readWorkflow, writeWorkflow, unlockWorkflow und getNodeByName können von beliebiger Stelle aus verwendet werden. Wenn mehrere Änderungen im gleichen Workflow durchgeführt werden müssen, kann man hierüber sicherstellen, dass der Workflow nur einmal gelesen und geschrieben wird und nicht x-mal für jede Operation.

# wf: Verfügbare Funktionen

Benutzernamen eines Personenknotens ändern: Die Funktion changeNodeUser(): tauscht im aktuellen Workflow im Workflowknoten mit dem Namen nodeName den Benutzer gegen einen neuen Benutzer nodeUserName aus.

Da dieser Aufruf stets den kompletten Workflow einliest, verändert und sofort wieder zurückschreibt, sollte dieser einfache Aufruf nur dann verwendet werden, wenn nur ein Knoten bearbeitet werden soll. Falls mehrere Änderungen notwendig sind, sollten die später beschriebenen Funktionen zum Lesen, Bearbeiten und Speichern eines Workflows verwendet werden.

Da diese Funktion die Workflow-ID aus dem aktuell aktiven Workflow ermittelt, darf er nur aus der Suche "WORKFLOW" heraus aufgerufen werden. Bei der Verwendung in einem TREEWALK oder einer normalen Suche heraus wird eine zufällige Workflow-ID verwendet.

changeNodeUser: function(nodeName, nodeUserName) {
    var diag = wf.readActiveWorkflow(true);
    var node = wf.getNodeByName(diag, nodeName);
    if (node) {
        node.setUserName(nodeUserName);
        wf.writeWorkflow(diag);
    }   else {
        wf.unlockWorkflow(diag);
    }
}

Benutzernamen eines Knotens kopieren: Die Funktion copyNodeUser() arbeitet ähnlich wie changeNodeUser, allerdings kopiert sie den Benutzernamen aus einem Knoten in einen anderen Knoten.

copyNodeUser: function(sourceNodeName, destinationNodeName) {
    var diag = wf.readActiveWorkflow(true);
    var sourceNode = wf.getNodeByName(diag, sourceNodeName);
    var destNode = wf.getNodeByName(diag, destinationNodeName);
    if (sourceNode && destNode) {
        var user = sourceNode.getUserName();
        destNode.setUserName(user);
        wf.writeWorkflow(diag);
        return user;
    }   else {
        wf.unlockWorkflow(diag);
        return null;
    }
}

Aktuellen Workflow einlesen: Die Funktion readActiveWorkflow() liest den aktuell aktiven Workflow in eine lokale Variable zur Bearbeitung ein. Er kann am Ende mit writeWorkflow zurückgeschrieben werden oder die Sperre kann per unlockWorkflow wieder freigegeben werden.

readActiveWorkflow: function(withLock) {
    var flowId = EM_WF_NODE.getFlowId();
    return wf.readWorkflow(flowId, withLock);
    },

Workflow einlesen: Die Funktion readWorkflow() liest einen Workflow in eine lokale Variable ein. Dieser kann dann ausgewertet und verändert werden. Wenn die Änderungen gespeichert werden sollen, dann können diese per writeWorkflow zurückgeschrieben werden. Wenn der Workflow mit Lock gelesen wurde aber keine Änderungen gespeichert werden sollen, kann die Sperre mit unlockWorkflow zurückgenommen werden.

readWorkflow: function(workflowId, withLock) {
    log.debug("Read Workflow Diagram, WorkflowId = " + workflowId);
    return ixConnect.ix().checkoutWorkFlow(String(workflowId),
                                           WFTypeC.ACTIVE,
                                           WFDiagramC.mbAll,
                                           (withLock) ? LockC.YES : LockC.NO);
},

Workflow zurückschreiben: Die Funktion writeWorkflow() schreibt den Workflow aus einer lokalen Variablen in die Datenbank. Eine eventuell vorhandene Schreibsperre wird automatisch zurückgesetzt.

writeWorkflow: function(wfDiagram) {
    ixConnect.ix().checkinWorkFlow(wfDiagram, WFDiagramC.mbAll, LockC.YES);
},

Lesesperre zurücksetzen: Funktion unlockWorkflow(). Wenn ein Workflow mit Schreibsperre gelesen wurde aber nicht verändert werden soll, kann man die Sperre mittels unlockWorkflow zurücksetzen.

unlockWorkflow: function(wfDiagram) {
    ixConnect.ix().checkinWorkflow(wfDiagram, WFDiagramC.mbOnlyLock, LockC.YES);
},

Workflowknoten suchen: Die Funktion getNodeByName() sucht den Workflowknoten zu einem Knotennamen. Der Namen muss eindeutig sein, andernfalls wird der erste gefundene Knoten geliefert.

getNodeByName: function(wfDiagram, nodeName) {
    var nodes = wfDiagram.getNodes();
    for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        if (node.getName() == nodeName) {
            return node;
        }
    }
    return null;
},

Workflow aus Vorlage starten: Die Funktion startWorkflow() startet einen neuen Workflow zu einer ELO Objekt-Id aus einer Workflow-Vorlage.

startWorkflow: function(templateName, flowName, objectId) {
    return ixConnect.ix().startWorkFlow(templateName, flowName, objectId);
}

# mail: Mail Utils

Dieses Modul ist zum Senden von E-Mails gedacht. Es benötigt dafür einen SMTP-Host, über den die E-Mails verschickt werden können. Dieser muss vor dem ersten Mailversand über die Funktion setSmtpHost bekannt gemacht werden. Anschließend kann man per SendMail oder SendMailWithAttachment Nachrichten versenden. Das Modul besteht aus zwei Teilen, zum Versenden von E-Mails und zum Lesen von E-Mail-Postfächern.

# mail: Verfügbare Funktionen zum Lesen eines Postfachs

Im Ruleset kann definiert werden, dass als Basis nicht eine Suche im ELO Repository oder in der ELO Aufgabenliste durchgeführt wird, sondern ein Postfach durchlaufen wird. Für jeden Postfachtyp muss im Modul mail eine Anmelderoutine hinterlegt werden. In dieser Funktion muss der Mail Server kontaktiert werden, der gewünschte Mail Folder gesucht werden und die Liste der Messages eingelesen werden. Danach übernimmt die normale ELOas Verarbeitung das Kommando. Für jede Mail wird ein Dokument in dem Ordner vorbereitet, der im SEARCHVALUE definiert wurde und anschließend wird darauf das Ruleset ausgeführt (der Betreff der Mail wird automatisch in die Kurzbezeichnung übernommen). Wenn der Eintrag am Ende nicht gespeichert wird, dann findet sich dazu auch nichts im Repository. Nur gespeicherte Mails werden ins Repository übertragen.

<search>
<name>"MAILBOX_GMAIL"</name>
<value>"ARCPATH:¶ELOas¶IMAP"</value>
<mask>2</mask>

Im Ruleset muss als Name MAILBOX_<Verbindungsname> definiert werden und als Wert der Ablagepfad oder die Nummer des Zielordners. Zudem muss auch die Maske definiert werden, die für die neuen Dokumente verwendet wird.

Im Skript des Rulesets wird dann die Mail verarbeitet. Auch hier bietet das Modul mail ein paar Hilfsroutinen, die das Leben etwas einfacher machen. In dem folgenden Beispiel wird der E-Mail-Körper in den Zusatztext übertragen, Absender, Empfänger und MailID in die entsprechenden Felder der E-Mail-Maske:

OBJDESC = mail.getBodyText(MAIL_MESSAGE);
ELOOUTL1 = mail.getSender(MAIL_MESSAGE);
ELOOUTL2 = mail.getRecipients(MAIL_MESSAGE, "¶");
ELOOUTL3 = msgId;
EM_WRITE_CHANGED = true;

Falls zusätzliche Werte oder Informationen benötigt werden, steht in der Variablen MAIL_MESSAGE ein vollständiges JavaMail-MimeMessage-Objekt zur Verfügung.

Damit bereits bearbeitete Mails nicht doppelt ins Repository übertragen werden, sollte vor der Verarbeitung eine Suche nach der MailID durchgeführt werden. Wenn die Mail bereits im Repository ist, wird einfach die Variable MAIL_ALLOW_DELETE auf true gesetzt, andernfalls wird die Mail verarbeitet. Durch das Setzen des Lösch-Flags wird die Mail beim Weiterschalten aus dem Postfach entfernt oder als Bearbeitet markiert.

var msgId = MAIL_MESSAGE.messageID;
if (ix.lookupIndexByLine(EM_SEARCHMASK, "ELOOUTL3", msgId) != 0) {
    log.debug("Mail bereits im Repository vorhanden, Ignorieren oder Löschen");
    MAIL_ALLOW_DELETE = true;
}   else {
    OBJDESC = mail.getBodyText(MAIL_MESSAGE);
    ELOOUTL1 = mail.getSender(MAIL_MESSAGE);
    ELOOUTL2 = mail.getRecipients(MAIL_MESSAGE, "¶");
    ELOOUTL3 = msgId;
    EM_WRITE_CHANGED = true;
}

Diese Vorgehensweise liest eine E-Mail zwar doppelt ein (einmal zur normalen Verarbeitung und einmal im nächsten Durchlauf zum Löschen), hat aber den großen Vorteil, dass sichergestellt ist, dass die E-Mail erst dann aus dem Postfach gelöscht wird, wenn sie im Repository auch wirklich vorhanden ist.

Wenn Sie ein Postfach zur Überwachung verwenden wollen, werden in der JavaScript-Library mail die folgenden vier Funktionen benötigt:

Verbindung aufnehmen, Postfachordner öffnen: connectImap_<Verbindungsname>

Nächste Nachricht der Liste zur Bearbeitung: nextImap_<Verbindungsname>

Nachricht als bearbeitet markieren oder löschen: finalizeImap_<Verbindungsname>

Verbindung schließen: closeImap_<Verbindungsname>

Von diesen vier Funktionen muss in einfachen Fällen nur eine einzige Implementiert werden: Verbindung aufnehmen – connectImap_<Verbindungsname>. Da hier eine Vielzahl von projektspezifischen Aktionen stattfindet (Anmeldeparameter, Zielordner aufsuchen), gibt es keine Standardimplementierung. Die drei anderen Funktionen sind bereits mit einer Standardfunktion im System vorhanden. Sie müssen nur implementiert werden, wenn man zusätzliche Funktionen ausführen möchte.

Mit IMAP Server verbinden: Die Funktion connectImap_<Verbindungsname>() muss eine Verbindung zum E-Mail-Server aufnehmen und das gewünschte Postfach aufsuchen und auslesen. Die vorhandenen Nachrichten werden in der Variablen MAIL_MESSAGES hinterlegt. Der Mail Store muss in der Variablen MAIL_STORE gespeichert werden und der ausgelesene Ordner in der Variablen MAIL_INBOX. Diese beiden Werte werden am Ende der Bearbeitung zum Schließen der Verbindung benötigt. Über die Variable MAIL_DELETE_ARCHIVED wird bestimmt, ob aus dem Postfach gelöscht werden darf. Wenn es auf false gesetzt wird, werden Löschanforderungen aus dem Ruleset ignoriert. Diese Funktion wird nicht direkt über ein Skript aufgerufen, sie wird ELOas-intern aktiviert (bei der MAILBOX-Suche, im Beispiel MAILBOX_GMAIL).

connectImap_GMAIL: function() {
    var props = new Properties();
    props.setProperty("mail.imap.host", "imap.gmail.com");
    props.setProperty("mail.imap.port", "993");
    props.setProperty("mail.imap.connectiontimeout", "5000");
    props.setProperty("mail.imap.timeout", "5000");
    props.setProperty("mail.imap.socketFactory.class",
                      "javax.net.ssl.SSLSocketFactory");
    props.setProperty("mail.imap.socketFactory.fallback", "false");
    props.setProperty("mail.store.protocol", "imaps");
    var session = Session.getDefaultInstance(props);
    MAIL_STORE = session.getStore("imaps");
    MAIL_STORE.connect("imap.gmail.com", "<<<USERNAME>>>@gmail.com",
                       "<<<PASSWORT>>>");
    var folder = MAIL_STORE.getDefaultFolder();
    MAIL_INBOX = folder.getFolder("INBOX");
    MAIL_INBOX.open(Folder.READ_WRITE);
    MAIL_MESSAGES = MAIL_INBOX.getMessages();
    MAIL_POINTER = 0;
    MAIL_DELETE_ARCHIVED = false;
},

Verbindung schließen: Die Funktion closeImap_<Verbindungsname> ist optional und schließt die aktuelle Verbindung zum IMAP-Server. Wenn es keine speziellen Aufgaben beim Schließen gibt, müssen Sie diese Funktion nicht implementieren. Es wird stattdessen dann die Standardimplementierung closeImap() aus der Library verwendet. Diese schließt den Folder und den Store.

closeImap_GMAIL: function() {
    // hier können eigene Aktionen vor dem Schließen ausgeführt werden
    // Standardaktion, Folder und Store schließen.
    MAIL_INBOX.close(true);
    MAIL_STORE.close();
},

Message als bearbeitet markieren oder löschen: Die Funktion finalizeImap_<Verbindungsname>() ist optional und löscht die aktuelle Nachricht oder markiert sie anderweitig als bereits bearbeitet. Wenn sie nicht implementiert wird, verwendet ELOam die Standardimplementierung, welche eine bearbeitete E-Mail aus dem Folder löscht.

Das Beispiel löscht die E-Mail nicht, sondern setzt sie nur auf "Gelesen".

finalizeImap_GMAIL: function() {
    if (MAIL_DELETE_ARCHIVED && MAIL_ALLOW_DELETE) {
        message.setFlag(Flags.Flag.SEEN, true);
    }
},

Nächste Message aus der Liste bearbeiten: Die Funktion nextImap_<Verbindungsname> ist optional und liefert die nächste Nachricht aus dem ausgewählten Postfach zur Bearbeitung an das Ruleset. Wenn die Funktion nicht implementiert wird, verwendet ELOas die Standardimplementierung, welche jedes Dokument in die Bearbeitung gibt.

Das Beispiel zeigt eine Implementierung, welche nur ungelesene E-Mails bearbeitet. Sie kann im Paar in der oben aufgeführten finalizeImap Implementierung verwendet werden, welche bearbeitete E-Mails nicht löscht, sondern nur als gelesen markiert.

Beachten Sie

Wenn Sie mit dieser Methode arbeiten, müssen Sie auf einen anderen Weg sicherstellen, dass das Postfach nicht über allen Maßen anwächst (z. B. durch eine automatische Löschung nach einem Zeitraum).

nextImap_GMAIL: function() {
    if (MAIL_POINTER > 0) {
        mail.finalizePreviousMessage(MAIL_MESSAGE);
    }
    for (;;) {
        if (MAIL_POINTER >= MAIL_MESSAGES.length) {
            return false;
        }
        MAIL_MESSAGE = MAIL_MESSAGES[MAIL_POINTER];
        var flags = MAIL_MESSAGE.getFlags();
        if (flags.contains(Flags.Flag.SEEN)) {
            MAIL_POINTER++;
            continue;
        }
        MAIL_ALLOW_DELETE = false;
        MAIL_POINTER++;
        return true;
    }
    return false;
},

Mailkörper Text lesen: Der Funktion getBodyText() wird die Nachricht als Parameter übergeben (im Skript über die Variable MAIL_MESSAGE verfügbar) und liefert als Rückgabeparameter den E-Mail-Körper. Dazu wird der erste MIME-Part vom Typ TEXT/PLAIN gesucht. Wenn kein entsprechender Part vorhanden ist, wird ein Leerstring geliefert.

getBodyText: function(message) {
    var content = message.content;
    if (content instanceof String) {
        return content;
    }   else if (content instanceof Multipart) {
        var cnt = content.getCount();
        for (var i = 0; i < cnt; i++) {
            var part = content.getBodyPart(i);
            var ct = part.contentType;
            if (ct.match("^TEXT/PLAIN") == "TEXT/PLAIN") {
                return part.content;
            }
        }
    }
    return "";
},

Absender ermitteln: Die Funktion getSender() liefert die E-Mail-Adresse des Absenders.

getSender: function(message) {
    var adress = message.sender;
    return adress.toString();
},

Empfänger ermitteln: Die Funktion getRecipients() liefert eine Liste aller Empfänger (TO und CC). Wenn es mehr als einen Empfänger gibt, wird die Liste im Spaltenindex Format geliefert, wenn man im Parameter delimiter das ELO Trennsymbol ¶ übergibt.

getRecipients: function(message, delimiter) {
    var adresses = message.allRecipients;
    var cnt = 0;
    if (adresses) { cnt = adresses.length; }
    var hasMany = cnt > 1;
    var result = "";
    for (var i = 0; i < cnt; i++) {
        if (hasMany) { result = result + delimiter; }
        result = result + adresses[i].toString();
    }
    return result;
}

# Verfügbare Funktionen zum Versenden von Mails

Die Versende-Funktionen werden nicht direkt vom ELOas verwendet. Es sind Hilfsfunktionen zur eigenen Skriptprogrammierung, um die Komplexität der JavaMail-API vor dem Skriptentwickler zu verdecken.

SMTP Server anmelden: Die Funktion setSmtpHost() macht der Library den zu verwendenden SMTP-Host bekannt. Er wird für den E-Mail-Versand verwendet. Diese Funktion muss vor dem ersten Aufruf sendMail aktiviert werden.

setSmtpHost: function(smtpHost) {
    if (MAIL_SMTP_HOST != smtpHost) {
        MAIL_SMTP_HOST = smtpHost;
        MAIL_SESSION = undefined;
    }
},

Mail versenden: Die Funktion sendMail() sendet eine E-Mail. Als Parameter werden die Absender- und Empfängeradresse mitgegeben sowie der Betreff und der E-Mail-Text.

sendMail: function(addrFrom, addrTo, subject, body) {
    mail.startSession();
    var msg = new MimeMessage(MAIL_SESSION);
    var inetFrom = new InternetAddress(addrFrom);
    var inetTo = new InternetAddress(addrTo);
    msg.setFrom(inetFrom);
    msg.addRecipient(Message.RecipientType.TO, inetTo);
    msg.setSubject(subject);
    msg.setText(body);
    Transport.send(msg);
},

Mail mit Attachment versenden: Die Funktion sendMailWithAttachment() sendet eine E-Mail. Als Parameter werden die Absender- und Empfängeradresse mitgegeben sowie der Betreff, der E-Mail-Text und die Objekt-ID für das Attachment aus ELO. Das Attachment wird als temporäre Datei im Temp-Pfad zwischengespeichert, dort muss also ausreichend Platz verfügbar sein.

sendMailWithAttachment: function(addrFrom, addrTo, subject, body, attachId) {
    mail.startSession();
    var temp = fu.getTempFile(attachId);
    var msg = new MimeMessage(MAIL_SESSION);
    var inetFrom = new InternetAddress(addrFrom);
    var inetTo = new InternetAddress(addrTo);
    msg.setFrom(inetFrom);
    msg.addRecipient(Message.RecipientType.TO, inetTo);
    msg.setSubject(subject);
    var textPart = new MimeBodyPart();
    textPart.setContent(body, "text/plain");
    var attachFilePart = new MimeBodyPart();
    attachFilePart.attachFile(temp);
    var mp = new MimeMultipart();
    mp.addBodyPart(textPart);
    mp.addBodyPart(attachFilePart);
    msg.setContent(mp);
    Transport.send(msg);
    temp["delete"]();
}

# fu: File Utils

Die Funktionen aus dem Bereich File Utils unterstützen den ELOas Benutzer bei Dateioperationen.

# fu: Verfügbare Funktionen

Dateiname bereinigen: Wenn ein Dateiname aus der Kurzbezeichnung erzeugt werden soll, dann kann diese kritischen Zeichen enthalten, die im Filesystem zu Problemen führen können (z. B. Doppelpunkt, Backslash \, &). Die Funktion clearSpecialChars() ersetzt deshalb alle Zeichen außer Ziffern und Buchstaben durch einen Unterstrich (auch Umlaute und ß).

clearSpecialChars: function(fileName) {
    var newFileName = fileName.replaceAll("\\W", "_");
    return newFileName;
},

Dokumentendatei laden: Diese Funktion getTempFile() lädt die Dokumentendatei des angegebenen ELO Objekts in das lokale Filesystem (in den Temp-Ordner des ELOas). Wenn die Datei nicht mehr benötigt wird, muss sie durch den Skriptentwickler über die Funktion deleteFile wieder entfernt werden. Andernfalls bleibt sie auf der Festplatte zurück.

Beachten Sie

Es wird nicht ein Dateiname, sondern ein Java-File-Objekt zurückgegeben.

getTempFile: function(sordId) {
    var editInfo = ixConnect.ix().checkoutDoc(sordId, null,
                                              EditInfoC.mbSordDoc, LockC.NO);
    var url = editInfo.document.docs[0].url;
    var ext = "." + editInfo.document.docs[0].ext;
    var name = fu.clearSpecialChars(editInfo.sord.name);
    var temp = File.createTempFile(name, ext);
    log.debug("Temp file: " + temp.getAbsolutePath());
    ixConnect.download(url, temp);
    return temp;
},

Datei löschen: Die Funktion deleteFile() erwartet als Parameter ein Java-File-Objekt (kein String) und löscht diese Datei.

deleteFile: function(delFile) {
    delFile["delete"]();
}

# run: Runtime Utilities

Dieses Modul enthält Routinen zum Zugriff auf die Java Runtime. Hierüber können externe Prozesse gestartet werden oder der aktuelle Speicherzustand abgefragt werden.

Prozess starten:: Der Befehl execute(command) dient zum Starten eines externen Prozesses. Der ELOas warten dann auf den Abschluss dieses Aufrufs und fährt erst dann mit der Bearbeitung fort. Somit können also auch Aktionen dieses Prozesses ausgewertet werden.

log.debug("Process: " + NAME );
run.execute("C:\\ Tools\\BAT\\dirlist.bat");
log.debug("Read Result");
var txt = dex.asString("dirlist.txt");

Freien und verfügbaren Speicher abfragen: Die Befehle freeMemory() und maxMemory() dienen zur Anzeige des aktuell verfügbaren freien Speichers und des maximal verfügbaren Speichers.

log.debug "freeMemory: " + run.freeMemory() +
        ", maxMemory: " + run.maxMemory());
Zuletzt aktualisiert: 31. Juli 2023 um 08:32