{"id":618,"date":"2012-04-08T22:56:01","date_gmt":"2012-04-08T20:56:01","guid":{"rendered":"http:\/\/hasselba.ch\/blog\/?p=618"},"modified":"2012-04-10T12:09:01","modified_gmt":"2012-04-10T10:09:01","slug":"lotusscript-in-xpages-2-lotusscript-wrapper","status":"publish","type":"post","link":"https:\/\/hasselba.ch\/blog\/?p=618","title":{"rendered":"LotusScript in XPages (2): LotusScript-Wrapper"},"content":{"rendered":"<h2>LotusScript in XPages<\/h2>\n<address>Dies ist der zweite Teil des Artikels &#8222;LotusScript in XPages&#8220;. Der erste Teil befindet sich <a title=\"LotusScript in XPages (1): Basics\" href=\"https:\/\/hasselba.ch\/blog\/?p=611\">hier<\/a>.<\/address>\n<p>&nbsp;<\/p>\n<h2>Der LotusScript-Wrapper<\/h2>\n<p>Um dynamischen LotusScript-Code auszuf\u00fchren, bietet sich die <em>Execute()<\/em>-Funktion an: Mit der Funktion l\u00e4sst sich fast der gesamte Umfang der LotusScript-eigenen Backendfunktionalit\u00e4t nutzen, also auch Scriptlibraries einbinden uvm.<\/p>\n<p>Leider steht diese Methode jedoch nicht\u00a0 in Java direkt zur Verf\u00fcgung (im Gegensatz zur <em>Session.evaluate()<\/em>-Methode f\u00fcr @Formelsprache), so dass nur der Umweg bleibt, die Funktion durch Aufruf eines LotusScript-Agenten zu verwenden, und das Ergebnis an die XPage zur\u00fcck zu liefern. Dabei wird der auszuf\u00fchrende LotusScript-Code und das Ergebnis der Operation \u00fcber ein tempor\u00e4res NotesDokument via <em>DocumentContext<\/em> hin- und hergereicht.<\/p>\n<p>Hier die Klasse &#8222;LSExceutor&#8220;, die die n\u00f6tigen Hilfsfunktionen bereitstellt:<\/p>\n<pre>package ch.hasselba.xpages.jsf.el;\r\n\r\nimport javax.faces.context.FacesContext;\r\nimport java.util.Vector;\r\nimport lotus.domino.Agent;\r\nimport lotus.domino.Database;\r\nimport lotus.domino.Document;\r\n\r\npublic class LSExecutor {\r\n\u00a0\u00a0 \u00a0private final static String agentName\u00a0 = \"(LSExecutor)\";\r\n\u00a0\u00a0 \u00a0private final static String fieldLSResult = \"LSResult\";\r\n\u00a0\u00a0 \u00a0private final static String fieldLSCode = \"LSCode\";\r\n\r\n\u00a0\u00a0 \u00a0public static Vector execLotusScriptCode( final String lscode ){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0try{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0Database curDB =\u00a0 (Database) getVariableValue(\"database\");\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0Document doc = curDB.createDocument();\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0String hlp = lscode.replace( \"\\n\", \"\\t\" );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0doc.appendItemValue( fieldLSCode, hlp );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0Agent agent = curDB.getAgent(\u00a0 agentName );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0agent.runWithDocumentContext( doc );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return doc.getItemValue( fieldLSResult );\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}catch(Exception e){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0e.printStackTrace();\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return null;\r\n\u00a0\u00a0 \u00a0}\r\n\r\n\u00a0\u00a0 \u00a0 public static Object getVariableValue(String varName) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 FacesContext context = FacesContext.getCurrentInstance();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return context.getApplication().getVariableResolver().\r\n          resolveVariable(context, varName);\r\n\u00a0\u00a0 \u00a0 }\r\n}<\/pre>\n<p>Die statische Methode<em> execLotusScriptCode()<\/em> wird in den Bindings verwendet, die in <a title=\"LotusScript in XPages (1): Basics\" href=\"https:\/\/hasselba.ch\/blog\/?p=611\">Teil 1<\/a> beschrieben wurden. Durch den Umstand, dass die <em>runWithDocumentContext()<\/em>-Methode auf das Ende der Agentenausf\u00fchrung wartet, ist eine sequentielle Verarbeitung gew\u00e4hrleistet.<\/p>\n<p>Der Agent ist ebenfalls recht einfach aufgebaut:<\/p>\n<pre>%REM\r\n\u00a0\u00a0 \u00a0Agent LSExecutor\r\n\u00a0\u00a0 \u00a0Created Apr 6, 2012 by Sven Hasselbach\/Sven Hasselbach\r\n\u00a0\u00a0 \u00a0Description: LSExecutor agent is a mapper for executing\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LotusScript code from XPages\r\n%END REM\r\nOption Public\r\nOption Declare\r\n\r\nConst fieldLSCode = \"LSCode\"\r\nConst fieldLSResult = \"LSResult\"\r\n\r\nDim returnValue\r\nSub Initialize\r\n\u00a0\u00a0 \u00a0Dim session As New NotesSession\r\n\u00a0\u00a0 \u00a0Dim doc As NotesDocument\r\n\u00a0\u00a0 \u00a0Dim lsCode, tmp , ret\r\n\r\n\u00a0\u00a0 \u00a0Set doc = session.Documentcontext\r\n\u00a0\u00a0 \u00a0lsCode = doc.Getitemvalue( fieldLSCode )\r\n\u00a0\u00a0 \u00a0tmp = Evaluate( | @ReplaceSubstring( \"| &amp; _\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0lsCode(0) &amp; |\"; @Char(9) ; @Char(10) ) | )\r\n\r\n\u00a0\u00a0 \u00a0ret = Execute( tmp(0) )\r\n\u00a0\u00a0 \u00a0doc.Replaceitemvalue fieldLSResult , returnValue\r\n\r\nEnd Sub<\/pre>\n<p>Um auf das Ergebnis der Berechnung zur\u00fcckgreifen zu k\u00f6nnen, muss eine globale Variable verwendet werden, da die <em>Execute()<\/em>-Funktion selbst keine R\u00fcckgabem\u00f6glichkeit bietet (siehe Domino Designer Hilfe). In diesem Fall ist es &#8222;returnValue&#8220;, dessen Wert in das via <em>DocumentContext<\/em> \u00fcbergebene Dokument geschrieben wird. Entsprechend muss der LotusScript-Code angepasst sein, siehe dazu auch die Beispiele am Anfang des <a title=\"LotusScript in XPages (1): Basics\" href=\"https:\/\/hasselba.ch\/blog\/?p=611\">1. Teils des Artikels<\/a>. Hier zeigt sich eine Schwachstelle: Es k\u00f6nnen keine Objekte zwischen Java und LotusScript \u00fcbergeben werden; ein Zugriff auf z.B. den FacesContext ist in LotusScript nicht m\u00f6glich. Soll eine DocumentCollection zur\u00fcck geliefert werden, muss dieses als Array von DocumentUniversalIds geschehen usw.<\/p>\n<p>Der Agent muss im Namen des Benutzers laufen, daher muss der &#8222;Run as Web user&#8220;-Haken gesetzt sein:<\/p>\n<p><img decoding=\"async\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHIAAAAaCAIAAADkGJ8dAAABKUlEQVRoge2WWw6CMBBFuzSX5vL45MP91A8SUudxpy1cDDonxhA6Lw5QLTUhUL49wG+SWimkVgqplUJqpZBaKaRWCkjrs4PLBr0XgdYH5LUulw16L2KtIOB2Wku5aNOb1LrNZ2otDaeMCGhbeMdePJUZrbsyT6t5zODeWsXEE1r1SfxQ6yUzONQqskDToXRxIcb8+tROq1W42AIOajVTzGqdASJ4qCkO9gLc18Ibtyqt+j73762jWkURdAFQq67jNQ2t4WpyKm+hfu6t2lSNntZprSDRvAHmty57sCmuJpe8hap+snQV0ibQuRTGn9sUV5MjeQt19n+rN27\/+2gGh\/uA171NFGVHm+pq5jw11PpaF\/wB6f8M0ppMk1oppFYKqZVCaqWQWim8AWce19xW3\/8kAAAAAElFTkSuQmCC\" alt=\"\" \/><\/p>\n<p>Im <a title=\"LotusScript in XPages (3): Quick-n-Dirty-Aktivierung\" href=\"https:\/\/hasselba.ch\/blog\/?p=642\">dritten Teil<\/a> wird eine Quick-n-Dirty-Variante gezeigt, die <em>BindingFactory<\/em> bekannt zu machen.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Anmerkung:<\/strong><\/p>\n<p>An dieser Stelle sei nocheinmal ausdr\u00fccklich darauf hingewiesen, das der hier gezeigte Code sich maximal im &#8222;Alpha&#8220;-Status befindet.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>LotusScript in XPages Dies ist der zweite Teil des Artikels &#8222;LotusScript in XPages&#8220;. Der erste Teil befindet sich hier. &nbsp; Der LotusScript-Wrapper Um dynamischen LotusScript-Code auszuf\u00fchren, bietet sich die Execute()-Funktion an: Mit der Funktion l\u00e4sst sich fast der gesamte Umfang &hellip; <a href=\"https:\/\/hasselba.ch\/blog\/?p=618\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,1,38,89,26,20,74,24],"tags":[33,79,7,30,88,39,31,86,80,3,85],"class_list":["post-618","post","type-post","status-publish","format-standard","hentry","category-agenten","category-allgemein","category-extensibility-api","category-java","category-jsf","category-lotus-script","category-xpages","category-xsp","tag-8-5-3","tag-agenten","tag-domino","tag-el","tag-expression-language","tag-extenisbility-api","tag-java","tag-jsf","tag-lotus-script","tag-xpages","tag-xsp"],"_links":{"self":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/618","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=618"}],"version-history":[{"count":9,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/618\/revisions"}],"predecessor-version":[{"id":638,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/618\/revisions\/638"}],"wp:attachment":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=618"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=618"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=618"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}