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://www.mindoo.com/web/blog.nsf/feed.rss

  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <rss version="2.0"
  3. xmlns:dc="http://purl.org/dc/elements/1.1/"
  4. xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  5. xmlns:admin="http://webns.net/mvcb/"
  6. xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  7. xmlns:content="http://purl.org/rss/1.0/modules/content/"
  8. xmlns:wfw="http://wellformedweb.org/CommentAPI/">
  9. <channel>
  10. <title>Mindoo Blog</title>
  11. <description>Cutting edge technologies - About Java, Lotus Notes and iPhone</description>
  12. <link>https://www.mindoo.de/web/blog.nsf/</link>
  13. <language>en-us</language>
  14. <lastBuildDate>Fri, 23 Aug 2024 23:22:29 +0200</lastBuildDate>
  15. <item>
  16. <title>Session recording for Domino JNA Virtual View API available on YouTube</title>
  17. <pubDate>Fri, 23 Aug 2024 23:22:29 +0200</pubDate>
  18. <description>
  19. <![CDATA[
  20. On the 18th of July 2024 I attended the OpenNTF "Develop Variety Hour" and presented the new Domino JNA Virtual View API. The recording for this session is now available here: https://www.youtube.com ...
  21. ]]>
  22. </description>
  23. <link>https://www.mindoo.com/web/blog.nsf/dx/23.08.2024232229KLET3L.htm</link>
  24. <category>Domino C API</category>
  25. <dc:creator>Karsten Lehmann</dc:creator>
  26. <comments>https://www.mindoo.com/web/blog.nsf/dx/23.08.2024232229KLET3L.htm?opendocument&amp;comments</comments>
  27. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/23.08.2024232229KLET3L.htm</guid>
  28. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">On the 18th of July 2024 I attended the OpenNTF "Develop Variety Hour" and presented the new Domino JNA Virtual View API.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The recording for this session is now available here: </span><a href="https://www.youtube.com/watch?v=TGsudzbvbmc&amp;t=1417s" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.youtube.com/watch?v=TGsudzbvbmc&amp;t=1417s</span></a> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Video description from YouTube:</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">In this webinar Jesse Gallagher is joined by Karsten Lehmann, Paul Withers and Alec Vincent Bardiano to touch on a set of developer-related topics in the HCL Domino world. &nbsp;Namely, Jesse talks about contributing to open source projects in general, and also highlights some relevant current projects including Domino JNX, Domino Rust Addin and HCL's Open-Source templates, Paul shares more about a project, Bali Unit, that is a port of VoltScript testing that may be used in LotusScript, and Alec presents some nice information about the Domino REST API Node.js and Go SDKs.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The slides for Jesse's portion of the webinar may be downloaded </span><a href="https://www.openntf.org/Public/presentations.nsf/0/EC05AD9CA48DE52D86258B79004CC639/$FILE/2024-07_OpenNTF_Developer_Variety_Hour.pdf" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.openntf.org/Public/presentations.nsf/0/EC05AD9CA48DE52D86258B79004CC639/$FILE/2024-07_OpenNTF_Developer_Variety_Hour.pdf</span></a> <br />  ]]></content:encoded>
  29. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/23.08.2024232229KLET3L.htm</wfw:commentRss>
  30. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/23.08.2024232229KLET3L.htm?opendocument&amp;comments</wfw:comment>
  31. </item>
  32. <item>
  33. <title>New Domino JNA version 0.9.53 and source code for our Virtual View API demo app</title>
  34. <pubDate>Sat, 20 Jul 2024 23:04:19 +0200</pubDate>
  35. <description>
  36. <![CDATA[
  37. As announced in the last article Demo application for Domino JNA Views to play with, I just released a new version of Domino JNA, version 0.9.53, with these changes; fixed a VirtualViewNavigator issu ...
  38. ]]>
  39. </description>
  40. <link>https://www.mindoo.com/web/blog.nsf/dx/20.07.2024230419KLESQ9.htm</link>
  41. <category></category>
  42. <dc:creator>Karsten Lehmann</dc:creator>
  43. <comments>https://www.mindoo.com/web/blog.nsf/dx/20.07.2024230419KLESQ9.htm?opendocument&amp;comments</comments>
  44. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/20.07.2024230419KLESQ9.htm</guid>
  45. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">As announced in the last article <a href="https://www.mindoo.com/web/blog.nsf/dx/18.07.2024175024KLELL4.htm">Demo application for Domino JNA Views to play with</a>, I just released a new version of Domino JNA, version 0.9.53, with these changes;</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><ul><li>fixed a VirtualViewNavigator issue where a navigator created via buildFromCategory(...) returns entries out of subtree when using gotoPos() and navigating</li><li>code for VirtualViewNavigator read access check can now be customized by implementing com.mindoo.domino.jna.virtualviews.security.IViewEntryAccessCheck or subclassing com.mindoo.domino.jna.virtualviews.security.ViewEntryAccessCheck when creating the navigator</li><li>new API method com.mindoo.domino.jna.virtualviews.VirtualViewNavigator.entriesForwardFromPosition(String, SelectedOnly)</li></ul></span> <br /><span style=" font-size:10pt;font-family:sans-serif">These were findings and feedback I got from creating/showing my Virtual View API demo application at the recent </span><a href="https://www.openntf.org/main.nsf/blog.xsp?permaLink=JGAR-D78NL4" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">OpenNTF developer webinar</span></a><span style=" font-size:10pt;font-family:sans-serif">.</span> <br /> <br /><img  alt="Image:New Domino JNA version 0.9.53 and source code for our Virtual View API demo app" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/20.07.2024230419KLESQ9.htm/content/M2?OpenElement" /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The source code for the demo application that can be tested here </span><a href=https://www.mindoo.de/test/jnavirtualviews.nsf/sunburst.xsp target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.mindoo.de/test/jnavirtualviews.nsf/sunburst.xsp</span></a><span style=" font-size:10pt;font-family:sans-serif"> is now also available on GitHub:</span> <br /> <br /><a href="https://github.com/klehmann/JNA-Virtual-Views-Demo" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://github.com/klehmann/JNA-Virtual-Views-Demo</span></a> <br /> <br /> <br />  ]]></content:encoded>
  46. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/20.07.2024230419KLESQ9.htm</wfw:commentRss>
  47. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/20.07.2024230419KLESQ9.htm?opendocument&amp;comments</wfw:comment>
  48. </item>
  49. <item>
  50. <title>Demo application for Domino JNA Views to play with</title>
  51. <pubDate>Thu, 18 Jul 2024 17:50:24 +0200</pubDate>
  52. <description>
  53. <![CDATA[
  54. Today I attended the "Developer Variety Hour" webinar of OpenNTF and did a demo of the new Virtual View API of Domino JNA. I built a small web application that combines a Sunburst diagram (taken from ...
  55. ]]>
  56. </description>
  57. <link>https://www.mindoo.com/web/blog.nsf/dx/18.07.2024175024KLELL4.htm</link>
  58. <category>Domino C API</category>
  59. <dc:creator>Karsten Lehmann</dc:creator>
  60. <comments>https://www.mindoo.com/web/blog.nsf/dx/18.07.2024175024KLELL4.htm?opendocument&amp;comments</comments>
  61. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/18.07.2024175024KLELL4.htm</guid>
  62. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">Today I attended the "Developer Variety Hour" webinar of OpenNTF and did a demo of the new <a href="https://www.mindoo.com/web/blog.nsf/dx/13.07.2024001044KLETZR.htm">Virtual View API of Domino JNA</a>.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">I built a small web application that combines a Sunburst diagram (taken from the </span><a href=https://d3js.org/ target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">D3 website</span></a><span style=" font-size:10pt;font-family:sans-serif">, enhanced by a training session with Anthropics Claude AI chat :-) ) with a categorized view, built on top of a Bootstrap 5 table.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The application looks like this:</span> <br /> <br /><img  alt="Image:Demo application for Domino JNA Views to play with" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/18.07.2024175024KLELL4.htm/content/M2?OpenElement" /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">and it's available for you to play with here: </span><a href=https://www.mindoo.de/test/jnavirtualviews.nsf/sunburst.xsp target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.mindoo.de/test/jnavirtualviews.nsf/sunburst.xsp</span></a> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Both components fetch their data from an XAgent style XPage where a Virtual View is used to read document information from two fakenames databases:</span> <br /> <br /><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>public</strong></span><span style=" font-size:8pt;font-family:Courier New"> Optional< VirtualView > getViewById(String </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">id</span><span style=" font-size:8pt;font-family:Courier New">) {</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; VirtualView </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">view</span><span style=" font-size:8pt;font-family:Courier New"> = </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>null</strong></span><span style=" font-size:8pt;font-family:Courier New">;</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>if</strong></span><span style=" font-size:8pt;font-family:Courier New"> (</span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"fakenames_bycontinent_categorized"</span><span style=" font-size:8pt;font-family:Courier New">.equals(</span><span style=" font-size:8pt;color:#622152;font-family:Courier New">id</span><span style=" font-size:8pt;font-family:Courier New">)) {</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">view</span><span style=" font-size:8pt;font-family:Courier New"> = VirtualViewFactory.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>INSTANCE</em></strong></span><span style=" font-size:8pt;font-family:Courier New">.createViewOnce(</span><span style=" font-size:8pt;color:#622152;font-family:Courier New">id</span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 17, </span><span style=" font-size:8pt;color:#3f8080;font-family:Courier New">// view version number</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10, TimeUnit.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>MINUTES</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#3f8080;font-family:Courier New">// keep in memory for 10 minutes</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (</span><span style=" font-size:8pt;color:#622152;font-family:Courier New">viewId</span><span style=" font-size:8pt;font-family:Courier New">) -> {</span> <br /> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>return</strong></span><span style=" font-size:8pt;font-family:Courier New"> VirtualViewFactory.<em>createView</em>(</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#3f8080;font-family:Courier New">// use a Java function to compute the "Continent" category:</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>new</strong></span><span style=" font-size:8pt;font-family:Courier New"> VirtualViewColumn(</span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Continent"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"$1"</span><span style=" font-size:8pt;font-family:Courier New">, Category.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>YES</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, Hidden.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NO</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, ColumnSort.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>ASCENDING</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, Total.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NONE</em></strong></span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>new</strong></span><span style=" font-size:8pt;font-family:Courier New"> VirtualViewColumnValueFunction< String >(1) {</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#5f5f5f;font-family:Courier New">@Override</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>public</strong></span><span style=" font-size:8pt;font-family:Courier New"> String getValue(String </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">origin</span><span style=" font-size:8pt;font-family:Courier New">, String </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">itemName</span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INoteSummary </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">columnValues</span><span style=" font-size:8pt;font-family:Courier New">) {</span> <br /> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">companyName</span><span style=" font-size:8pt;font-family:Courier New"> = </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">columnValues</span><span style=" font-size:8pt;font-family:Courier New">.getAsString(</span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"CompanyName"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">""</span><span style=" font-size:8pt;font-family:Courier New">);</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Map<String,String> </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">lookupMap</span><span style=" font-size:8pt;font-family:Courier New"> = getCompanyContinentMap();</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>return</strong></span><span style=" font-size:8pt;font-family:Courier New"> </span><span style=" font-size:8pt;color:#622152;font-family:Courier New">lookupMap</span><span style=" font-size:8pt;font-family:Courier New">.getOrDefault(</span><span style=" font-size:8pt;color:#622152;font-family:Courier New">companyName</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Unknown"</span><span style=" font-size:8pt;font-family:Courier New">);</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }),</span> <br /> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#3f8080;font-family:Courier New">// use formula language for the remaining columns:</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>new</strong></span><span style=" font-size:8pt;font-family:Courier New"> VirtualViewColumn(</span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Company Name"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"$2"</span><span style=" font-size:8pt;font-family:Courier New">, Category.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>YES</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, Hidden.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NO</em></strong></span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ColumnSort.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>ASCENDING</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, Total.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NONE</em></strong></span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"@Left(CompanyName;1) + \"\\\\\" + CompanyName"</span><span style=" font-size:8pt;font-family:Courier New">),</span> <br /> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>new</strong></span><span style=" font-size:8pt;font-family:Courier New"> VirtualViewColumn(</span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Lastname"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Lastname"</span><span style=" font-size:8pt;font-family:Courier New">, Category.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NO</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, Hidden.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NO</em></strong></span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ColumnSort.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>ASCENDING</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, Total.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NONE</em></strong></span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Lastname"</span><span style=" font-size:8pt;font-family:Courier New">),</span> <br /> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>new</strong></span><span style=" font-size:8pt;font-family:Courier New"> VirtualViewColumn(</span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Firstname"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Firstname"</span><span style=" font-size:8pt;font-family:Courier New">, Category.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NO</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, Hidden.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NO</em></strong></span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ColumnSort.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>ASCENDING</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, Total.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NONE</em></strong></span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Firstname"</span><span style=" font-size:8pt;font-family:Courier New">),</span> <br /> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>new</strong></span><span style=" font-size:8pt;font-family:Courier New"> VirtualViewColumn(</span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"CompanyName"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"CompanyName"</span><span style=" font-size:8pt;font-family:Courier New">, Category.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NO</em></strong></span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Hidden.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>YES</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, ColumnSort.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NONE</em></strong></span><span style=" font-size:8pt;font-family:Courier New">, Total.</span><span style=" font-size:8pt;color:#0021bf;font-family:Courier New"><strong><em>NONE</em></strong></span><span style=" font-size:8pt;font-family:Courier New">,</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"CompanyName"</span><span style=" font-size:8pt;font-family:Courier New">)</span> <br /> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#3f8080;font-family:Courier New">// load data from two <span style="text-decoration:underline">fakenames</span> databases</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .withDbSearch(</span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"fakenames1"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">""</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"fakenames.nsf"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Form=\"Person\""</span><span style=" font-size:8pt;font-family:Courier New">)</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .withDbSearch(</span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"fakenames2"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">""</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"fakenames2.nsf"</span><span style=" font-size:8pt;font-family:Courier New">, </span><span style=" font-size:8pt;color:#4200ff;font-family:Courier New">"Form=\"Person\""</span><span style=" font-size:8pt;font-family:Courier New">)</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .build();</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });</span> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; }</span> <br /> <br /><span style=" font-size:8pt;font-family:Courier New">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=" font-size:8pt;color:#820040;font-family:Courier New"><strong>return</strong></span><span style=" font-size:8pt;font-family:Courier New"> Optional.<em>ofNullable</em>(</span><span style=" font-size:8pt;color:#622152;font-family:Courier New">view</span><span style=" font-size:8pt;font-family:Courier New">);</span> <br /><span style=" font-size:8pt;font-family:Courier New">}</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Initial index generation for about 40.000 fakenames docs takes 5 seconds on our server. The view is set to expire after 10 minutes and will be automatically be rebuilr.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The first column value is computed via Java code and looks up the continent for the company name of a fakenames person (let's call it a JOIN operation).</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Since all data access is done in-memory (no legacy Domino view is required), REST API response times are ultra-fast and take 50ms for each request. Part of those 50ms is opening the two fakenames database and checking if anything relevant has been changed/added/deleted. As presented in the webinar, changing DB documents is immediately reflected in the web app.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Building this demo app this week I discovered a few issues in the Virtual View API of Domino JNA 0.9.52 especially when processing NSF changes (the code produced duplicate rows).</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">I will publish a new Domino JNA version this week with fixes.</span> <br /> <br /> <br />  ]]></content:encoded>
  63. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/18.07.2024175024KLELL4.htm</wfw:commentRss>
  64. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/18.07.2024175024KLELL4.htm?opendocument&amp;comments</wfw:comment>
  65. </item>
  66. <item>
  67. <title>Domino JNA Virtual Views: The Next Step in Domino Data Retrieval</title>
  68. <pubDate>Sun, 14 Jul 2024 00:10:00 +0200</pubDate>
  69. <description>
  70. <![CDATA[
  71. In the previous two articles, "The pain of reading data as a Domino developer - and solutions" and "Overview of Domino Data Retrieval: Exploring NSF Search, DQL, Domino Views, and the QueryResultsProc ...
  72. ]]>
  73. </description>
  74. <link>https://www.mindoo.com/web/blog.nsf/dx/13.07.2024001044KLETZR.htm</link>
  75. <category>Domino C API</category>
  76. <dc:creator>Karsten Lehmann</dc:creator>
  77. <comments>https://www.mindoo.com/web/blog.nsf/dx/13.07.2024001044KLETZR.htm?opendocument&amp;comments</comments>
  78. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/13.07.2024001044KLETZR.htm</guid>
  79. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">In the previous two articles, "<a href="https://www.mindoo.com/web/blog.nsf/dx/19.06.2024110207KLECLW.htm">The pain of reading data as a Domino developer - and solutions</a>" and "<a href="https://www.mindoo.com/web/blog.nsf/dx/13.07.2024000446KLETW2.htm">Overview of Domino Data Retrieval: Exploring NSF Search, DQL, Domino Views, and the QueryResultsProcessor</a>", we explored the challenges and solutions for efficiently accessing and processing data in Domino.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Now, let's delve into the next evolution in Domino data handling.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Version 0.9.49 of our </span><a href="https://github.com/klehmann/domino-jna" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">Domino JNA open-source project</span></span></a><span style=" font-size:10pt;font-family:sans-serif"> introduced a new API called "Virtual Views", built with all the NIF, formula search, DQL, and QueryResultsProcessor history and limitations in mind.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> In short, you define the view structure as a VirtualView object in your Java code (columns with sorting, categorization, total, and average values) and then add one or more data providers that incrementally push data into the view (or remove it).</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> This article will guide you through the innovative features and capabilities of the Virtual View API, demonstrating how it simplifies and enhances data retrieval and manipulation in Domino.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Now, let's take a closer look at how you can leverage the Virtual View API to define and manage views dynamically in your Java code.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> To illustrate, consider the following code:</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <code></span><tt><span style=" font-size:10pt">Map<String,String> someExternalData = new HashMap<>();</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br /> someExternalData.put("Revoco", "Revoco Street 5, Los Angeles");</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br /> someExternalData.put("Omnis", "Omnis Boulevard 12, New York");</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt;color:#008000"><br /> // by using "createViewOnce", we mark the view to be stored in memory,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br /> // as a version "1" and to auto discard it</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br /> // after 5 minute of inactivity (just for testing, in production you'd use a higher value)</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt;color:#008000"><br /> // changing the version number to "2" would force a new view to be created</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br /> VirtualView view = VirtualViewFactory.INSTANCE.createViewOnce("fakenames_namelengths",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp;1, </span></tt><tt><span style=" font-size:10pt;color:#008000">// version "1"</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp;5, TimeUnit.MINUTES, </span></tt><tt><span style=" font-size:10pt;color:#008000">// auto discard after 5 minute of inactivity</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // (calling createViewOnce resets the counting)</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp;(id) -> {</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;return VirtualViewFactory.createView(</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumn("Lastname", "Lastname",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Category.YES, Hidden.NO, ColumnSort.ASCENDING, Total.NONE,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"Lastname"),</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumn("Firstname", "Firstname",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Category.NO, Hidden.NO, ColumnSort.ASCENDING, Total.NONE,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"Firstname"),</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumn("Total Name Length", "TotalNameLength",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Category.NO, Hidden.NO, ColumnSort.NONE, Total.SUM,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumnValueFunction< Integer >(1) {</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // this 1 is a version number for</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // the column function, might become</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // relevant later when we store the index to disk</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@Override</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;public Integer getValue(String origin, String itemName,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;INoteSummary columnValues) {</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return columnValues.getAsString("Firstname", "").length() + 1 +</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;columnValues.getAsString("Lastname", "").length();</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}),</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumn("Average Name Length", "AverageNameLength",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Category.NO, Hidden.NO, ColumnSort.NONE, Total.AVERAGE,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumnValueFunction< Integer >(1) {</span></tt><span style=" font-size:12pt"> <br /> <br /> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@Override</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;public Integer getValue(String origin, String itemName,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;INoteSummary columnValues) {</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return columnValues.getAsString("Firstname", "").length() + 1 +</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;columnValues.getAsString("Lastname", "").length();</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}),</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumn("Company Address", "CompanyAddress",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Category.NO, Hidden.NO, ColumnSort.NONE, Total.NONE,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumnValueFunction< String >(1) {</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@Override</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;public String getValue(String origin, String itemName,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;INoteSummary columnValues) {</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></tt><tt><span style=" font-size:10pt;color:#008000">// poor man's JOIN :-)</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// we fetch the company address from a map</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// using the company name as key</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;String companyName = columnValues.getAsString("CompanyName", "");</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return someExternalData.getOrDefault(companyName, "");</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}),</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumn("Last Update", "LastMod",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Category.NO, Hidden.NO, ColumnSort.NONE, Total.NONE,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"LastMod"),</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></tt><tt><span style=" font-size:10pt;color:#008000">// required to have the CompanyName value available in the summary</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// buffer so that the Java column function can use it</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new VirtualViewColumn("Company Name", "CompanyName",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Category.NO, Hidden.YES, ColumnSort.NONE, Total.NONE,</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"CompanyName")</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;)</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></tt><tt><span style=" font-size:10pt;color:#008000">// add one or more data providers with an origin id (here "myfakenames1")</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.withDbSearch("myfakenames1",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"Server1/Mindoo", "fakenames.nsf",</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"Form=\"Person\"")</span></tt><span style=" font-
  80. size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></tt><tt><span style=" font-size:10pt;color:#008000">// let's move the categories above the docs like in Windows Explorer</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.withCategorizationStyle(CategorizationStyle.CATEGORY_THEN_DOCUMENT)</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.build();</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br /> });</code></span></tt><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> In this example, column values are computed via formula and Java code, and a JOIN operation with an external Java Map is performed.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> More examples can be found here: </span><a href="https://github.com/klehmann/domino-jna/blob/develop/domino-jna/src/test/java/com/mindoo/domino/jna/test/TestVirtualView.java"><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://github.com/klehmann/domino-jna/blob/develop/domino-jna/src/test/java/com/mindoo/domino/jna/test/TestVirtualView.java</span></span></a><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> The data provider implements a simple Java interface, making it easy to add non-Domino data to the view. For Domino, we built several standard implementations that can be mixed and matched for one or multiple databases:</span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <ul><li>datasource 1: run NSF search with a formula (incrementally), can search data and design documents, optional post processing with FT search</li><li>datasource 2: profile documents filtered with a formula</li><li>datasource 3: read note ids from a folder (incrementally), &nbsp;ideal for displaying folder content in different ways</li><li>datasource 4: compute column values from any list of note IDs (e.g. a DQL result)</li></ul></span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> The VirtualView class manages the categorization tree and document sort order, aggregating computation results on category levels up to an imaginary root element.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><br /> Readers lists</strong></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Readers lists are a first-class citizen in the Virtual View API. For documents, we store the individual readers within the view index entry, along with the origin database information. When traversing the view, we compare the readers list with the usernames list of the current user in that specific database. This also works with ACL roles which are defined per database.</span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <br /> We also aggregate read access rights of documents in their parent category entries to determine if a user can see at least one document below a category without needing to traverse all child entries (to implement the option "don't show empty categories" without degrading performance).</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> These aggregated readers stats can be read in code, offering insights into the distribution of read access rights across multiple databases.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Virtual Views do not need to be created on a per-user basis. The VirtualView object contains all data the server is allowed to see. To traverse the virtual view, we built our own VirtualViewNavigator, instantiated for a specific user and for the whole view or a single category:</span><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br /> <code>VirtualViewNavigator nav = view</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;.createViewNav()</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;.withCategories()</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;.withDocuments()</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;.withEffectiveUserName("CN=Karsten Lehmann/O=Mindoo")</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;.build();</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt;color:#008000"><br /> // &nbsp;other methods to build the navigator:</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br /> // &nbsp;.buildFromCategory("Abbott");</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt;color:#008000"><br /> // &nbsp;.buildFromDescendants(otherViewEntryInTheView);</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br /> nav.expandAll().collapse("1.1");</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br /> if (nav.gotoFirst()) {</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;do {</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; VirtualViewEntryData currentEntry = nav.getCurrentEntry();</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; String firstName = currentEntry.getAsString("firstname", "");</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; String lastName = currentEntry.getAsString("lastname", "");</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;}</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;while (nav.gotoNext());</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br /> }</code></span></tt><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> gotoPrev() and gotoNext() manage the expanded/collapsed entries. If you prefer a non-goto syntax, methods like entriesForward(), entriesBackward() and others return Java Streams:</span><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br /> <code>Stream<VirtualViewEntryData> stream = nav</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp;.entriesForward()</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp;.skip(3000)</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp; &nbsp; &nbsp;.limit(200);</span></tt><span style=" font-size:12pt"> <br /> </span><tt><span style=" font-size:10pt"><br /> stream</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br /> .forEach(((entry) -> {</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;String firstName = entry.getAsString("firstname","");</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br />  &nbsp; &nbsp;String lastName = entry.getAsString("firstname","");</span></tt><span style=" font-size:12pt"> </span><tt><span style=" font-size:10pt"><br /> }));</code></span></tt><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> The view index is currently stored in memory. We may add a feature to save indexes to disk for quick reloading after an HTTP task restart.</span><span style=" font-size:12pt"> <br /> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><br /> Conclusion</strong></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Here is the full feature list for the Virtual View API in its first version:</span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <ul><li>Multi-DB views</li><li>Works locally, client-server and server-server</li><li>View structure similar to Domino (multi-level categorization, sorted columns)</li><li>Support for sums/average values</li><li>Compute column values via formula or Java code</li><li>Option to place categories above or below documents in categorized views</li><li>Incremental view updates (no rebuild required)</li><li>Full control over when the view is updated, with optional read locks for exclusive access</li><li>Server-populated views, shared across users</li><li>User-specific view entry visibility checks (DB ACL level and usernames list for each DB compared with computed document readers list)</li><li>Aggregated readers stats for categories to quickly skip empty categories for users</li><li>Collected readers stats for analysis purposes</li><li>Several data providers combined to produce view data</li><li>Standard Domino data providers for data/profile/design docs</li><li>Custom non-Domino data support</li><li>VirtualViewNavigator for reading view entries visible to a user, with support for expanded/selected entries, upwards/downwards paging, keyword, and range lookups</li><li>Fast performance (e.g., processes 40,000 fake name docs and builds the view in 2-3 seconds)</li><li>VirtualView currently stored in Java heap (each VirtualViewEntry with a ConcurrentSkipListMap for sorted children), with potential future support for disk serialization</li><li>Not Domino-specific; works for other kinds of data</li></ul></span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> I hope you enjoy this new feature, try it out, and provide feedback!</span><span style=" font-size:12pt"> </span>  ]]></content:encoded>
  81. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/13.07.2024001044KLETZR.htm</wfw:commentRss>
  82. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/13.07.2024001044KLETZR.htm?opendocument&amp;comments</wfw:comment>
  83. </item>
  84. <item>
  85. <title>Overview of Domino Data Retrieval: Exploring NSF search, DQL, Domino Views and the QueryResultsProcessor</title>
  86. <pubDate>Sat, 13 Jul 2024 23:29:18 +0200</pubDate>
  87. <description>
  88. <![CDATA[
  89. As you read in the previous article "The pain of reading data as a Domino developer - and solutions", looking up data on Domino is not as easy as it seems - especially compared to other platforms like ...
  90. ]]>
  91. </description>
  92. <link>https://www.mindoo.com/web/blog.nsf/dx/13.07.2024000446KLETW2.htm</link>
  93. <category>Domino C API</category>
  94. <dc:creator>Karsten Lehmann</dc:creator>
  95. <comments>https://www.mindoo.com/web/blog.nsf/dx/13.07.2024000446KLETW2.htm?opendocument&amp;comments</comments>
  96. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/13.07.2024000446KLETW2.htm</guid>
  97. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">As you read in the previous article "<a href="https://www.mindoo.com/web/blog.nsf/dx/19.06.2024110207KLECLW.htm">The pain of reading data as a Domino developer - and solutions</a>", looking up data on Domino is not as easy as it seems - especially compared to other platforms like SQL. Let's explore the available options.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><br /> NSF search with formula</strong></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> For many years, formula language was the only universal search language on the platform. However, searching the database took time (method <code>lotus.domino.Database.search(String formula, DateTime dt, int max)</code>) since each document had to be scanned and processed by the formula. The result, a DocumentCollection, is said to have "no particular order," but this isn't entirely accurate. The underlying C data structure of the returned DocumentCollection is an IDTable containing note IDs. To store it efficiently, early Domino core developers decided to sort the note IDs in ascending order.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> For more on the storage format of IDTables, refer to this interesting knowledge base article:</span><span style=" font-size:12pt"> </span><span style=" font-size:12pt;color:blue"><span style="text-decoration:underline"><br /> </span></span><a href="https://support.hcltechsw.com/csm?id=kb_article&amp;sysparm_article=KB0026700"><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://support.hcltechsw.com/csm?id=kb_article&amp;sysparm_article=KB0026700</span></span></a><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> In data processing, the order in which documents are returned by the search call (NSFSearch in the C API) does not matter. You search the entire database and process it (one by one or quickly with one of the stamp methods). To improve performance, the NSFSearch call returns a TIMEDATE value that you can use for subsequent calls to fetch only documents created, changed, or deleted since the given time and whether they do or no longer match the selection formula.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Normal NSFSearch calls return the whole summary buffer for each matching document, which can contain a lot of irrelevant information. However, by using a special undocumented format for the compiled search formula (with merged column formulas), some undocumented flags, an undocumented item name ("$C1$"), and an undocumented NSFSearchExtended3 call, things get more interesting.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> With this method, the search operation only copies the summary buffer data you are interested in, speeding up the search. The item "$C1$" contains the document's readers list, showing who can view a document. If readers are present, it also includes the document's authors. This means there's no need to manually extract this data in your own code; the NSF search operation handles it.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Our open-source project, </span><a href="https://github.com/klehmann/domino-jna" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Domino JNA</span></a><span style=" font-size:10pt;font-family:sans-serif">, utilizes this powerful search method in the </span><a href="https://github.com/klehmann/domino-jna/blob/master/domino-jna/src/main/java/com/mindoo/domino/jna/NotesSearch.java#L372" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">com.mindoo.domino.jna.NotesSearch</span></a><span style=" font-size:10pt;font-family:sans-serif"> class, which is an excellent tool for syncing Domino data with external systems or building custom indexes.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> These undocumented flags, item and calls are the magic behind Domino views:</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><br /> Domino views </strong></span><span style=" font-size:12pt"><br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> End users typically want tabular data sorted by one or more columns, not data sorted by note ID. Domino views are designed for this purpose. They consist of a search formula to select relevant data and column information to visualize the data in a specific order.</span><span style=" font-size:12pt"> <br /> </span> <br /><img  alt="Image:Overview of Domino Data Retrieval: Exploring NSF search, DQL, Domino Views and the QueryResultsProcessor" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/13.07.2024000446KLETW2.htm/content/M2?OpenElement" /> <br /><span style=" font-size:10pt;font-family:sans-serif"><br /> Domino views provide multi-level categories for drilling down into data, which can be expanded/collapsed, and where sums and averages are aggregated (e.g., costs per team, costs per department, costs for a whole company). The view index represents a persistent and always up-to-date formula search result of one NSF database. Only one instance of a specific view index exists on the server. Since view entries contain readers information, the Notes Indexing Facility (NIF) skips rows that a user is not allowed to see by comparing their personal user names list with the allowed readers of a document.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> String comparison takes time, so if you have a database with 1 million documents and you can only see 10, traversing a view is not fast because 999,990 rows have to be skipped. Domino 14 includes optimizations for these edge cases, such as maintaining an IDTable per user with document note IDs they are allowed to see. This allows the NIF code to skip string comparison and just check if the IDTable contains the note ID. However, these optimizations are not enabled by default for all users.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Domino view columns can display document item content, values computed via formula language (e.g., Lastname + ", " + Firstname), or special values like child and descendant counts read from the view index itself.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> For more details on NIF, check out John Curtis's blog post:</span><span style=" font-size:12pt"> </span><span style=" font-size:12pt;color:blue"><span style="text-decoration:underline"><br /> </span></span><a href="https://jdcurtis.blog/2019/12/16/tdr-notes-indexing-facility"><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://jdcurtis.blog/2019/12/16/tdr-notes-indexing-facility</span></span></a><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><br /> Folders</strong></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Folders work like Domino views, but their content (note IDs) is not retrieved via formula search. Instead, it is added manually by the end user or the application developer. The main use case of a folder is to pick and bookmark documents for future analysis or processing.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><br /> Domino Query Language</strong></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Introduced in Domino 10, the Domino Query Language (DQL) provides a concise syntax for finding documents based on a wide variety of terms. It leverages existing design elements without requiring detailed code to access them.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Like formula language, DQL can filter documents from a single NSF and return an "unsorted" IDTable. Here is an example of DQL:</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <code>Order_origin in ('Detroit', 'Albuquerque', 'San Diego') and Date_origin >= @dt('2014-07-15') and Date_origin <@dt('2015-07-14â\x80\x99) and <br /> partno in all ( 389, 27883, 388388, 587992 ) and not in ('Special Processing', 'Special2' , 'Soon to be specialâ\x80\x99) and not sales_person in ('Christen Summer', 'Isaac Hart')</code> </span><span style=" font-size:12pt"><br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> DQL provides a more efficient way to perform searches compared to formula language. A query planner analyzes a DQL statement and finds the best strategy to quickly reduce the number of relevant documents, such as by doing view lookups or FT searches.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> A DQL search always returns the complete search result and does not support incremental searching. You can specify views, folders, or document collections to limit the results:</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <code>in ('TrudisDocs', â\x80\x98Ordersâ\x80\x99, â\x80\x99Special orders folder 1â\x80\x99, â\x80\x98Old_orders 2â\x80\x99)</code></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> For more DQL examples, visit: </span><span style=" font-size:12pt;color:blue"><span style="text-decoration:underline"><br /> </span></span><a href=https://help.hcltechsw.com/dom_designer/14.0.0/basic/dql_simple_examples.html><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://help.hcltechsw.com/dom_designer/14.0.0/basic/dql_simple_examples.html</span></span></a><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> As of Domino 14, a DQL search only covers data documents, not design documents.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> For more details on DQL, see this Admincamp presentation from HCL:</span><span style=" font-size:12pt"> </span><span style=" font-size:12pt;color:blue"><span style="text-decoration:underline"><br /> </span></span><a href="https://admincamp.de/konferenz/ent2019.nsf/bc36cf8d512621e0c1256f870073e627/6c2e835120d74a18c1258327003f8d83/$FILE/T3S4-Demo%20and%20Deep%20Dive%20-%20Domino%20General%20Query%20Facility%20.pdf"><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://admincamp.de/konferenz/ent2019.nsf/bc36cf8d512621e0c1256f870073e627/6c2e835120d74a18c1258327003f8d83/$FILE/T3S4-Demo%20and%20Deep%20Dive%20-%20Domino%20General%20Query%20Facility%20.pdf</span></span></a><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><br /> QueryResultsProcessor</strong></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Introduced in Domino 12, the QueryResultsProcessor processes a list of documents, reads selected values from the documents' summary buffer, and creates tabular data with sorted, categorized, or unsorted columns. The processing result can be returned in JSON format for web applications or materialized as a Domino view in any NSF as a QRP view.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Unlike standard Domino views, data from multiple NSFs can be combined in a single QueryResultsProcessor call. For JSON output, there is no paging support (skip/limit), and the result is recomputed on every call. The QRP view is created once and does not update its content, making it suitable for producing snapshots of Domino data at a point in time.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Since you can use the normal View APIs (e.g., the ViewNavigator), returning paged data is not difficult. However, the QRP view does not store any readers lists on the row level. The view contains the data that the user creating it was allowed to see. You can only restrict access on the view level, e.g., to hide financial data from normal employees.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> The primary purpose of QRP views is to produce a snapshot of Domino data at a point in time. They are more of a reporting tool than a good option for real-time queries, because you would need to build one QRP view for each user/user group and discard it as soon as the underlying data has changed, since there is no in-place index update.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> John Curtis has documented the QueryResultsProcessor in a series of blog articles:</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:12pt;color:blue"><span style="text-decoration:underline"><br /> </span></span><a href="https://jdcurtis.blog/2021/11/29/the-query-results-processor-part-one/"><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://jdcurtis.blog/2021/11/29/the-query-results-processor-part-one/</span></span></a><span style=" font-size:12pt"> <br /> </span><span style=" font-size:12pt;color:blue"><span style="text-decoration:underline"><br /> </span></span><a href="https://jdcurtis.blog/2021/11/30/the-query-results-processor-part-two/"><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://jdcurtis.blog/2021/11/30/the-query-results-processor-part-two/</span></span></a><span style=" font-size:12pt"> <br /> </span><span style=" font-size:12pt;color:blue"><span style="text-decoration:underline"><br /> </span></span><a href="https://jdcurtis.blog/2021/12/02/the-queryresultsprocessor-part-three/"><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://jdcurtis.blog/2021/12/02/the-queryresultsprocessor-part-three/</span></span></a><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Curtis mentioned plans for the future of the QueryResultsProcessor, including refreshable QRP views, joins/lookups across QRP input collections, and incorporating external data into QRP views. However, he retired at the end of 2022, and the QueryResultsProcessor API has since lost momentum.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><br /> What is missing?</strong></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> As described above, using NSFSearch, it is not difficult to mirror Domino data in real-time in other databases with more capable query languages like SQL, GraphQL, or Cypher (for the Graph DB fans). You can let Domino do all the work, including computing formula values and readers lists.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> In the past, we built web applications for customers where we pulled the content of 30 NSFs (one for each department) into the JVM heap (max heap set to 30 GB) on HTTP task startup. We used CQEngine (</span><a href=https://github.com/npgall/cqengine><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://github.com/npgall/cqengine</span></span></a><span style=" font-size:10pt;font-family:sans-serif">) to build indexes for the data, resulting in extremely fast REST APIs with dynamic filter and sorting options.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> However, these are custom solutions for each use case. Instead, there should be a standard way that fits many use cases and feels "Domino-like."</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <strong>Let's take the QueryResultsProcessor concept to another level! Let's reinvent the wheel one more time! :-)</strong></span><span style=" font-size:12pt"><strong> </strong><br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> In the <a href="https://www.mindoo.com/web/blog.nsf/dx/13.07.2024001044KLETZR.htm">next article</a>, I will introduce Domino JNA's new Virtual View API.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Stay tuned!</span>  ]]></content:encoded>
  98. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/13.07.2024000446KLETW2.htm</wfw:commentRss>
  99. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/13.07.2024000446KLETW2.htm?opendocument&amp;comments</wfw:comment>
  100. </item>
  101. <item>
  102. <title>The pain of reading data as a Domino developer - and solutions</title>
  103. <pubDate>Wed, 19 Jun 2024 11:02:08 +0200</pubDate>
  104. <description>
  105. <![CDATA[
  106. On my endless path of reinventing the wheel regarding Domino APIs, my latest adventure has once again led me to find efficient and powerful ways to query Domino data. For many years, this topic has b ...
  107. ]]>
  108. </description>
  109. <link>https://www.mindoo.com/web/blog.nsf/dx/19.06.2024110207KLECLW.htm</link>
  110. <category>Domino C API</category>
  111. <dc:creator>Karsten Lehmann</dc:creator>
  112. <comments>https://www.mindoo.com/web/blog.nsf/dx/19.06.2024110207KLECLW.htm?opendocument&amp;comments</comments>
  113. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/19.06.2024110207KLECLW.htm</guid>
  114. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">On my endless path of reinventing the wheel regarding Domino APIs, my latest adventure has once again led me to find efficient and powerful ways to query Domino data.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">For many years, this topic has been a pain point for me. Back in the IBM Design Partner program, I wrote many entries in the discussions database, asking IBM core development for better and faster ways to read Domino data.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">View traversal speed</span></strong></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">In the old days, according to Domino core developers, there was no priority for LotusScript or Java API methods to read data as fast as possible, "since most of the code was running at night in agents anyway" (that is what they told me).</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Things changed a bit when XPages were introduced in 2009. Core development began to tweak the codebase for performance, for example, to not just read one view row at a time in the ViewNavigator API, since the underlying C API call NIFReadEntries has never had this restriction. It has others; the return data buffer has a max size of 64K, but depending on the type of view data, this buffer can contain lots of rows. For example, if you just read note IDs (4 bytes each), one NIFReadEntries call returns about 16,000 rows at once.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">New API methods like ViewNavigator.setBufferMaxEntries(...) and ViewNavigator.setCacheGuidance(...) were the result. They sped up view traversal A LOT.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Unfortunately, Domino core development thought there was no need to ever write documentation for them. Check for yourself: Go into your Domino Designer help and try to find information about these methods, same with a Google search. At least you will find a few community blogs (like ours) that wrote about this topic and how to use these methods.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">This </span><a href=https://youtu.be/rTmxIZjeoJ8 target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">video</span></a><span style=" font-size:10pt;font-family:sans-serif"> on YouTube might also help.</span> <br /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">Data consistency</span></strong></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">In addition to faster view traversal, Domino core development also started working on ways to read view data more consistently and better handle concurrent data updates.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Compared to SQL databases or more modern NoSQL databases like CouchDB, Domino has always had poor data consistency. Although transaction support has existed in the Domino API since Domino 12, these transactions can only be used to modify multiple database documents atomically. They do not cover reading data from views.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">For example, if you want to read all view rows matching a lookup key using the publicly available C API methods, you would open the view (NIFOpenCollection), find the position of the first row matching the lookup key and determine the number of matches (NIFFindByKey, which returns a position like "1.2.3"), and start reading row data at that position (using one or more NIFReadEntries calls, depending on how much row data fits into the 64K buffer).</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">These are <span style="text-decoration:underline">three separate C API calls</span>. The view index that you are working on is NOT your private copy. So, if other users change data at the same time and the view indexer kicks in, things become challenging.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">To be fair, you receive signals from NIFReadEntries (e.g., SIGNAL_ANY_CONFLICT) indicating that the view index or view design has changed in the meantime. This means that your start position "1.2.3" might be completely wrong.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">If you know the note ID that your code read last in addition to its position, NIFLocateNote might be handy. It tries to find the new position of this row "nearby." However, it's possible that this exact document no longer matches the lookup key and has been moved somewhere else in the view.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Instead, you could re-run your lookup repeatedly until none of the NIFReadEntries calls signal a view index change.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">If only there were a way to prevent view index updates while lookups were running!</span> <br /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">NIFFindByKeyExtended2 to the rescue</span></strong></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The C API of Domino 12 exposed a new method, NIFFindByKeyExtended2, which had been added to Domino years earlier. NIFFindByKeyExtended2 combines NIFFindByKey and the first NIFReadEntries call in an atomic manner. This means that the view index is locked, ensuring data consistency, at least if you don't have more than 16,000 rows for the same lookup key, or significantly fewer rows if you are also reading the column values (e.g., in one of our applications, only 70 rows filled the entire 64K buffer).</span> <br /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">I am not a C developer! Do I have to care?</span></strong></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Life as a LotusScript or Java developer on Domino is easier than for C developers.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">You just call View.getAllDocumentsByKey(...) or View.getDocumentByKey(...), and the black magic happens under the covers. These methods have been using NIFFindByKeyExtended2 internally for many years, I think since R9 (or the undocumented NIFFindByKeyExtended3, which returns the result in a callback).</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">There is a small chance that the document in the returned DocumentCollection might have changed in the meantime and no longer matches the lookup key that produced the DocumentCollection. As a paranoid person, you could check this. But as soon as the document is loaded and concurrent updates to it happen, you get a save error and can decide in your code if you want to reload the document or create a save conflict.</span> <br /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">I use View.setAutoUpdate(false), does this help to get consistent view data?</span></strong></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">In short: no.</span> <br /><span style=" font-size:10pt;font-family:sans-serif">There is an old article in the Domino development wiki (</span><a href="https://ds-infolib.hcltechsw.com/ldd/ddwiki.nsf/dx/View.AutoUpdate_?OpenDocument&amp;sa=true"><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://ds-infolib.hcltechsw.com/ldd/ddwiki.nsf/dx/View.AutoUpdate_?OpenDocument&amp;sa=true</span></a><span style=" font-size:10pt;font-family:sans-serif">) which explains the AutoUpdate flag.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">It just changes the strategy how the API recovers in case of view index changes:</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">AutoUpdate=true means "use NIFLocateNote and go on reading at the new position".</span> <br /><span style=" font-size:10pt;font-family:sans-serif">AutoUpdate=false means "don't care, just go on reading at the current position"</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The same applies for LotusScript/Java as for C - you don't get a private copy of the view index.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">So things can change all the time and they sometimes shine through when using the LotusScript/Java API:<br /> <br /> NotesException: Notes error: Entry not found in index (Articles\Latest Issue)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; at lotus.domino.local.ViewNavigator.NgotoEntry(Native Method)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; at lotus.domino.local.ViewNavigator.gotoX(Unknown Source)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; at lotus.domino.local.ViewNavigator.gotoChild(Unknown Source)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; at lotus.domino.local.ViewNavigator.getChild(Unknown Source)</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">NotesException: Notes error: Entry not found in index (Articles\Quota Computation)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; at lotus.domino.local.ViewNavigator.NgotoEntry(Native Method)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; at lotus.domino.local.ViewNavigator.gotoX(Unknown Source)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; at lotus.domino.local.ViewNavigator.gotoNextSibling(Unknown Source)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; at lotus.domino.local.ViewNavigator.getNextSibling(Unknown Source)</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Here, the ViewNavigator is trying to change the cursor position and notices that the view index has changed in a way that it cannot recover.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">These are actual exceptions from production apps.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">By using setBufferMaxEntries() / setCacheGuidance(), these errors might happen less often, because the next children or sibling entries are already precached in the buffer.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">But the ViewNavigator precaching is only working with AutoUpdate=false and the cache is invalidated when you change navigation direction. When the ViewNavigator then runs out of cache entries, it does not care about view index changes and consistency.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Hooray.</span> <br /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">What about DQL? Does that help?</span></strong></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">In short: yes.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">When using DQL, it is HCL's responsibility to ensure data consistency during view lookups, FT searches, or NSF scans with a search formula. The DQL engine returns matches as an IDTable for C developers (compressed storage of note IDs), which the LotusScript/Java API translates into a DocumentCollection. This translation is slower because it unnecessarily loads each document even if you only need the note IDs.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">If you believe you have found an example of data inconsistency, create a reproducible test case and submit a support ticket.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">Cliffhanger :-)</span></strong></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">In the next article, I will discuss the new QueryResultsProcessor in Domino 12, covering its capabilities and limitations. I will also explain how I rebuilt cross-database Domino view indexing in Domino JNA from scratch, avoiding these limitations.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">So stay tuned.</span> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />  ]]></content:encoded>
  115. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/19.06.2024110207KLECLW.htm</wfw:commentRss>
  116. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/19.06.2024110207KLECLW.htm?opendocument&amp;comments</wfw:comment>
  117. </item>
  118. <item>
  119. <title>Configure Eclipse 4.6.x with HCL Notes 12.0.1 FP1</title>
  120. <pubDate>Fri, 18 Nov 2022 22:29:22 +0200</pubDate>
  121. <description>
  122. <![CDATA[
  123. Once again I had to ask HCL development for setup instructions how to launch the HCL Notes Standard Client from an Eclipse IDE, this time for Notes 12.0.1 FP1. The instructions I had gotten earlier f ...
  124. ]]>
  125. </description>
  126. <link>https://www.mindoo.com/web/blog.nsf/dx/18.11.2022222922KLET7X.htm</link>
  127. <category>Eclipse</category>
  128. <dc:creator>Karsten Lehmann</dc:creator>
  129. <comments>https://www.mindoo.com/web/blog.nsf/dx/18.11.2022222922KLET7X.htm?opendocument&amp;comments</comments>
  130. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/18.11.2022222922KLET7X.htm</guid>
  131. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">Once again I had to ask HCL development for setup instructions how to launch the HCL Notes Standard Client from an Eclipse IDE, this time for Notes 12.0.1 FP1.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The instructions I had gotten earlier for Notes 10 have not changed much (I think there's one additional VM argument at the end of the list), but enough so that they did not work anymore.</span> <br /><span style=" font-size:10pt;font-family:sans-serif"><br /> The document links to Eclipse Neon 4.6.3, but it's still working for me in later versions, I tried it with Eclipse 2020-09 (4.17.0, 64 bit).</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">I used my local installation directory in the text below (C:\Program Files (x86)\HCL\Notes) and the plugin version for com.ibm.rcp.base in Notes 12.0.1 FP1.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Of course these need to match your local environment.<br /> <br /> <strong><span style="text-decoration:underline"><br /> 1. Download Eclipse Neon (4.6.3) or later from link below:</span></strong></span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;color:blue"><span style="text-decoration:underline"><br /> </span></span><a href="http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/neon/3/eclipse-committers-neon-3-win32-x86_64.zip" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/neon/3/eclipse-committers-neon-3-win32-x86_64.zip</span></a><span style=" font-size:10pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> 2. Get HCL Notes 12.0.1 FP1</span></strong></span><span style=" font-size:10pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif">I used the instructions with the 32 bit Notes Client so far.</span> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> 3. Go to Windows => Preferences => Java => Installed JREs</span></strong></span><span style=" font-size:10pt"> </span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">Add => Standard VM =></span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">JRE home: <code>C:\Program Files (x86)\HCL\Notes\jvm</code></span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">JRE name: â\x80\x9cNotes JREâ\x80\x9d</span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Select the JRE to point to this and Apply</span></li></ul><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> 4. Go to Windows => Preferences => Plug-in Development => Target Platform</span></strong></span><span style=" font-size:10pt"> </span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">Add => default => Target Content</span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Name: â\x80\x9cNotes Targetâ\x80\x9d</span></li></ul><span style=" font-size:10pt;font-family:sans-serif"><br /> 4a. In Locations Tab:</span><span style=" font-size:10pt"> </span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">Add => Directory => Location => <code>C:\Program Files (x86)\HCL\Notes\framework\rcp\eclipse\plugins</code></span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Add => Directory => Location => <code>C:\Program Files (x86)\HCL\Notes\framework\shared\eclipse\plugins</code></span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Finish</span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Select the Target platform to point to â\x80\x9cNotes Targetâ\x80\x9d and Apply</span></li></ul> <br /><span style=" font-size:10pt;font-family:sans-serif">4 b. In Content Tab:</span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">go through the plugin list</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">for duplicate plugins, deactivate the older one</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">only relevant if you have installed a fixpack</span></li></ul><span style=" font-size:10pt;font-family:sans-serif"><br /> 4 c. In Environment Tab:</span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Please select following settings:</span><span style=" font-size:10pt"> </span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">Operating System: win32</span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Windowing System: win32</span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Architecture: x86</span><span style=" font-size:10pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Locale: en_US - English (United States)</span></li></ul><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> 5. Go to Windows => Preferences => Run/Debug => String Substitution</span></strong></span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> New => Add 2 strings (change plugin version and path based on your setup)</span><span style=" font-size:10pt"><br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> 5a. Name: rcp_home</span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Value: <code>C:\Program Files (x86)\HCL\Notes\framework</code><br /> <br /> 5b. Name: rcp_base</span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Value: <code>C:\Program Files (x86)\HCL\Notes\framework\rcp\eclipse\plugins\com.ibm.rcp.base_10.0.0.20211117-0921</code></span><span style=" font-size:10pt"><br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> OK</span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Close this Preferences Window</span><span style=" font-size:10pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> 6. Put the following file inside the below plugin:</span></strong></span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <code>C:\Program Files (x86)\HCL\Notes\framework\rcp\eclipse\plugins\com.ibm.rcp.base_10.0.0.20211117-0921</code></span><span style=" font-size:10pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <a href="https://www.mindoo.com/web/blog.nsf/dx/rcp.security.properties/$file/rcp.security.properties" target="_blank" title="rcp.security.properties">rcp.security.properties</a></span><span style=" font-size:10pt"> <br /> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> 7. Open Debug Configurations in the â\x80\x98Debug Perspectiveâ\x80\x99 => Eclipse Configuration => New</span></strong></span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> 7a. In the Main tab:</span><span style=" font-size:10pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Name: NotesDebug</span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Program to Run => &nbsp;Run a product => <code>com.ibm.notes.branding.notes</code><br /> Java Runtime Environment => Runtime JRE => Select â\x80\x9cNotes JREâ\x80\x9d i.e. the one we added in step 3</span><span style=" font-size:10pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> 7b. In the Arguments tab: </span><span style=" font-size:10pt"><br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Program Arguments:</span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <code>-clean -console -debug -log -personality com.ibm.rcp.platform.personality -config notes</code></span><span style=" font-size:10pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> VM Arguments:</span><span style=" font-size:10pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <code>-Xquickstart<br>-Xss384k<br>-Xshareclasses<br>-Drcp_home="${rcp_home}"<br>-Drcp.install.config=user<br>-Dosgi.install.area="${rcp_home}\eclipse"<br>-Disa.ignoreESR=true<br>-Dcom.ibm.pvc.osgiagent.core.logfileloc="${rcp_home}\rcp"<br>-Dcom.ibm.pvc.webcontainer.port=0<br>-Declipse.pluginCustomization="${rcp_home}\rcp\plugin_customization.ini"<br>-Djava.security.properties="${rcp_base}\rcp.security.properties"<br>-Declipse.registry.nulltoken=true<br>-Djava.protocol.handler.pkgs=com.ibm.net.ssl.www.protocol<br>-Djava.util.logging.config.class=com.ibm.rcp.core.internal.logger.boot.LoggerConfig<br>-Dosgi.hook.configurators.exclude=org.eclipse.core.runtime.internal.adaptor.EclipseLogHook<br>-Dosgi.framework.extensions=com.ibm.rcp.core.logger.frameworkhook,com.ibm.rds,com.ibm.cds<br>"-Xbootclasspath/a:${rcp_base}\rcpbootcp.jar"<br>-Xdump:system:events=user</code></span><span style=" font-size:10pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> 8. Apply => Debug â\x80\x93 This will launch your Notes in Debug mode. </span></strong><br /> Ensure that whenever you launch the Notes from Eclipse, there should be no other instance of Notes already running. If so, please close Notes and then launch from Eclipse to debug.</span>  ]]></content:encoded>
  132. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/18.11.2022222922KLET7X.htm</wfw:commentRss>
  133. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/18.11.2022222922KLET7X.htm?opendocument&amp;comments</wfw:comment>
  134. </item>
  135. <item>
  136. <title>New release of Open Eclipse Update Site to fix issues with Win/64 Notes Client 12.0.2</title>
  137. <pubDate>Thu, 17 Nov 2022 23:24:41 +0200</pubDate>
  138. <description>
  139. <![CDATA[
  140. As Jesse blogged there are some issues in the new Windows 64 Bit Notes Client 12.0.2 that break the "Import Local Update Site" functionality of the standard Update Site template of Domino. To fix thi ...
  141. ]]>
  142. </description>
  143. <link>https://www.mindoo.com/web/blog.nsf/dx/17.11.2022232441KLEUAH.htm</link>
  144. <category>DDE</category>
  145. <dc:creator>Karsten Lehmann</dc:creator>
  146. <comments>https://www.mindoo.com/web/blog.nsf/dx/17.11.2022232441KLEUAH.htm?opendocument&amp;comments</comments>
  147. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/17.11.2022232441KLEUAH.htm</guid>
  148. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">As </span><a href="https://frostillic.us/blog/posts/2022/11/17/notes-domino-12-0-2-fallout" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Jesse blogged</span></a><span style=" font-size:10pt;font-family:sans-serif"> there are some issues in the new Windows 64 Bit Notes Client 12.0.2 that break the "Import Local Update Site" functionality of the standard Update Site template of Domino.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">To fix this and other issues, I just uploaded a new release of the </span><a href="https://www.openntf.org/main.nsf/project.xsp?r=project/Open%20Eclipse%20Update%20Site/releases/8AC6CDB1EC752629862588FD007AA5F0" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Open Eclipse Update Site</span></a><span style=" font-size:10pt;font-family:sans-serif"> on OpenNTF.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Here is the fixlist:</span> <br /><span style=" font-size:12pt">&nbsp;</span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">This release fixes LS errors in the new Windows 12.0.2 64 Bit client that occur because LS tries to load SWT Java classes, but they do not seem to be available in the Windows 64 Bit client (same for Mac/64 which had already been fixed in earlier releases).</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">In addition we fixed feature deletion. You can now delete disabled features, not just enabled features like in 1.1.</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">"IBM" has been replaced with "HCL" in several areas to match the current R11 standard Update Site template of Domino.</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">broken links in the about/using this database pages have been fixed</span></li></ul>  ]]></content:encoded>
  149. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/17.11.2022232441KLEUAH.htm</wfw:commentRss>
  150. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/17.11.2022232441KLEUAH.htm?opendocument&amp;comments</wfw:comment>
  151. </item>
  152. <item>
  153. <title>Java class line numbers for plugin developers</title>
  154. <pubDate>Tue, 25 Oct 2022 10:32:42 +0200</pubDate>
  155. <description>
  156. <![CDATA[
  157. This is a shameless copy of Mikkel Heisterberg's blog article (https://lekkimworld.com/2010/04/14/java-class-line-numbers-for-plugin-developers/) to have this helpful information twice in the Google i ...
  158. ]]>
  159. </description>
  160. <link>https://www.mindoo.com/web/blog.nsf/dx/25.10.2022103242KLEC2H.htm</link>
  161. <category></category>
  162. <dc:creator>Karsten Lehmann</dc:creator>
  163. <comments>https://www.mindoo.com/web/blog.nsf/dx/25.10.2022103242KLEC2H.htm?opendocument&amp;comments</comments>
  164. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/25.10.2022103242KLEC2H.htm</guid>
  165. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">This is a shameless copy of Mikkel Heisterberg's blog article (</span><a href="https://lekkimworld.com/2010/04/14/java-class-line-numbers-for-plugin-developers/"><span style=" font-size:10pt;color:blue;font-family:sans-serif"><span style="text-decoration:underline">https://lekkimworld.com/2010/04/14/java-class-line-numbers-for-plugin-developers/</span></span></a><span style=" font-size:10pt;font-family:sans-serif">) to have this helpful information twice in the Google index and save me time when I need it in the future. :-)</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Hiding line numbers in stacktraces for performance reasons is pretty high on my top list of the most stupid ideas in Notes/Domino history.</span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <hr></span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> If youâ\x80\x99ve been tasked with developing and/or debugging Java extensions for the Notes 8 client you know that line numbers has been missing from the stacktraces produced by Notes. This can be a real problem when trying to debug stuff in a production client. There has been some discussion among the ones of us developing these extensions on how to enable these line numbers. The other day this information was provided by Srinivas Rao of IBM and I wanted to publish it here for all to read.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Line numbers are removed from the classes added to the shared class cache to reduce the memory needed for the memory mapped classes. To re-enable the line numbers, one needs to edit the <notes>frameworkrcpdeployjvm.properties file and add comment out the ignorelinenumbers vm argument. However, if the classes have already been added to the JVM shared class cache, then they will have been added without line numbers. Either comment out the shared class cache (which will dramatically affect performance at startup) for temporary work, or shutdown notes and remove the shared class cache so that it can be repopulated with classes with line numbers. Of course, this will also affect the startup performance, but not so much as not having a cache</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> These are two of the key lines â\x80¦ to comment them out, add a # to the front of the line</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <code>vmarg.Xnolinenumbers=-Xnolinenumbers</code></span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <code>vmarg.Dshare=-Xshareclasses:name=xpdplat_.jvm, **line cont**</code><br /> <code> &nbsp; controlDir=${prop.jvm.shareclasses.loc}, **line cont**</code><br /> <code> &nbsp; groupAccess,keep,singleJVM,nonfatal</code></span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> <code>jvm.shareclasses.loc=${rcp.data}/.config/org.eclipse.osgi</code></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> The shared class cache is typically located in the data/workspace/.config/org.eclipse.osgi</span><span style=" font-size:12pt"> </span>  ]]></content:encoded>
  166. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/25.10.2022103242KLEC2H.htm</wfw:commentRss>
  167. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/25.10.2022103242KLEC2H.htm?opendocument&amp;comments</wfw:comment>
  168. </item>
  169. <item>
  170. <title>Domino crashes with &quot;CheckTheProcesses&quot; message - explanation and workaround for dev environments</title>
  171. <pubDate>Wed, 13 Jul 2022 10:10:42 +0200</pubDate>
  172. <description>
  173. <![CDATA[
  174. Since Domino 8.5.3, there is a built-in facility that checks if all server processes are running. When the server detects that one has disappeared/crashed, the server triggers an NSD to document this ...
  175. ]]>
  176. </description>
  177. <link>https://www.mindoo.com/web/blog.nsf/dx/13.07.2022101042KLEBLS.htm</link>
  178. <category>Notesdev</category>
  179. <dc:creator>Karsten Lehmann</dc:creator>
  180. <comments>https://www.mindoo.com/web/blog.nsf/dx/13.07.2022101042KLEBLS.htm?opendocument&amp;comments</comments>
  181. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/13.07.2022101042KLEBLS.htm</guid>
  182. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">Since Domino 8.5.3, there is a built-in facility that checks if all server processes are running. When the server detects that one has disappeared/crashed, the server triggers an NSD to document this event and crashes/restarts.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">In general, this is a clean approach to keep the server in a consistent state.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">But when you develop Java applications against the Domino Server's Java API, those Java processes are treated as child processes and monitored as well</span> <br /><span style=" font-size:10pt;font-family:sans-serif">It's important to develop the applications in a clean way, so every Thread accessing Domino objects should be initialized with </span><tt><span style=" font-size:10pt">NotesThread.sinitThread()</span></tt><span style=" font-size:10pt;font-family:sans-serif"> and properly uninitialized with </span><tt><span style=" font-size:10pt">NotesThread.stermThread()</span></tt><span style=" font-size:10pt;font-family:sans-serif">.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">To ensure that this is also the case when errors occur in code, use try/finally:</span> <br /> <br /><tt><span style=" font-size:10pt">NotesThread.sinitThread();</span></tt> <br /><tt><span style=" font-size:10pt">Session session = null;</span></tt> <br /><tt><span style=" font-size:10pt">try {</span></tt> <br /><tt><span style=" font-size:10pt">&nbsp; &nbsp;session = NotesFactory.createSession();</span></tt> <br /><tt><span style=" font-size:10pt">&nbsp; &nbsp;// do something with the session object</span></tt> <br /><tt><span style=" font-size:10pt">}</span></tt> <br /><tt><span style=" font-size:10pt">catch (NotesException e) {</span></tt> <br /><tt><span style=" font-size:10pt">&nbsp; &nbsp;e.printStackTrace();</span></tt> <br /><tt><span style=" font-size:10pt">}</span></tt> <br /><tt><span style=" font-size:10pt">finally {</span></tt> <br /><tt><span style=" font-size:10pt">&nbsp; &nbsp;if (session!=null) {</span></tt> <br /><tt><span style=" font-size:10pt">&nbsp; &nbsp; &nbsp; try { session.recycle(); } catch (NotesException e) {e.printStackTrace();}</span></tt> <br /><tt><span style=" font-size:10pt">&nbsp; &nbsp;}</span></tt> <br /><tt><span style=" font-size:10pt">&nbsp; &nbsp;NotesThread.stermThread();</span></tt> <br /><tt><span style=" font-size:10pt">}</span></tt> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">This works in general, but often during development, you step through the code in debugger and just stop its execution, which produces this annoying result:</span> <br /> <br /><img  alt="Image:Domino crashes with &quot;CheckTheProcesses&quot; message - explanation and workaround for dev environments" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/13.07.2022101042KLEBLS.htm/content/M2?OpenElement" /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Fortunately it is possible disable the automatic Domino crash/restart with this Notes.ini variable:</span> <br /> <br /><tt><span style=" font-size:10pt">NO_TERM_EXIT_NO_PANIC=1</span></tt> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The server still complains about the missing child process, but keeps on running.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Of course, it would be even better if there was a way to exclude specific processes/process names from the monitoring.</span> <br />  ]]></content:encoded>
  183. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/13.07.2022101042KLEBLS.htm</wfw:commentRss>
  184. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/13.07.2022101042KLEBLS.htm?opendocument&amp;comments</wfw:comment>
  185. </item>
  186. <item>
  187. <title>Domino JNA version 0.9.48: API to read/write Notes workspace, some formula magic and QueryResultsProcessor API</title>
  188. <pubDate>Wed, 1 Jun 2022 00:43:40 +0200</pubDate>
  189. <description>
  190. <![CDATA[
  191. Today we released version 0.9.48 of Domino JNA as OSGi plugin for XPages developers and on Maven Central. Here is a list of new features: API to read and write the Notes workspace (read, create an ...
  192. ]]>
  193. </description>
  194. <link>https://www.mindoo.com/web/blog.nsf/dx/01.06.2022004339KLEUND.htm</link>
  195. <category>Domino C API</category>
  196. <dc:creator>Karsten Lehmann</dc:creator>
  197. <comments>https://www.mindoo.com/web/blog.nsf/dx/01.06.2022004339KLEUND.htm?opendocument&amp;comments</comments>
  198. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/01.06.2022004339KLEUND.htm</guid>
  199. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">Today we released version 0.9.48 of </span><a href="https://github.com/klehmann/domino-jna" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Domino JNA</span></a><span style=" font-size:10pt;font-family:sans-serif"> as OSGi plugin for XPages developers and on Maven Central.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Here is a list of new features:</span><span style=" font-size:12pt"> </span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">API to read and write the Notes workspace (read, create and modify pages and icons, change page order, move replicas on top etc.)</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Formula execution now supports more than 64k of return data</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">API to apply security to formula execution (e.g. prevent Notes.ini changes)</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">API for QueryResultsProcessor (produces JSON and views)</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Java 8 date/time support for NotesNote.replaceItemValue(...)</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">New utility class to format view data as markdown table</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Added method to get agent design doc UNID</span><span style=" font-size:12pt"> </span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Added hierarchical recycling (parent/child auto recycle)</span></li></ul><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> Notes Workspace API</span></strong></span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> The new Notes workspace API is pretty feature complete. It let's you read and modify the workspace content and contains functionality that I have long been waiting for in the Notes Client user interface like a method to change the order of tabs.</span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Actually I built this for my own purpose because I needed a tool to remove icons that no longer exist.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> To play with the API and as a sample for a standalone application using Domino JNA, I created a small Maven project that you can find here:</span><span style=" font-size:12pt"> </span><span style=" font-size:12pt;color:blue"><span style="text-decoration:underline"><br /> </span></span><a href="https://github.com/klehmann/domino-jna/tree/develop/workspace-demo"><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://github.com/klehmann/domino-jna/tree/develop/workspace-demo</span></a><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> The application creates a new workspace page:</span><span style=" font-size:12pt"> <br /> <br /> </span><img  alt="Image:Domino JNA version 0.9.48: API to read/write Notes workspace, some formula magic and QueryResultsProcessor API" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/01.06.2022004339KLEUND.htm/content/M2?OpenElement" /><span style=" font-size:12pt"><br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> and a database icon with a red rectangle:</span><span style=" font-size:12pt"><br /> <br /> </span><img  alt="Image:Domino JNA version 0.9.48: API to read/write Notes workspace, some formula magic and QueryResultsProcessor API" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/01.06.2022004339KLEUND.htm/content/M3?OpenElement" /><span style=" font-size:12pt"><br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> We support both the classic 32x32 pixel icons and the new 64x64 true color ones. By passing a NotesDatabase object to NotesWorkspace.addIcon(...), the current DB icon gets extracted from the NSF design and copied into the workspace.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Please make sure that the Notes Client is not running or in its early startup phase when you modify the workspace. Otherwise the changes will not be visible in the Notes UI and might later be overwritten.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> Formula magic</span></strong></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Classic formula execution is limited to 64K of return data. We found a way to remove this limit (e.g. to use @DbColumn to read the whole column of a view) and you can even run formulas in a restricted environment, e.g. to prevent them from changing the Notes.ini or setting document items.</span><span style=" font-size:12pt"> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> Methods have been added to analyze a formula in order to see if it's time variant, just contains a field name or uses special functions like @DocSiblings or @DocDescendants.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline"><br /> QueryResultsProcessor API</span></strong></span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> The </span><a href="https://jdcurtis.blog/2021/11/29/the-query-results-processor-part-one/" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">QueryResultsProcessor</span></a><span style=" font-size:10pt;font-family:sans-serif"> lets you build views across NSF boundaries, have them displayed in the Notes Client or exported in JSON format as string.</span><span style=" font-size:12pt"> <br /> </span><span style=" font-size:10pt;font-family:sans-serif"><br /> In contrast to the implementation in the legacy Notes.jar and LotusScript API, we provide methods to get the JSON result back in a streaming way so that it can be parsed without storing the whole content in the Java heap.</span><span style=" font-size:12pt"> <br /> </span>  ]]></content:encoded>
  200. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/01.06.2022004339KLEUND.htm</wfw:commentRss>
  201. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/01.06.2022004339KLEUND.htm?opendocument&amp;comments</wfw:comment>
  202. </item>
  203. <item>
  204. <title>Chad Schelfhout&#8217;s toolbar code to change document properties</title>
  205. <pubDate>Tue, 26 Apr 2022 11:10:22 +0200</pubDate>
  206. <description>
  207. <![CDATA[
  208. I just noticed that Chad Schelfhout's website is no longer available, that contained formula code for a toolbar icon to read/edit document properties. So here it is to not get lost - the latest versio ...
  209. ]]>
  210. </description>
  211. <link>https://www.mindoo.com/web/blog.nsf/dx/26.04.2022111021KLECS3.htm</link>
  212. <category></category>
  213. <dc:creator>Karsten Lehmann</dc:creator>
  214. <comments>https://www.mindoo.com/web/blog.nsf/dx/26.04.2022111021KLECS3.htm?opendocument&amp;comments</comments>
  215. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/26.04.2022111021KLECS3.htm</guid>
  216. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">I just noticed that Chad Schelfhout's website is no longer available, that contained formula code for a toolbar icon to read/edit document properties.</span> <br /><span style=" font-size:10pt;font-family:sans-serif">So here it is to not get lost - the latest version I have.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Please note that the Notes Client 12 contains Panagenda's Advanced Properties Box plugin to read and compare document properties.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">And Daniel Nashed describes how to get an extended version of the plugin that supports editing as well:</span> <br /><a href="https://blog.nashcom.de/nashcomblog.nsf/dx/advanced-document-properties-including-edit.htm" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://blog.nashcom.de/nashcomblog.nsf/dx/advanced-document-properties-including-edit.htm</span></a> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">So the code below is probably only relevant anymore for older Notes Client installs or the Basic Client.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Edit Document Fields 6.0.0 by Chad Schelfhout.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Visit </span><a href=http://www.chadsmiley.com/EditDocumentFields><span style=" font-size:10pt;color:blue;font-family:sans-serif">http://www.chadsmiley.com/EditDocumentFields</span></a><span style=" font-size:10pt;font-family:sans-serif"> for the latest updates};</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Changable constants};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cEnableConfirmation := @True;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cFieldHistoryValues := 10;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cStandardSeparators := ":" : ";" : " ";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cPromptTitle :@DbTitle + " - " + @ViewTitle;</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Unchangable constants};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cProfileName :"ChadSmiley Tools";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cEditLastField := "edfLastField";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cEditLastFieldDataType := "edfLastFieldDataType";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cEditLastFieldDataTypeValue := "edfLastFieldDataTypeValue";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cEditLastSeparator := "%~%";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cValueListSeparator := "^";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cFromRawValueSeparator := "%@%";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cSemicolonReplace := "#SC#";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cMaxSearchForSelectedDocs := 5520;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cMaxUpdatedDocuments := 1000;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cArraySeparator := ";";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cNoteEntryLength := 11;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cPromptNewLineOne := @Char(13);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cPromptNewLineTwo := cPromptNewLineOne + cPromptNewLineOne;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cPromptTab :@Char(9);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cCategoryNoteID := "NT00000000";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cTextExtractList := "Text Left":"Text Left Back":"Text Right":"Text Right Back";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cNoPromptList := cTextExtractList:"Remove Field":"Unique":"Sort Ascending":"Sort Descending":"Implode":"Explode":"Proper Case Text":"Proper Case Text Multi Value":"Lower Case Text":"Lower Case Text Multi Value":"Upper Case Text":"Upper Case Text Multi Value":"Password Convert":"Trim":"Trim then Unique";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cErrorCheckCode := "@Implode( @Unique( @Explode( NoteIDList : ErrorNoteID ; cArraySeparator ; @False ) ) )";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">cErrorInformation := "\"Error documents: \" + @Implode( @Unique( @Explode( ErrorNoteIDList ; cArraySeparator ; @False ) ) ; \", \" ) + cPromptNewLineOne + \"Not updated documents: \" + @Implode( @Unique( @Explode( ErrorNoteIDList ; cArraySeparator ; @False ) ) ; \", \" )";</span> <br /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Data types|@Function execution};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">DataTypesCombo := @Explode(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Integer|@TextToNumber( RawValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Integer Multi Value|@TextToNumber( @Explode( RawValue ; Separator; @True) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Date|@ToTime( RawValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Date Multi Value|@ToTime( @Explode( RawValue ; Separator; @True) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Text|@Text( RawValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Text Multi Value|@Text( @Explode( RawValue ; Separator; @True) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Text Left|@Left( @Text( @GetField( EditField&#91;ef&#93; ) ) ; ExtractValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Text Left Back|@LeftBack( @Text( @GetField( EditField&#91;ef&#93; ) ) ; ExtractValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Text Right|@Right( @Text( @GetField( EditField&#91;ef&#93; ) ) ; ExtractValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Text Right Back|@RightBack( @Text( @GetField( EditField&#91;ef&#93; ) ) ; ExtractValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Trim|@Trim( @Text( @GetField( EditField&#91;ef&#93; ) ) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Trim then Unique|@Unique(@Trim( @Text( @GetField( EditField&#91;ef&#93; ) ) ) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Name|RawValue$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Name Multi Value|RawValue$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Common Name|@Name( &#91;CN&#93;; RawValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Common Name Multi Value|@Name( &#91;CN&#93;; @Explode( RawValue ; \":\"; @True ) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Upper Case Text|@UpperCase( @Implode( @Text( @GetField( EditField&#91;ef&#93; ) ) ) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Lower Case Text|@LowerCase( @Implode( @Text( @GetField( EditField&#91;ef&#93; ) ) ) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Proper Case Text|@ProperCase( @Implode( @Text( @GetField( EditField&#91;ef&#93; ) ) ) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Upper Case Text Multi Value|@UpperCase( @Explode( @Text( @GetField( EditField&#91;ef&#93; ) ) ; Separator; @True ))$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Lower Case Text Multi Value|@LowerCase( @Explode( @Text( @GetField( EditField&#91;ef&#93; ) ) ; Separator; @True) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Proper Case Text Multi Value|@ProperCase( @Explode( @Text( @GetField( EditField&#91;ef&#93; ) ) ; Separator; @True) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Replace Substring|@ReplaceSubstring( @GetField( EditField&#91;ef&#93; ); FromRawValue ; RawValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Replace|@Explode( @Replace( @GetField( EditField&#91;ef&#93; ) ; FromRawValue ; RawValue ) ; Separator ; @True )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Implode|@Implode( @Text( @GetField( EditField&#91;ef&#93; ) ) ; Separator )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Explode|@Explode( @Text( @GetField( EditField&#91;ef&#93; ) ) ; Separator; @True )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Formula|@Eval( RawValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Abbreviate Name|@Name(&#91;Abbreviate&#93;; RawValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Abbreviate Name Multi Value|@Name( &#91;Abbreviate&#93;; @Explode( RawValue ; Separator; @True ) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Password Set|@Password( RawValue )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Password Convert|@Password( @GetField( EditField&#91;ef&#93; ) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Remove Field|@DeleteField$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Unique|@Unique(@GetField( EditField&#91;ef&#93;))$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"+ Append Values|@If(" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; @GetField(EditField&#91;ef&#93;) = \"\"; RawValue;" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; @Contains(DefaultDataType; \"Date\");" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; &nbsp;@If( @IsError( @ToTime( RawValue ) ) ;" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; &nbsp; \"\" ;" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; &nbsp; @SetField( EditField&#91;ef&#93; ; @GetField(EditField&#91;ef&#93;) : @TextToTime( @Explode( RawValue ; Separator ) ) ) ) ;" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; @Contains(DefaultDataType; \"Integer\" );" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; &nbsp;@If( @IsError( @TextToNumber( @Explode( RawValue ; Separator ) ) ) ;" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; &nbsp; \"\" ;" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; &nbsp; @SetField( EditField&#91;ef&#93; ; @GetField(EditField&#91;ef&#93;) : @TextToNumber( @Explode( RawValue ; Separator ) ) ) ) ;" +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">" &nbsp; &nbsp; @SetField( EditField&#91;ef&#93; ; @GetField(EditField&#91;ef&#93;) : @Explode( RawValue ; Separator ) ) )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Sort Ascending|@Sort(@GetField(EditField&#91;ef&#93;) ; &#91;Ascending&#93; )$"+</span> <br /><span style=" font-size:10pt;font-family:sans-serif">"Sort Descending|@Sort(@GetField(EditField&#91;ef&#93;); &#91;Descending&#93;)" ; "$" );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">DataTypes := @Word( DataTypesCombo ; "|" ; 1 );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">DataTypesAction := @Word( DataTypesCombo ; "|" ; 2 );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Get a listing of all the fields on the current document};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">List := @Sort( @DocFields );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Look for last field modified in Profile Doc};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FieldList := @Explode( @GetProfileField( cProfileName ; cEditLastField ; @UserName ) ; cArraySeparator ; @True ) ;</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Get the list of forms and field that was updated using Edit Document Fields};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FieldListForms := @Word( FieldList ; cEditLastSeparator ; 1 );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FieldListField := @Word( FieldList ; cEditLastSeparator ; 2 );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FieldListLastIndex := @Member( Form; FieldListForms );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {If the FieldListLastIndex is greater than zero then set the last field to the what was in the profile document};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@If( FieldListLastIndex > 0;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Do( LastField := FieldListField&#91; FieldListLastIndex &#93;;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; FieldList := @ReplaceSubstring( FieldList ; FieldList&#91; FieldListLastIndex &#93; ; "" ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;LastField :="" );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Prompt for which field needs to be updated. Loop until a field is selected or 'Cancel' is selected};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@DoWhile(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;EditField := @Prompt( &#91;OkCancelEditCombo&#93; ; cPromptTitle ; "Select the field you wish to alter or enter a new field to add:" ; LastField ; @Trim( @Unique( List : LastField ) ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;EditField = "" );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">EditFieldPromptTitle := "Change '" + EditField + "' in " + cPromptTitle;</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {This will allow the retrieval of the data type of the field that was last selected. Data is stored like Form+Field%~%DataType.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FormFieldList := @Explode( @GetProfileField( cProfileName ; cEditLastFieldDataType ; @UserName ) ; cArraySeparator ; @True ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FormFieldListFormField := @Word( FormFieldList ; cEditLastSeparator ; 1 );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FormFieldListDataType := @Word( FormFieldList ; cEditLastSeparator ; 2 );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FormFieldListFormulaCode := @ReplaceSubstring( @Word( FormFieldList ; cEditLastSeparator ; 3 ) ; cSemicolonReplace ; ";" );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FormFieldListIndex := @Member( Form + EditField; FormFieldListFormField );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@If( FormFieldListIndex > 0;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Do( DefaultDataType := FormFieldListDataType&#91; FormFieldListIndex &#93;;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; FormFieldListFormulaCode := FormFieldListFormulaCode&#91; FormFieldListIndex &#93;;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; FormFieldList := @ReplaceSubstring( FormFieldList ; FormFieldList&#91; FormFieldListIndex &#93; ; "" ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;DefaultDataType :="" );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {If there was no data type used for the field on the form the try to determine the data type};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">DefaultDataType :=</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@If( DefaultDataType != "" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; DefaultDataType ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @If(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;@IsNumber( @GetField( EditField ) ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; @If( @Count( @GetField( EditField ) ) > 1 ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;"Integer Multi Value" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;"Integer" ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;@IsTime( @GetField( EditField ) ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; @If( @Count( @GetField( EditField ) ) > 1 ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;"Date Mult iValue" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;"Date" ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;@If( @Count( @GetField( EditField ) ) > 1 ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;"Text Multi Value" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;"Text" )</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;);</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {If the data type is a type of error then select the data type of text};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">DefaultDataType := @IfError( DefaultDataType ; "Text" );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Prompt for which data type you would like the data to be. This needs to be done before value prompt to determine if the Picklist or any prompting needs to be used.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">DataType := @Prompt( &#91;OkCancelList&#93; ; EditFieldPromptTitle; "Please select the correct data type or action for field: " + EditField + "."; DefaultDataType ; DataTypes );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {The DataTypeAction will contain the formula that will be executed to retrieve the new value};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">DataTypeAction := DataTypesAction&#91; @Member( DataType ; DataTypes ) &#93;;</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {If formula was used on this field then use that instead of the fields value. Format the original value as text because the @Prompt command requires text.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">OriginalValue := @If( DataType = "Formula" &amp; DefaultDataType = "Formula" &amp; FormFieldListFormulaCode != "" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;FormFieldListFormulaCode ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@If( @Contains( DefaultDataType ; MultiValue ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @Implode( @Text( @GetField( EditField ) ) ; cArraySeparator );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @Text( @GetField( EditField ) ) )</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;);</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {This will allow the retrieval of history of values of the field. Data is stored like Form+Field+DataType%~%ValueList.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FormFieldListDataTypeValues := @Explode( @GetProfileField( cProfileName ; cEditLastFieldDataTypeValue ; @UserName ) ; cArraySeparator ; @True ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FormFieldListFormFieldDataType := @Word( FormFieldListDataTypeValues ; cEditLastSeparator ; 1 ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FormFieldListValuesLists := @Word( FormFieldListDataTypeValues ; cEditLastSeparator ; 2 ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">FormFieldListDTIndex := @Member( Form + EditField + DataType; FormFieldListFormFieldDataType );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@If( FormFieldListDTIndex > 0;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Do( FormFieldListValuesList := FormFieldListDataTypeValues&#91; FormFieldListDTIndex &#93;;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; FormFieldListValuesList := @ReplaceSubstring( @Trim( @Explode( FormFieldListValuesLists&#91; FormFieldListDTIndex &#93; ; cValueListSeparator ; @False ) ) ; cSemicolonReplace; ";" );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; FormFieldListDataTypeValues := @ReplaceSubstring( FormFieldListDataTypeValues ; FormFieldListDataTypeValues&#91; FormFieldListDTIndex &#93; ; "" ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;FormFieldListValuesList :="" );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Prompt for additional fields and determine the string that they are searching for.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@If( DataType = ("Replace Substring":"Replace" ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Do( EditField := @Unique( EditField : @Prompt( &#91;OkCancelListMult&#93; ; cPromptTitle ; "Select any addtional fields you wish to alter:" ; EditField ; List ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; FromRawValue := @Prompt( &#91;OkCancelEditCombo&#93; ; EditFieldPromptTitle ; "Enter or select the text (case sensitive) to search for in: " + @Implode( EditField ; ", " ) + "." ; "" ; @Unique( @Word( FormFieldListValuesList ; cFromRawValueSeparator ; 2 ) ) ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Do( EditField := EditField;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; FromRawValue := "" )</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;);</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM { With the Edit combo there will be a list of standard seperators to choose from.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">Separator := @If( DataType = ("Implode":"Explode" ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Prompt( &#91;OkCancelEditCombo&#93; ; cPromptTitle ; "Enter or select the " + @If( DataType = "Implode" ; "separator" ; "separators" ) + ":" &nbsp;; "" ; @Unique( @If( FormFieldListValuesList = "" ; cStandardSeparators &nbsp;; &nbsp;FormFieldListValuesList : cStandardSeparators ) ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;cArraySeparator );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Determine the string to search for};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">ExtractValue :@If( DataType = cTextExtractList ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Prompt( &#91;OkCancelEditCombo&#93; ; cPromptTitle ; "Enter or select the search string or string length:" ; @Subset( FormFieldListValuesList ; 1 ) ; @Unique( FormFieldListValuesList ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;"" );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Based on what type of data is being entered different prompts will happen if any at all.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">RawValue := @If(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Contains( DataType ; "Name Multi Value" ) ; @PickList( &#91;Name&#93; );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Contains( DataType ; "Name" ) ; @PickList( &#91;Name&#93; : &#91;Single&#93; );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;DataType = ( cNoPromptList ) ; "" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Contains( DataType ; "Multi Value" ) ; @Prompt( &#91;OkCancelEditCombo&#93; ; EditFieldPromptTitle; "Enter or select the new desired value for: " + @Implode( EditField ; ", " ) + "." + cPromptNewLineTwo + "Seperated with ; for each value." ; OriginalValue ; @Unique( OriginalValue : FormFieldListValuesList ) ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Contains( DataType ; "+ Append Values" ) ; @Prompt( &#91;OkCancelEditCombo&#93; ; EditFieldPromptTitle; "Enter or select values to append: " + @Implode( EditField ; ", " ) + "." + cPromptNewLineTwo + "Seperated with ; for each value." ; "" ; @Unique( FormFieldListValuesList ) ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;DataType = ("Replace Substring":"Replace" ) ; @Prompt( &#91;OkCancelEditCombo&#93; ; EditFieldPromptTitle ; "Enter or select the text to repalce with in: " + EditField + "." ; "" ; @Unique( @Word( FormFieldListValuesList ; cFromRawValueSeparator ; 1 ) ) ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;DataType = "Formula" ; @Do( @DoWhile(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; OriginalValue := @Prompt( &#91;OkCancelEditCombo&#93; ; EditFieldPromptTitle ; "Enter or select the new desired formula for: " + EditField + "." ; OriginalValue ; @Unique( OriginalValue : FormFieldListValuesList ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; tempReturnCheck := @CheckFormulaSyntax( OriginalValue );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @If( tempReturnCheck != "1"; @Prompt( &#91;Ok&#93; ; "Invalid Formula - " + EditFieldPromptTitle ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;"Invalid Formula entered: " +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;cPromptNewLineTwo + cPromptTab + "Error: " + cPromptTab + cPromptTab + @Text( tempReturnCheck ) +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;cPromptNewLineOne + cPromptTab + "Formula: " + cPromptTab + &nbsp;cPromptTab + OriginalValue ) ; "" );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;tempReturnCheck != "1" );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;OriginalValue );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Prompt( &#91;OkCancelEditCombo&#93; ; EditFieldPromptTitle ; "Enter or select the new desired value for: " + EditField + "." ; OriginalValue &nbsp;; @Unique( OriginalValue : FormFieldListValuesList ) )</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;);</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Store Field in Profile doc};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@SetProfileField( cProfileName ; cEditLastField ; @Unique( @Trim( FieldList : ( Form + cEditLastSeparator + EditField&#91;1&#93; ) ) ); @UserName );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Store Data Type of Field in Profile doc};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@SetProfileField( cProfileName ; cEditLastFieldDataType ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Unique( @Trim( FormFieldList : ( Form + EditField&#91;1&#93; + cEditLastSeparator + DataType + cEditLastSeparator +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @ReplaceSubstring(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;@If( DataType = "Formula" ; RawValue ; FormFieldListFormulaCode ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;";" ; cSemicolonReplace ) ) ) ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@UserName );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Store Data Value of Field in Profile doc};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@SetProfileField( cProfileName ; cEditLastFieldDataTypeValue ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Unique( @Trim( FormFieldListDataTypeValues : ( Form + EditField&#91;1&#93; + DataType + cEditLastSeparator +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @Implode(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;@Subset(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; @Unique(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; @ReplaceSubstring(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;@If( DataType = ("Implode":"Explode" ) ; Separator ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; DataType = cTextExtractList ; ExtractValue ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; DataType = ( "Replace Substring":"Replace" ) ; RawValue + cFromRawValueSeparator + FromRawValue ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; RawValue ) : FormFieldListValuesList &nbsp;;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;";" ; cSemicolonReplace ) ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; cFieldHistoryValues );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;cValueListSeparator ) ) ) ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@UserName );REM {If multi docs selected, only process those checked ... an unchecked doc cannot be NavNextSelected};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@Command(&#91;NavNextSelected&#93;);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@UpdateFormulaContext;</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Store all Note IDs before manipulation in case field modifications cause categorized views or sorted columns to reorganize};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">NoteIDList :@Text( @NoteID );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">ErrorNoteIDList := "";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@Command(&#91;NavNextSelected&#93;);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@UpdateFormulaContext;</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Start Looping Selected documents to gather all the documents that need to be updated.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@While( ( @Left( NoteIDList ; cNoteEntryLength ) != ( @Text( @NoteID + cArraySeparator ) ) ) &amp; ( @Length( NoteIDList ) < cMaxSearchForSelectedDocs ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;NoteIDList := NoteIDList + cArraySeparator + @Text( @NoteID );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;NoteIDList := @ReplaceSubstring( NoteIDList ; cCategoryNoteID + cArraySeparator ; "" );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Command(&#91;NavNextSelected&#93;);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@UpdateFormulaContext</span> <br /><span style=" font-size:10pt;font-family:sans-serif">);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Remove all category Note IDs};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">NoteIDList :@ReplaceSubstring( NoteIDList ; cCategoryNoteID ; "" );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Remove all duplicate Note IDs};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">NoteIDList :@Unique( @Explode( NoteIDList ; cArraySeparator ; @False ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@StatusBar( "Found " + @Text( @Elements( NoteIDList ) ) + " documents." );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">NotNoteIDList := "";</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Determine if the document should be updated.};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">tmpPrompt := @Implode( "The following information will be used to update the " + @Text( @Elements( NoteIDList ) ) + " document" + @If( @Elements( NoteIDList ) > 1 ; "s" ; "" ) + "." + cPromptTab + cPromptTab +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;cPromptNewLineTwo + cPromptTab + "Field:" + cPromptTab + cPromptTab + EditField +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;cPromptNewLineOne + cPromptTab + "Data type/action: " + cPromptTab + DataType +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;cPromptNewLineOne + cPromptTab +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @If( &nbsp;DataType = ("Implode":"Explode" ) ; "Separator: &nbsp;" + cPromptTab + Separator ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; DataType = ("Text Left":"Text Left Back":"Text Right":"Text Right Back" ) ; "Search string: &nbsp;" + cPromptTab + ExtractValue ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; DataType = ("Replace Substring":"Replace" ) ; "Search string: &nbsp;" + cPromptTab + FromRawValue + cPromptNewLineOne + cPromptTab + "Replace string: &nbsp;" + cPromptTab + RawValue ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; DataType = cNoPromptList;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; "" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; "Value: &nbsp;" + cPromptTab + cPromptTab + @Text( RawValue ) ) +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;cPromptNewLineTwo + "Would you like to continue?" );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@If( cEnableConfirmation ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Do(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;@StatusBar( @Explode( tmpPrompt ; cPromptNewLineOne ; @True ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @If( @Prompt( &#91;YesNo&#93;; EditFieldPromptTitle ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;tmpPrompt );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;"" ; @Return ( "" ) ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;"" );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">REM {Loop through selected docs taking each NoteIDList out of the list as it is processed};</span> <br /><span style=" font-size:10pt;font-family:sans-serif">DocUpdateCount := 0;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">DocNavigationCount := 0;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@While( DocUpdateCount < @Elements( NoteIDList ) ;</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@If( @TextToNumber( @Text( @DocumentUniqueID ) ) != 0 ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @Do(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;NoteIDList := @Replace( NoteIDList ; @NoteID ; "" ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;NotNoteIDList := NotNoteIDList : @NoteID;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;@For( ef := 1; ef <= @Elements( EditField ); ef := ef + 1;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; formulaResult := @Eval( DataTypeAction );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">REMark := " **REM** The values entered above will be applied to all selected doc. If data conversion doesn't work then don't set field.";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; @If( @IsError( formulaResult );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;@Do(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; tmpPrompt := "Error with NoteID of " + @NoteID + ". Continue?" + cPromptTab +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; cPromptNewLineOne + cPromptTab + "Error: " + cPromptTab + cPromptTab + @Text( FormulaResult ) +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; cPromptNewLineOne + cPromptTab + "Formula: " + cPromptTab + &nbsp;cPromptTab + DataTypeAction +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; cPromptNewLineOne + cPromptTab + @If( @Contains( DataTypeAction ; "EditField&#91;ef&#93;" ) ; "EditField&#91;ef&#93;:" ; "Field:" + cPromptTab ) + cPromptTab + EditField&#91;ef&#93; +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; cPromptNewLineOne + cPromptTab + "Data type/action: " + cPromptTab + DataType +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; cPromptNewLineOne + cPromptTab +</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; @If( &nbsp;DataType = ("Replace Substring":"Replace" ) ; "FromRawValue: &nbsp;" + cPromptTab + @Text( FromRawValue )+ cPromptNewLineOne + cPromptTab + "RawValue: &nbsp;" + cPromptTab + @Text( RawValue ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; DataType = cNoPromptList;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; "" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; "RawValue: &nbsp;" + cPromptTab + @Text( RawValue ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;@StatusBar( @Explode( tmpPrompt ; cPromptNewLineOne ; @True ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;@If( @Prompt( &#91;YesNo&#93; ;"Error - " + EditFieldPromptTitle ; tmpPrompt ) ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;ErrorNoteIDList := ErrorNoteIDList+ cArraySeparator + @Text( @NoteID );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; @Return( @If( @Eval( cErrorCheckCode ) != "" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;@StatusBar( @Explode( @Eval( cErrorInformation ) ; cPromptNewLineOne ; @True ) ):</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;@Prompt( &#91;Ok&#93; ; "Unable to Update - " + EditFieldPromptTitle ; @Eval( cErrorInformation ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; "" ) ) ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; @SetField( EditField&#91;ef&#93; ; formulaResult )</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; )</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;@If( DocNavigationCount > cMaxUpdatedDocuments ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;NoteIDList := "";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; @Do(</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;DocUpdateCount := DocUpdateCount + 1;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;@Command(&#91;NavNextSelected&#93;);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;@UpdateFormulaContext;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">REMark := " **REM** If we haven't processed all docs yet but the current doc is not in the NoteIDList list, keep looping ... if cnt exceeds MaxUpdatedDocuments assume infinite loop and stop ";</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;@If( DocUpdateCount < @Elements( NoteIDList ) &amp; ( !@Member( @NoteID ; NoteIDList ) ) &amp; ( !@Member( @NoteID ; NotNoteIDList) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; @While( (! @Member( @NoteID ; NoteIDList ) &amp; DocNavigationCount < cMaxUpdatedDocuments );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;@Command(&#91;NavNextSelected&#93;);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;@UpdateFormulaContext;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;DocNavigationCount := DocNavigationCount + 1);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; &nbsp;"")</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp; )</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; &nbsp;)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Do( @Command(&#91;NavNextSelected&#93;);</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp; @UpdateFormulaContext )</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;)</span> <br /><span style=" font-size:10pt;font-family:sans-serif">);</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">@If( @Implode( @Unique( @Explode( NoteIDList : ErrorNoteIDList ; cArraySeparator ; @False ) ) ) != "" ;</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@StatusBar( @Explode( @Eval( cErrorInformation ) ; cPromptNewLineOne ; @True ) ):</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;@Prompt( &#91;Ok&#93; ; "Unable to Update - " + EditFieldPromptTitle ; @Eval( cErrorInformation ) );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">&nbsp;"" );</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">@StatusBar( "Navigated through " + @Text( DocUpdateCount + DocNavigationCount ) + " documents." );</span> <br /><span style=" font-size:10pt;font-family:sans-serif">@StatusBar( "Performed '" + DataType + "' for '" + @Implode( EditField ; ", " ) + "' field" + @If( @Elements( EditField ) > 1; "s " ; " " ) + "on " + @Text( DocUpdateCount ) + " document" + @If( DocUpdateCount > 1 ; "s" ; "" ) + "." )</span> <br /> <br />  ]]></content:encoded>
  217. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/26.04.2022111021KLECS3.htm</wfw:commentRss>
  218. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/26.04.2022111021KLECS3.htm?opendocument&amp;comments</wfw:comment>
  219. </item>
  220. <item>
  221. <title>Ralf Petter&#8217;s blog about Notes, Eclipse and Expeditor back online</title>
  222. <pubDate>Mon, 20 Dec 2021 14:06:16 +0200</pubDate>
  223. <description>
  224. <![CDATA[
  225. Yesterday I noticed that Ralf Petter's blog "Everything about IT" is not online anymore. Ralf died years ago from cancer and his blog contains invaluable tips around Notes, Eclipse and Expeditor devel ...
  226. ]]>
  227. </description>
  228. <link>https://www.mindoo.com/web/blog.nsf/dx/20.12.2021140602KLEHDH.htm</link>
  229. <category></category>
  230. <dc:creator>Karsten Lehmann</dc:creator>
  231. <comments>https://www.mindoo.com/web/blog.nsf/dx/20.12.2021140602KLEHDH.htm?opendocument&amp;comments</comments>
  232. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/20.12.2021140602KLEHDH.htm</guid>
  233. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">Yesterday I noticed that Ralf Petter's blog "Everything about IT" is not online anymore. Ralf died years ago from cancer and his blog contains invaluable tips around Notes, Eclipse and Expeditor development.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">In June 2017 when I heard about his death, I downloaded all blog articles and kept them on my local disk.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Now that the official blog is gone, I uploaded them to our server, added them to the Google index and made them available here:</span> <br /> <br /><a href="https://ralfpetter-blog-mirror.mindoo.de/" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://ralfpetter-blog-mirror.mindoo.de</span></a> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Unfortunately I did not create copies of his free tools and they are not on OpenNTF or Github.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">I could find the ZIP archive with the latest DocumentSpy plugin in the Wayback machine and fixed the download link in this article:</span> <br /> <br /><a href="https://ralfpetter-blog-mirror.mindoo.de/www.everythingaboutit.eu/p/install-document-spy.html" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://ralfpetter-blog-mirror.mindoo.de/www.everythingaboutit.eu/p/install-document-spy.html</span></a> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">If anybody has a copy of these three tools, please send them to me:</span> <br /> <br /><a href="https://ralfpetter-blog-mirror.mindoo.de/www.everythingaboutit.eu/p/install-extension-spy.html" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://ralfpetter-blog-mirror.mindoo.de/www.everythingaboutit.eu/p/install-extension-spy.html</span></a> <br /> <br /><a href="https://ralfpetter-blog-mirror.mindoo.de/www.everythingaboutit.eu/p/install-todoactivator.html" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://ralfpetter-blog-mirror.mindoo.de/www.everythingaboutit.eu/p/install-todoactivator.html</span></a> <br /> <br /><a href="https://ralfpetter-blog-mirror.mindoo.de/www.everythingaboutit.eu/p/install-shortcutbuttonbar-enabler.html" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://ralfpetter-blog-mirror.mindoo.de/www.everythingaboutit.eu/p/install-shortcutbuttonbar-enabler.html</span></a> <br />  ]]></content:encoded>
  234. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/20.12.2021140602KLEHDH.htm</wfw:commentRss>
  235. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/20.12.2021140602KLEHDH.htm?opendocument&amp;comments</wfw:comment>
  236. </item>
  237. <item>
  238. <title>Mindoo CMS on Domino: Some examples</title>
  239. <pubDate>Tue, 27 Jul 2021 07:42:43 +0200</pubDate>
  240. <description>
  241. <![CDATA[
  242. Mindoo CMS is a Domino powered web content management system that we developed as part of a large project for a local print shop to build a web authoring system for the articles of their local newspap ...
  243. ]]>
  244. </description>
  245. <link>https://www.mindoo.com/web/blog.nsf/dx/27.07.2021074242KLE8QA.htm</link>
  246. <category></category>
  247. <dc:creator>Karsten Lehmann</dc:creator>
  248. <comments>https://www.mindoo.com/web/blog.nsf/dx/27.07.2021074242KLE8QA.htm?opendocument&amp;comments</comments>
  249. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/27.07.2021074242KLE8QA.htm</guid>
  250. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">Mindoo CMS is a Domino powered web content management system that we developed as part of a large project for a local print shop to build a web authoring system for the articles of their local newspapers with approval workflow, custom spellchecker with dictionary stored in Domino (based on </span><a href=http://hunspell.github.io/><span style=" font-size:10pt;color:blue;font-family:sans-serif">http://hunspell.github.io/</span></a><span style=" font-size:10pt;font-family:sans-serif">) and various data exports (e.g. responsive UI and EPUB for subscribers, QuarkXPress and Adobe InDesign for printing machines).</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The CMS does not just display the final articles, it's driving the whole web application to compose and approve articles as well.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Here is a list of the main features:</span> <br /> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">responsive user interface for desktop and mobile browsers</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">live editing of websites: as logged in user, just shift-click on any test in the live website and edit it or add content</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">full support of the Domino access model, e.g. to built corporate intranets with different layout/content for target groups</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">very flexible templating system based on custom </span><a href=https://handlebarsjs.com/ target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Handlebars</span></a><span style=" font-size:10pt;font-family:sans-serif"> tags</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">no developer skills needed for authors</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">compose web site pages out of building blocks predefined by the template editor with unrestricted complexity<br /> (e.g. add base page layout, sections for text/images, gallery block and gallery images with meta data; data model is 100% defined within the CMS)</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">automatic history of all CMS pages, files and templates: compare current state with any previous versions and revert back changed as needed</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">implemented/deployed as OSGi plugins on Domino</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">extensible to add custom CMS tags via OSGi extension points</span></li></ul> <br /><span style=" font-size:10pt;font-family:sans-serif">Here are some references of web sites that we developed and that are powered by Mindoo CMS:</span> <br /> <ul> <li><a href=https://www.duerrschnabel.com/web/index.html><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.duerrschnabel.com/web/index.html</span></a> </li><li><a href=https://www.bietigheim.de/web/index.html><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.bietigheim.de/web/index.html</span></a> </li><li><a href="https://www.gms-bietigheim.de/web/index.html"><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.gms-bietigheim.de/web/index.html</span></a> </li><li><a href=https://www.durmersheim.de/web/index.html><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.durmersheim.de/web/index.html</span></a> </li><li><a href=https://www.auamrhein.de/web/index.html><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.auamrhein.de/web/index.html</span></a> </li><li><a href="https://www.elchesheim-illingen.de/web/index.html"><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.elchesheim-illingen.de/web/index.html</span></a> </li><li><a href=https://www.weilgut.de/web/index><span style=" font-size:10pt;color:blue;font-family:sans-serif">https://www.weilgut.de/web/index</span></a></li></ul> <br />  ]]></content:encoded>
  251. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/27.07.2021074242KLE8QA.htm</wfw:commentRss>
  252. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/27.07.2021074242KLE8QA.htm?opendocument&amp;comments</wfw:comment>
  253. </item>
  254. <item>
  255. <title>News Update from Mindoo Land:  Domino JNA / JNX</title>
  256. <pubDate>Mon, 26 Jul 2021 13:15:43 +0200</pubDate>
  257. <description>
  258. <![CDATA[
  259. In a pandemic (in particular with two young kids of 5 and 7 years), times flies by even faster than in regular times, so it's no surprise that this blog has not seen many updates for a very long time. ...
  260. ]]>
  261. </description>
  262. <link>https://www.mindoo.com/web/blog.nsf/dx/26.07.2021131539KLEF8D.htm</link>
  263. <category></category>
  264. <dc:creator>Karsten Lehmann</dc:creator>
  265. <comments>https://www.mindoo.com/web/blog.nsf/dx/26.07.2021131539KLEF8D.htm?opendocument&amp;comments</comments>
  266. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/26.07.2021131539KLEF8D.htm</guid>
  267. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">In a pandemic (in particular with two young kids of 5 and 7 years), times flies by even faster than in regular times, so it's no surprise that this blog has not seen many updates for a very long time.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Just wanted to let you know that we are still very busy, leveraging and improving the Domino AppDev platform.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The biggest project I have been working on in 2020 and so far in 2021 has to do with our </span><a href="https://github.com/klehmann/domino-jna" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Domino JNA</span></a><span style=" font-size:10pt;font-family:sans-serif"> codebase. For the project itself, we released 11 new versions since the beginning of 2020.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">We added functionality that we needed for our own development projects and the project got additional traction because it was used by the <strong>HCL Innovation Labs</strong> initially for </span><a href="https://opensource.hcltechsw.com/domino-keep-docs/" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Project Keep</span></a><span style=" font-size:10pt;font-family:sans-serif">, now called <strong>HCL Domino REST API</strong> and in </span><a href="https://blog.hcltechsw.com/domino/announcing-the-domino-rest-api-beta-program%E2%80%AF%E2%80%AF/" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">public beta</span></a><span style=" font-size:10pt;font-family:sans-serif"> for a few week.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">After the first few internal Keep versions, the HCL Innovation Labs team decided that having a modern Java API for Domino would not just be relevant for their own projects but for every developer out there and that this should (hopefully) become the new standard for Java development on Domino.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">That's why we teamed up with </span><a href=https://frostillic.us/blog target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Jesse Gallagher</span></a><span style=" font-size:10pt;font-family:sans-serif"> to build something even better than Domino JNA - called </span><a href="https://opensource.hcltechsw.com/domino-keep-docs/howkeepworks/dominojnx/" target=_blank><span style=" font-size:10pt;color:red;font-family:sans-serif"><strong><span style="text-decoration:underline">Domino JNX</span></strong></span></a><span style=" font-size:10pt;font-family:sans-serif">.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Let's call it <strong>Domino JNA on steroids</strong>. We took the codebase of Domino JNA and built a powerful API that is both easy to use and has <strong>even more features than Domino JNA</strong>.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Some examples:</span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">automatic garbage collection for Domino C handles (based on Java's </span><a href="https://www.baeldung.com/java-phantom-reference" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">PhantomReference</span></a><span style=" font-size:10pt;font-family:sans-serif">)</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">leverages modern Java language features like </span><a href="https://www.baeldung.com/java-generics" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Generics</span></a><span style=" font-size:10pt;font-family:sans-serif">, </span><a href=https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">lambda expressions</span></a><span style=" font-size:10pt;font-family:sans-serif">, the </span><a href="https://www.baeldung.com/java-8-streams" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Stream API</span></a><span style=" font-size:10pt;font-family:sans-serif"> and </span><a href="https://www.baeldung.com/java-optional" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Optional's</span></a> </li><li><span style=" font-size:10pt;font-family:sans-serif">more APIs, e.g. to read the database design and current efforts to provide write access as well</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">JSON serialization support</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">extensible, e.g. to store your own objects in Domino documents</span></li></ul> <br /><span style=" font-size:10pt;font-family:sans-serif">JNX is the foundation for the HCL Domino REST API which itself is the foundation for other cool projects like the <strong>OpenClient initiative that will provide a native EWS/JMAP API for Domino</strong> and therefore native access for Microsoft Outlook, the Apple Mail client and others.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">There are ongoing efforts to give you, the Domino developer community, access to the JNX API (not just as part of the existing public beta release of the Domino REST API).</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">So stay stuned for upcoming announcements! :-)</span>  ]]></content:encoded>
  268. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/26.07.2021131539KLEF8D.htm</wfw:commentRss>
  269. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/26.07.2021131539KLEF8D.htm?opendocument&amp;comments</wfw:comment>
  270. </item>
  271. <item>
  272. <title>OpenNTF May 2021 Webinar: recent Mindoo ToDoManager changes for Notes 12</title>
  273. <pubDate>Thu, 20 May 2021 21:10:19 +0200</pubDate>
  274. <description>
  275. <![CDATA[
  276. Today I took part in OpenNTF's May webinar on recent project updates. I presented the results of my efforts to leverage new functionality of the upcoming Notes 12 client to make our Mindoo ToDoManager ...
  277. ]]>
  278. </description>
  279. <link>https://www.mindoo.com/web/blog.nsf/dx/20.05.2021211015KLEQGZ.htm</link>
  280. <category></category>
  281. <dc:creator>Karsten Lehmann</dc:creator>
  282. <comments>https://www.mindoo.com/web/blog.nsf/dx/20.05.2021211015KLEQGZ.htm?opendocument&amp;comments</comments>
  283. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/20.05.2021211015KLEQGZ.htm</guid>
  284. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">Today I took part in OpenNTF's </span><a href="https://openntf.org/main.nsf/blog.xsp?permaLink=JGAR-C2ZLMR" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">May webinar on recent project updates</span></a><span style=" font-size:10pt;font-family:sans-serif">. I presented the results of my efforts to leverage new functionality of the upcoming Notes 12 client to make our </span><a href="https://openntf.org/main.nsf/project.xsp?r=project/Mindoo%20TodoManager" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Mindoo ToDoManager application</span></a><span style=" font-size:10pt;font-family:sans-serif"> more responsive and adaptable to the available screen real estate.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The application now autodetects the size of the Notes/Nomad client window on startup and picks the best application layout: you either see all four quadrants</span> <br /> <br /> <div align=center><img  alt="Image:OpenNTF May 2021 Webinar: recent Mindoo ToDoManager changes for Notes 12" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/20.05.2021211015KLEQGZ.htm/content/M2?OpenElement" /></div> <br /><span style=" font-size:10pt;font-family:sans-serif">or the mobile optimized narrow layout with a single quadrant at a time:</span> <br /> <br /> <div align=center><img  alt="Image:OpenNTF May 2021 Webinar: recent Mindoo ToDoManager changes for Notes 12" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/20.05.2021211015KLEQGZ.htm/content/M3?OpenElement" /></div> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Notes 12 provides two new @formulas </span><tt><span style=" font-size:10pt">@ResolutionWidth</span></tt><span style=" font-size:10pt;font-family:sans-serif"> / </span><tt><span style=" font-size:10pt">@ResolutionHeight</span></tt><span style=" font-size:10pt;font-family:sans-serif"> to read the dimension of the current UI form or UI view.</span> <br /><span style=" font-size:10pt;font-family:sans-serif">And you get a new form/view event "onsize" that gets triggered on window resize. Enter the formula </span><tt><span style=" font-size:10pt">@Command(&#91;RelayoutWindow&#93;)</span></tt><span style=" font-size:10pt;font-family:sans-serif"> here and your layout gets recomputed when the window is resized by the user, e.g. hide/when or subform formulas that depend on the form dimension might produce a different output.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">To be honest I was fighting a bit to get this new functionality to work reliable in the latest R12 beta 3 client. The TodoManager proves that responsive layouts for Notes applications <span style="text-decoration:underline">are indeed possible</span>. </span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">But I reported a bunch of issues in the beta program that hopefully get fixed until the final R12 release to make this easier to use.</span> <br /><span style=" font-size:10pt;font-family:sans-serif">E.g. my Designer installation does not save the code that I enter in the "onsize" event. And the resolution formulas often seem to be computed too early, e.g. you still get UI view dimensions back <span style="text-decoration:underline">after</span> you have opened a doc in a view.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">While I was updating the OpenNTF project download with the latest version, I also added some documentation and references on the project summary page. I highly recommend watching the two videos that are linked in the text if you haven't done already. They were recorded in 2007, but are still very inspiring.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Anyway, I hope you like the new version. Here is the updated project description:</span> <br /> <br /> <br /><span style=" font-size:12pt;color:#2f2f2f;font-family:sans-serif"><strong>Four Quadrant Theory</strong></span> <br /> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">The TodoManager is based on Covey's Four Quadrant theory that is described in this article: </span> <br /><a href="https://appfluence.com/productivity/time-management-strategies-for-busy-people-using-the-4-quadrant-method/" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Time management strategies for busy people using the 4-quadrant method</span></a> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">It provides a graphical concept of todo management where you place your todos in a 2x2matrix of four quadrants. By doing that you decide whether your topic is important/ not important and due soon/ not due soon.</span> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif"><strong>Following the order of the quadrants is key to organizing your life:</strong> </span> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">Start with quadrant 1 (important/ due soon), continue with 2 (important/ not due soon), 3 (not important/ due soon) and end with todos in quadrant 4 (not important/ not due soon). In each quadrant, pick the ugliest task first.</span> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">I got to know Covey's theory when I was watching </span><a href="https://www.youtube.com/watch?v=ji5_MqicxSo" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Randy Pausch's Last Lecture</span></a><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif"> and his </span><a href="https://www.youtube.com/watch?v=oTugjssqOT0" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Lecture about Time Management</span></a><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">. Both recordings are <strong>highly recommended</strong> to put your daily struggles and project deadlines into perspective: </span> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">Carnegie Mellon Professor Randy Pausch (Oct. 23, 1960 - July 25, 2008) gave his last lecture at the university Sept. 18, 2007, before a packed McConomy Auditorium, months before he died from pancreatic cancer and reflects on how much he achieved his childhood dreams.</span> <br /> <br /><span style=" font-size:12pt;color:#2f2f2f;font-family:sans-serif"><strong>Usage</strong></span> <br /> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">Use the â\x80\x9c\x80\x9d icon to create new todos and decide in which quadrant (=Notes folder) it should be moved on first save. </span> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">Use drag and drop or context menu actions to move your tasks between quadrants (numbers â\x80\x9c\x80\x9d, â\x80\x9c\x80\x9d, â\x80\x9c\x80\x9d, â\x80\x9c\x80\x9d are drop targets) or into the recycle bin.</span> <br /> <br /><span style=" font-size:12pt;color:#2f2f2f;font-family:sans-serif"><strong>Responsive UI</strong></span> <br /> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">The TodoManager application has a responsive user interface that works on desktop Notes Client, HCL Nomad clients on tablets/phones and even the new Nomad web client. By providing two different application layouts it adapts to the available screen real estate: one layout that displays all 4 quadrants at once and a second one where you only see a single quadrant and have hotspots to change quadrants in the top navigation.</span> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">On Notes 12 we leverage new @formulas to query the current window dimension while still being backward compatible with older Notes Client versions. That means that even in the desktop Notes Client you get a different user experience when the client window width is not very wide. The window size is detected on application startup.</span> <br /> <br /><span style=" font-size:12pt;color:#2f2f2f;font-family:sans-serif"><strong>Installation</strong></span> <br /> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">Just copy the provided application template to your server, sign it and create a new database instance. Then give yourself editor access in the ACL and all others no access. </span> <br /><span style=" font-size:10pt;color:#2f2f2f;font-family:sans-serif">There are currently no background agents to enable.</span> <br />  ]]></content:encoded>
  285. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/20.05.2021211015KLEQGZ.htm</wfw:commentRss>
  286. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/20.05.2021211015KLEQGZ.htm?opendocument&amp;comments</wfw:comment>
  287. </item>
  288. <item>
  289. <title>Mindoo TodoManager on OpenNTF</title>
  290. <pubDate>Sat, 14 Dec 2019 09:30:14 +0200</pubDate>
  291. <description>
  292. <![CDATA[
  293. I created a small sample application for the HCL Nomad Client on the iPad and iPhone. It's a TodoManager that uses the 4 Quadrant time management method to structure the Todos. The application is now ...
  294. ]]>
  295. </description>
  296. <link>https://www.mindoo.com/web/blog.nsf/dx/14.12.2019093007KLEBYY.htm</link>
  297. <category>Free Tools</category>
  298. <dc:creator>Karsten Lehmann</dc:creator>
  299. <comments>https://www.mindoo.com/web/blog.nsf/dx/14.12.2019093007KLEBYY.htm?opendocument&amp;comments</comments>
  300. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/14.12.2019093007KLEBYY.htm</guid>
  301. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">I created a small sample application for the HCL Nomad Client on the iPad and iPhone. It's a TodoManager that uses the 4 Quadrant time management method to structure the Todos.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The application is now available for free on OpenNTF: </span><a href="https://openntf.org/main.nsf/project.xsp?r=project/Mindoo%20TodoManager" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Mindoo TodoManager</span></a> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">In the desktop Notes Client, to dos can be moved between the quadrants and to the recycle bin via drag and drop ("1" - "4" and the recycle bin icon are drop targets).</span> <br /><span style=" font-size:10pt;font-family:sans-serif">In HCL Nomad, just do a long click on a document to see the available options.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The UI is responsive and should fit on all devices.</span> <br /> <br /><img  alt="Image:Mindoo TodoManager on OpenNTF" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/14.12.2019093007KLEBYY.htm/content/M2?OpenElement" /> <br /> <br /><img  alt="Image:Mindoo TodoManager on OpenNTF" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/14.12.2019093007KLEBYY.htm/content/M3?OpenElement" /> <br /> <br /><img  alt="Image:Mindoo TodoManager on OpenNTF" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/14.12.2019093007KLEBYY.htm/content/M4?OpenElement" /> <br /> <br /><img  alt="Image:Mindoo TodoManager on OpenNTF" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/14.12.2019093007KLEBYY.htm/content/M5?OpenElement" /> <br /> <br /><img  alt="Image:Mindoo TodoManager on OpenNTF" border="0" src="https://www.mindoo.com/web/blog.nsf/dx/14.12.2019093007KLEBYY.htm/content/M6?OpenElement" /> <br /> <br />  ]]></content:encoded>
  302. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/14.12.2019093007KLEBYY.htm</wfw:commentRss>
  303. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/14.12.2019093007KLEBYY.htm?opendocument&amp;comments</wfw:comment>
  304. </item>
  305. <item>
  306. <title>Documentation for &#64;GetMachineInfo</title>
  307. <pubDate>Wed, 4 Dec 2019 14:47:07 +0200</pubDate>
  308. <description>
  309. <![CDATA[
  310. Since there currently is no place to find this information on HCL websites in Google, I am adding it here: @GetMachineInfo new in 8.5.3 New @Function to support Machine Specific Policy Settings Sy ...
  311. ]]>
  312. </description>
  313. <link>https://www.mindoo.com/web/blog.nsf/dx/04.12.2019144707KLEJ72.htm</link>
  314. <category></category>
  315. <dc:creator>Karsten Lehmann</dc:creator>
  316. <comments>https://www.mindoo.com/web/blog.nsf/dx/04.12.2019144707KLEJ72.htm?opendocument&amp;comments</comments>
  317. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/04.12.2019144707KLEJ72.htm</guid>
  318. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">Since there currently is no place to find this information on HCL websites in Google, I am adding it here:</span> <br /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong>@GetMachineInfo new in 8.5.3</strong></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">New @Function to support Machine Specific Policy Settings</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><span style="text-decoration:underline">Syntax:</span></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><code>@GetMachineInfo( &#91;Keyword&#93;; "Needed for some Keywords string" )</code></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><span style="text-decoration:underline">Keywords:</span></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">IsLaptop - boolean return - True if machine is a laptop, otherwise false</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">IsDesktop - boolean return - True if machine is NOT a laptop, otherwise false</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">IsSingleLogOn - boolean return - True if machine has Notes client installed with "single sign on", otherwise false</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">IsMultiUser - boolean return - True if machine has Notes client installed as Multi-User, otherwise false</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">HasDesigner - boolean return - True if machine has Designer client installed, otherwise false</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">HasAdmin - boolean return - True if machine has Admin client installed, otherwise false</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">IsStandard - boolean return - True if machine is running Standard Notes client, otherwise false</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">MachineName - string return - Name of the machine</span> <br /><span style=" font-size:10pt;font-family:sans-serif">boolean return &nbsp; &nbsp; &nbsp; &nbsp;True if MachineName string after keyword matches this machine's MachineName, otherwise false</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Memory - number return - Total amount of memory (RAM)</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">DiskSpace - number return - Amount of free disk space</span> <br /><span style=" font-size:10pt;font-family:sans-serif">Note: With this keyword, you can add a second parameter for the drive to scan for free space. If this parameter is not passed</span> <br /><span style=" font-size:10pt;font-family:sans-serif">to the function, free space for the first (logical) drive - for example, drive C on Windows system - is displayed.</span> <br /><span style=" font-size:10pt;font-family:sans-serif">Example: <code>@GetMachineInfo(&#91;DiskSpace&#93;;"d:")</code></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">EnvVariable - string return - Requires string of the variable name in Notes.ini to read, and returns the value of that ini variable or "" (null string) if not found</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">SysEnvVariable - string return - Requires string of the variable name in system environment to read, and returns the value of that variable or "" (null string) if not</span> <br /><span style=" font-size:10pt;font-family:sans-serif">found</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">IP - string/list return - String representation of the IP address(es) in the form XXX.XXX.XXX.XXX , otherwise "" (null string) if not available</span> <br /><span style=" font-size:10pt;font-family:sans-serif">boolean return &nbsp; &nbsp; &nbsp; &nbsp;True if pattern IP string after keyword matches this machine's IP address, otherwise false</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">MAC - string/list return - String representation of the MAC address(es) in the form XX:XX:XX:XX:XX:XX , otherwise "" (null string) if not available</span> <br /><span style=" font-size:10pt;font-family:sans-serif">boolean return &nbsp; &nbsp; &nbsp; &nbsp;True if MAC string after keyword matches this machine's MAC address, otherwise false</span> <br />  ]]></content:encoded>
  319. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/04.12.2019144707KLEJ72.htm</wfw:commentRss>
  320. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/04.12.2019144707KLEJ72.htm?opendocument&amp;comments</wfw:comment>
  321. </item>
  322. <item>
  323. <title>Configure Eclipse 4.6.x with HCL Notes 10</title>
  324. <pubDate>Mon, 4 Nov 2019 16:06:07 +0200</pubDate>
  325. <description>
  326. <![CDATA[
  327. For years, whenever I needed to configure an Eclipse IDE for IBM Notes plugin development, I used Mikkel Heisterberg's instructions on his blog. Since I currently have a customer requirement to updat ...
  328. ]]>
  329. </description>
  330. <link>https://www.mindoo.com/web/blog.nsf/dx/04.11.2019160604KLEKQD.htm</link>
  331. <category>Eclipse</category>
  332. <dc:creator>Karsten Lehmann</dc:creator>
  333. <comments>https://www.mindoo.com/web/blog.nsf/dx/04.11.2019160604KLEKQD.htm?opendocument&amp;comments</comments>
  334. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/04.11.2019160604KLEKQD.htm</guid>
  335. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">For years, whenever I needed to configure an Eclipse IDE for IBM Notes plugin development, I used Mikkel Heisterberg's instructions on his </span><a href="https://lekkimworld.com/configure-eclipse-4-2-for-notes-9/" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">blog</span></a><span style=" font-size:10pt;font-family:sans-serif">.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Since I currently have a customer requirement to update an existing plugin that we built for them years ago to a newer Java version (1.8), I tried to set up Eclipse 2019-09 with HCL Notes 10.0.1FP2, but failed.</span> <br /><span style=" font-size:10pt;font-family:sans-serif">The launching Client did not show any file/edit/view menus, probably caused by a ClassCastException I could see in the launch console.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">I guess the reason is that 9.0.1 FP10 brought a major update for the underlying Eclipse and OSGi platform.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">So I contacted HCL development and asked for the updated parameters to make this work again and quickly got a response that I would like to share with you.</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">The document links to Eclipse Neon 4.6.3, but it's still working for me in Eclipse 2019-09 (4.13.0).</span> <br /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">1. Download Eclipse Neon (4.6.3) or later from link below:</span></strong></span> <br /><a href="http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/neon/3/eclipse-committers-neon-3-win32-x86_64.zip" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/neon/3/eclipse-committers-neon-3-win32-x86_64.zip</span></a> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">2. Get the latest V10 build</span></strong></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">3. Go to Windows => Preferences => Java => Installed JREs</span></strong></span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">Add => Standard VM =></span> </li><li><span style=" font-size:10pt;font-family:sans-serif">JRE home: <code><em>&#91;Notes Install path&#93;</em>\jvm</code>, e.g. <code>C:\Program Files (x86)\IBM\Notes\jvm</code></span> </li><li><span style=" font-size:10pt;font-family:sans-serif">JRE name: â\x80\x9cNotes JREâ\x80\x9d</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Select the JRE to point to this and Apply</span></li></ul> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">4. Go to Windows => Preferences => Plug-in Development => Target Platform</span></strong></span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">Add => default => Target Content</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Name: â\x80\x9cNotes Targetâ\x80\x9d</span></li></ul> <br /><span style=" font-size:10pt;font-family:sans-serif">4a. In Locations Tab:</span> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">Add => Directory => Location => <code><em>&#91;Notes Install path&#93;</em>\framework\rcp\eclipse\plugins</code></span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Add => Directory => Location => <code><em>&#91;Notes Install path&#93;</em>\framework\shared\eclipse\plugins</code></span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Finish</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Select the Target platform to point to â\x80\x9cNotes Targetâ\x80\x9d and Apply</span></li></ul> <br /><span style=" font-size:10pt;font-family:sans-serif">4 b. In Environment Tab:</span> <br /><span style=" font-size:10pt;font-family:sans-serif">Please select following settings:</span> <br /> <ul> <li><span style=" font-size:10pt;font-family:sans-serif">Operating System: win32</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Windowing System: win32</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Architecture: x86</span> </li><li><span style=" font-size:10pt;font-family:sans-serif">Locale: en_US - English (United States)</span></li></ul> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">5. Go to Windows => Preferences => Run/Debug => String Substitution</span></strong></span> <br /><span style=" font-size:10pt;font-family:sans-serif">New => Add 2 strings (replace "xxxx" with the right plugin version!)</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">5a. Name: rcp_home</span> <br /><span style=" font-size:10pt;font-family:sans-serif">Value: <code><em>&#91;Notes Install path&#93;</em>\framework</code></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">5b. Name: rcp_base</span> <br /><span style=" font-size:10pt;font-family:sans-serif">Value: <code><em>&#91;Notes Install path&#93;</em>\framework\rcp\eclipse\plugins\com.ibm.rcp.base_10.0.0.xxxx</code></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">OK</span> <br /><span style=" font-size:10pt;font-family:sans-serif">Close this Preferences Window</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">6. Put the following file inside the below plugin:</span></strong></span> <br /><span style=" font-size:10pt;font-family:sans-serif"><code><em>&#91;Notes Install path&#93;</em>\framework\rcp\eclipse\plugins\com.ibm.rcp.base_10.0.0.xxxx</code></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><a href="https://www.mindoo.com/web/blog.nsf/dx/rcp.security.properties/$file/rcp.security.properties" target="_blank" title="rcp.security.properties">rcp.security.properties</a></span> <br /> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">7. Open Debug Configurations in the â\x80\x98Debug Perspectiveâ\x80\x99 => Eclipse Configuration => New</span></strong></span> <br /><span style=" font-size:10pt;font-family:sans-serif">7a. In the Main tab:</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Name: NotesDebug</span> <br /><span style=" font-size:10pt;font-family:sans-serif">Program to Run => &nbsp;Run a product => com.ibm.notes.branding.notes</span> <br /><span style=" font-size:10pt;font-family:sans-serif">Java Runtime Environment => Runtime JRE => Select â\x80\x9cNotes JREâ\x80\x9d i.e. the one we added in step 3</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">7b. In the Arguments tab: </span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">Program Arguments:</span> <br /><span style=" font-size:10pt;font-family:sans-serif"><code>-clean -console -debug -log -personality com.ibm.rcp.platform.personality -config notes</code></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif">VM Arguments:</span> <br /><span style=" font-size:10pt;font-family:sans-serif"><code>-Xquickstart<br>-Xss384k<br>-Xshareclasses<br>-Drcp_home="${rcp_home}"<br>-Drcp.install.config=user<br>-Dosgi.install.area="${rcp_home}\eclipse"<br>-Disa.ignoreESR=true<br>-Dcom.ibm.pvc.osgiagent.core.logfileloc="${rcp_home}\rcp"<br>-Dcom.ibm.pvc.webcontainer.port=0<br>-Declipse.pluginCustomization="${rcp_home}\rcp\plugin_customization.ini"<br>-Djava.security.properties="${rcp_base}\rcp.security.properties"<br>-Declipse.registry.nulltoken=true<br>-Djava.protocol.handler.pkgs=com.ibm.net.ssl.www.protocol<br>-Djava.util.logging.config.class=com.ibm.rcp.core.internal.logger.boot.LoggerConfig<br>-Dosgi.hook.configurators.exclude=org.eclipse.core.runtime.internal.adaptor.EclipseLogHook<br>-Dosgi.framework.extensions=com.ibm.rcp.core.logger.frameworkhook,com.ibm.rds,com.ibm.cds<br>-Xbootclasspath/a:${rcp_base}\rcpbootcp.jar;<br-Xdump:system:events=user</code></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><strong><span style="text-decoration:underline">8. Apply => Debug â\x80\x93 This will launch your Notes in Debug mode. </span></strong></span> <br /><span style=" font-size:10pt;font-family:sans-serif">Ensure that whenever you launch the Notes from Eclipse, there should be no other instance of Notes already running. If so, please close Notes and then launch from Eclipse to debug.</span> <br />  ]]></content:encoded>
  336. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/04.11.2019160604KLEKQD.htm</wfw:commentRss>
  337. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/04.11.2019160604KLEKQD.htm?opendocument&amp;comments</wfw:comment>
  338. </item>
  339. <item>
  340. <title>New Domino JNA version available with LOTS of new features</title>
  341. <pubDate>Thu, 19 Sep 2019 17:23:43 +0200</pubDate>
  342. <description>
  343. <![CDATA[
  344. It's been a long time since the last release of our Domino JNA project. Version 0.9.21 is now available for download as XPages Extensibility Plugin and on its way to Maven Central (takes a few hours t ...
  345. ]]>
  346. </description>
  347. <link>https://www.mindoo.com/web/blog.nsf/dx/19092019172343KLEL3E.htm</link>
  348. <category>Domino C API</category>
  349. <dc:creator>Karsten Lehmann</dc:creator>
  350. <comments>https://www.mindoo.com/web/blog.nsf/dx/19092019172343KLEL3E.htm?opendocument&amp;comments</comments>
  351. <guid isPermaLink="true">https://www.mindoo.com/web/blog.nsf/dx/19092019172343KLEL3E.htm</guid>
  352. <content:encoded><![CDATA[ <span style=" font-size:10pt;font-family:sans-serif">It's been a long time since the last release of our Domino JNA project. Version 0.9.21 is now available for </span><a href="https://github.com/klehmann/domino-jna/releases/tag/0.9.21" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">download as XPages Extensibility Plugin</span></a><span style=" font-size:10pt;font-family:sans-serif"> and on its way to </span><a href="https://mvnrepository.com/artifact/com.mindoo.domino/domino-jna" target=_blank><span style=" font-size:10pt;color:blue;font-family:sans-serif">Maven Central</span></a><span style=" font-size:10pt;font-family:sans-serif"> (takes a few hours to appear).</span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><span style="text-decoration:underline">Here are a some highlights of the new version:</span></span> <br /> <br /><span style=" font-size:10pt;font-family:sans-serif"><ul><li>New method to read item definition table of a database</li><li>Added function to get the template db path by the template name</li><li>Support for profile note reading and writing</li><li>Added API to export mails as EML files on client and server</li><li>Added API to read client and server statistics</li><li>Tested in Notes/Domino 11 beta 1</li><li>Added method to harvest DB design for DQL speedup</li><li>DQL query builder updated for new Domino 11 "contains" terms (FT search)</li><li>New method to send server console commands</li><li>Improved richtext to HTML conversion sample to extract files as well</li><li>Added convenience functions NotesDatabase.toUnid / toNoteId</li><li>Added NotesDatabase.getAllCollections() to read infos about all views</li><li>NotesTimeDate.toString method with date/time/timezone formatting options</li><li>Added NotesIntlFormat argument to NotesTimeDate.fromString</li><li>Added setter to change timezone of NotesTimeDate</li><li>New methods to read ACL entries and all ACL roles</li><li>New methods in NotesCollection to read view design properties, e.g. .isConflict(), .isCollapsed(), isGotoTopOnOpen() etc.</li><li>Added method to check if $file item belongs to a TYPE_MIME_PART item</li><li>Added method NotesItem.copyToNote() with parameter to rename the item</li><li>Added check method to large summary buffer support on DB</li><li>Added checks for ERR 1028 when openings docs to return null if not found</li><li>Improved reading of data below view categories</li><li>Added method to convert RFC822 items to native Domino format</li><li>NotesDatabase.openMailDatabase(), hasFullAccess() and runWithDbLock()</li><li>Changed flag to find view in design, did not find all available views</li><li>Flags to update note without triggering replication (used by replicator)</li><li>Added experimental code to set sequence number and time</li><li>Added more HTML conversion options</li><li>More FTSearch options for NotesDatabase searches (e.g. get result sorted by created/modified/score)</li><li>Additional methods to write Notes.ini variables (e.g. OSGI_HTTP_DYNAMIC_BUNDLES)</li><li>Added getter to read TIMEDATE value from Notes.ini with testcase</li><li>NotesCollection column title/name no longer converted to lowercase</li><li>Removed ICU4J dependency, now using undocumented method OSTranslate32 to translate between LMBCS and Java strings with support for long texts (length > WORD size that OSTranslate supports)</li><li>Performance optimizations, fixed memory handle leaks</li></ul></span> <ul> <li></li></ul>  ]]></content:encoded>
  353. <wfw:commentRss> https://www.mindoo.com/web/blog.nsf/dxcomments/19092019172343KLEL3E.htm</wfw:commentRss>
  354. <wfw:comment> https://www.mindoo.com/web/blog.nsf/dx/19092019172343KLEL3E.htm?opendocument&amp;comments</wfw:comment>
  355. </item>
  356. </channel></rss>
  357.  

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//www.mindoo.com/web/blog.nsf/feed.rss

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