Congratulations!

[Valid RSS] This is a valid RSS feed.

Recommendations

This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.

Source: http://linqed.eu/?feed=rss2

  1. <?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
  2. xmlns:content="http://purl.org/rss/1.0/modules/content/"
  3. xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  4. xmlns:dc="http://purl.org/dc/elements/1.1/"
  5. xmlns:atom="http://www.w3.org/2005/Atom"
  6. xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  7. xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  8. >
  9.  
  10. <channel>
  11. <title>LinQed</title>
  12. <atom:link href="https://linqed.eu/feed/" rel="self" type="application/rss+xml" />
  13. <link>https://linqed.eu</link>
  14. <description>Mark Leusink on Domino, Angular, XPages, web dev, ...</description>
  15. <lastBuildDate>Thu, 06 Jul 2023 06:30:32 +0000</lastBuildDate>
  16. <language>en-US</language>
  17. <sy:updatePeriod>
  18. hourly </sy:updatePeriod>
  19. <sy:updateFrequency>
  20. 1 </sy:updateFrequency>
  21. <generator>https://wordpress.org/?v=6.4.4</generator>
  22. <item>
  23. <title>Setting up an environment to develop OSGi plugins for HCL Domino &#8211; 2022 edition</title>
  24. <link>https://linqed.eu/2022/11/24/setting-up-an-environment-to-develop-osgi-plugins-for-hcl-domino-2022-edition/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=setting-up-an-environment-to-develop-osgi-plugins-for-hcl-domino-2022-edition</link>
  25. <comments>https://linqed.eu/2022/11/24/setting-up-an-environment-to-develop-osgi-plugins-for-hcl-domino-2022-edition/#comments</comments>
  26. <dc:creator><![CDATA[mleusink]]></dc:creator>
  27. <pubDate>Thu, 24 Nov 2022 09:11:23 +0000</pubDate>
  28. <category><![CDATA[Niet gecategoriseerd]]></category>
  29. <category><![CDATA[Domino]]></category>
  30. <guid isPermaLink="false">https://linqed.eu/?p=1060</guid>
  31.  
  32. <description><![CDATA[While testing the v12 version of the org.openntf.domino library I found a bug that stopped me from deploying it to v12.0.x Domino servers. I found out what the cause for the issue was, so I decided to take a shot at fixing it myself. There was just one problem: I didn&#8217;t have a development setup [&#8230;]]]></description>
  33. <content:encoded><![CDATA[
  34. <p>While testing the v12 version of the <strong>org.openntf.domino</strong> library I found a <a rel="noreferrer noopener" href="https://github.com/OpenNTF/org.openntf.domino/issues/182" data-type="URL" data-id="https://github.com/OpenNTF/org.openntf.domino/issues/182" target="_blank">bug</a> that stopped me from deploying it to v12.0.x Domino servers. I found out what the cause for the issue was, so I decided to take a shot at fixing it myself. There was just one problem: I didn&#8217;t have a development setup for OSGi plugins anymore. Online I could find most of the steps involved, but the guides could use an update here and there.</p>
  35.  
  36.  
  37.  
  38. <p>That&#8217;s what this post is about. It is mostly based on <a href="https://github.com/OpenNTF/XPagesExtensionLibrary/wiki/Development-Environment">https://github.com/OpenNTF/XPagesExtensionLibrary/wiki/Development-Environment</a></p>
  39.  
  40.  
  41.  
  42. <h2 class="has-medium-font-size wp-block-heading">The basics</h2>
  43.  
  44.  
  45.  
  46. <p>Let&#8217;s start with the basics: I&#8217;m using Windows 10, although this will most like work with Windows 11. I&#8217;ve installed Domino 12.0.1 and Notes 12.0.1 locally.</p>
  47.  
  48.  
  49.  
  50. <ul>
  51. <li>Install a Java SDK. I&#8217;ve used an OpenJDK version for Java 8 downloaded from <a href="https://adoptium.net/temurin/releases/?version=8">https://adoptium.net/temurin/releases/?version=8</a></li>
  52.  
  53.  
  54.  
  55. <li>Install Git. Use the command line or any Git client you prefer: SourceTree, GitKraken, Tower</li>
  56.  
  57.  
  58.  
  59. <li>Install Maven. I installed the 3.8.6 version from <a href="https://maven.apache.org/download.cgi">https://maven.apache.org/download.cgi</a></li>
  60.  
  61.  
  62.  
  63. <li>You&#8217;ll need to generate a Domino Update site that needs to be added to your Target Platform (I&#8217;ll convert that later). Clone it from <a href="https://github.com/OpenNTF/generate-domino-update-site">https://github.com/OpenNTF/generate-domino-update-site</a>. I&#8217;ve used the 4.2.1 version. </li>
  64. </ul>
  65.  
  66.  
  67.  
  68. <p>Add the OpenNTF Maven server to your Maven settings.xml file. Edit or create if in in C:\users\&lt;your name\.m2 with these contents:</p>
  69.  
  70.  
  71.  
  72. <pre class="wp-block-code"><code>&lt;?xml version="1.0"?&gt;
  73. &lt;settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  74.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  75.    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"&gt;
  76.    &lt;profiles&gt;
  77.        &lt;profile&gt;
  78.            &lt;id&gt;openntf&lt;/id&gt;
  79.            
  80.            &lt;pluginRepositories&gt;
  81.                &lt;pluginRepository&gt;
  82.                    &lt;id&gt;artifactory.openntf.org&lt;/id&gt;
  83.                    &lt;name&gt;artifactory.openntf.org&lt;/name&gt;
  84.                    &lt;url&gt;https://artifactory.openntf.org/openntf&lt;/url&gt;
  85.                &lt;/pluginRepository&gt;
  86.            &lt;/pluginRepositories&gt;
  87.        &lt;/profile&gt;
  88.    &lt;/profiles&gt;
  89.    &lt;activeProfiles&gt;
  90.        &lt;activeProfile&gt;openntf&lt;/activeProfile&gt;
  91.    &lt;/activeProfiles&gt;
  92. &lt;/settings&gt;</code></pre>
  93.  
  94.  
  95.  
  96. <p>Open a terminal and go to the update site repo folder. It should have a file named pom.xml. Run the following command:</p>
  97.  
  98.  
  99.  
  100. <pre class="wp-block-code"><code>mvn install</code></pre>
  101.  
  102.  
  103.  
  104. <p>This will install the dependencies.</p>
  105.  
  106.  
  107.  
  108. <p>Next run this command (from the same folder) to create a so called p2 repository:</p>
  109.  
  110.  
  111.  
  112. <pre class="wp-block-code"><code>mvn org.openntf.p2:generate-domino-update-site:generateUpdateSite -Dsrc="C:\IBM\Domino" -Ddest="C:\UpdateSite"</code></pre>
  113.  
  114.  
  115.  
  116. <p>Notice the 2 parameters:</p>
  117.  
  118.  
  119.  
  120. <p>-Dsrc = location of your local Domino install (mine is in c:\IBM\domino)</p>
  121.  
  122.  
  123.  
  124. <p>-Ddest = folder where the update site will be generated. Remember this: you&#8217;ll need it later.</p>
  125.  
  126.  
  127.  
  128. <p>If all goes well you&#8217;ll get a success message:</p>
  129.  
  130.  
  131.  
  132. <figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="639" height="517" src="https://linqed.eu/wp-content/uploads/2022/11/image-5.png" alt="" class="wp-image-1066" srcset="https://linqed.eu/wp-content/uploads/2022/11/image-5.png 639w, https://linqed.eu/wp-content/uploads/2022/11/image-5-300x243.png 300w" sizes="(max-width: 639px) 100vw, 639px" /></figure>
  133.  
  134.  
  135.  
  136. <h2 class="wp-block-heading">Eclipse configuration</h2>
  137.  
  138.  
  139.  
  140. <p>Install Eclipse IDE for RCP and RAP Developers from <a href="https://www.eclipse.org/downloads/packages/release/2022-09/r/eclipse-ide-rcp-and-rap-developers">https://www.eclipse.org/downloads/packages/release/2022-09/r/eclipse-ide-rcp-and-rap-developers</a>. I&#8217;ve used the 2022-09 64bit version.</p>
  141.  
  142.  
  143.  
  144. <p>We&#8217;ll need to install 2 additional pieces of software in Eclipse.<br>Start Eclipse and go to Help > Eclipe Marketplace. In the dialog search for &#8220;XPages&#8221;  and install the XPages SDK plugin.</p>
  145.  
  146.  
  147.  
  148. <figure class="wp-block-image size-full"><img decoding="async" width="635" height="741" src="https://linqed.eu/wp-content/uploads/2022/11/image.png" alt="" class="wp-image-1061" srcset="https://linqed.eu/wp-content/uploads/2022/11/image.png 635w, https://linqed.eu/wp-content/uploads/2022/11/image-257x300.png 257w" sizes="(max-width: 635px) 100vw, 635px" /></figure>
  149.  
  150.  
  151.  
  152. <p>We&#8217;ll also need an updated Tycho version as well: in Eclipse go to Help > Install new software. In the &#8216;work with&#8217; field enter the URL of the Github repo that contains the updated version: <a href="https://github.com/tesla/m2eclipse-tycho/releases/download/latest/">https://github.com/tesla/m2eclipse-tycho/releases/download/latest/</a>. Expand the category and select the &#8220;Tycho Project Configurators&#8221; feature. Accept the license, install it and restart Eclipse.</p>
  153.  
  154.  
  155.  
  156. <figure class="wp-block-image size-full"><img decoding="async" width="950" height="706" src="https://linqed.eu/wp-content/uploads/2022/11/image-1.png" alt="" class="wp-image-1062" srcset="https://linqed.eu/wp-content/uploads/2022/11/image-1.png 950w, https://linqed.eu/wp-content/uploads/2022/11/image-1-300x223.png 300w, https://linqed.eu/wp-content/uploads/2022/11/image-1-768x571.png 768w" sizes="(max-width: 950px) 100vw, 950px" /></figure>
  157.  
  158.  
  159.  
  160. <p>Go to the Eclipse preferences.</p>
  161.  
  162.  
  163.  
  164. <p>On the XPages SDK tab, check the paths of your local Domino &amp; Notes install. Check &#8220;automatically create JRE for Domino&#8221;.</p>
  165.  
  166.  
  167.  
  168. <figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="652" height="601" src="https://linqed.eu/wp-content/uploads/2022/11/image-6.png" alt="" class="wp-image-1067" srcset="https://linqed.eu/wp-content/uploads/2022/11/image-6.png 652w, https://linqed.eu/wp-content/uploads/2022/11/image-6-300x277.png 300w" sizes="(max-width: 652px) 100vw, 652px" /></figure>
  169.  
  170.  
  171.  
  172. <p>On the Java &gt; Installed JRE screen, check if the new Domino JRE is selected. Eclipse will use this to compile code.</p>
  173.  
  174.  
  175.  
  176. <figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="697" height="600" src="https://linqed.eu/wp-content/uploads/2022/11/image-2.png" alt="" class="wp-image-1063" srcset="https://linqed.eu/wp-content/uploads/2022/11/image-2.png 697w, https://linqed.eu/wp-content/uploads/2022/11/image-2-300x258.png 300w" sizes="(max-width: 697px) 100vw, 697px" /></figure>
  177.  
  178.  
  179.  
  180. <p>On the Plugin Development &gt; Target Platform screen, there should be an entry that is checked and set to &#8216;Active&#8217;. The name doesn&#8217;t matter, but the locations do. If you select it you should see 3 locations in the bottom:</p>
  181.  
  182.  
  183.  
  184. <figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="695" height="643" src="https://linqed.eu/wp-content/uploads/2022/11/image-7.png" alt="" class="wp-image-1068" srcset="https://linqed.eu/wp-content/uploads/2022/11/image-7.png 695w, https://linqed.eu/wp-content/uploads/2022/11/image-7-300x278.png 300w" sizes="(max-width: 695px) 100vw, 695px" /></figure>
  185.  
  186.  
  187.  
  188. <p></p>
  189.  
  190.  
  191.  
  192. <p><strong>${eclipse_home}</strong> is added by Eclipse</p>
  193.  
  194.  
  195.  
  196. <p><strong>C:\java-dev\UpdateSite</strong> is the folder where I created my p2 repository (see above)</p>
  197.  
  198.  
  199.  
  200. <p><strong>C:\IBM\Notes\Data\workspace\applications\eclipse</strong> : folder in the local Notes install</p>
  201.  
  202.  
  203.  
  204. <p>If you click &#8216;Edit&#8217; you can add folders if any of the 3 above aren&#8217;t present. While you&#8217;re there, also make sure that on the Environment tab, the XPages Domino JRE is selected:</p>
  205.  
  206.  
  207.  
  208. <figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="718" height="656" src="https://linqed.eu/wp-content/uploads/2022/11/image-4.png" alt="" class="wp-image-1065" srcset="https://linqed.eu/wp-content/uploads/2022/11/image-4.png 718w, https://linqed.eu/wp-content/uploads/2022/11/image-4-300x274.png 300w" sizes="(max-width: 718px) 100vw, 718px" /></figure>
  209.  
  210.  
  211.  
  212. <p>This completes my setup.<br><br>Next I created a fork from the org.openntf.domino repo in my Github account from <a href="https://github.com/OpenNTF/org.openntf.domino.git">https://github.com/OpenNTF/org.openntf.domino.git</a>. I cloned the fork and switched to the latest commit for my Domino version (12.0.1). The project in Eclipse will show errors if the code is newer than your local Domino install (because that&#8217;s what the plugins in the p2 site is based on).</p>
  213.  
  214.  
  215.  
  216. <p>The projects in the cloned repo need to be imported into Eclipse. Click File > Import and choose Maven > Existing Maven Projects. Select the folder that contains the repo and import them into Eclipse.</p>
  217.  
  218.  
  219.  
  220. <p>Now you&#8217;re ready to debug the code. Click the Debug icon in Eclipse and select &#8220;Debug Configurations&#8221;. Select &#8220;OSGI Framework&#8221; in the left hand list and click &#8220;New run configuration&#8221; (new icon at the top). Give it a name (in the screenshot below it&#8217;s &#8216;oda&#8217;). The screen will look like this:</p>
  221.  
  222.  
  223.  
  224. <figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="636" src="https://linqed.eu/wp-content/uploads/2022/11/image-8-1024x636.png" alt="" class="wp-image-1069" srcset="https://linqed.eu/wp-content/uploads/2022/11/image-8-1024x636.png 1024w, https://linqed.eu/wp-content/uploads/2022/11/image-8-300x186.png 300w, https://linqed.eu/wp-content/uploads/2022/11/image-8-768x477.png 768w, https://linqed.eu/wp-content/uploads/2022/11/image-8.png 1166w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
  225.  
  226.  
  227.  
  228. <p>Make sure that:</p>
  229.  
  230.  
  231.  
  232. <ul>
  233. <li>Default auto-start (top right) is set to false</li>
  234.  
  235.  
  236.  
  237. <li>Framework is set to &#8220;Domino OSGi framework&#8221;</li>
  238.  
  239.  
  240.  
  241. <li>In the bundles section, all items in the target platform are NOT selected, only the plugins from the Workspace are selected.</li>
  242. </ul>
  243.  
  244.  
  245.  
  246. <p>If you now click Debug, the XPages SDK will create a file named <strong>pde.launch.ini</strong> for you in your local Domino folder (&lt;domino data>/domino/workspace). It will show you this dialog first:</p>
  247.  
  248.  
  249.  
  250. <figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="744" height="297" src="https://linqed.eu/wp-content/uploads/2022/11/image-3.png" alt="" class="wp-image-1064" srcset="https://linqed.eu/wp-content/uploads/2022/11/image-3.png 744w, https://linqed.eu/wp-content/uploads/2022/11/image-3-300x120.png 300w" sizes="(max-width: 744px) 100vw, 744px" /></figure>
  251.  
  252.  
  253.  
  254. <p></p>
  255.  
  256.  
  257.  
  258. <p>Click &#8216;Ok&#8217; to generate the file. Restart the HTTP task on Domino and the plugins will be loaded from the repo/ Eclipse instead of the update site database). You can work with the plugin. When you&#8217;re done,  simply delete the &#8216;pde.launch.ini&#8217; file and restart the HTTP task.</p>
  259.  
  260.  
  261.  
  262. <p>Oh and in case you&#8217;re wondering: the <a rel="noreferrer noopener" href="https://github.com/OpenNTF/org.openntf.domino/pull/183" data-type="URL" data-id="https://github.com/OpenNTF/org.openntf.domino/pull/183" target="_blank">pull request</a> for the issue is ready and merged in the project!</p>
  263. ]]></content:encoded>
  264. <wfw:commentRss>https://linqed.eu/2022/11/24/setting-up-an-environment-to-develop-osgi-plugins-for-hcl-domino-2022-edition/feed/</wfw:commentRss>
  265. <slash:comments>2</slash:comments>
  266. </item>
  267. <item>
  268. <title>Getting started with DQL</title>
  269. <link>https://linqed.eu/2020/03/22/getting-started-with-dql/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=getting-started-with-dql</link>
  270. <dc:creator><![CDATA[]]></dc:creator>
  271. <pubDate>Sun, 22 Mar 2020 19:47:51 +0000</pubDate>
  272. <category><![CDATA[Niet gecategoriseerd]]></category>
  273. <guid isPermaLink="false">http://linqed.eu/?p=1008</guid>
  274.  
  275. <description><![CDATA[Do you remember? A little over 2 weeks ago was Engage. How quickly everything can change&#8230; When you were at Engage you might have seen the session I did with Oliver Busse on DQL. The slides and demo code can be found here and here. We touched how to get started with DQL briefly, and [&#8230;]]]></description>
  276. <content:encoded><![CDATA[<p>Do you remember? A little over 2 weeks ago was Engage. How quickly everything can change&#8230;</p>
  277. <p>When you were at Engage you might have seen the session I did with Oliver Busse on DQL. The slides and demo code can be found <a href="https://www.slideshare.net/MarkLeusink/now-what-can-you-really-build-with-dql-and-web-components" target="_blank" rel="noopener noreferrer">here</a> and <a href="https://gitlab.com/obusse/engage2020_dql" target="_blank" rel="noopener noreferrer">here</a>. We touched how to get started with DQL briefly, and based on the questions we received I think it&#8217;s a good idea to write a couple of articles on the topic. This is the first.</p>
  278. <h2>Fakenews</h2>
  279. <p>Let me start by explaining what you need to start using DQL: that would be a <b>HCL/IBM Domino server</b>, <b>version 10 or higher</b>. That&#8217;s it. No more. No <a href="https://doc.cwpcollaboration.com/appdevpack/docs/en/homepage.html" target="_blank" rel="noopener noreferrer">AppDev pack</a>. No Node.js.</p>
  280. <p>Apparently this still confuses a lot of people. So what about that AppDev pack? Well you only need it if you want to talk to Domino from a Node.js server: the <b>domino-db</b> part is the part you need to install in your Node.js project. It also requires an extra component on the server called <b>Proton</b>. If you&#8217;re not interested in that yet and just want to write LotusScript/ Java, then you&#8217;re all set.</p>
  281. <p>By the way: since Domino 11 the documentation is part of the standard server help and not available on the AppDev pack site anymore.</p>
  282. <p>From a (vanilla) Domino v10+ server you can run your first DQL query with just a couple of lines of code in either LotusScript or Java: create an instance from the <b>DominoQuery </b>(NotesDominoQuery in LS) and query away!</p>
  283. <p>In LotusScript:</p>
  284. <pre class="brush: cpp; title: ; notranslate">Sub Initialize
  285.  
  286. Dim session As New NotesSession
  287. Dim db As NotesDatabase
  288. Dim dql As NotesDominoQuery
  289. Dim col As NotesDocumentCollection
  290. Dim doc As NotesDocument
  291.  
  292. Set db = session.Currentdatabase
  293. Set dql = db.Createdominoquery()
  294.  
  295. Set col = dql.Execute(&quot;your query goes here&quot;)
  296.  
  297. Set doc = col.Getfirstdocument()
  298.  
  299. Do While Not doc Is Nothing
  300.  
  301.  ' do whatever you want
  302.  
  303.  Set doc = col.Getnextdocument(doc)
  304. Loop
  305.  
  306. End Sub</pre>
  307. <p>Or Java:</p>
  308. <pre class="brush: java; title: ; notranslate">Session session = ExtLibUtil.getCurrentSession();
  309.  
  310. Database db = session.getCurrentDatabase();
  311. DominoQuery dql = db.createDominoQuery();
  312. DocumentCollection result = dql.execute(&quot;your query here&quot;);
  313.  
  314. Document doc = result.getFirstDocument();
  315.  
  316. while (null != doc) {
  317.  
  318.  //do what you want with the doc
  319.  
  320.  Document tmp = dc.getNextDocument(doc);
  321.  doc.recycle();
  322.  doc = tmp;
  323. }</pre>
  324. <p>Note that the result of executing a DQL query is an (unsorted) document collection. You can loop over it to get the information from the result set you need.</p>
  325. <h2>DQL Design Catalog</h2>
  326. <p>When you run the query above, the DQL engine will perform a scan of all the documents in your database. That&#8217;s because it doesn&#8217;t know yet what views it can use to optimise the query. For that it needs the so called <strong>Design Catalog</strong>. You can think of it as a summary of the elements in the design of your database that DQL might/ can use to optimise queries. Before version 11, this information was stored in a separate database (GQFdsgn.cat), but since version 11 it is stored in &#8216;hidden&#8217; design elements in the NSF.</p>
  327. <p>To create the design catalog you call <strong>load updall -e &lt;your-db&gt; </strong> or if you want to update it <strong>load updall -d &lt;your -db&gt;</strong>.</p>
  328. <p>The design catalog isn&#8217;t automatically updated when the design changes, so you should take care of that yourself. It&#8217;s good to know that the design catalog can also be updated programmatically by calling <strong>setRebuildDesignCatalog()</strong> or <strong>setRefreshDesignCatalog()</strong>. You can also list all current indexes by calling <strong>listIndexes()</strong>. These are all Java methods, but the names in LotusScript are similar. You call them from an instance of the <strong>DominoQuery</strong> class.</p>
  329. <p>If you don&#8217;t have a design catalog in your database, any query that needs it will throw an error (e.g. a view query):</p>
  330. <pre class="brush: plain; title: ; notranslate">Domino Query execution error: Entry not found in index - syntax error
  331. Error validating view column name - &#x5B;'contacts'.city] ..
  332. invalid view name or database needs to be cataloged via updall -e
  333. (Call hint: NSFDbGetNamedObjectID, Core call #0) ******************</pre>
  334. <h2>DQL Exploring</h2>
  335. <p>HCL / IBM gave you the <a href="https://github.com/icstechsales/dql-explorer">DQL Explorer</a> application to play with DQL. But I think it&#8217;s overcomplicated for an introduction: it was written in React, which a lot people aren&#8217;t familiar with. I think this just adds to the confusion. So I wrote a simpler one as an XPages application: just 1 XPage with an input field to enter a query and a search button that call a Java method. The result is shown in a repeat control. You can try download it <a href="https://github.com/markleusink/simple-dql-explorer" target="_blank" rel="noopener noreferrer">here</a> or try it out:</p>
  336. <p><a href="https://demo.linqed.eu/dql/explorer.nsf/explore.xsp" target="_blank" rel="noopener noreferrer">Simple DQL Explorer</a></p>
  337. <p>From the XPage you can click one of the sample queries and try them out. Check the &#8216;Explain&#8217; checkbox to get more details on how Domino executed the query (this is also a standard feature of the DQL engine: call the <strong>explain() </strong>method on your DominoQuery instance).</p>
  338. <p>FYI: The demo app runs on a very basic VPS with 2 GB RAM that runs Domino 11 (so please be gentle). It queries a database with 100,000 fakenames, created using https://www.fakenamegenerator.com/. The fakenames database can also be downloaded from the link at the top of this post.</p>
  339. <p>Enough for now, in the next articles I want to cover more search syntax, and approaches how to use search results in your app (e.g. REST) and sorting and paging of results.</p>
  340. ]]></content:encoded>
  341. </item>
  342. <item>
  343. <title>XPages partial refresh issue in Domino 10.0.1</title>
  344. <link>https://linqed.eu/2019/02/07/xpages-partial-refresh-issue-in-domino-10-0-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=xpages-partial-refresh-issue-in-domino-10-0-1</link>
  345. <dc:creator><![CDATA[]]></dc:creator>
  346. <pubDate>Thu, 07 Feb 2019 14:10:49 +0000</pubDate>
  347. <guid isPermaLink="false">http://linqed.eu/?p=925</guid>
  348.  
  349. <description><![CDATA[A couple of days ago I tweeted about an XPages partial refresh issue I ran into in Domino 10.0.1. I got it on a freshly installed Domino 10.0.1 server with our main XPages app on it. Within a couple of clicks it started throwing errors, so I was kind of disappointed. Did some more investigation [&#8230;]]]></description>
  350. <content:encoded><![CDATA[<p>A couple of days ago I <a href="https://twitter.com/markleusink/status/1087986000763281408">tweeted</a> about an XPages partial refresh issue I ran into in Domino 10.0.1. I got it on a freshly installed Domino 10.0.1 server with our main XPages app on it. Within a couple of clicks it started throwing errors, so I was kind of disappointed.</p>
  351. <p>Did some more investigation and was able to reproduce the issue in an <a href="https://gist.github.com/markleusink/096048c08722a2cad339be5956294ab4">isolated sample</a> .</p>
  352. <p>IBM/ HCL support read my tweet and got in touch (+1 for that!). Created a case for this issue and I must honestly say that they handled very well.</p>
  353. <p>Turns out that the error handling for partial refreshes has changed in v10. I didn&#8217;t know that and you probably did neither. It&#8217;s more strict in v10 and will throw an error in some specific scenarios (like my example that worked perfectly in 9.0.1).</p>
  354. <p>The solution/ workaround is to revert to the way errors are handled (or are actually NOT handled <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> )  in 9.0.1 by adding this to your XSP properties in the NSF:</p>
  355. <p><strong>xsp.error.disable.detection.set01=true</strong></p>
  356. <p><strong>UPDATE</strong></p>
  357. <p>IBM/ HCL published a technote describing the changes partial refresh behaviour in v10. You can read it <a href="https://www-01.ibm.com/support/docview.wss?uid=ibm10871610" target="_blank" rel="noopener noreferrer">here</a>.</p>
  358. ]]></content:encoded>
  359. </item>
  360. <item>
  361. <title>Query Domino data with Domino JNA (part 3): REST API and infinite scroll</title>
  362. <link>https://linqed.eu/2018/11/02/query-domino-data-with-domino-jna-part-3-rest-api-and-infinite-scroll/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=query-domino-data-with-domino-jna-part-3-rest-api-and-infinite-scroll</link>
  363. <comments>https://linqed.eu/2018/11/02/query-domino-data-with-domino-jna-part-3-rest-api-and-infinite-scroll/#comments</comments>
  364. <dc:creator><![CDATA[]]></dc:creator>
  365. <pubDate>Fri, 02 Nov 2018 11:23:08 +0000</pubDate>
  366. <guid isPermaLink="false">http://linqed.eu/?p=896</guid>
  367.  
  368. <description><![CDATA[With the demos from part 1 and part 2 we now have a list running in XPages that has sorting, paging and filtering. But what if you want to use Domino JNA in a REST API? To serve a JavaScript/ Angular/ React/ Vue application or, why not, an app running in Office 365? The good [&#8230;]]]></description>
  369. <content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="alignright wp-image-913" src="http://linqed.eu/wp-content/uploads/2018/11/Screenshot-2018-11-02-at-12.20.36.png" alt="" width="299" height="214" srcset="https://linqed.eu/wp-content/uploads/2018/11/Screenshot-2018-11-02-at-12.20.36.png 428w, https://linqed.eu/wp-content/uploads/2018/11/Screenshot-2018-11-02-at-12.20.36-300x214.png 300w" sizes="(max-width: 299px) 100vw, 299px" />With the demos from <a href="http://linqed.eu/2018/10/02/query-domino-data-and-faceted-search-with-domino-jna-part-1/" target="_blank" rel="noopener noreferrer">part 1</a> and <a href="http://linqed.eu/2018/10/08/query-domino-data-and-faceted-search-with-domino-jna-part-2/" target="_blank" rel="noopener noreferrer">part 2</a> we now have a list running in XPages that has sorting, paging and filtering. But what if you want to use Domino JNA in a REST API? To serve a JavaScript/ Angular/ React/ Vue application or, why not, an app running in Office 365?</p>
  370. <p>The good news is that we already have most of the code for that. So we can take the code from demo 6, do a little refactoring, write a class for the REST API, and we&#8217;re done! In this post I&#8217;ll show you how to create the JNA-powered REST API and use it in a JavaScript grid component (for Domino people: a &#8216;view&#8217;) called AG Grid. Want to see the <a href="https://demo.linqed.eu/demos/jna-grid/index.html" target="_blank" rel="noopener noreferrer">demo</a> first?</p>
  371. <h3>REST API in Domino</h3>
  372. <p>The main reason why we need to refactor the controller class from demo 6. is that REST APIs are stateless, so we need to get rid of all Java class variables. We end up with one (public static) <strong>getEntries()</strong> method and add parameters to set the start index, number of entries to return, sort order and filter.</p>
  373. <p>Creating a REST API in Domino can be done in multiple ways:</p>
  374. <ul>
  375. <li>Using an <a href="http://www.wissel.net/blog/d6plinks/shwl-7mgfbn" target="_blank" rel="noopener noreferrer">XAgent</a> (don&#8217;t want to go that way anymore)</li>
  376. <li><a href="https://stephankopp.net/notes-with-vaadin-tutorial/part-4-our-first-rest-api/" target="_blank" rel="noopener noreferrer">XPages ExtLib REST control</a> (relatively simple)</li>
  377. <li>running a servlet <a href="https://edm00se.io/servlet-series/" target="_blank" rel="noopener noreferrer">in the NSF</a> (little harder)</li>
  378. <li>running a <a href="https://tobysamples.wordpress.com/2015/06/23/jax-rs-or-the-way-to-do-rest-in-domino-part-2/" target="_blank" rel="noopener noreferrer">servlet in an OSGi plugin</a> (harder)</li>
  379. </ul>
  380. <p>For the purpose of this demo, and to keep things simple, I&#8217;ve used the ExtLib REST control. In short: you  create an XPage (e.g. api.xsp), add the ExtLib control, set the <strong>path</strong> (the part in the URL after the XPage name, e.g. &#8216;contacts&#8217;), configure it as a<strong> custom REST service</strong> and point it to a Java class (<strong>eu.linqed.api.ContactsService</strong>). In that class you extend <strong>com.ibm.xsp.extlib.component.rest.CustomServiceBean</strong> and implement the <strong>doService()</strong> method to handle the request. See the demo database for an <a href="https://github.com/markleusink/domino-jna-demos/blob/master/nsf/XPages/api.xsp" target="_blank" rel="noopener noreferrer">example</a>. With that in place, we now have a working REST API serving the contacts data. The data can be sorted, paged and filtered by combining URL parameters (start, count, sortCol, sortAsc and filter).</p>
  381. <h3>Using the REST API in an app</h3>
  382. <p>For this post I created a small JavaScript demo app that uses <a href="https://ag-grid.com" target="_blank" rel="noopener noreferrer">ag-grid</a> to show the contacts. ag-grid is a very feature-rich, open source component to build grids (sorry if that sounded like marketing &#8211; I&#8217;m not affiliated in any way with them). It comes with built-in support for sorting, filtering and <a href="https://www.ag-grid.com/javascript-grid-infinite-scrolling/#example-infinite-scroll" target="_blank" rel="noopener noreferrer">infinite scrolling</a> using a virtual row model. Plus it has versions for all the major <a href="https://www.ag-grid.com/javascript-grid-getting-started/" target="_blank" rel="noopener noreferrer">JavaScript frameworks</a>. Since I&#8217;m the most comfortable writing <a href="https://angular.io/" target="_blank" rel="noopener noreferrer">Angular</a> I used that one.</p>
  383. <p>After following the <a href="https://www.ag-grid.com/angular-getting-started/" target="_blank" rel="noopener noreferrer">getting started</a> tutorial I ended up with a working grid, linked to their sample data. We&#8217;re now ready to change that and link it to the Domino JNA-driven REST API we just created. The documentation describes what events we can use.</p>
  384. <p><img loading="lazy" decoding="async" class="alignright wp-image-918" src="http://linqed.eu/wp-content/uploads/2018/11/Screenshot-2018-11-02-at-12.25.17.png" alt="" width="201" height="273" srcset="https://linqed.eu/wp-content/uploads/2018/11/Screenshot-2018-11-02-at-12.25.17.png 264w, https://linqed.eu/wp-content/uploads/2018/11/Screenshot-2018-11-02-at-12.25.17-221x300.png 221w" sizes="(max-width: 201px) 100vw, 201px" />Most changes need to be made in the <a href="https://github.com/markleusink/domino-jna-powered-grid/blob/master/src/app/app.component.ts" target="_blank" rel="noopener noreferrer">app.component.ts</a> file: the component definition and configuration for the grid. We&#8217;ll first change the <strong>endpoint</strong> and immediately run into an error: the Angular app is running on a different server, so the browser shows a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target="_blank" rel="noopener noreferrer">CORS</a> security warning. You can fix that by (1) adding an <strong>Access-Control-Allow-Origin</strong> header to your servers&#8217; response or (2) simply run the Angular on your Domino server. When you&#8217;re running Domino behind a proxy you can add it to the proxy configuration. Or you (normally) would create rule for your website document in names.nsf. Unfortunately those rules don&#8217;t seem to be added when you&#8217;re using an ExtLib REST Control, so you either need to use a proxy (=recommended) or add the header to the ContactsService class.</p>
  385. <p>We then have the change the column definition to display properties from the contacts received from the REST API in the &#8216;columnDefs&#8217; property of AG Grid (lines 25-30).</p>
  386. <p>Infinite scrolling on the grid is enabled by setting the &#8216;infinite&#8217; row model, according to <a href="https://www.ag-grid.com/javascript-grid-infinite-scrolling/" target="_blank" rel="noopener noreferrer">this</a> guide. The datasource can be found in rows 102-156. The basic idea is that when the user (almost) scrolled to the end of the list, it sends a request to the REST API to load more data. With that request it includes the current &#8216;state&#8217; of the grid (sort column, filtering). You can see the request being made on line 135. Note that I&#8217;m connecting to the endpoint configured in the &#8216;environments&#8217; configuration file.</p>
  387. <p>Last thing is to handle a user entering something in the search field or sorting the grid. We change the &#8216;state&#8217; object of the grid in the appropriate events (onGridSortChanged, onGridFilterChanged) and the grid takes care of the rest!</p>
  388. <p>Have fun with the <a href="https://demo.linqed.eu/demos/jna-grid/index.html" target="_blank" rel="noopener noreferrer">demo</a> and don&#8217;t forget the explore the source code of the <a href="https://github.com/markleusink/domino-jna-demos" target="_blank" rel="noopener noreferrer">demo database</a> and <a href="https://github.com/markleusink/domino-jna-powered-grid" target="_blank" rel="noopener noreferrer">Angular demo app</a>.</p>
  389. <p>&nbsp;</p>
  390. ]]></content:encoded>
  391. <wfw:commentRss>https://linqed.eu/2018/11/02/query-domino-data-with-domino-jna-part-3-rest-api-and-infinite-scroll/feed/</wfw:commentRss>
  392. <slash:comments>1</slash:comments>
  393. </item>
  394. <item>
  395. <title>Query Domino data and faceted search with Domino JNA (part 2): filtering</title>
  396. <link>https://linqed.eu/2018/10/08/query-domino-data-and-faceted-search-with-domino-jna-part-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=query-domino-data-and-faceted-search-with-domino-jna-part-2</link>
  397. <comments>https://linqed.eu/2018/10/08/query-domino-data-and-faceted-search-with-domino-jna-part-2/#comments</comments>
  398. <dc:creator><![CDATA[]]></dc:creator>
  399. <pubDate>Mon, 08 Oct 2018 08:52:59 +0000</pubDate>
  400. <guid isPermaLink="false">http://linqed.eu/?p=848</guid>
  401.  
  402. <description><![CDATA[In the first post in this serie I covered the basics on how to create a list of Domino view data with pagination and sorting using the Domino JNA project. We can now get into the more interesting stuff: filtering the dataset. Background on filtering with Domino JNA Before diving into the code, it might be [&#8230;]]]></description>
  403. <content:encoded><![CDATA[<p>In the <a href="http://linqed.eu/2018/10/02/query-domino-data-and-faceted-search-with-domino-jna-part-1/">first post</a> in this serie I covered the basics on how to create a list of Domino view data with pagination and sorting using the <a href="https://github.com/klehmann/domino-jna" target="_blank" rel="noopener noreferrer">Domino JNA</a> project. We can now get into the more interesting stuff: filtering the dataset.</p>
  404. <h3>Background on filtering with Domino JNA</h3>
  405. <p>Before diving into the code, it might be good te offer some background. Like I mentioned in the first post, Domino JNA surfaces some low level Domino (C) APIs. With those APIs it is possible to apply a selection/ filter on a view. Think of it as opening a view in the Notes client, and selecting a number of documents according to some selection criteria. The nice part about this is that it is really fast and is able to keep the sort order of the view, as well as doing pagination.</p>
  406. <p>A selection is applied to a view by giving it a list of Note IDs:</p>
  407. <pre class="brush: plain; title: ; notranslate">Set&lt;Integer&gt; selectionList = new HashSet&lt;Integer&gt;();
  408. collection.select(selectionList, true);</pre>
  409. <p>How you retrieve the list of Note IDs of documents that you want to select/ filter, is up to you: if a user wants to search for a specific last name, you can perform a view lookup to get a list of all the entries that match that name. But you can also get results from another view. Or, if you linked documents together using some ID, from related documents (e.g. performing JOIN-like queries).</p>
  410. <h3>Optimised lookups</h3>
  411. <p>To perform fast view lookups, JNA offers an optimised lookup function that performs better than the standard methods. Instead of using:</p>
  412. <pre class="brush: plain; title: ; notranslate">view.getColumnValues(colIndex);</pre>
  413. <p>You use:</p>
  414. <pre class="brush: plain; title: ; notranslate">collection.getColumnValues(colName, locale);</pre>
  415. <p>I used this optimised lookup function on the contacts list in the demo database to get a unique list of all cities and found the Domino JNA method to be about 7 times faster!</p>
  416. <h3>Note IDs as Integers, not Strings</h3>
  417. <p>When working with Domino JNA you&#8217;ll notice that it uses Integers to represent Note IDs in a database. This is done for efficiency reasons. Converting a Note ID from a String to an Integer can be done with a single line of code:</p>
  418. <pre class="brush: plain; title: ; notranslate">Integer id = Integer.parseInt(noteId, 16);</pre>
  419. <h3>Filtering the contacts by cities</h3>
  420. <p>The demo application uses a list of 50,000 contacts. Every contact lives in a <strong>city</strong>, so let&#8217;s start with a filter on that. You could of course query the contacts by adding a <strong>Full Text</strong> index and using that, but I always run into issues. For example it isn&#8217;t really good at doing exact matches: if I only want people in city &#8220;X&#8221;, I don&#8217;t want them from &#8220;XY&#8221; (or &#8220;X Y&#8221;). Keeping the FT index up to date is also a challenge (BTW: looking forward to the changes in this area in Domino v10!).</p>
  421. <p>For the cities filter I added to the <a href="https://demo.linqed.eu/jna/jna-demo.nsf/demo3.xsp" target="_blank" rel="noopener noreferrer">third demo</a> I used a <a href="https://select2.org/" target="_blank" rel="noopener noreferrer">Select2</a> item picker and populated that with all the available cities by performing a fast view lookup in the view (see the code below, rows 9-27). On my local VM it takes about 900 ms (for about 8,000 unique cities in the 50,000 contacts). The resulting list is cached in the applicationScope. Note that for the demo I populate the Select2 picker with a subset of all the available cities: 8,000 entries would really slow it down in the UI. In a real application you would use a server side lookup.</p>
  422. <p>When the filter is applied, the list is reduced to those contacts that match the city/ cities: for every city selected in the filter, a lookup is performed to get the matching Note IDs (rows 95-99). Reading the entries that should be displayed on the current page is done in the <strong>loadEntries() </strong>function. It checks if there&#8217;s a filter applied (row 49), and if there is, it applies the list of matching Note IDs to the collection. It then iterates over the matching entries only (rows 54-56).</p>
  423. <p><script src="https://gist.github.com/markleusink/20b755287854a8ff2bd0611fab742434.js"></script></p>
  424. <h3>Adding more filters</h3>
  425. <p>Using this method, we can add more filters and combine the results. In <a href="https://demo.linqed.eu/jna/jna-demo.nsf/demo4.xsp" target="_blank" rel="noopener noreferrer">demo 4</a> and <a href="https://demo.linqed.eu/jna/jna-demo.nsf/demo5.xsp" target="_blank" rel="noopener noreferrer">demo 5</a> I added an extra filter on <strong>country</strong> (similar to the city filter) and on<strong> last name</strong>. Note that the demos do an &#8220;OR&#8221; lookup with all filters: if you select a city and country, the resulting list shows the results for the city as well as the country. The can easily be changed in the controller class by intersecting the lists of matching IDs.</p>
  426. <p>The <strong>last name</strong> filter is a bit different: instead of doing a view entries/ column lookup to get an exact match, I do a lookup on a column that contains all last names and Note IDs. That list is cached in the applicationScope and used to find (partial) matches. The design of the &#8216;contacts&#8217; view I used is available in the demo database.</p>
  427. <p>The last en best demo (<a href="https://demo.linqed.eu/jna/jna-demo.nsf/demo6.xsp" target="_blank" rel="noopener noreferrer">demo 6</a>) shows how you can make filtering the list more user friendly/ intuitive: it updates the results after each change of one of the filters.</p>
  428. <p>The source code for all demos is available on <a href="https://github.com/markleusink/domino-jna-demos" target="_blank" rel="noopener noreferrer">Github</a>.</p>
  429. <h3>Finally</h3>
  430. <p>With just a few days ahead until <a href="https://www.ibm.com/collaboration/ibm-domino" target="_blank" rel="noopener noreferrer">Domino V10</a> is released, one of the first things that comes to my mind is: how does this all stack up against the new <strong>Domino Query Language</strong>. I guess that has to be the topic of a follow up post&#8230;</p>
  431. ]]></content:encoded>
  432. <wfw:commentRss>https://linqed.eu/2018/10/08/query-domino-data-and-faceted-search-with-domino-jna-part-2/feed/</wfw:commentRss>
  433. <slash:comments>3</slash:comments>
  434. </item>
  435. <item>
  436. <title>Query Domino data and faceted search with Domino JNA (part 1): setup, sorting and pagination</title>
  437. <link>https://linqed.eu/2018/10/02/query-domino-data-and-faceted-search-with-domino-jna-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=query-domino-data-and-faceted-search-with-domino-jna-part-1</link>
  438. <comments>https://linqed.eu/2018/10/02/query-domino-data-and-faceted-search-with-domino-jna-part-1/#comments</comments>
  439. <dc:creator><![CDATA[]]></dc:creator>
  440. <pubDate>Tue, 02 Oct 2018 12:06:46 +0000</pubDate>
  441. <guid isPermaLink="false">http://linqed.eu/?p=832</guid>
  442.  
  443. <description><![CDATA[Every web application I build includes lists (or as Domino people like to call them: views) in one form of another. And then users start asking question like &#8220;But can it do sorting?&#8221; &#8220;How about a search function (on just these fields?)&#8221; &#8220;And filtering?&#8221;. With &#60;insert-you-favorite-framework-here&#62; that&#8217;s not too hard on short lists. I&#8217;m an [&#8230;]]]></description>
  444. <content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="alignright wp-image-856 size-thumbnail" src="http://linqed.eu/wp-content/uploads/2018/10/Screenshot-2018-10-02-at-13.09.48-150x150.png" alt="" width="150" height="150" srcset="https://linqed.eu/wp-content/uploads/2018/10/Screenshot-2018-10-02-at-13.09.48-150x150.png 150w, https://linqed.eu/wp-content/uploads/2018/10/Screenshot-2018-10-02-at-13.09.48-60x60.png 60w" sizes="(max-width: 150px) 100vw, 150px" />Every web application I build includes lists (or as Domino people like to call them: views) in one form of another. And then users start asking question like &#8220;But can it do sorting?&#8221; &#8220;How about a search function (on just these fields?)&#8221; &#8220;And filtering?&#8221;. With &lt;insert-you-favorite-framework-here&gt; that&#8217;s not too hard on short lists. I&#8217;m an Angular guy and can easily give them sorting and filtering.</p>
  445. <p>But then the data grows. And you need to find a solution for paging. Or build an infinite scroll. So the fun starts: <strong>how do I get paged/ sorted/ filtered data from my Domino database?</strong> My favorite goto place for this always used to be the XPages REST controls. But they have limitations. Luckily I recently discovered an alternative: the <a href="https://github.com/klehmann/domino-jna" target="_blank" rel="noopener noreferrer"><strong>Domino JNA</strong></a> project by Karsten Lehmann.</p>
  446. <p>In short: it gives you an API you can use to access Domino data in ways you never did before. It does that by surfacing low-level Domino APIs that you normally don&#8217;t have access to. You&#8217;ll be amazed at all the gems hidden away in the product. One of the things I particularly like about the Domino JNA API is being able to work with Domino view data, perform JOIN-like queries  (yes, you read that right), and use the built-in sorting and pagination functions. That allowed me to build a faceted search. How I did that is the topic of this series of articles.</p>
  447. <p>Note: the demos for this post are created using XPages as the front end. Everything that I write here will also benefit you when you&#8217;re creating a REST API on Domino. I might even do a follow-up article describing that.</p>
  448. <p>In this first post I cover the basics: installing the plugin, setup a structure to read view data and create a first basic example of showing a sorted list of entries (from a view) using JNA.</p>
  449. <h3>Installation of JNA</h3>
  450. <p>Download the latest version of Domino JNA from the <a href="https://github.com/klehmann/domino-jna/releases" target="_blank" rel="noopener noreferrer">Github repo</a>. Domino JNA is delivered as an OSGi plugin and needs to be installed on both the server and client. Restart the server and client and you&#8217;re good to go.</p>
  451. <p>In the application properties of the database you want to use Domino JNA in, you need to enable it on the Page Generation tab:</p>
  452. <p><img loading="lazy" decoding="async" class="size-full wp-image-844 alignnone" src="http://linqed.eu/wp-content/uploads/2018/10/Screenshot-2018-10-02-at-09.16.59.png" alt="" width="387" height="232" srcset="https://linqed.eu/wp-content/uploads/2018/10/Screenshot-2018-10-02-at-09.16.59.png 387w, https://linqed.eu/wp-content/uploads/2018/10/Screenshot-2018-10-02-at-09.16.59-300x180.png 300w" sizes="(max-width: 387px) 100vw, 387px" /></p>
  453. <h3><strong>Fake data database with 50,000 contacts</strong></h3>
  454. <p>For testing I created a database with 50.000 contacts. The fake contacts were created by the <a href="https://www.fakenamegenerator.com">Fake Name Generator</a> and imported into an NSF that can be downloaded <a href="http://linqed.eu/wp-content/uploads/2018/08/fakenames2018.nsf_.zip">here</a>. The NSF just contains the data and a view.</p>
  455. <h3><strong>A basic list with pagination</strong></h3>
  456. <p>Lets start with the basics: accessing a view and show the entries in a list. The demo can be viewed <a href="https://demo.linqed.eu/jna/jna-demo.nsf/demo1.xsp" target="_blank" rel="noopener noreferrer">here</a> (source code on <a href="https://github.com/markleusink/domino-jna-demos" target="_blank" rel="noopener noreferrer">Github</a>) and consists of an XPage with a data table and a Java (controller) class to drive the backend. In the controller class you&#8217;ll find this:</p>
  457. <p>&nbsp;</p>
  458. <p><script src="https://gist.github.com/markleusink/0878a306f63a92ab486451bc749bf056.js"></script></p>
  459. <p>Let&#8217;s walk through the code.</p>
  460. <p>Opening a view (in JNA called a &#8216;collection&#8217;) is done similar as with the standard API: open the database and then the view/collection (<strong>lines 4 and 5</strong>).</p>
  461. <p>Once you have the collection, you start to read entries from it. That&#8217;s done a little different then what you&#8217;re used to. You start of by specifying how to &#8216;walk&#8217; the view entries. The simplest form is just move from one entry to the next using <strong>Navigate.NEXT</strong> (<strong>line 11</strong>). JNA also offers alternatives like moving to the next category or next &#8216;unread&#8217; entry. More on that in another post.</p>
  462. <p>Normally you retrieve a <strong>ViewEntry</strong> from a view (or view navigator) that includes all column data as well as metadata like the Note ID. You can&#8217;t control what data to read or ignore.  With JNA you can specify exactly what data to retrieve for every column. That allows you to code for performance: if you don&#8217;t need the column data, you just don&#8217;t read it. In the controller class in <strong>line 15</strong> you can see that I&#8217;m reading the Note ID and all column values (<strong>ReadMask.SUMMARYVALUES</strong>) for each entry.</p>
  463. <p>The API call on lines 21 to 24 is where the entries are actually read from the view. The <strong>skipEntries</strong> parameter allows me to start reading from a certain location in the view (useful for pagination or an infinite scrolling list) and with the <strong>NUM_PER_PAGE</strong> paramater I&#8217;m telling the API the number of entries to read in one request. The final parameter is the callback function that specifies what to do with every entry (a <strong>NotesViewEntryData</strong> object) retrieved from the view. In the example I&#8217;m using the built-in <strong>EntriesAsListCallback</strong> that returns a Java list containing the entries from the view. You can also write you own callback function to convert every entry in (for example) your own Java models.</p>
  464. <p>Since I&#8217;m using XPages for the demo, I need the controller class to be serializable. The list of <strong>NotesViewEntryData</strong> object isn&#8217;t serializable, so in the last lines I&#8217;m converting the 15 entries read from the view to a list of Java maps, containing only the primitive values from the columns.</p>
  465. <h3>Pagination</h3>
  466. <p>If you look at the full code of the <strong>ListController</strong> class, you&#8217;ll see that I&#8217;m keeping track of a &#8216;<strong>skipEntries</strong>&#8216; variable. If a user navigates to the next page of data, I update this variable (incrementing it by the number of entries per page) and by adding that variable to the <strong>getAllEntries()</strong> method call I start reading at the new index. That, combined with the number of entries shown on every page allow me to add a pager.</p>
  467. <h3>Sorting</h3>
  468. <p>To enable sorting on the dataset, you need to make a change to the view design. For every column that should be sortable you enable the option <strong>&#8220;Click on column header to sort&#8221;</strong>. With that in place you can change the sort order of the view data with this API call:</p>
  469. <p><script src="https://gist.github.com/markleusink/0fefbc5e82b628d712a5d6b3a6dbf5cf.js"></script></p>
  470. <p>Combine that with a click handler on the view columns and two variables in the controller class to store the current sort order and direction and <a href="https://demo.linqed.eu/jna/jna-demo.nsf/demo2.xsp" target="_blank" rel="noopener noreferrer">this</a> is what you get.</p>
  471. <h3>Finally</h3>
  472. <p>This article describes how you can start using Domino JNA to work view Domino view data. In the <a href="http://linqed.eu/2018/10/08/query-domino-data-and-faceted-search-with-domino-jna-part-2/">next article</a> I&#8217;ll show you how you can use the built-in entry selection methods to filter the data (based on search results in the current or a different view), while maintaining the sort order and pagination functions.</p>
  473. <p>(UPDATE: don&#8217;t forget to read <a href="http://linqed.eu/2018/10/08/query-domino-data-and-faceted-search-with-domino-jna-part-2/">part 2</a> and <a href="http://linqed.eu/2018/11/02/query-domino-data-with-domino-jna-part-3-rest-api-and-infinite-scroll/">part 3</a> of this Domino JNA series)</p>
  474. ]]></content:encoded>
  475. <wfw:commentRss>https://linqed.eu/2018/10/02/query-domino-data-and-faceted-search-with-domino-jna-part-1/feed/</wfw:commentRss>
  476. <slash:comments>3</slash:comments>
  477. </item>
  478. <item>
  479. <title>Time for a new Notes/ Domino support model</title>
  480. <link>https://linqed.eu/2018/02/08/time-for-a-new-notes-domino-support-model/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=time-for-a-new-notes-domino-support-model</link>
  481. <comments>https://linqed.eu/2018/02/08/time-for-a-new-notes-domino-support-model/#comments</comments>
  482. <dc:creator><![CDATA[]]></dc:creator>
  483. <pubDate>Thu, 08 Feb 2018 07:56:13 +0000</pubDate>
  484. <guid isPermaLink="false">http://linqed.eu/?p=822</guid>
  485.  
  486. <description><![CDATA[I&#8217;m pretty happy with FP10: great that with we now have up-to-date Eclipse/ Java/ OSGi version. Despite some obvious glitches it works reasonably well for me. But if you read the blogs and follow Twitter: a lot of people are having issues. The current &#8216;gold&#8217; version would have been a great beta (2) and with [&#8230;]]]></description>
  487. <content:encoded><![CDATA[<p>I&#8217;m pretty happy with FP10: great that with we now have up-to-date Eclipse/ Java/ OSGi version. Despite some obvious glitches it works reasonably well for me. But if you read the blogs and follow Twitter: a lot of people are having issues. The current &#8216;gold&#8217; version would have been a great beta (2) and with a couple of fixes a great release.</p>
  488. <p><a href="http://linqed.eu/wp-content/uploads/2018/02/help.png"><img loading="lazy" decoding="async" class="alignright size-medium wp-image-823" src="http://linqed.eu/wp-content/uploads/2018/02/help-279x300.png" alt="" width="279" height="300" srcset="https://linqed.eu/wp-content/uploads/2018/02/help-279x300.png 279w, https://linqed.eu/wp-content/uploads/2018/02/help-768x825.png 768w, https://linqed.eu/wp-content/uploads/2018/02/help-953x1024.png 953w, https://linqed.eu/wp-content/uploads/2018/02/help.png 1427w" sizes="(max-width: 279px) 100vw, 279px" /></a>I can confirm that I also have most of the issues described in <a href="https://www.ibm.com/developerworks/community/blogs/LotusSupport/entry/Listening_to_your_feedback_on_Notes_Domino_9_0_1_FP10?lang=en" target="_blank" rel="noopener noreferrer">this blog post</a> (and more). I also can/ really want to elaborate on them by providing more info/ screenshots just to make FP10 better.<br />
  489. ​<br />
  490. ​But&#8230; although I appreciate IBM (ArnazR) asking for more info in one of the more recent comments I don&#8217;t think that is the place. I also support software and absolutely hate it when people introduces new issues in a comments section.<br />
  491. ​<br />
  492. ​Creating PMR&#8217;s is way too much overhead. It is mentioned that a PMR exists for most issues. Can I simply add more info with just a line of text? Add a screenshot in under a minute? I don&#8217;t think so. Since I&#8217;m a consultant/ business partner and not a customer, I can&#8217;t even create PMR&#8217;s (seriously?). Don&#8217;t want to bother one of my customers for it neither.</p>
  493. <p>Wouldn&#8217;t it be great if we had a simple way to log the issue we&#8217;re having with FP10? Just have a look at the Github issues section for inspiration. ​The delivery model for Notes/ Domino has changed in light of what the rest of the world is doing. I think it&#8217;s time the support model follows.</p>
  494. <p>PS. For ArnazR: have a look at the screenshot. I would also say that this help screen looks &#8216;curious&#8217;).</p>
  495. ]]></content:encoded>
  496. <wfw:commentRss>https://linqed.eu/2018/02/08/time-for-a-new-notes-domino-support-model/feed/</wfw:commentRss>
  497. <slash:comments>9</slash:comments>
  498. </item>
  499. <item>
  500. <title>Convenience at a cost: comparing Domino Java APIs performance (standard, ODA, JNA)</title>
  501. <link>https://linqed.eu/2017/05/12/convenience-at-a-cost-comparing-domino-java-apis-performance-oda-legacy-jna/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=convenience-at-a-cost-comparing-domino-java-apis-performance-oda-legacy-jna</link>
  502. <comments>https://linqed.eu/2017/05/12/convenience-at-a-cost-comparing-domino-java-apis-performance-oda-legacy-jna/#comments</comments>
  503. <dc:creator><![CDATA[]]></dc:creator>
  504. <pubDate>Fri, 12 May 2017 13:29:26 +0000</pubDate>
  505. <guid isPermaLink="false">http://linqed.eu/?p=779</guid>
  506.  
  507. <description><![CDATA[I&#8217;m into performance at the moment, trying to solve some nasty issues in one of the applications I work on. While researching the topic I came across Karsten Lehmann&#8217;s Domino JNA project that allows you to use some low-level C-API methods using Java. It contains functions that are very useful in my scenario, but I [&#8230;]]]></description>
  508. <content:encoded><![CDATA[<p>I&#8217;m into performance at the moment, trying to solve some nasty issues in one of the applications I work on. While researching the topic I came across Karsten Lehmann&#8217;s <a href="https://github.com/klehmann/domino-jna" target="_blank" rel="noopener noreferrer">Domino JNA</a> project that allows you to use some low-level C-API methods using Java. It contains functions that are very useful in my scenario, but I also wondered how the library performed. So I wrote some basic tests, comparing JNA with the &#8216;standard&#8217; (or &#8216;legacy&#8217;) Domino API and, while I was at it, the <a href="https://openntf.org/main.nsf/project.xsp?r=project/OpenNTF%20Domino%20API" target="_blank" rel="noopener noreferrer">org.openntf.domino</a> (ODA) API.</p>
  509. <p><img loading="lazy" decoding="async" class="alignright size-medium wp-image-781" src="http://linqed.eu/wp-content/uploads/2017/05/fast-300x174.jpeg" alt="" width="300" height="174" srcset="https://linqed.eu/wp-content/uploads/2017/05/fast-300x174.jpeg 300w, https://linqed.eu/wp-content/uploads/2017/05/fast.jpeg 600w" sizes="(max-width: 300px) 100vw, 300px" />So I wrote a couple of tests using the 3 APIs that traverse a view from the well known &#8216;Fakenames&#8217; database. It is based on the Domino Name &amp; Address book template and contains 40,000 documents. The tests will loop through a view called &#8216;People&#8217; containing all the documents and will read a value from one of the columns.</p>
  510. <p>At this point I will be taking bets:</p>
  511. <p>Note: There is a poll embedded within this post, please visit the site to participate in this post's poll.</p>
  512. <p>Time to see for yourself! I created a simple application that allows you to test the different methods and view the results (latest 10 are shown only): <b>take a look <a href="https://demo.linqed.eu/performance.nsf" target="_blank" rel="noopener noreferrer">here</a></b>.</p>
  513. <p>The source code of the application and test code can be found <a href="https://github.com/markleusink/viewtraversalperformance" target="_blank" rel="noopener noreferrer">here</a>. The environment: CentOS 6 (64 bit), SSD, 1GB RAM, Domino 901FP5 (64 bit), ExtLib 17, ODA 3.2.1, JNA 0.9.5. Please let me know if I made any errors in the tests.</p>
  514. <p>I don&#8217;t know what about you, but the results surprised me! I didn&#8217;t expect the overhead of the non-standard APIs to be that big. In every day use I guess this won&#8217;t affect your applications a lot, but it&#8217;s something you definitely have to be aware of if you needs to squeeze just a bit more performance out of your application.</p>
  515. <p><strong>UPDATE</strong></p>
  516. <p>&#8211; Upgraded the JNA project to 0.9.5<br />
  517. &#8211; Based on Andy Cunliffe&#8217;s comment I&#8217;ve added a new test using a &#8216;manual&#8217; Java loop in the ODA:</p>
  518. <p><code>ViewEntry ve = nav.getFirst();<br />
  519. while (null != ve) {</code></p>
  520. <p>// code here</p>
  521. <p>ve = nav.getNext();<br />
  522. }</p>
  523. <p>That code seems to run about 30% faster that a standard Java loop in ODA:</p>
  524. <p><code>for (ViewEntry ve : nav) {</code></p>
  525. <p>// code here</p>
  526. <p>}</p>
  527. ]]></content:encoded>
  528. <wfw:commentRss>https://linqed.eu/2017/05/12/convenience-at-a-cost-comparing-domino-java-apis-performance-oda-legacy-jna/feed/</wfw:commentRss>
  529. <slash:comments>3</slash:comments>
  530. </item>
  531. <item>
  532. <title>Getting the IBM Connections API to play nice with Postman/ Chrome</title>
  533. <link>https://linqed.eu/2016/07/05/getting-the-ibm-connections-api-to-play-nice-with-postman-chrome/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=getting-the-ibm-connections-api-to-play-nice-with-postman-chrome</link>
  534. <comments>https://linqed.eu/2016/07/05/getting-the-ibm-connections-api-to-play-nice-with-postman-chrome/#comments</comments>
  535. <dc:creator><![CDATA[]]></dc:creator>
  536. <pubDate>Tue, 05 Jul 2016 15:02:16 +0000</pubDate>
  537. <guid isPermaLink="false">http://linqed.eu/?p=763</guid>
  538.  
  539. <description><![CDATA[I was doing some work with an Angular application talking to the IBM Connections API. More specifically: I wanted to show and create activities based on some user input. The Connections API is pretty complex, so I normally run some &#8216;manual&#8217; tests first based on the documentation, and then use those result to write the code to [&#8230;]]]></description>
  540. <content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="size-full wp-image-770 alignright" src="http://linqed.eu/wp-content/uploads/2016/07/postman.png" alt="postman" width="128" height="128" srcset="https://linqed.eu/wp-content/uploads/2016/07/postman.png 128w, https://linqed.eu/wp-content/uploads/2016/07/postman-60x60.png 60w" sizes="(max-width: 128px) 100vw, 128px" />I was doing some work with an Angular application talking to the <a href="https://www-10.lotus.com/ldd/lcwiki.nsf/xpAPIViewer.xsp?lookupName=IBM+Connections+5.0+API+Documentation#action=openDocument&amp;content=catcontent&amp;ct=api" target="_blank" rel="noopener noreferrer">IBM Connections API</a>. More specifically: I wanted to show and create activities based on some user input.</p>
  541. <p>The Connections API is pretty complex, so I normally run some &#8216;manual&#8217; tests first based on the documentation, and then use those result to write the code to call the API. My preferred application for that is <a href="https://www.getpostman.com/">Postman</a>.</p>
  542. <p>While running the tests in Postman I ran into a big issue. All <strong>GET</strong> and <strong>PUT</strong> requests came through fine, but I wasn&#8217;t able to create anything using a <strong>POST</strong> request to the API: every request I made returned a 403 error:</p>
  543. <p><code>&lt;error xmlns="http://www.ibm.com/xmlns/prod/sn"&gt;<br />
  544. &lt;code&gt;403&lt;/code&gt;<br />
  545. &lt;message&gt;You are not authorized to perform the requested action.&lt;/message&gt;<br />
  546. &lt;trace&gt;&lt;/trace&gt;<br />
  547. &lt;/error&gt;</code></p>
  548. <p>The funny thing was that using the same credentials, I could create items using the web interface just fine. My first thought was that it must be some strange access control setting hidden away deep in a config file (&#8220;don&#8217;t allow users to create stuff using the API&#8221;), but then I found someone with a similar issue on <a href="http://stackoverflow.com/questions/33803364/ibm-connections-5-post-giving-403-for-forum-blog-board-posts-from-android-app">StackOverflow.</a> And I found <a href="http://www-01.ibm.com/support/docview.wss?uid=swg1LO79992">this</a> IBM Technote. So, apparently there&#8217;s something fishy going on with Postman.</p>
  549. <p>So by enabling the <a href="http://blog.getpostman.com/2014/01/27/enabling-chrome-developer-tools-inside-postman/">Chrome Developer tools</a> for Postman, I was able to look at the exact HTTP request that Postman sends. And I found the <strong>Origin</strong> header that was already mentioned in the StackOverflow post:</p>
  550. <p><code>Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop</code></p>
  551. <p>Turns out that IBM Connections doesn&#8217;t really like that. That&#8217;s by design and has something to do with <a href="http://bastide.org/2014/10/08/cross-site-request-forgery-and-ibm-connections-micro-blog/">cross-site request forgery.</a>. Using a <strong>curl</strong> command I could easily bypass the header and confirm that it was indeed the cause of my problem.</p>
  552. <p>So the only thing left (since I like testing with Postman), was to figure out how to change that <strong>Origin</strong> header. The header is one of the &#8216;restricted&#8217; headers that is automatically added by the browser (Chrome) and can&#8217;t be easily changed. Luckily, the people at Postman also thought of that and created the &#8220;<a href="https://chrome.google.com/webstore/detail/postman-interceptor/aicmkgpgakddgnaphhhpliifpcfhicfo">Postman Interceptor</a>&#8220;: a Chrome extension that sits as a sort of proxy between your Postman requests. After <a href="https://beta.getpostman.com/docs/requests">enabling</a> that in Postman I was able to change the Origin header of my requests. I set it to the hostname of the IBM Connections server and voila: happy times!</p>
  553. ]]></content:encoded>
  554. <wfw:commentRss>https://linqed.eu/2016/07/05/getting-the-ibm-connections-api-to-play-nice-with-postman-chrome/feed/</wfw:commentRss>
  555. <slash:comments>3</slash:comments>
  556. </item>
  557. <item>
  558. <title>Visual Studio Code, SourceTree and terminal/ command line integration</title>
  559. <link>https://linqed.eu/2016/04/22/visual-studio-code-sourcetree-and-terminal-integration-on-a-mac/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=visual-studio-code-sourcetree-and-terminal-integration-on-a-mac</link>
  560. <comments>https://linqed.eu/2016/04/22/visual-studio-code-sourcetree-and-terminal-integration-on-a-mac/#comments</comments>
  561. <dc:creator><![CDATA[]]></dc:creator>
  562. <pubDate>Fri, 22 Apr 2016 09:06:10 +0000</pubDate>
  563. <guid isPermaLink="false">http://linqed.eu/?p=749</guid>
  564.  
  565. <description><![CDATA[Over the past couple of weeks, Visual Studio Code has become my favorite editor. It has some great features, is fast and relatively easy to use. Of course I&#8217;m still learning how to use it most effectively. Here&#8217;s what I learned today. Starting Visual Studio Code from the terminal Visual Studio Code has a built-in function [&#8230;]]]></description>
  566. <content:encoded><![CDATA[<p><a href="https://code.visualstudio.com/"><img loading="lazy" decoding="async" class="alignright wp-image-751 size-medium" src="http://linqed.eu/wp-content/uploads/2016/04/download-300x200.jpeg" alt="download" width="300" height="200" srcset="https://linqed.eu/wp-content/uploads/2016/04/download-300x200.jpeg 300w, https://linqed.eu/wp-content/uploads/2016/04/download.jpeg 718w" sizes="(max-width: 300px) 100vw, 300px" /></a>Over the past couple of weeks, <a href="https://code.visualstudio.com/">Visual Studio Code</a> has become my favorite editor. It has some great features, is fast and relatively easy to use. Of course I&#8217;m still learning how to use it most effectively. Here&#8217;s what I learned today.</p>
  567. <p><b>Starting Visual Studio Code from the terminal</b></p>
  568. <p>Visual Studio Code has a built-in function to add a shortcut to it in your OS X environment. That allows you to start it from a terminal. The procedure is described <a href="https://code.visualstudio.com/docs/editor/setup">here</a> and comes down to:</p>
  569. <ul>
  570. <li>Open Visual Studio Code</li>
  571. <li>Bring up the Command Palette ( Cmd &#8211; Ctrl &#8211; P ) and type &#8220;shell command&#8221;</li>
  572. <li>Execute the <strong>&#8216;Shell Command: Install &#8216;code&#8217; command in PATH&#8217;</strong> command</li>
  573. </ul>
  574. <p>When you&#8217;ve done that, you can simply type &#8216;<strong>code</strong>&#8216; in your terminal to start Visual Studio Code. If you want to open a specific file with Code, type <strong>&#8216;code &lt;filename&gt;&#8217;</strong>.</p>
  575. <p><strong>Note:</strong> Windows users get this feature automatically when installing Code.</p>
  576. <p><b>Open a file directly from a repo in SourceTree</b></p>
  577. <p>SourceTree has a function that allows you to define &#8216;Custom Actions&#8217; that can be started from files in any repo. If you&#8217;ve added the &#8216;code&#8217; command from the previous step, you can create a Custom Action to open any selected file with Visual Studio Code:</p>
  578. <ul>
  579. <li>Bring up the SourceTree preferences (Cmd + comma)</li>
  580. <li>Go to the Custom Actions tab and configure it like this <strong>(OS X users)</strong>:</li>
  581. </ul>
  582. <p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-750" src="http://linqed.eu/wp-content/uploads/2016/04/Screenshot-2016-04-21-10.03.58.png" alt="Screenshot 2016-04-21 10.03.58" width="671" height="419" srcset="https://linqed.eu/wp-content/uploads/2016/04/Screenshot-2016-04-21-10.03.58.png 671w, https://linqed.eu/wp-content/uploads/2016/04/Screenshot-2016-04-21-10.03.58-300x187.png 300w" sizes="(max-width: 671px) 100vw, 671px" /></p>
  583. <p>Note that <strong>Windows</strong> users need to configure the custom action with the full path to the Code executable:</p>
  584. <p><img loading="lazy" decoding="async" src="http://linqed.eu/wp-content/uploads/2016/04/Capture.png" alt="Capture" width="499" height="244" class="aligncenter size-full wp-image-760" srcset="https://linqed.eu/wp-content/uploads/2016/04/Capture.png 499w, https://linqed.eu/wp-content/uploads/2016/04/Capture-300x147.png 300w" sizes="(max-width: 499px) 100vw, 499px" /></p>
  585. <p>If you now select a file in your repo, you can right click &gt; Custom Actions &gt; Edit in Visual Studio Code to immediately open a file with Code.</p>
  586. <p>Happy coding!</p>
  587. ]]></content:encoded>
  588. <wfw:commentRss>https://linqed.eu/2016/04/22/visual-studio-code-sourcetree-and-terminal-integration-on-a-mac/feed/</wfw:commentRss>
  589. <slash:comments>1</slash:comments>
  590. </item>
  591. </channel>
  592. </rss>
  593.  

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid RSS" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

http://www.feedvalidator.org/check.cgi?url=http%3A//linqed.eu/%3Ffeed%3Drss2

Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda