<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
 xmlns:admin="http://webns.net/mvcb/"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:content="http://purl.org/rss/1.0/modules/content/"
 xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<channel>
<title>Mindoo Blog</title>
<description>Cutting edge technologies - About Java, Lotus Notes and iPhone</description>
<link>http://www.mindoo.de/web/blog.nsf/</link>
<language>en-us</language>
<lastBuildDate>Fri, 27 Apr 2012 19:00:09 +0200</lastBuildDate>
<item>
<title>XPages series #14: Using MongoDB&#8217;s geo-spatial indexing in XPages apps part 2</title>
<pubDate>Fri, 27 Apr 2012 19:00:09 +0200</pubDate>
<description>
<![CDATA[ 
This is part 2 of an article about using MongoDB in Notes/Domino. Click here for part 1. Diving into the code: client side The UI stuff is stored in an NSF database with basic page layout defined i ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/27.04.2012190009KLEMXN.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/27.04.2012190009KLEMXN.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/27.04.2012190009KLEMXN.htm</guid>
<content:encoded><![CDATA[ This is part 2 of an article about using MongoDB in Notes/Domino. <a href="http://www.mindoo.com/web/blog.nsf/dx/27.04.2012185938KLEMXB.htm" target="_blank">Click here for part 1</a>. <br /> <br /> <br /><strong>Diving into the code: client side</strong> <br /> <br />The UI stuff is stored in an NSF database with basic page layout defined in an XPage and the client-side application logic code stored as Dojo class file in the Java perspective of Domino Designer. <br /> <br /> <div align=center><img  src="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-dbdesign-small.jpg/$file/nosql-mongodb-dbdesign-small.jpg"></div> <br /> <br />The Dojo class location is defined and the class is loaded with the following code in the XPage "start.xsp": <br /> <br /><code><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:this.resources<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:dojoModulePath prefix="mongo"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:this.url<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!&#91;CDATA&#91;#{javascript:'/dojo/mongo';}&#93;&#93;><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:this.url<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:dojoModulePath<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:dojoModule name="mongo.test.PageHandler"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:dojoModule<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/this.resources<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />></code> <br /> <br />After that, the class can be instantiated in a script block: <br /> <br /><code><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:scriptBlock type="text/javascript"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:this.value<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!&#91;CDATA&#91; <br />&nbsp; &nbsp; &nbsp; &nbsp; dojo.addOnLoad(function() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; window.pageHandler=new mongo.test.PageHandler(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; window.pageHandler.init(); <br />&nbsp; &nbsp; &nbsp; &nbsp; }); <br />&nbsp; &nbsp; &nbsp; &nbsp; &#93;&#93;<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:this.value<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:scriptBlock<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />></code> <br /> <br />In the init() method, the page handler class registers event code for the form fields and buttons in the UI and creates the Dojo grid components (<code>dojox.grid.LazyTreeGrid</code>) to display the database content. <br /> <br />Now let's take a look at two UI operations in detail, to see how the UI communicates with the server-side code. <br /> <br /><strong>Adding data to the database</strong> <br /> <br />When places get added through the Administration tab, we first use the servlet "/mongogeo" to convert the addresses into coordinates: <br /> <br /> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-addentries-geo-large.jpg/$file/nosql-mongodb-addentries-geo-large.jpg" target="_blank"><img  src="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-addentries-geo-small.jpg/$file/nosql-mongodb-addentries-geo-small.jpg"></a></div> <br /> <br />What we get back is the JSON response of &nbsp;the <a href="https://developers.google.com/maps/documentation/geocoding/" target="_blank">Google Geocoding API</a>. It does not only contain the coordinates of an address, but other quite useful information like the name of the federal state, the country code and coordinates of a bounding box (for general addresses like city names that don't have exact coordinates). <br /> <br />Next, a POST operation to "/mongotest/addplaces" creates the actual place documents in the database followed by a reload operation of our Dojo grid to reflect the new data in the UI: <br /> <br /> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-addentries-restoverview-large.jpg/$file/nosql-mongodb-addentries-restoverview-large.jpg" target="_blank"><img  src="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-addentries-restoverview-small.jpg/$file/nosql-mongodb-addentries-restoverview-small.jpg"></a></div> <br /> <br /><strong>Query the database</strong> <br /> <br />The REST service "/mongotest/queryplaces" is used both for reading all places (on the Administration tab) and finding the nearest places for a certain position (on the Search tab). For the latter, we specify additional longitude/latitude arguments in the URL: <br /> <br /><code>http://localhost/dev/ec12/nosql/mongodb/geo.nsf/mongotest/queryplaces?distance=3&amp;<span style="color:#ff0000"><strong>longitude=8.3799444&amp;latitude=49.009148</strong></span>&amp;type=Shop&amp;start=0&amp;count=100</code> <br /> <br />Dynamic sorting can be applied to the result with and without longitude/latitude arguments by specifying a sort parameter. <br />If no sort parameter and no position is specified, places are sorted by name as default sorting. For queries with longitude/latitude parameters, the distance between both points is used as default sorting. <br /> <br /><code>http://localhost/dev/ec12/nosql/mongodb/geo.nsf/mongotest/queryplaces?distance=3&amp;longitude=8.3799444&amp;latitude=49.009148&amp;type=Shop&amp;start=0&amp;count=100&amp;<span style="color:#ff0000"><strong>sort=name</strong></span></code> <br /> <br />In the UI, data can be sorted by clicking one of the grid column headers. <br /> <br /> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-queryplaces-large.jpg/$file/nosql-mongodb-queryplaces-large.jpg" target="_blank"><img  src="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-queryplaces-small.jpg/$file/nosql-mongodb-queryplaces-small.jpg"></a></div> <br /> <br /> <br />Enough technical details, let's come to an end with this long blog article! :-) <br /> <br />If you would like to try out the sample in your own environment, here are the setup instructions: <br /> <br /> <br /><strong>Setup instructions - Prerequisites</strong> <br /> <br />I expect that you have downloaded and installed the latest version of <a href="http://www.mongodb.org/downloads" target="_blank">MongoDB</a> for your operating system. The sample was built for version 2.0.3 and I just found out that 2.0.4 is already available. <br /> <br />The server code is using <code>localhost</code> and port 27017 by default, but this can be changed by setting the environment variable <code>NOSQL_MONGO_SERVER</code> to something like "hostname1,hostname2:27123,hostname3", a comma separated list with hostname and optional port. The Mongo driver will use the list of servers for failover in case a server goes down. <br /> <br /><strong>Plugin installation</strong> <br /> <br />Download and extract the archive file from the specified download link. <br /> <br />Then follow the instructions in the Domino wiki article <a href="http://www-10.lotus.com/ldd/ddwiki.nsf/dx/XPages_Extension_Library_Deployment" target="_blank">XPages Extension Library Deployment in Domino 8.5.3 and IBM XWork Server</a> to create an NSF based update site database on the Domino server and import the update site from the download archive into the update site database, followed by a HTTP task restart (<code>restart task http</code>). <br /> <br /><strong>Database installation</strong> <br /> <br />Copy the sample database from the download archive to your Domino server and sign it with your Notes ID. Now open the database in the browser. <br /> <br />There is a section "Initialization" on the Administration tab which lets you import a set of default addresses (from Mindoo's home town Karlsruhe, Germany). This step is optional. <br /> <br /><strong>Download link</strong> <br /> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/NoSQL-MongoDB.zip/$file/NoSQL-MongoDB.zip">Click here</a> to download the sample application <br /> <br /> <br /> <br />Phew... That was a long text. Thanks for reading until here! <br /> <br />And stay tuned for an article about my second demo from Entwicklercamp 2012: <br /> <br /> <div align=center><strong>Using Neo4J to solve the travelling salesman problem in XPages apps</strong></div> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/27.04.2012190009KLEMXN.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/27.04.2012190009KLEMXN.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #14: Using MongoDB&#8217;s geo-spatial indexing in XPages apps part 1</title>
<pubDate>Fri, 27 Apr 2012 18:59:38 +0200</pubDate>
<description>
<![CDATA[ 
This article presents the first demo of my session about NoSQL databases at the German Entwicklercamp conference in March 2012. It demonstrates how the document-oriented NoSQL database MongoDB can be ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/27.04.2012185938KLEMXB.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/27.04.2012185938KLEMXB.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/27.04.2012185938KLEMXB.htm</guid>
<content:encoded><![CDATA[ This article presents the first demo of my <a href="http://www.mindoo.com/web/blog.nsf/dx/05.04.2012000741KLETXV.htm" target="_blank">session about NoSQL databases</a> at the German Entwicklercamp conference in March 2012. It demonstrates how the document-oriented NoSQL database <a href="http://www.mongodb.org/" target="_blank">MongoDB</a> can be used in an XPages web application for the IBM Lotus Domino server. <br /> <br /><strong>The rise of location based services</strong> <br /> <br /><a href="http://en.wikipedia.org/wiki/Location-based_service" target="_blank">Location based services</a> have become quite popular in the past years: Most of the smartphones carry a GPS sensor, and there are a lot of popular apps out there (e.g. <a href="https://foursquare.com/" target="_blank">Foursquare</a>, <a href="http://www.yelp.com/" target="_blank">Yelp</a>) that use cloud services to find people, restaurants and places nearby. <br /> <br />For a number of reasons (mostly scalability/performance related), the NSF database of Lotus Notes/Domino is not the best choice to implement these kind of applications/services. MongoDB is much more suited for this use case and the article shows how you can integrate MongoDB into Notes/Domino to combine both worlds and get the best from both of them. <br /> <br />The Dojo based web application that I am going to discuss in detail uses <a href="http://www.mongodb.org" target="_blank">MongoDB's</a> <a href="http://www.mongodb.org/display/DOCS/Geospatial+Indexing" target="_blank">geospatial indexing feature</a> to easily find the nearest points of interest for a mobile web user. <br /> <br />Here is how our application looks like: <br /> <br /> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-admin-large.jpg/$file/nosql-mongodb-admin-large.jpg" target="_blank"><img  src="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-admin-small.jpg/$file/nosql-mongodb-admin-small.jpg"></a></div> <br /> <br />The "Administration" tab provides a user interface to add/remove places to/from the MongoDB database. A place is stored as a document in a MongoDB document collection and consists of a name, a type (e.g. shop/gas station) and the position information as &#91;longitude, latitude&#93; value pair. <br /> <br />The database can be queried on the "Search" tab by entering an address, a distance in kilometers and an optional type. The address will automatically get converted to &#91;longitude, latitude&#93; coordinates by using the <a href="https://developers.google.com/maps/documentation/geocoding/" target="_blank">Google Geocoding API</a>, which is then used to find places within the specified distance. <br /> <br />Our MongoDB document collection is indexed in a way so that we can quickly query the database for places that surround the current user's position and sort them by ascending distance between both points. <br /> <br /> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-search-large.jpg/$file/nosql-mongodb-search-large.jpg" target="_blank"><img  src="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-search-small.jpg/$file/nosql-mongodb-search-small.jpg"></a></div> <br /> <br />Since geospatial indexing is a built-in feature of MongoDB, the solution is very easy to implement. <br /> <br /><strong>Limitations of NSF</strong> <br /> <br />While it is not impossible to build this application in pure Lotus Notes/Domino technology with an NSF database, the missing geo index and limited scalability of NSF would make it difficult to keep response times low with large data sets, e.g. millions or even billions of places worldwide. MongoDB instead provides a <a href="http://www.mongodb.org/display/DOCS/Sharding+Introduction">sharding feature</a> to distribute the data evenly to several servers and reduce server load. <br /> <br />Additional indexer like <a href="http://lucene.apache.org/core" target="_blank">Apache Lucene</a> in combination with the <a href="http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&amp;name=OSGI%20Tasklet%20Service%20for%20IBM%20Lotus%20Domino" target="_blank">OSGi tasklet service plugin's extension hooks</a> might help to improve Domino's limited indexing support (we already used a Lucene index with Domino data in a big customer project) , but using MongoDB for this use case is just so much easier. <br /> <br /><strong>Architecture</strong> <br /> <br />The application consists of client-side and server-side code:<br /> Client-side code is written in JavaScript language as a Dojo class using <a href="http://dojotoolkit.org/documentation/tutorials/1.6/declare/" target="_blank">the class declaration system of Dojo 1.6</a>. This Dojo class handles all user interface operations. <br /> <br />Server-side code is written in Java as a servlet and is exposed to the client-side via REST API's (here: GET/POST requests sent via <code>dojo.xhrGet</code> / <code>dojo.xhrPost</code>). <br /> <br />We developed two servlets for this application. The first servlet handles init/add/remove/query operations in MongoDB. The second servlet simply acts as a proxy to access the <a href="https://developers.google.com/maps/documentation/geocoding/" target="_blank">Google Geocoding API</a> from client-side Javascript in order to convert between addresses and geo coordinates (longitude/latitude). <br /> <br />Since the REST protocol is completely stateless, the server-side code is very easy to test. With a bit of refactoring, it's even possible to run the whole application in alternative servlet containers like Jetty, Tomcat or directly within the Eclipse IDE instead of the Domino server. <br /> <br />Personally, I really like this REST API based approach because it's clean, transparent and keeps technologies separated.  <br />It enables you to replace the server environment, the database system and the client-side UI toolkit at any time. You can even build multiple UIs (e.g. based on Dojo 1.6, 1.7 and Sencha's ExtJS) or mobile clients that work with the same REST API. <br /> <br /><strong>Diving into the code: server side</strong> <br />Our sample comes as an Eclipse plugin "<code>com.mindoo.mongo.test</code>" to be run on Domino's OSGi framework (tested with Domino 8.5.3 GA without any fixpacks or XPages extension library): <br /> <br /> <div align=center><img  src="http://www.mindoo.com/web/blog.nsf/dx/nosql-mongodb-plugin-small.jpg/$file/nosql-mongodb-plugin-small.jpg"></div> <br /> <br />As you can see above, I added the <a href="http://api.mongodb.org/java/2.6/overview-summary.html" target="_blank">Mongo API</a> classes to the plugin's classpath. <br />Adding the Mongo API classes to an NSF and using them directly from SSJS code <em>might</em> also be possible, but I prefer the plugin solution, because the MongoDB access is supposed to be a central service on the Domino server. In addition, by using a plugin we don't have any issues with Domino's restricted security manager that prevents operations to run properly in an XPages context (e.g. a lot of drivers are using Log4J for logging, which does not run well within an XPages application). <br /> <br />Our two servlets are defined in the plugin.xml file of the plugin: <br /> <br /><code><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />?xml version="1.0" encoding="UTF-8"?<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />?eclipse version="3.4"?<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />plugin<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />extension point="org.eclipse.equinox.http.registry.servlets"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />servlet alias="/mongotest" class="com.mindoo.mongo.test.servlet.MongoTestServlet" <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; load-on-startup="true"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/servlet<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/extension<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />extension point="org.eclipse.equinox.http.registry.servlets"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />servlet alias="/mongogeo" class="com.mindoo.mongo.test.servlet.GeoQueryServlet" <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; load-on-startup="true"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/servlet<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/extension<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/plugin<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />></code> <br /> <br />That's all you need to declare your own servlet on Domino. <br />After that, the servlet can either be accessed on the URL base level (<code>http://server/mongogeo</code>) or in the context of a Domino database (<code>http://server/path/to/db.nsf/mongotest</code>). <br /> <br />If called in the context of a database, the Domino HTTP server first makes sure that the current user is allowed to access the database and if not, it displays a login prompt. A utility class (<code>com.ibm.domino.osgi.core.context.ContextInfo</code>) can be used to get session/database objects for the current HTTP request. <br /> <br />In our sample, we use the first format for our Geo API query, because it's an open service of the server without access restriction. Anyone can use it and the URL is simple to remember. <br /> <br />The second URL format (/path/to/db.nsf/mongotest) is used to access MongoDB data. This enables us to check the user against the Notes database ACL to see if he is allowed to read or write MongoDB data. <br /> <br />Here is the method of our MongoDB access servlet that handles POST requests: <br /> <br /><code>protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { <br />&nbsp; &nbsp; &nbsp; &nbsp; Session session=ContextInfo.getUserSession(); <br />&nbsp; &nbsp; &nbsp; &nbsp; Database dbContext=ContextInfo.getUserDatabase(); <br />&nbsp; &nbsp; &nbsp; &nbsp; if (dbContext==null) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ServletUtils.sendHttpError(resp, HttpServletResponse.SC_FORBIDDEN, <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Servlet must be run in the context of a Domino database", null); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; try { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String pathInfo=req.getPathInfo(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ("/deleteplaces".equals(pathInfo)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isUserAuthenticated(MongoAccessMode.Write, session, dbContext)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ServletUtils.sendHttpError(resp, HttpServletResponse.SC_FORBIDDEN, <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Current user is not allowed to write data", null); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; <br />&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; doDeleteGridData(session, dbContext, req, resp); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if ("/addplaces".equals(pathInfo)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isUserAuthenticated(MongoAccessMode.Write, session, dbContext)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ServletUtils.sendHttpError(resp, HttpServletResponse.SC_FORBIDDEN, <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Current user is not allowed to write data", null); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; <br />&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; doAddGridData(session, dbContext, req, resp); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if ("/queryplaces".equals(pathInfo)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isUserAuthenticated(MongoAccessMode.Read, session, dbContext)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ServletUtils.sendHttpError(resp, HttpServletResponse.SC_FORBIDDEN, <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Current user is not allowed to read data", null); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; <br />&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; doQueryPlaces(session, dbContext, req, resp); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if ("/initdb".equals(pathInfo)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isUserAuthenticated(MongoAccessMode.Write, session, dbContext)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ServletUtils.sendHttpError(resp, HttpServletResponse.SC_FORBIDDEN, <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Current user is not allowed to write data", null); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; <br />&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; doInitDbWithValues(session, dbContext, req, resp); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if ("/cleardb".equals(pathInfo)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isUserAuthenticated(MongoAccessMode.Write, session, dbContext)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ServletUtils.sendHttpError(resp, HttpServletResponse.SC_FORBIDDEN, <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Current user is not allowed to write data", null); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; <br />&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; doClearDb(session, dbContext, req, resp); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ServletUtils.sendHttpError(resp, 500, "Unsupported command "+pathInfo, null); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; catch (Throwable e1) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e1.printStackTrace(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //avoid posting the full stacktrace to the user (for security reasons) <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ServletUtils.sendHttpError(resp, 500, "An error occurred processing the request. The error has been logged. Please refer to the server log files/console for details", null); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />}</code> <br /> <br />The code is pretty simple: We check if the user is allowed to call the specific service (read operations require the role <code>&#91;MongoDBRead&#93;</code>, write operations the role <code>&#91;MongoDBWrite&#93;</code> ) and then forward the request to helper methods. <br /> <br />Note that I am not going into full detail in this blog article how we actually access data in MongoDB. You can find that in the provided download archive and there is a great <a href="http://www.mongodb.org/display/DOCS/Java+Tutorial" target="_blank">tutorial at the MongoDB website about using the Java API</a>. <br /> <br />Believe me, this stuff is really easy to use! <br /> <br /> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/27.04.2012190009KLEMXN.htm" target="_blank">Click here for part 2 of this article!</a>  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/27.04.2012185938KLEMXB.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/27.04.2012185938KLEMXB.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>English slides for my Entwicklercamp 2012 session about NoSQL databases</title>
<pubDate>Thu, 5 Apr 2012 00:07:41 +0200</pubDate>
<description>
<![CDATA[ 
As promised, here are the translated files for my NoSQL session at this year's Entwicklercamp (developer camp) conference in Gelsenkirchen, Germany. I am still searching for time to polish the two ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/05.04.2012000741KLETXV.htm</link>
<category>NoSQL</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/05.04.2012000741KLETXV.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/05.04.2012000741KLETXV.htm</guid>
<content:encoded><![CDATA[ As promised, here are the translated files for my <a href="http://www.mindoo.com/web/blog.nsf/dx/27.03.2012190043KLEMY2.htm" target="_blank">NoSQL session</a> at this year's <a href=http://www.entwicklercamp.de/ec12/home target=_blank>Entwicklercamp</a> (developer camp) conference in Gelsenkirchen, Germany. <br /> <br /> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/EC12_Mindoo_T4S6-NoSQL_en.pdf/$file/EC12_Mindoo_T4S6-NoSQL_en.pdf"><img  alt="Image:English slides for my Entwicklercamp 2012 session about NoSQL databases" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/05.04.2012000741KLETXV.htm/content/M2?OpenElement" /></a> <br /></div> <br />I am still searching for time to polish the two demos: MongoDb integration in XPages apps and NoSQL integration in XPages apps. <br />Next week is blocked for German holidays. Need to work on the demos afterwards. <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/05.04.2012000741KLETXV.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/05.04.2012000741KLETXV.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Download link for my Entwicklercamp 2012 session slides about NoSQL databases (German)</title>
<pubDate>Tue, 27 Mar 2012 19:00:43 +0200</pubDate>
<description>
<![CDATA[ 
Here are the slides for my session about NoSQL databases at Entwicklercamp 2012 today. For the non-German audience: sorry for the German content, I hope Google translate will help. :-) I plan to tran ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/27.03.2012190043KLEMY2.htm</link>
<category>NoSQL</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/27.03.2012190043KLEMY2.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/27.03.2012190043KLEMY2.htm</guid>
<content:encoded><![CDATA[ Here are the slides for my session about NoSQL databases at Entwicklercamp 2012 today. For the non-German audience: sorry for the German content, I hope Google translate will help. :-) <br /> I plan to translate them to English, but this may take some time.  <br /><br> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/EC12_Mindoo_T4S6-NoSQL.pdf/$file/EC12_Mindoo_T4S6-NoSQL.pdf" target="_blank"><img  alt="Image:Download link for my Entwicklercamp 2012 session slides about NoSQL databases (German)" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/27.03.2012190043KLEMY2.htm/content/M2?OpenElement" /></a></div> <br /><br /> I will also write blog entries about my two demos: leveraging the MongoDb geo index feature from an XPages application and embedding the Neo4J graph databases in XPages (travelling salesman algorithm to find the best route in a graph). <br /> <br /><strong><span style="text-decoration:underline">Update:</span></strong> <br />The English slides of the session <a href="http://www.mindoo.com/web/blog.nsf/dx/05.04.2012000741KLETXV.htm" target="_blank">are now online</a>. <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/27.03.2012190043KLEMY2.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/27.03.2012190043KLEMY2.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Speaking at Entwicklercamp 2012 about NoSQL databases</title>
<pubDate>Mon, 19 Mar 2012 09:08:18 +0200</pubDate>
<description>
<![CDATA[ 
Yesterday I submitted my slides for this years Entwicklercamp in Gelsenkirchen, Germany. My session will provide an overview of the NoSQL market for the database types key value stores column orient ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/19.03.2012090818KLEBKA.htm</link>
<category>NoSQL</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/19.03.2012090818KLEBKA.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/19.03.2012090818KLEBKA.htm</guid>
<content:encoded><![CDATA[ Yesterday I submitted my slides for this years <a href=http://www.entwicklercamp.de target=_blank>Entwicklercamp</a> in Gelsenkirchen, Germany. My session will provide an overview of the NoSQL market for the database types <br /> <ul> <li>key value stores </li><li>column oriented databases </li><li>document oriented databases </li><li>and graph database</li></ul> <br />It discusses <a href=http://redis.io/ target=_blank>Redis</a>, <a href=http://cassandra.apache.org/ target=_blank>Apache Cassandra</a>, <a href=http://www.mongodb.org/ target=_blank>MongoDB</a> and <a href=http://neo4j.org/ target=_blank>Neo4j</a> in detail and I will be demo'ing, how to integrate MongoDB's geo-spatial indexing feature and Neo4j's graph search algorithms in XPages applications. <br /> <br />Finally, the session compares the feature sets of Lotus Notes with other NoSQL to see how compatitive Lotus Notes, one of the oldest NoSQL database systems, is today in this moving market. <br /> <br />Working on this topic was quite challenging, because there is A LOT of material to check out on the web, but it also was a lot of fun playing with the databases and building the demos. <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/19.03.2012090818KLEBKA.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/19.03.2012090818KLEBKA.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Icon resources on the web for commercial and non-commercial use</title>
<pubDate>Wed, 8 Feb 2012 08:44:18 +0200</pubDate>
<description>
<![CDATA[ 
As Web and Notes developers, we often need to find icons of various sizes to use them in our applications. Since I found a new massive resource of free icons yesterday, I thought it might be a good i ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/08.02.2012084418KLEB4A.htm</link>
<category>Notesdev</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/08.02.2012084418KLEB4A.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/08.02.2012084418KLEB4A.htm</guid>
<content:encoded><![CDATA[ As Web and Notes developers, we often need to find icons of various sizes to use them in our applications. <br /> Since I found a new <a href=http://openiconlibrary.sourceforge.net/ target=_blank>massive resource of free icons</a> yesterday, I thought it might be a good idea so share some URLs. <br /> <br /> For commercial applications, we bought the Icon Experience library a few years ago, which contains about 2500+ icons in 7 sizes at a very affordable price: <span style="text-decoration:underline"><br /> </span><a href=http://www.iconexperience.com/ target=_blank>http://www.iconexperience.com</a> <br /> <br /> Free icons with varying licenses can be found here: <br /> <span style="text-decoration:underline"><br /> </span><a href=http://openiconlibrary.sourceforge.net/ target=_blank>http://openiconlibrary.sourceforge.net</a> <span style="text-decoration:underline"><br /> </span><a href=http://www.freeiconsweb.com/>http://www.freeiconsweb.com</a> <span style="text-decoration:underline"><br /> </span><a href=http://www.famfamfam.com/ target=_blank>http://www.famfamfam.com</a> <span style="text-decoration:underline"><br /> </span><a href=http://p.yusukekamiyamane.com/ target=_blank>http://p.yusukekamiyamane.com</a> <br /> <br /> For the latter, licenses reach from GPL, LGPL, Creative Commons to Public Domain. I guess for pure inhouse development, this is not that important, but if you plan to sell your application or publish it on <a href=http://openntf.org/ target=_blank>OpenNTF</a>, you should doublecheck if the icon license is ok for your use case. <br /> <br /> Feel free to add your own favorites by commenting on this article!   ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/08.02.2012084418KLEB4A.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/08.02.2012084418KLEB4A.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #13: XPiNC app development tool</title>
<pubDate>Thu, 2 Feb 2012 16:24:12 +0200</pubDate>
<description>
<![CDATA[ 
I was just working on an XPiNC integration of a quite large application and had some trouble getting it to work in the Notes Client (the app was working well on the web already). Finding out why it wa ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/02.02.2012162412KLEL3Q.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/02.02.2012162412KLEL3Q.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/02.02.2012162412KLEL3Q.htm</guid>
<content:encoded><![CDATA[ I was just working on an XPiNC integration of a quite large application and had some trouble getting it to work in the Notes Client (the app was working well on the web already). Finding out why it was not working was even harder in this case than when dealing with "normal" XPages applications, because the application is not based on the Dojo web toolkit, but uses <a href=http://www.sencha.com/products/extjs/ target=_blank>Sencha's Ext JS</a> for the UI and is completely based on our own web app development framework. <br />The framework does not use XPages design elements at all, but follows a simple REST API architecture with standard servlets to produce the data and user interface. <br /> <br />The benefit of this approach is that web applications can be developed, run and debugged from a pure Eclipse environment. They can even run on an different servlet engine than the Domino server's http task and - thanks to our data abstraction layer - they can even store the whole app data in a non-Domino database and mix/merge data between different database types. <br /> <br />Another benefit is that almost all the code has been written by ourselves. So it's not a kind of blackbox, made by IBM, where it's hard to work around occuring issues, but we are able to track issues down right until the <tt>service(HttpServletRequest req, HttpServletResponse response) </tt>call coming from the web container. <br /> <br />The downside is of course, that apps developed with the framework do not make use of IBM's <a href=http://extlib.openntf.org/ target=_blank>XPages Extension Library</a>, that contains various powerful UI controls. So we needed to create them ourselves. <br /> <br />And regarding XPiNC development, there is another downside: JavaScript errors do not get logged/displayed in the Notes Client, unless you register your own global error handler (providing a function for window.onerror). <br />Normal XPiNC applications do already contain such an error handler (somewhere within the XSP API object), which uses an internal bridge to post the error content to the Notes Client's status bar. <br /> <br /><strong>The development tool</strong> <br /> <br />To make development of XPiNC applications easier, I have created a small Eclipse plugin that displays three icons in the Client's toolbar: <br /> <div align=center><img  alt="Image:XPages series #13: XPiNC app development tool" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/02.02.2012162412KLEL3Q.htm/content/M2?OpenElement" /></div> <br /> <br />The third icon lauches a piece of code that injects <a href=http://getfirebug.com/firebuglite target=_blank>Firebug lite</a> into the currently visible XPage: <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; <code><strong>public</strong> <strong>void</strong> run(IAction action) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IWorkbenchPart part =  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PlatformUI.<em>getWorkbench</em>().getActiveWorkbenchWindow().getPartService().getActivePart(); <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>if</strong> (part <strong>instanceof</strong> XspViewPart) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; XspViewPart xPart=(XspViewPart)part; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; XspXulRunnerBrowser browser=xPart.getWebBrowser(); <br />&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; HTMLDocument doc=browser.getDocument(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NodeList headNodes=doc.getElementsByTagName("head"); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>if</strong> (headNodes!=<strong>null</strong> &amp;&amp; headNodes.getLength()>0 <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp;&amp; headNodes.item(0) <strong>instanceof</strong> Element) { <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //add this snippet to the HTML DOM tree: <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //< script type="text/javascript" <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // src="https://getfirebug.com/firebug-lite.js" > < /script > <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String firebugUrl="https://getfirebug.com/firebug-lite-debug.js"; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Element headNode=(Element) headNodes.item(0); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Element scriptNode=doc.createElement("script"); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; scriptNode.setAttribute("type", "text/javascript"); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; scriptNode.setAttribute("src", firebugUrl); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headNode.appendChild(scriptNode); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>else</strong> { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MessageDialog.<em>openError</em>(Display.<em>getDefault</em>().getActiveShell(), "Error", <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "This action does only work within an XPiNC application!"); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; }</code> <br /> <br />The result looks like this: <br /><br> <div align=center><img  alt="Image:XPages series #13: XPiNC app development tool" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/02.02.2012162412KLEL3Q.htm/content/M3?OpenElement" /></div> <br /> <br />Using Firebug Lite, you can easily inspect the HTML DOM tree and CSS attributes of the current page. Another very useful feature is the <a href=http://getfirebug.com/logging target=_blank>Console API</a>, which you may know already from classic browser development: <br />it lets you write log/debug messages to the browser console (by calling console.log('...')) and has other nice features like stacktrace dumping of JavaScript calls. <br /> <br />To our surprise we found out that the pure Xulrunner engine, that is used to display XPages in the Notes Client, does not register the global "console" at all. So Firebug lite came to the rescue. You can find all your log messages in the Console tab. <br /> <br />The other two toolbar actions are even more powerful. One lets you define a custom script library URL, e.g. to a script library design element on a public or intranet web server. The other actions will then create a script tag in the current XPage that points to the library. That way, you can inject any code you like into the XPiNC application. <br /> <br /><strong>Download</strong> <br /> <br />Finally, here is the download link with the Eclipse plugin project, feature project and update site: <br /> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/xpinc-firebuglite-helper.zip/$file/xpinc-firebuglite-helper.zip" title="xpinc-firebuglite-helper.zip">xpinc-firebuglite-helper.zip</a> <br /> <br />Hope this helps! <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/02.02.2012162412KLEL3Q.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/02.02.2012162412KLEL3Q.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Lotusphere 2012: Download links for 105 additional session slides</title>
<pubDate>Sun, 22 Jan 2012 22:59:10 +0200</pubDate>
<description>
<![CDATA[ 
I just compared the current state of the Lotusphere 2012 website with my previously released list of session slide download links. I found 105 new slide downloads: ls12_20120122.csv ls12_20120122.htm ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/22.01.2012225910KLETSK.htm</link>
<category>Lotusphere 2012</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/22.01.2012225910KLETSK.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/22.01.2012225910KLETSK.htm</guid>
<content:encoded><![CDATA[ I just compared the current state of the <a href=http://www.socialbizonline.com target=_blank>Lotusphere 2012 website</a> with <a href="http://www.mindoo.com/web/blog.nsf/dx/17.01.2012105009KLELKX.htm" target="_blank">my previously released list of session slide download links</a>. <br />I found 105 new slide downloads: <br /> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/ls12_20120122.csv/$file/ls12_20120122.csv">ls12_20120122.csv</a> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/ls12_20120122.html/$file/ls12_20120122.html">ls12_20120122.html</a> <br /> <br />There are still a few missing slide decks, but it's a big step forward.  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/22.01.2012225910KLETSK.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/22.01.2012225910KLETSK.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Lotusphere 2012: download links for session slides</title>
<pubDate>Tue, 17 Jan 2012 10:50:09 -0400</pubDate>
<description>
<![CDATA[ 
I just spent some time to grab the download links of the sessions slides from the Lotusphere 2012 website. Since my Macbook Pro could not get a proper connection to the wireless network in Dolphin (ne ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/17.01.2012105009KLELKX.htm</link>
<category>Lotusphere 2012</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/17.01.2012105009KLELKX.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/17.01.2012105009KLELKX.htm</guid>
<content:encoded><![CDATA[ I just spent some time to grab the download links of the sessions slides from the <a href=http://www.socialbizonline.com target=_blank>Lotusphere 2012 website</a>. Since my Macbook Pro could not get a proper connection to the wireless network in Dolphin (network is quite bad both at Lotusphere and in the Yacht Club we are staying in), I had to do this on the iPhone, because it was the only device that got an IP address. That was fun. ;-) <br /> <br />So here are the links to the slides that are available so far, sorted by session ID. Unfortunately, many are still missing. From our last years experience, the speakers are not the one to blame here. All had to submit their slides back in December. <br /> <br />Hopefully, the remaining session slides will follow shortly. <br /> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/ls12_20120117.csv/$file/ls12_20120117.csv">ls12_20120117.csv</a> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/ls12_20120117.html/$file/ls12_20120117.html">ls12_20120117.html</a> <br /> <br />Use your preferred download utility (e.g. <a href=https://addons.mozilla.org/de/firefox/addon/downthemall/ target=_blank>DownThemAll</a>) for download. You need to be logged in on the LS12 website before downloading.  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/17.01.2012105009KLELKX.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/17.01.2012105009KLELKX.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Status report / no session submission for LS12</title>
<pubDate>Mon, 7 Nov 2011 10:27:35 +0200</pubDate>
<description>
<![CDATA[ 
It's been some time since the last blog post in July. The last weeks have been incredibly busy, working five days a week on 3-4 projects at customers on-site does not leave much time for blogging and it does not look like this will change very soon.
To give you an impression, here are a few things that we've been working on ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/07.11.2011102731KLED4S.htm</link>
<category>Lotusphere 2012</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/07.11.2011102731KLED4S.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/07.11.2011102731KLED4S.htm</guid>
<content:encoded><![CDATA[ It's been some time since the last blog post in July. The last weeks have been incredibly busy, working five days a week on 3-4 projects at customers on-site does not leave much time for blogging and it does not look like this will change very soon. <br /> To give you an impression, here are a few things that we've been working on: <br /> <strong><br /> Development of an OSGi based web application framework with Ext.js UI </strong><br /> Abstraction layer for web applications that unifies data access across document-oriented and relational database systems, allows for tracking of data object changes (old/new values, group multi-object changes as transactions), different kinds of data serialization like XML or JSON and visualizing data with an Ext.js based, dynamically created web UI (using <a href=http://jamon.org/ target=_blank>Jamon</a> template language) that reads and writes contents through REST APIs. The framework can run from pure Eclipse and also in Domino's OSGi container. <br /> <strong><br /> Development of an OSGi based XPages application framework with Dojo UI</strong> <br /> XPages extensibility API add-on to develop the backend code of XPages directly in Java instead of writing SSJS code or Expression Language to bridge between UI element events/properties and application code. <br /> The framework uses Java Annotations and Java Reflection APIs for UI/backend code weaving. <br /> <strong><br /> Development of an IBM Websphere portal server applications</strong> <br /> Custom development of market-analysis application for consumer goods industry. <br /> <strong><br /> Development of dynamic web application based on Glassfish and JPA, with jQuery and Highcharts</strong> <br /> Data analysis tool for the buying department of a German automotive company. <br /> <strong><br /> Plugin development for the Lotus Notes Client</strong> <br /> Several productivity enhancement plugins for the Lotus Notes Client <br /> <strong><br /> Plugin deployment support</strong> <br /> Autodetection routine for XPages applications in Client/Server to automatically check for required Eclipse features/plugins when an application is opened (implemented in Lotusscript) so that the XPages runtime does not display those confusing error messages about missing XPages extensions. Instead, errors are properly handled without user interaction and missing features are automatically deployed on the machine. <br /> <strong><br /> XPiNC development framework</strong> <br /> Spent time to work on enhancements for the <a href=http://xpages2eclipse.mindoo.com/ target=_blank>XPages2Eclipse</a> toolkit that provides Eclipse APIs to XPages applications in the Lotus Notes Client. <br /> <strong><br /> Classic Domino web application development</strong> <br /> Improved round tripping quality of richtext editing between web browser and Notes Client including paste optimization from MS Word. Solution uses a combination of CKeditor add-ons and HTML/DXL conversions developed in Lotussript code for R7. &nbsp;Customer: print industry <br /> <strong><br /> Classic Notes Client development</strong> <br /> Built a Notes application to automatically deploy and update a list of mail folders to iOS users on Traveler. <br /> <br /> <strong><hr><br /> A word about Lotusphere 2012</strong> <br /> Since time is so limited, <strong>we decided not to submit a session proposal for Lotusphere 2012</strong>. <br /> <br /> We will however participate with full conference pass and I just booked hotel and flight two days ago. In contrast to previous years, we will arrive one day earlier, on Friday, 13th of January 2012 (hopefully not a bad day for travel, at least it's a direct flight :-)). <strong><br /> Are there any plans yet for a blogger meeting for a beer or two on Saturday 14th like in previous years?</strong> <br /> <br /> Another reason not to submit a session is that things get more complicated year after year. To learn about OSGi development or XPages extensibility APIs in a hands-on session for a day or two does make much more sense than watching a one hour presentation. <br /> <br /> We could have submitted our plugin development session from last year another time (<a href="http://www.mindoo.com/web/blog.nsf/dx/06.02.2011171725KLEM4Y.htm" target="_blank">overview of plugin development for Notes Client and DDE with 14 demos</a>), because slides and demos are already done. But that session (which got very good feedback at LS11) has now been presented four times at two conferences (Lotusphere and German Entwicklercamp 2010/2011). It's hard to get motivated for the 5th time :-). <br /> <br /> <br /> So, to sum up this long blog entry, I am really looking forward to seeing many of you guys at LS12 - and to having more time to work on concepts and product prototypes in the next weeks.   ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/07.11.2011102731KLED4S.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/07.11.2011102731KLED4S.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #12: XAgents and performance bottlenecks</title>
<pubDate>Sun, 17 Jul 2011 10:18:55 +0200</pubDate>
<description>
<![CDATA[ 
XAgent is a term that describes the equivalent of a classic Notes web agent in XPages technology: an XPage is called via URL and produces any kind of data (e.g. HTML, dynamic images, data in JSON form ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/17.07.2011101855KLEBRW.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/17.07.2011101855KLEBRW.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/17.07.2011101855KLEBRW.htm</guid>
<content:encoded><![CDATA[ <em>XAgent</em> is a term that describes the equivalent of a classic Notes web agent in XPages technology: an XPage is called via URL and produces any kind of data (e.g. HTML, dynamic images, data in JSON format or ODF documents) by sending Strings or even raw bytes directly to the browser. <br />&nbsp;<br /> Chris Toohey and Stephan Wissel have already blogged about this topic a few years ago and discussed some use cases: <br /> <span style="text-decoration:underline"><br /> </span><a href=http://www.dominoguru.com/pages/domino_rest_xpages_part1.html target=_blank><span style="text-decoration:underline">IBM Lotus Notes Domino REST Web Services via XPage XAgents</span></a> <span style="text-decoration:underline"><br /> </span><a href="http://www.wissel.net/blog/d6plinks/SHWL-7MGFBN" target=_blank><span style="text-decoration:underline">Web Agents XPages style</span></a>  <br /> <br /><strong>How to write an XAgent</strong> <br />To write an XAgent, you basically need to do two things: first you add the attribute <code>rendered="false"</code> to the <code>xp:view</code> tag of an XPage to prevent the XPages engine from rendering any output. Second, you need to write the code that produces the data and add it to the beforeRenderResponse event of an XPage. <br /> <br />Here are two simple example XAgents. The first one writes XML content to the writer object of the servlet response (which is used to return character data): <br /> <br /><code><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />?xml version="1.0" encoding="UTF-8"?<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:this.beforeRenderResponse<img  src="http://www.mindoo.com/web/blog.nsf/dx//$file//icons/ecblank.nsf" width="1" height="1" /<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!&#91;CDATA&#91;#{javascript:try { <br />&nbsp; &nbsp; &nbsp; &nbsp; var uName = session.createName(session.getEffectiveUserName()); <br />&nbsp; &nbsp; &nbsp; &nbsp; var exCon = facesContext.getExternalContext(); <br />&nbsp; &nbsp; &nbsp; &nbsp; var response = exCon.getResponse(); <br />&nbsp; &nbsp; &nbsp; &nbsp; var writer = response.getWriter(); <br />&nbsp; &nbsp; &nbsp; &nbsp; response.setContentType("text/xml"); <br />&nbsp; &nbsp; &nbsp; &nbsp; response.setHeader("Cache-Control", "no-cache"); <br />&nbsp; &nbsp; &nbsp; &nbsp; writer.write("<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />?xml version=\"1.0\" encoding=\"UTF-8\"?<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>\n"); <br />&nbsp; &nbsp; &nbsp; &nbsp; writer.write("<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />test<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>Hello "+uName.getAbbreviated()+"<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/test<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>"); <br />&nbsp; &nbsp; &nbsp; &nbsp; facesContext.responseComplete(); <br />} <br />catch (e) { <br />&nbsp; &nbsp; &nbsp; &nbsp; _dump(e); <br />}}&#93;&#93;><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:this.beforeRenderResponse<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:view<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />></code> <br /> <br />The second example demonstrates how you can load a file resource from the database design and write it to the output stream object of the servlet response: <br /> <br /><code><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />?xml version="1.0" encoding="UTF-8"?<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:this.beforeRenderResponse<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!&#91;CDATA&#91;#{javascript:try { <br />&nbsp; &nbsp; &nbsp; &nbsp; var exCon = facesContext.getExternalContext(); <br />&nbsp; &nbsp; &nbsp; &nbsp; var response = exCon.getResponse(); <br />&nbsp; &nbsp; &nbsp; &nbsp; var outStream = response.getOutputStream(); <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; //load a file resource from db design and write it to the output stream <br />&nbsp; &nbsp; &nbsp; &nbsp; var cl=com.ibm.domino.xsp.module.nsf.NotesContext.getCurrent().getModule().getModuleClassLoader(); <br />&nbsp; &nbsp; &nbsp; &nbsp; var buf=new byte&#91;16384&#93;; <br />&nbsp; &nbsp; &nbsp; &nbsp; var len; <br />&nbsp; &nbsp; &nbsp; &nbsp; var filePath="/test/document.docx"; <br />&nbsp; &nbsp; &nbsp; &nbsp; var inStream=cl.getResourceAsStream(filePath); <br />&nbsp; &nbsp; &nbsp; &nbsp; if (inStream==null) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var errMsg="File "+filePath+" not found"; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _dump(errMsg); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.sendError(404, errMsg); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; else { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //set mime type according to file type <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.setHeader("Cache-Control", "no-cache"); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //send http header with filename (needed so that the browser does not use the XPage's name as filename) <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.setHeader("Content-Disposition", 'attachment; filename="document.docx"'); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //read bytes from inStream into the buffer <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while ((len=inStream.read(buf))<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />-1) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //and write the data to the output stream <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; outStream.write(buf, 0, len); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inStream.close(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; outStream.close(); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; facesContext.responseComplete(); <br />} <br />catch (e) { <br />&nbsp; &nbsp; &nbsp; &nbsp; _dump(e); <br />}}&#93;&#93;<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:this.beforeRenderResponse<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:view<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />></code> <br /> <br />The loaded file resource must be part of the NSF project's build path to make the XPage code find it (that's where the module classloader is looking for files). <br />Please refer to <a href="http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm" target="_blank"/>part two of this XPages series</a> to get more information about how to add a folder to the build path. <br /> <br /> <div align=center> <br /><img  alt="Image:XPages series #12: XAgents and performance bottlenecks" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/17.07.2011101855KLEBRW.htm/content/M2?OpenElement" /></div> <br />If you just want to offer a file for download, developing an XAgent to stream the data would probably be the wrong solution. <br /> <br />In that case, you should add your files to the database design in the Java Perspective of Domino Designer instead and reference them directly in a URL. This is something that is used in the OpenNTF project <a href=http://mobilecontrols.openntf.org/ target=_blank>XPages Mobile Controls</a> to add a newer Dojo version (e.g. 1.6 with advanced mobile device support) to a Domino server than the default one (e.g. version 1.4.3 for Lotus Domino 8.5.2). <br /> <br />But the second code example from above could of course be modified to do something more useful, for example to replace placeholders in the file, create a zip file from multiple files on the fly using Java's <a href=http://download.oracle.com/javase/6/docs/api/java/util/zip/ZipOutputStream.html target=_blank>ZipOutputStream</a> or render a <a href="http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&amp;name=Xpages%20Captcha%20Custom%20Control" target=_blank>captcha image</a> for spam protection. <br /> <br /><strong>Sounds great?</strong> <br />Well, before you start thinking about building large applications based on this approach, you should read on to get to know about it's limitations. <br /> <br /><strong>The limitations</strong> <br />What I'm going to show you is not only a limitation of XAgents, but of XPages technology in general. For XPages producing the user interface of an application, this limitation may not be critical, but it can become a <strong>show stopper</strong> for using them the XAgent way. <br /> <br />I've created a small test application with three XPages: Start.xsp, Frame1.xsp and Frame2.xsp (<a href="http://www.mindoo.com/web/blog.nsf/dx/xsp-rendering-synchronization.zip/$file/xsp-rendering-synchronization.zip">download link</a>). The first one (Start.xsp) contains two iframes and a button. By clicking on the button, the other two XPages are loaded as iframe contents:  <br /> <br /><code>var now=new Date(); <br />var nowTime=now.getTime(); <br />var iframe1=document.getElementById("iframe1"); <br />var iframe2=document.getElementById("iframe2"); <br />iframe1.src=document.location.pathname+"/Frame1.xsp?startTime="+nowTime; <br />iframe2.src=document.location.pathname+"/Frame2.xsp?startTime="+nowTime;</code> <br /> <br />Frame1.xsp contains beforeRenderResponse event code that delays the rendering for 5000 milliseconds (<code>java.lang.Thread.sleep(5000)</code>), while Frame2.xsp waits for 2500 milliseconds. <br /> <br />You would expect that both XPages are opened and rendered concurrently. Because of the delay, Frame2.xsp should be visible first, then Frame1.xsp. <br /> <br />Unfortunately, the output looks like this instead (click on the image to open the test application): <br /> <div align=center> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx//web/samples/xsp-rendering-synchronization.nsf" target=_blank><img  alt="Image:XPages series #12: XAgents and performance bottlenecks" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/17.07.2011101855KLEBRW.htm/content/M3?OpenElement" /></a></div> <br />Frame1.xsp is displayed first, followed by Frame2.xsp. Frame2.xsp takes about 7600 milliseconds to be rendered, which is the sum of both delays, because <font color="#ff0000"><strong>the XPages engine does not render multiple XPages in an application at the same time for a single user</strong></font>. <br /> <br />It was a real surprise when we noticed this effect in a customer project. Our UI was based on the <a href=http://www.sencha.com/ target=_blank>Ext JS</a> toolkit which is heavily using REST services to read the UI component data. Our plan was to use XAgents for those REST services, but we quickly noticed that all UI elements only received data one at a time, which was a no-go for the application UI performance. Nothing was loading in parallel. <br /> <br />There are technical reasons for such a restriction, as Philippe Riand, XPages Chief Architect at IBM, explained to me in April 2011. <br />As you may know, the XPages runtime is based on JSF technology, which uses a tree of components on the server side that represents the structure of a web page and its current state. The tree is created/restored when a HTTP request comes in and saved/discarded after it is completed. <br />Unfortunately, this tree does not support being accessed by two concurrent threads, which would break many things like data sources and component states. <br /> <br />To prevent this to happen, XPages synchronizes on the user session object (<a href=http://download.oracle.com/javaee/6/api/javax/servlet/http/HttpSession.html target=_blank>HttpSession</a>), so that only one thread can access the tree at a time. But by synchronizing on the user session (and not just on the component tree instance), the XPages dev crew also prevented any other XPage in an application from running (the Domino server seems to assign session objects on a per database basis).  <br /> <br />The consequence is that you should think twice about your XPages application architecture, if you have many concurrent HTTP requests or if some of them take a lot of time to be processed. <strong>An XAgent may be the easiest solution to deploy, but may not produce the best user experience in all cases</strong>. <br /> <br /><strong>Workarounds and solution</strong> <br />There is some hope that the situation will improve in Domino 8.5.3. <br /> <br />As Philippe said, the next XPages engine will be smarter in synchronization and synchronize less than previously. <br />In addition, there will be a new database property called <code>xsp.session.transient</code>. This flag means that unique session objects will be created per request to the server and discarded right after the request ended. This is a first attempt to provide session less mode. <br />If you use this option, then you can create one database with all the services and no synchronization will happen, as each request will have its own session object. <br /> <br />I have requested a more granular option so that you can activate session less mode for single XPages in an application, but I'm not sure if this will make 8.5.3. <br /> <br />For Domino 8.5.2, I can see three things that you can do if you can't live with this performance issue: <br /> <br /><strong>1. Move XPages that run for a long time to separate databases</strong> <br />This does not help a lot, but if you have an XPages application with an XPage that needs some time to process, you could move it to different database. In that case, the rest of the application would still be responsive, although your long running XPage for example produces a 100 MB log output in XML format that you want to download. <br /> <br /><strong>2. &nbsp;Write your own servlet in Java</strong> <br />By writing your own servlet as an Eclipse plugin running in Domino 8.5.2's OSGi framework, your code can run without any performance bottleneck caused by synchronization. See <a href="http://www.openntf.org/blogs/openntf.nsf/d6plinks/NHEF-8JB9DN" target=_blank>this article in the OpenNTF blog</a> for implementation details. <br /> <br /><strong>3. There is an app for that :-)</strong> <br />As you may know, we have developed <a href=http://xpages2eclipse.mindoo.com target=_blank>XPages2Eclipse</a>, an extensive toolkit for XPages development, which is currently in beta-testing (June 2011). The articles <a href=http://xpages2eclipse.mindoo.com/web/x2ewiki.nsf/dx/JavaScriptServletMode target=_blank>Building servlets in JavaScript</a> and <a href=http://xpages2eclipse.mindoo.com/web/x2ewiki.nsf/dx/JavaServletMode target=_blank>Building servlets in Java</a> demonstrate how you can write your own servlet implementation in JavaScript or Java language. <br />This solution reads all your code from the database design, so that you don't have to deploy every servlet individually. Just install the toolkit on a Domino server once, then you can create any number of servlets by writing code in Domino Designer and replicate them to the server. <br /> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/17.07.2011101855KLEBRW.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/17.07.2011101855KLEBRW.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages2Eclipse: New Beta-Build available</title>
<pubDate>Mon, 11 Jul 2011 21:48:16 +0200</pubDate>
<description>
<![CDATA[ 
Today I got notified by one of the beta testers that the keystore template in the update site database is corrupt/incomplete. Thanks for that! The issue should now be fixed, I just uploaded a new ver ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/11.07.2011214816KLER8Q.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/11.07.2011214816KLER8Q.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/11.07.2011214816KLER8Q.htm</guid>
<content:encoded><![CDATA[ Today I got notified by one of the beta testers that the keystore template in the update site database is corrupt/incomplete. Thanks for that! <br /> <br />The issue should now be fixed, I just uploaded a new version of the update site archive, which you can download via the download link on the <a href=/web/web.nsf/id/pa_products_xpages2eclipse_en.html target=_blank>product website</a> : <br /> <div align=center> <br /><img  alt="Image:XPages2Eclipse: New Beta-Build available" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/11.07.2011214816KLER8Q.htm/content/M2?OpenElement" /></div> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/11.07.2011214816KLER8Q.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/11.07.2011214816KLER8Q.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Beta version of XPages2Eclipse available: Development toolkit for XPages in the Notes Client</title>
<pubDate>Wed, 29 Jun 2011 09:10:37 +0200</pubDate>
<description>
<![CDATA[ 
It's been quite silent in this blog since the last posting in March, but we had a good reason to concentrate on our work: Today we are releasing the first public beta version of a new XPages develop ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/29.06.2011091037KLEAF7.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/29.06.2011091037KLEAF7.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/29.06.2011091037KLEAF7.htm</guid>
<content:encoded><![CDATA[ It's been quite silent in this blog since the last posting in March, but we had a good reason to concentrate on our work: <br /> <div align=center> <br /><font color="#ff0000"><strong>Today we are releasing the first public beta version of a new XPages development toolkit to the public!</strong></font></div> <br />It's called <strong>XPages2Eclipse</strong>, a language extension for XPages development in the Lotus Notes Client 8.5.2 and higher.  <br /> <div align=center> <br /><font color="#ff0000"><strong>With XPages2Eclipse, XPages applications become first class citizens in the Lotus Notes Client.</strong></font></div> <br />The toolkit contains a variety of APIs that developers can leverage to connect their XPages applications to the Eclipse-based Notes Client UI, classic Lotus Notes applications and even communicate with IBM Lotus Symphony R3, <strong>all from server-side JavaScript (SSJS) code</strong>. <br /> <br />Here are only a few features that the toolkit has to offer: <ul> <li><strong>Embed existing Notes applications:</strong> fill in Notes forms and Emails with data from XPages applications, access documents selected in classical Notes views, run existing LotusScript code </li><li><strong>Import or export of data from IBM Lotus Symphony</strong>, supporting documents, spreadsheets and presentations </li><li><strong>Execute document attachments</strong> with associated desktop-applications (for Windows, Linux and Mac OS) </li><li><strong>Access the system clipboard</strong> to store HTML, text, images or files </li><li><strong>Execute long-running operations in the background</strong>, display their progress and let the user cancel the operation if necessary </li><li><strong>Convenient features</strong> like file selection, including multi-selection, and folder selection </li><li><strong>Launch JavaScript code</strong> on Notes Client startup, when a toolbar button is clicked and on specific UI events like focus changes in the Client  </li><li><strong>Develop servlets using Javascript and Java</strong> with code stored in NSF</li></ul>To get more information, download a beta version and find <strong>a lot of documentation with demo applications</strong> please visit the XPages2Eclipse product area on our website: <br /> <br /> <div align=center> <br /><span style="font-size:16px;"><a href=http://xpages2eclipse.mindoo.com target=_blank>http://xpages2eclipse.mindoo.com - for our English audience</a></span> <br /> <br /> <br /><span style=font-size:16px;"><a href=http://xpages2eclipse.mindoo.de target=_blank>http://xpages2eclipse.mindoo.de - for our German audience</a></span></div> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/29.06.2011091037KLEAF7.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/29.06.2011091037KLEAF7.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #11: Log data changes using beans and the DataObject interface</title>
<pubDate>Fri, 18 Mar 2011 10:47:26 +0200</pubDate>
<description>
<![CDATA[ 
As promised last week, this blog article demonstrates how managed beans can be used to create and edit Notes documents, transparently log data changes and even support alternative storage systems. Thi ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm</link>
<category>Lotusphere 2011</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm</guid>
<content:encoded><![CDATA[ As promised <a href="http://www.mindoo.de/web/blog.nsf/dx/22.07.2009175255KLELM7.htm?opendocument&amp;comments#10.03.2011115229SERERU.htm">last week</a>, this blog article demonstrates how managed beans can be used to create and edit Notes documents, transparently log data changes and even support alternative storage systems. This is my third and final sample from the Lotusphere 2011 session <a href="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011105917KLEDQM.htm" target="_blank">BP212</a>.  <br /> <br />If you followed this <a href="http://www.mindoo.com/web/blog.nsf/dx//web/blog.nsf/archive?openview&amp;title=XPages&amp;type=cat&amp;cat=XPages" target=_blank>blog series</a> from the beginning and take a look at the slides for the session BP212, you already know most of the technical details this sample is about: <ul> <li>declare managed beans </li><li>bind XPages UI fields with bean properties </li><li>use managed properties to declaratively configure managed beans</li></ul> <br />So there is not much new content, but it's a nice sample that shows how all the parts fit together in an application. <br /> <br /> <br />The download for this article contains a simple Notes database with four XPages: <br /> <br /><strong>Start.xsp</strong> <br />This XPage is the starting point when you open the database. It contains three buttons to create new company documents, view a list of existing documents and a button to view a change log that tracks data changes in the database: <br /> <div align=center> <br /><img  alt="Image:XPages series #11: Log data changes using beans and the DataObject interface" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm/content/M2?OpenElement" /></div> <br /> <br /><strong>Company.xsp</strong> <br />The Company XPage let's you create and edit company documents with fields for the company name and its address: <br /> <div align=center> <br /><img  alt="Image:XPages series #11: Log data changes using beans and the DataObject interface" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm/content/M3?OpenElement" /></div> <br /> <br />Here is the source code for the XPage. The important parts are marked in <font color="#ff0000">red</font>: <br /> <br /><code><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />?xml version=<em>"1.0"</em> encoding=<em>"UTF-8"</em>?<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:view xmlns:xp=<em>"http://www.ibm.com/xsp/core"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:span style=<em>"font-size:18pt;text-decoration:underline"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>Company information<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:span<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br style=<em>"font-size:18pt"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:span style=<em>"font-size:18pt"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>Company name:<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:span<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:inputText id=<em>"inputText1"</em> style=<em>"width:295.0px;font-size:18pt"</em> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value=<em>"<font color="#ff0000">#{data.companyname}</font>"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:inputText<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:span style=<em>"font-size:18pt"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>Address 1<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:span<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br style=<em>"font-size:18pt"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:inputText id=<em>"inputText2"</em> style=<em>"width:295.0px;font-size:18pt"</em> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value=<em>"<font color="#ff0000">#{data.address1}</font>"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:inputText<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:span style=<em>"font-size:18pt"</em>>Address 2 <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:span<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:inputText id=<em>"inputText3"</em> style=<em>"width:295.0px;font-size:18pt"</em> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value=<em>"<font color="#ff0000">#{data.address2}</font>"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:inputText<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:span style=<em>"font-size:18pt"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; City <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:span<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br style=<em>"font-size:18pt"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:inputText id=<em>"inputText4"</em> style=<em>"width:295.0px;font-size:18pt"</em> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value=<em>"<font color="#ff0000">#{data.city}</font>"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:inputText<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:button value=<em>"Save"</em> id=<em>"saveButton"</em> style=<em>"font-size:18pt"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:eventHandler event=<em>"onclick"</em> submit=<em>"true"</em> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; refreshMode=<em>"complete"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:this.action<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!&#91;CDATA&#91;#{javascript:<em><font color="#ff0000"></em>actions&#91;"save"&#93;.execute();</font> <br />context.redirectToPage("CompanyList");}&#93;&#93;<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:this.action<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:eventHandler<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:button<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:button value=<em>"Cancel"</em> id=<em>"cancelButton"</em> style=<em>"font-size:18pt"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:eventHandler event=<em>"onclick"</em> submit=<em>"true"</em> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; refreshMode=<em>"complete"</em><img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:this.action<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!&#91;CDATA&#91;#{javascript:context.redirectToPage("Start");}&#93;&#93;<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:this.action<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:eventHandler<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:button<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:view<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />></code> <br /> <br />We do not directly bind UI fields to document items (there is no document datasource declaration), but use a managed bean called "data" instead, hence the EL strings like <code>#{data.companyname}</code>. <br /> <br />Actually, the bean implementation does not handle the load/store operation itself, it just redirects the calls to another class that handles them. This redirection is used to be able to change the storage system later on, e.g. from NSF to SQL, without modifying anything in the XPages UI. <br /> <br />All we need to do is change a single managed property in the faces-config.xml file, which can be found in the WebContent/WEB-INF folder in the <a href="http://www.mindoo.com/web/blog.nsf/dx//web/blog.nsf/dx/15.07.2009152504KLEHR8.htm?opendocument&amp;comments" target=_blank>Java perspective of DDE</a>: <br /> <br /><code><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />?xml version=<em>"1.0"</em> encoding=<em>"UTF-8"</em>?<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />faces-config<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />managed-bean<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />managed-bean-name<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>data<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/managed-bean-name<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />managed-bean-class<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>com.ls11.uibackend.PageDataBean <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/managed-bean-class<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />managed-bean-scope<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>request<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/managed-bean-scope<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />managed-property<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />property-name<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>dataProviderClass<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/property-name<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <font color="#009000"><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!-- Dummy implementation to simulate loaded data --<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!-- <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />value<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>com.ls11.uibackend.dummy.DummyPageDataProvider<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/value<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!-- Implementation that loads/stores data in a Notes database --<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!--  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />value<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>com.ls11.uibackend.nsf.NSFPageDataProvider<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/value<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;--<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />></font> <br />&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; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />value<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><font color="#ff0000">com.ls11.uibackend.dummy.DummyPageDataProvider</font><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/value<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/managed-property<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/managed-bean<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />managed-bean<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />managed-bean-name>actions</managed-bean-name<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />managed-bean-class>com.ls11.uibackend.PageActionsBean <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/managed-bean-class<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />managed-bean-scope>request</managed-bean-scope<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; &nbsp; &nbsp; &nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/managed-bean<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!--AUTOGEN-START-BUILDER: Automatically generated by IBM Lotus Domino Designer. Do not modify.--<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />&nbsp; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />!--AUTOGEN-END-BUILDER: End of automatically generated section--<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/faces-config<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />></code> <br /> <br />As you can see, the database contains two implementations to load/store data: <br />The <code>NSFPageDataProvider</code> &nbsp;reads the <code>documentId</code> query string parameter and uses the corresponding Notes document to get the data. <code>DummyPageDataProvider</code> is just a dummy implementation that creates placeholder text, which might be useful for the UI designer to already test the UI even though the database developer is still working on the NSF/SQL storage code. <div align=center> <br /><img  alt="Image:XPages series #11: Log data changes using beans and the DataObject interface" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm/content/M4?OpenElement" /> <br />Company XPage powered by the DummyPageDataProvider</div> <br /> <br /> <br /><strong>CompanyList.xsp</strong> <br />The CompanyList XPage contains a view control and displays the company documents in the database: <div align=center> <br /><img  alt="Image:XPages series #11: Log data changes using beans and the DataObject interface" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm/content/M5?OpenElement" /></div> <br /> <br /><strong>ChangeLog.xsp</strong> <br />The main benefit of using managed beans for the UI bindings instead of directly binding fields to document datasource properties is that you can track, log, transform and prevent data changes in your code. During the page request, JSF calls the method <code>setValue</code> in our Java class with the item names and the new item values. <br /> <br />We can then compare the old and new values and create a log record if the value has been changed: <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; <strong><code>public</strong> <strong>void</strong> setValue(Object id, Object newValue) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Object oldValue=getValue(id); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>boolean</strong> changed=(newValue==<strong>null</strong> &amp; oldValue!=<strong>null</strong>) || (newValue!=<strong>null</strong> &amp;&amp; !newValue.equals(oldValue)); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>if</strong> (changed) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_changedValues.put(id.toString(), newValue==<strong>null</strong> ? <strong>null</strong> : newValue.toString()); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <font color="#ff0000">logChangedData(id.toString(), oldValue, newValue);</font> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; <font color="#009000">/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Create a new change log entry for the modified field <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <strong>@param</strong> id field name <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <strong>@param</strong> oldValue old value <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <strong>@param</strong> newValue new value <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</font> <br />&nbsp; &nbsp; &nbsp; &nbsp; <strong>private</strong> <strong>void</strong> logChangedData(String id, Object oldValue, Object newValue) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Session session=NotesContext.<em>getCurrent</em>().getCurrentSession(); <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>try</strong> { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DataChangeLogEntry newEntry=<strong>new</strong> DataChangeLogEntry(m_documentId==<strong>null</strong> || "".equals(m_documentId) ? "-New-" : m_documentId, session.getUserName(), <strong>new</strong> Date(), id, oldValue==<strong>null</strong> ? <strong>null</strong> : oldValue.toString(), newValue==<strong>null</strong> ? <strong>null</strong> : newValue.toString()); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_pendingLogEntries.add(newEntry); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <strong>catch</strong> (NotesException e) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>throw</strong> <strong>new</strong> FacesException(e); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; }</code> <br /> <br />When the Company XPage is saved, all pending log records are written to a permanent log list which is displayed in a data table on the ChangeLog XPage: <br /> <div align=center> <br /><img  alt="Image:XPages series #11: Log data changes using beans and the DataObject interface" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm/content/M6?OpenElement" /></div> <br /> <br /><strong>A word about com.ibm.xsp.model.DataObject</strong> <br />If you take a deeper look at the code in the sample database, you might notice that the data bean implements the interface <code>com.ibm.xsp.model.DataObject</code>. <br />This interface is part of the XPages runtime (<strong>not part of the JSF standard!</strong>) and simplifies both writing beans and the EL syntax to access bean properties. <br /> <br />You will also find this interface in the session slides for <a href="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011105917KLEDQM.htm" target="_blank">BP212</a>. Here is an excerpt from the slides: <br /> <br /><code> &nbsp; &nbsp; &nbsp; &nbsp;package com.acme.demo.persondata; <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; import com.ibm.xsp.model.DataObject; <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; public class PersonData implements DataObject { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public Class<?> getType(Object id) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <font color="#009000">// Return the type of class that id resolves to. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Complex case could return Employee or Customer</font> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Person.class; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public Object getValue(Object id) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <font color="#009000">// Retrieve a record from some store, based on id</font> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public boolean isReadOnly(Object id) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <font color="#009000">// You are free to implement your own, or rely on your underlying data store</font> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void setValue(Object id, Object value) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <font color="#009000">// Store value in your data store using id</font> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; }</code> <br /> <br />Implementing the <code>DataObject</code> interface makes JSF call the <code>setValue/getValue</code> methods in your bean for any string behind the bean name in the EL string: #{data.companyname&#93;, #{data.address1}, #{data.address2}, #{data.whatever}. <br /> <br />You don't have to write getter and setter methods for every property! <br /> <br />Please note that this could already be done without the <code>DataObject</code> interface by implementing the <code>java.util.Map</code> interface (JSF then calls the method <code>Map.get(Object)</code> instead of <code>DataObject.getValue(Object)</code>), but this XPages runtime class makes the implementation much easier and cleaner. <br /> <br />That's it for today! Here is the download archive with the sample database: <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/ls11_uibackendsep.zip/$file/ls11_uibackendsep.zip">ls11_uibackendsep.zip</a> <br /> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/18.03.2011104725KLEDH8.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/18.03.2011104725KLEDH8.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>The View article: XPath - A Flexible Solution for Filtering, Visualizing, and Binding XML Data in Your XPages Applications</title>
<pubDate>Thu, 3 Mar 2011 22:52:42 +0200</pubDate>
<description>
<![CDATA[ 
I just received the information that an article that I wrote for The View has been published on their website. This article describes a way to use the XPath query language in XPages Expression Language, something I demonstrated in the Lotusphere session BP212. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/03.03.2011225242KLETNJ.htm</link>
<category>The View</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/03.03.2011225242KLETNJ.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/03.03.2011225242KLETNJ.htm</guid>
<content:encoded><![CDATA[ I just received the information that an article that I wrote for <strong>The View</strong> has been published on their website. This article describes a way to use the XPath query language in XPages Expression Language, something I demonstrated in the Lotusphere session <a href="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011105917KLEDQM.htm" target="_blank">BP212</a>. <br /> <br />Here is the public abstract: <br /> <br /><strong>XPath - A Flexible Solution for Filtering, Visualizing, and Binding XML Data in Your XPages Applications</strong> <br /> <br />By using the XPath query language, you can query XML data in an XPages application and then seamlessly bind the results to the application&#8217;s fields and repeater controls. This enables you to easily and dynamically build interfaces using resources in your application or display XML data in a data table. Learn the syntaxes to use and get a demonstration of how to implement them in this flexible, easy-to-maintain solution. <br />XPath, the XML path query language, is a powerful tool for selecting nodes and attributes from an XML document. Using XPath statements in XPages expression language, you can build dynamic XPages content based on an XML configuration document. No third-party library is required for this task. All the functionality you need is already available in IBM Lotus Notes and Domino 8.5.2, and all the information you need is here. <br /><br> <div align=center><img  alt="Image:The View article: XPath - A Flexible Solution for Filtering, Visualizing, and Binding XML Data in Your XPages Applications" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/03.03.2011225242KLETNJ.htm/content/M2?OpenElement" /></div> <br />Download link of sample application: <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/theview_xpath-el.zip/$file/theview_xpath-el.zip">theview_xpath-el.zip</a> <br /> <br />Full article (subscription required): <br /><a href="http://bitly.com/fVj7zX" target="_blank">Article on eview.com</a>  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/03.03.2011225242KLETNJ.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/03.03.2011225242KLETNJ.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Slides from my two sessions at Entwicklercamp 2011 (German content)</title>
<pubDate>Mon, 28 Feb 2011 09:25:21 +0200</pubDate>
<description>
<![CDATA[ 
Here are the slides of my two sessions at Entwickercamp 2011, Gelsenkirchen/Germany. As always, it was an interesting and very well organized event. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/28.02.2011092521KLEBVX.htm</link>
<category>Entwicklercamp 2011</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/28.02.2011092521KLEBVX.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/28.02.2011092521KLEBVX.htm</guid>
<content:encoded><![CDATA[ Here are the slides of my <a href="http://www.mindoo.com/web/blog.nsf/dx/07.02.2011094938KLECD3.htm" target="_blank">two sessions</a> at Entwickercamp 2011, Gelsenkirchen/Germany. As always, it was an interesting and very well organized event. <br /> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/EC11_T1S5-XPages-Desktop-Features.pdf/$file/EC11_T1S5-XPages-Desktop-Features.pdf" title="XPages mit Desktop-Features ausstatten"><img  alt="Image:Slides from my two sessions at Entwicklercamp 2011 (German content)" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/28.02.2011092521KLEBVX.htm/content/M2?OpenElement" /><br>Session 1: Enhance XPages applications in the client with desktop features </a><br />  <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/EC11_T4S8-Java-APIs.pdf/$file/EC11_T4S8-Java-APIs.pdf" title="Add-ons für Client/Designer auf Basis neuer Java APIs von Lotus Notes 8.5.1 und höher"><br /> <img  alt="Image:Slides from my two sessions at Entwicklercamp 2011 (German content)" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/28.02.2011092521KLEBVX.htm/content/M3?OpenElement" /><br>Session 2: Leveraging the new Java APIs in IBM Lotus Notes 8.5.1/8.5.2 </a></div>  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/28.02.2011092521KLEBVX.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/28.02.2011092521KLEBVX.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Speaking at Entwicklercamp conference 2011 with two sessions</title>
<pubDate>Mon, 7 Feb 2011 09:49:38 +0200</pubDate>
<description>
<![CDATA[ 
Now that Lotusphere 2011 is over, I'm already preparing for the next conference: Entwicklercamp 2011 in Gelsenkirchen, Germany from 21st-23rd of February.

I will contribute two sessions to this great event with three days packed full of sessions for Notes/Domino developers. The first one is a rerun of an Entwicklercamp 2010 session with updated content, the second one is a completely new session. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/07.02.2011094938KLECD3.htm</link>
<category>Entwicklercamp 2011</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/07.02.2011094938KLECD3.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/07.02.2011094938KLECD3.htm</guid>
<content:encoded><![CDATA[ Now that Lotusphere 2011 is over, I'm already preparing for the next conference: <a href=http://www.entwicklercamp.de/ target=_blank>Entwicklercamp 2011</a> in Gelsenkirchen, Germany from 21st-23rd of February. <br /> <br /> I will contribute two sessions to this great event with three days packed full with sessions for Notes/Domino developers. The first one is a rerun of an Entwicklercamp 2010 session with updated content, the second one is a completely new session. <br /> <hr> <span style="text-decoration:underline"><br /> German session descriptions:</span> <br /> <strong><br /> Add-ons für Client/Designer auf Basis neuer Java APIs von Lotus Notes 8.5.1 und höher</strong> <br /> <br /> Wir präsentieren in der Session, wie sich Lotus Notes Client und Domino Designer (DDE) durch die Verwendung neuer Java-Programmierschnittstellen von Lotus Notes 8.5.1 und höher erweitern lassen. <br /> Nutzen Sie die neuen Java UI-Klassen, um Lösungen zu entwickeln, die mit bestehenden Domino-Anwendungen interagieren und diese erweitern, ohne dass das Design der Anwendungen geändert werden muss. Wir demonstrieren die Entwicklung solcher Erweiterungen in der Programmiersprache Java, gehen jedoch auch auf Wege ein, wie sich herkömmlicher Lotusscript-Code einbinden lässt. <br /> Der Domino Designer wird durch Eclipse-Plugins erweitert, um eigene Designänderungen an ausgewählten Designelementen durchzuführen. <br /> Die Session geht auf die verfügbaren APIs ein und gibt Tips&amp;Tricks für Einsteiger. Eine Reihe von kleinen Beispielanwendungen steht im Abschluss an die Session zum Download zur Verfügung. <br /> <strong><br /> XPages-Anwendungen mit Desktop-Features ausstatten</strong> <br /> <br /> Der IBM Lotus Notes Client stellt eine Fülle von Services und Features bereit, die in XPages-Anwendungen genutzt werden können, um mehr zu sein als nur lokale Web-Applikationen. <br /> In dieser Session zeigen wir, wie XPages-Anwendungen durch lokale Desktop-Features wie Menü-Integration, Office-Automation, Interaktion mit klassischen NSF-Inhalten, Eclipse API-Aufrufe und mehr erweitert werden können, ohne jedoch die gesamte Anwendung plattformabhängig zu machen. <br /> Die Session enthält eine Vielzahl an Demos und Tipps&amp;Tricks, um die Benutzerakzeptanz Ihrer eigenen Anwendung zu erhöhen! <br /> <hr> <span style="text-decoration:underline"><br /> English session descriptions:</span> <br /> <strong><br /> Leveraging the new Java APIs in IBM Lotus Notes 8.5.1/8.5.2</strong> <br /> <br /> The session demonstrates how IBM Lotus Notes and Domino Designer on Eclipse (DDE) clients can be enhanced by using the Java programming interfaces of IBM Lotus Notes 8.5.1 and above. Leverage new features such as new Java UI classes to build solutions that interact with and enrich existing Lotus Notes client applications &#8211; without actually changing the application's design. We'll show you how to develop usable extensions in Java, and introduce ways to reuse existing IBM LotusScript code! DDE can also easily be enhanced with Eclipse plug-ins that do exciting things such as add custom design functionality. You'll learn through many code examples, and take away best practices for developers new to Java. <br /> <strong><br /> Enhance XPages applications in the client with desktop features</strong> <br /> <br /> The IBM Lotus Notes client offers a rich set of services and features that XPages applications can leverage to be more than just local web applications. During this session, we'll demonstrate how local desktop features like menu integration, Office automation, interaction with legacy NSF contents, Eclipse API calls and more can greatly enhance Xpages applications without actually making the whole application platform dependent. Take away lots of demos and best practices to improve the usability of your own applications! <br />   ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/07.02.2011094938KLECD3.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/07.02.2011094938KLECD3.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #10: Running JUnit tests on XPages code</title>
<pubDate>Mon, 7 Feb 2011 09:03:00 +0200</pubDate>
<description>
<![CDATA[ 
The 10th article of the XPages series deals with the first sample I demo'ed for the Lotusphere session BP212 - Deep Dive into IBM XPage Expression Language Syntax:
It shows how you can develop and test most of your XPages code outside of DDE. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm</link>
<category>Lotusphere 2011</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm</guid>
<content:encoded><![CDATA[ The 10th article of the XPages series deals with the first sample I demo'ed for the Lotusphere session <a href="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011105917KLEDQM.htm" target="_blank">BP212 - Deep Dive into IBM XPage Expression Language Syntax</a>: <br /> It shows how you can develop and test most of your XPages code outside of DDE. <br /> <strong><br /> So why should you development code outside of DDE?</strong> <span style="text-decoration:underline"><br /> 1. Workaround for classloader issues</span> <br /> Well, you can experience a very nasty caching behaviour when you develop Java code in the Java perspective of DDE and test it live in an XPages application on the client. This might result in ClassCastExceptions like "com.company.packagename.MyClass cannot be cast to com.company.packagename.MyClass", which is caused by the JSF servlet: It still has a cached instance of the first bean in memory, created with one classloader while it tries to run the XPages application after code changes with a new classloader which is incompatible with the first one used. <br /> <br /> This behaviour is discussed in <a href="http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Creating_a_Java_Control_in_an_NSF" target=_blank>an article</a> in the Lotus Notes and Domino Application Development Wiki and IBM recommends to restart the http task in this case (only a viable option if you develop on a local Domino server), because this shuts down and restarts the JVM used to load the classes. Unfortunately this is not an option for development in the Notes Client, since you really don't want to restart your Notes Client/DDE every time you change code. <br /> In addition to classloader issues, the JSF runtime also seems to cache Java classes and XPages intermittently, a problem that I faced just recently when I worked on the demos for BP212 and tested them in the client. <br /> <span style="text-decoration:underline"><br /> 2. Version control for source code</span> <br /> Another reason why you should develop code outside of DDE is that you can use version control systems like Subversion or CVS. With 8.5.2 and an <a href="http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&amp;name=Source%20Control%20Enablement%20for%20Designer" target=_blank>additional source control plugin from OpenNTF</a> this aspect is less important than before, but I still prefer to have my code outside of a virtual file system that is stored in an NSF. I just don't trust that stuff and don't want to lose my code, e.g. if DDE does a rebuild on two developer machines and then they replicate with the same db instance on a server. <br /> <span style="text-decoration:underline"><br /> 3. Use code in other Non-XPages projects</span> <br /> We do not only develop XPages apps, we develop libraries to be used in agents, standalone Eclipse RCP/Swing applications, server-side OSGi plugins and for many other areas. That's why we want to share most of the code between multiple development projects. <br /> <span style="text-decoration:underline"><br /> 4. Run unit tests on the code for quality checks</span> <br /> To ensure that our code still produces the expected results after a code change, we use <a href=http://www.junit.org/ target=_blank>JUnit</a> test cases on a manual or scheduled basis. <br /> <br /> And that is exactly what this sample is about. <br /> <strong><br /> Workspace content</strong> <br /> The download archive for this blog article contains two directories: a sample XPages application and an exported Eclipse workspace. <br /> <br /> The XPages application consists of a simple XPage: <br /> <br>  <div align=center><img  alt="Image:XPages series #10: Running JUnit tests on XPages code" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm/content/M2?OpenElement" /></div> <br /><br /> <br /> Here is the source code: <br /> <br /> <code><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />?xml version="1.0" encoding="UTF-8"?<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /> <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:view xmlns:xp="http://www.ibm.com/xsp/core"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:span style="font-size:20pt"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>Current User Information<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:span<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:span style="font-size:16pt"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Common Name: <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:text escape="true" id="commonName" value="#{currentUser.commonName}" <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;style="color:rgb(0,128,255)"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:text<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:span style="font-size:16pt"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>Abbreviated Username:<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:span<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:br<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />xp:text escape="true" id="abbrName" value="#{currentUser.abbreviatedName}" <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;style="color:rgb(0,128,255)"<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />><<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:text<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br />  &nbsp; &nbsp; &nbsp; &nbsp;<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:span<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> <br /> <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/xp:view<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />></code> <br /> <br /> All it does is read the name information of the current user from a managed bean "currentUser" and display it on screen. <br /> The managed bean class is not directly part of the NSF, but has been added in a "lib" folder below the WebContent/WEB-INF folder as a JAR file and then added to the classpath of the NSF project in DDE (after that, it's not visible in the "lib" folder anymore, but below "Referenced Libraries"). <br /> <br /> After you import the projects of the "workspace" directory into your personal Eclipse workspace, it should look like this: <br /> <br>  <div align=center><img  alt="Image:XPages series #10: Running JUnit tests on XPages code" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm/content/M3?OpenElement" /></div> <br /><br /> Please note that you might get compile errors and need to change the path of the referenced "Notes.jar" file in the com.ls11.dominohelper project to fit your Notes configuration. <br /> <br /> There are four projects in the workspace: <br /> <br /> com.ls11.dominohelper  <ul> <li>The project contains helper classes to execute a piece of code in the context of a Notes session (see below for details)</li></ul>com.ls11.externalcodesample  <ul> <li>This project contains the bean implementation to read the current username</li></ul>com.ls11.externalcodesample.build  <ul> <li>We use the ANT script of this project to create the JAR file with the necessary content to work in an XPages app</li></ul>com.ls11.externalcodesample.test  <ul> <li>Finally this project contains a JUnit test case to check that our bean is working correctly</li></ul><strong><br /> Running the same code standalone and from an XPages request</strong> <br /> Let's dive into the class CurrentUserInfo.java. The method .getCommonName() looks like this: <br /> <br /> <code>/** <br />  * Returns the common name of the current user <br />  * <br />  * @return common name <br />  */ <br /> public String getCommonName() { <br />  &nbsp; &nbsp; &nbsp; &nbsp;if (m_commonName==null) { <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IDominoCallable<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />String<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> callable=new IDominoCallable<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />String<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>() { <br /> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@Override <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;public String call(Session session) throws NotesException { <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Name currName=session.createName(session.getUserName()); <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;String commonName=currName.getCommon(); <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;currName.recycle(); <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &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; &nbsp; &nbsp;return commonName; <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}; <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;try { <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;m_commonName=DominoExecution.run(callable).get(); <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} catch (InterruptedException e) { <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throw new RuntimeException("Could not read username info", e); <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} catch (ExecutionException e) { <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throw new RuntimeException("Could not read username info", e); <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; <br />  &nbsp; &nbsp; &nbsp; &nbsp;} <br />  &nbsp; &nbsp; &nbsp; &nbsp;return m_commonName; <br /> }</code> <br /> <br /> Now that looks interesting: We are using an <code>IDominoCallable</code> implementation to retrieve the common name part of the username. <br /> We do this in order to run the same code from an XPages environment and from a standalone application. In the <code>DominoExecution</code> there's some <em>magic</em> that detects whether it gets executed from XPages code or not. <br /> <br /> In standalone mode, <code>DominoExecution</code> currently launches a new <code>NotesThread</code> for every call, but that could easily be changed to have a permanent thread and just feed it with the <code>IDominoCallable's</code> one after another. <br /> <br /> The run method of DominoExecution returns a <code>Future</code> object of <a href=http://download.oracle.com/javase/1.5.0/docs/guide/concurrency/overview.html target=_blank>Java's concurrency framework</a>. Calling its .get() method let's the executing code wait for the result to be computed. <br /> In XPages mode, the <code>IDominoCallable</code> is executed synchronously, because the code is already running in a Domino enabled thread. <br /> <strong><br /> Running JUnit in Eclipse</strong> <br /> The project com.ls11.externalcodesample.test contains a JUnit test case that checks whether the methods of the bean are working correctly: For example it ensures that abbreviated name and common name are both not null and compares the first part of the abbreviated name with the common name. <br /> <br /> <code>/** <br />  * Check that common and abbreviated name <br />  */ <br /> public void testCommonNameAndAbbrNameConsistent() { <br />  &nbsp; &nbsp; &nbsp; &nbsp;String commonName=m_currUserInfo.getCommonName(); <br />  &nbsp; &nbsp; &nbsp; &nbsp;String abbrName=m_currUserInfo.getAbbreviatedName(); <br />  &nbsp; &nbsp; &nbsp; &nbsp;<br />  &nbsp; &nbsp; &nbsp; &nbsp;//the values cannot be null <br />  &nbsp; &nbsp; &nbsp; &nbsp;assertNotNull(commonName); <br />  &nbsp; &nbsp; &nbsp; &nbsp;assertNotNull(abbrName); <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />  &nbsp; &nbsp; &nbsp; &nbsp;int iPos=abbrName.indexOf("/"); <br />  &nbsp; &nbsp; &nbsp; &nbsp;assertTrue((iPos ! = - 1) &amp;&amp; (iPos ! = 0) ); <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />  &nbsp; &nbsp; &nbsp; &nbsp;String firstAbbrNamePart=abbrName.substring(0, iPos); <br />  &nbsp; &nbsp; &nbsp; &nbsp;assertEquals(commonName, firstAbbrNamePart); <br /> }</code> <br /> <br /> You can launch the test case by first creating a JUnit run configuration: <br /> <br>  <div align=center><img  alt="Image:XPages series #10: Running JUnit tests on XPages code" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm/content/M4?OpenElement" /></div> <br /><br /> On the Environment tab, please add a variable "PATH" that contains the path to your Lotus Notes program directory: <br /> <br>  <div align=center><img  alt="Image:XPages series #10: Running JUnit tests on XPages code" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm/content/M5?OpenElement" /></div> <br /><br /> Now you can execute the test case and get the following result: <br /> <br>  <div align=center><img  alt="Image:XPages series #10: Running JUnit tests on XPages code" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm/content/M6?OpenElement" /></div> <br /><br /> The method testCommonNameAndAbbrNameConsistent could be executed without errors, but calling testOrganisation led to an error. <br /> It checks that CurrentUserInfoTest.getOrganisation() is not null, but unfortunately, it seems like we forgot the method's implementation: <br /> <tt><br /> <code>public String getOrganisation() {</tt> <tt><br />  &nbsp; &nbsp; &nbsp; &nbsp;// TODO Auto-generated method stub</tt> <tt><br />  &nbsp; &nbsp; &nbsp; &nbsp;return null;</tt> <tt><br /> }</code></tt> <br /> <br /> After fixing that, the JUnit succeeds: <br /> <br>  <div align=center><img  alt="Image:XPages series #10: Running JUnit tests on XPages code" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm/content/M7?OpenElement" /></div> <br /><br /> <br /> Now that we know that the bean works, we can package everything by right clicking on the ANT script of project com.ls11.externalcodesample.build, choose "Run As/Ant Build", then do a refresh on the "lib" folder and replace the JAR in the XPages application database with the new one. <br /> <br /> That's it! <br /> <br /> Here is the download link for the archive: <br /> <a href="http://www.mindoo.com/web/blog.nsf/dx/LS11-BP212-JUnit.zip/$file/LS11-BP212-JUnit.zip">LS11-BP212-JUnit.zip</a>   ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/05.02.2011131456KLEGDD.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/05.02.2011131456KLEGDD.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>LS11: Slides for session BP203 - Leverage the New Java APIs in IBM Lotus Notes 8.5.1 and 8.5.2!</title>
<pubDate>Sun, 6 Feb 2011 17:17:25 +0200</pubDate>
<description>
<![CDATA[ 
Here are the slides for the session "Leverage the New Java APIs in IBM Lotus Notes 8.5.1 and 8.5.2!" from Lotusphere 2011 ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/06.02.2011171725KLEM4Y.htm</link>
<category>Lotusphere 2011</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/06.02.2011171725KLEM4Y.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/06.02.2011171725KLEM4Y.htm</guid>
<content:encoded><![CDATA[ Here are the slides for the session "Leverage the New Java APIs in IBM Lotus Notes 8.5.1 and 8.5.2!" from Lotusphere 2011: <br /> <br> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/BP203_LS11.pdf/$file/BP203_LS11.pdf"><img  alt="Image:LS11: Slides for session BP203 - Leverage the New Java APIs in IBM Lotus Notes 8.5.1 and 8.5.2!" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/06.02.2011171725KLEM4Y.htm/content/M2?OpenElement" /></a></div> <br /> <br />Compared to the slides posted on the Lotusphere website, we changed the order of the slides (DDE part in the middle, not at the end) and changed a few demos.  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/06.02.2011171725KLEM4Y.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/06.02.2011171725KLEM4Y.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>LS11: Slides for session BP212 - Deep Dive into IBM XPage Expression Language Syntax</title>
<pubDate>Sat, 5 Feb 2011 10:59:17 +0200</pubDate>
<description>
<![CDATA[ 
Here are the slides for the session "Deep Dive into IBM XPage Expression Language Syntax" from Lotusphere 2011. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/05.02.2011105917KLEDQM.htm</link>
<category>Lotusphere 2011</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/05.02.2011105917KLEDQM.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/05.02.2011105917KLEDQM.htm</guid>
<content:encoded><![CDATA[ Here are the slides for the session "Deep Dive into IBM XPage Expression Language Syntax" from Lotusphere 2011: <br /><br> <div align=center><a href="http://www.mindoo.com/web/blog.nsf/dx/BP212_LS11.pdf/$file/BP212_LS11.pdf"><img  alt="Image:LS11: Slides for session BP212 - Deep Dive into IBM XPage Expression Language Syntax" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/05.02.2011105917KLEDQM.htm/content/M2?OpenElement" /></a></div> <br /> <br />I will provide downloads for the three demos that I did at the end of the session and write blog articles about them as part of the XPages blog series. <br /> <br />I'm trying to do this as soon as possible, but I'm already preparing slides for the next conference: <br /><br> <div align=center><a href=http://www.entwicklercamp.de/ target=_blank>Entwicklercamp 2011</a> in Gelsenkirchen, Germany</div>  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/05.02.2011105917KLEDQM.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/05.02.2011105917KLEDQM.htm?opendocument&amp;comments</wfw:comment>
</item>
</channel></rss>

