<?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>Sat, 30 Jan 2010 15:43:12 +0200</lastBuildDate>
<item>
<title>LS10 session sample #1: Notes Bookmark tools</title>
<pubDate>Sat, 30 Jan 2010 15:43:12 +0200</pubDate>
<description>
<![CDATA[ 
This is the first sample that we developed for our Lotusphere session about the Java APIs of Lotus Notes 8.5.1. And it's already the first one that we did not  actually show at Lotusphere, because we ran out of session time in our rehearsals and felt the need to reduce the amount of live demos.

The sample plugin is called "com.mindoo.bookmarktools". It adds two actions to the Open List of Lotus Notes: "Locate on workspace" and "Open as workspace" ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/30.01.2010154312KLEKA4.htm</link>
<category>Lotusphere 2010</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/30.01.2010154312KLEKA4.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/30.01.2010154312KLEKA4.htm</guid>
<content:encoded><![CDATA[ This is the first sample that we developed for our <a href="http://www.mindoo.com/web/blog.nsf/dx/25.01.2010004124KLEVSF.htm" target="_blank">Lotusphere session about the Java APIs of Lotus Notes 8.5.1</a>. And it's already the first one that we did <em>not</em> &nbsp;actually show at Lotusphere, because we ran out of session time in our rehearsals and felt the need to reduce the amount of live demos. <br /> <br /> The sample plugin is called "com.mindoo.bookmarktools". It adds two actions to the Open List of Lotus Notes:  <div align=center> <br /><img  alt="Image:LS10 session sample #1: Notes Bookmark tools" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/30.01.2010154312KLEKA4.htm/content/M2?OpenElement" /></div> <br /><strong>Locate on workspace</strong> <br /> This action uses the methods <code>NotesUIWorkspace.addDatabase(NotesDatabaseData)</code> of the new UI API, but instead of adding databases to the client's workspace, it actually only leverages the fact that <code>addDatabase</code> selects already existing databases and opens the right workspace tab. <br /> As you may know, we are the developers of the <a href=/web/web.nsf/id/pa_products_mindplan_en.html target=_blank>MindPlan</a> application (mindmapping and project management based on Lotus Notes). That's why my Open List looks like this when I'm searching for the keyword "mindplan" in my bookmarks: <div align=center> <br /><img  alt="Image:LS10 session sample #1: Notes Bookmark tools" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/30.01.2010154312KLEKA4.htm/content/M3?OpenElement" /></div> <br />Sometimes you want to know where a specific database is located on your workspace. One way is to open the database in the client and then switch to the workspace, where in most cases the right database chicklet is selected. That takes a lot of time in case the database needs to be loaded from a server. And sometimes opening the database does not really help to find it on the workspace, for example if the database opens a frameset that displays a view of your mail database. In that case, it's the mail database that is selected on the workspace, not the database with the frameset. <br /> <br /> This new action helps in this case. <br /> <strong><br /> Open as workspace</strong> <br /> The second action "Open as workspace" is something that you might know from older Notes Clients, e.g. from version R7. You could right click on a bookmark and select "Open as workspace". This would open a new tab that displays the bookmark folder content as chicklets like this:  <div align=center> <br /><img  alt="Image:LS10 session sample #1: Notes Bookmark tools" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/30.01.2010154312KLEKA4.htm/content/M4?OpenElement" /></div> <br />Well, although this feature <a href="http://www-01.ibm.com/support/docview.wss?rs=475&amp;context=SSKTWP&amp;dc&Ucirc;520&amp;dc&Ucirc;560&amp;uid=swg21296580&amp;loc=en_US&amp;cs=UTF-8&amp;lang=en&amp;rss=ct475lotus" target=_blank>has not been officially implemented in the 8.x Standard Client</a> (the was some <a href="http://www.notesdesignblog.com/notesdesignblog/ndblog.nsf/dx/do-you-miss-the-open-as-workspace-feature.htm" target=_blank>discussion</a> whether it should return in 8.5.2, but IBM decided to <a href="http://www.notesdesignblog.com/notesdesignblog/ndblog.nsf/dx/our-decision-regarding-open-as-workspace.htm" target=_blank>keep it out</a> of the Standard Client), there <em>is</em> a way to open the workspace view for a bookmark folder. <br /> <br /> Actually, it's pretty simple: <br /> You may know that the Notes URL "<strong>notes:///ClientBookmark?OpenWorkspace</strong>" opens the normal workspace tab. <br /> All you have to do is add a query parameter "id" to that URL: "<strong>notes:///ClientBookmark?OpenWorkspace&amp;id=0</strong>". That ID is the internal bookmark folder id. The id 0 tells the workspace viewpart to display the first level of your open list (e.g. with your mail, calendar and a chicklet to start Domino Designer). <br /> I haven't found out so far where the other id's come from (just checked the design of the bookmark.nsf, but it's no obvious ID of the folders design elements). But by using some internal Notes functions, we are able to grab the folder id when you right click on an Open List entry and launch the corresponding Notes URL. <br /> <br /> So, what to do with this second action? I don't know. :-) <br /> My first thought was to use this special Notes URL in a Composite Application, something like my personal start page for the Notes Client. You can for example use the Notes Document Container to display this URL and send URL changes to the "SetNotesDocumentURL" action to switch between several workspace folders. In my first tests, quickly changing this URL did not appear very stable (the client crashed) and I did not look into this any further. <br /> <br /> Anyway, here are the source code for this sample and an update site for the installation (please refer to <a href="http://www.mindoo.com/web/blog.nsf/dx/09.07.2009160821KLEJLA.htm" target="_blank">this article</a> if you don't know how to install from an update site).  <ul> <li><a href="http://www.mindoo.com/web/blog.nsf/dx/ls10-com.mindoo.bookmarktools.zip/$file/ls10-com.mindoo.bookmarktools.zip" title="ls10-com.mindoo.bookmarktools.zip"ls10-com.mindoo.bookmarktools.zip/>ls10-com.mindoo.bookmarktools.zip</a>  </li><li><a href="http://www.mindoo.com/web/blog.nsf/dx/ls10-com.mindoo.bookmarktools-updatesite.zip/$file/ls10-com.mindoo.bookmarktools-updatesite.zip" title="ls10-com.mindoo.bookmarktools-updatesite.zip"ls10-com.mindoo.bookmarktools-updatesite.zip/>ls10-com.mindoo.bookmarktools-updatesite.zip</a></li></ul>  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/30.01.2010154312KLEKA4.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/30.01.2010154312KLEKA4.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>I will be presenting a session about the new Java APIs of Lotus Notes 8.5.1 at the German Entwicklercamp conference (Developer camp)</title>
<pubDate>Thu, 28 Jan 2010 07:30:23 +0200</pubDate>
<description>
<![CDATA[ 
Now that Lotusphere is over, we are already preparing for our next session, this time for the German Entwicklercamp conference. 
The topic is Add-ons for Notes Client/Domino Designer based on new Java APIs of Lotus Notes 8.5.1 (track 4, session 5 in the session list). 
It's similar to our Lotusphere session, so if you missed it at Lotusphere, make sure to not miss it again. :-) 

The Entwicklercamp is an annual conference taking place from 8th to 10th of March in Gelsenkirchen, Germany, with a well known list of both national and international speakers and a lot of high-quality developer sessions. 
You can find more information on the Entwicklercamp website. Unfortunately it's only available in German language, but maybe Google translator will help you out if your German needs some training.  ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/28.01.2010073023KLE9N3.htm</link>
<category>Entwicklercamp 2010</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/28.01.2010073023KLE9N3.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/28.01.2010073023KLE9N3.htm</guid>
<content:encoded><![CDATA[ Now that Lotusphere is over, we are already preparing for our next session, this time for the German Entwicklercamp conference. <br /> The topic is <a href=http://www.entwicklercamp.de/EntwicklerCamp/Themen target=_blank><span style="text-decoration:underline">Add-ons for Notes Client/Domino Designer based on new Java APIs of Lotus Notes 8.5.1</span></a> (track 4, session 5 in the session list). <br /> It's similar to our Lotusphere session, so if you missed it at Lotusphere, make sure to not miss it again. :-) <br /> <br /> The Entwicklercamp is an annual conference taking place from 8th to 10th of March in Gelsenkirchen, Germany, with a well known list of both national and international speakers and a lot of high-quality developer sessions. <br /> You can find more information on the <a href=http://www.entwicklercamp.de/ target=_blank><span style="text-decoration:underline">Entwicklercamp website</span></a>. Unfortunately it's only available in German language, but maybe Google translator will help you out if your German needs some training.   ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/28.01.2010073023KLE9N3.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/28.01.2010073023KLE9N3.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Our Lotusphere 2010 slides: BP203 - Leverage the New Java APIs in IBM Lotus Notes 8.5.1!</title>
<pubDate>Mon, 25 Jan 2010 00:41:24 +0200</pubDate>
<description>
<![CDATA[ 
We had a very positive response to our session about the Notes Client and Domino Designer extensibility Java APIs in Lotus Notes 8.5.1 at Lotusphere. All the feedback evaluations where either "Excelle ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/25.01.2010004124KLEVSF.htm</link>
<category>Lotusphere 2010</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/25.01.2010004124KLEVSF.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/25.01.2010004124KLEVSF.htm</guid>
<content:encoded><![CDATA[ We had a very positive response to our session about the Notes Client and Domino Designer extensibility Java APIs in Lotus Notes 8.5.1 at Lotusphere. <br />All the feedback evaluations where either "Excellent" or "Good" and in addition, we also got personal feedback from 4-5 participants (even in the bus to the Hollywood studios on Wednesday) who especially liked the fact that we showed so many demos. <br /> <br />Well, to be honest, we even planned and developed more demos than we actually could show. We decided to remove some of them when we were doing a test run in the hotel room and easily exceeded the session limit of 60 minutes. :-) <br />If you look at the original BP203 slides that we submitted back in December and compare them to the presented slides, you will notice the missing pieces. <br /> <br />Since removing some of the demos was a last minute decision, all of them were already developed and running. So we plan to publish them in this blog in the next few weeks. Simply publishing the code would not help you much to learn about the Eclipse/Expeditor platform. That's why we will explain them in detail, each demo in its own blog article. <br /> <br />Let's start this demo article series with the session slides. Click on the image to download the PDF file: <div align=center> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/BP203_LS10.pdf/$file/BP203_LS10.pdf" title="BP203 slides"><img  alt="Image:Our Lotusphere 2010 slides: BP203 - Leverage the New Java APIs in IBM Lotus Notes 8.5.1!" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/25.01.2010004124KLEVSF.htm/content/M2?OpenElement" /></a></div> <br /> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/25.01.2010004124KLEVSF.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/25.01.2010004124KLEVSF.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Our LS10 session offering on Wednesday: BP203 - new Java APIs in 8.5.1 with up to 10 demos, 2 undocumented Notes functions and Lotusscript like you have never seen it before</title>
<pubDate>Wed, 20 Jan 2010 00:26:26 -0400</pubDate>
<description>
<![CDATA[ 
Our session "BP203 Leverage the New Java APIs in IBM Lotus Notes 8.5.1!" will provide a high-level overview of two new Java APIs in Lotus Notes 8.5.1 - the UI API and the Domino Designer API. Instead ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/20.01.2010002624KLE8E3.htm</link>
<category>Lotusphere 2010</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/20.01.2010002624KLE8E3.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/20.01.2010002624KLE8E3.htm</guid>
<content:encoded><![CDATA[ Our session "BP203 Leverage the New Java APIs in IBM Lotus Notes 8.5.1!" will provide a high-level overview of two new Java APIs in Lotus Notes 8.5.1 - the UI API and the Domino Designer API. <br />Instead of showing too many technical details, our plan is to focus on real-life scenarios for the new APIs. <br /> <br />We have created a collection of up to 10 demos for both APIs, including <ul> <li>a universal help system for the Notes sidebar that provides information for the current database, form and field </li><li>an integration of <a href=http://blog.lsdoc.org/ target=_blank>Mikkel Heisterberg's LotusScript.doc</a> into Domino Designer </li><li>an alternative picture based address selection dialog for emails that can be used without modifying the mail template</li></ul> <br />and we'll demonstrate ways how LotusScript code can communicate with the Eclipse framework to leverage the new API functionality as well. <br />This will include an application that uses multithreaded LotusScript - a new technology to move your long running LotusScript tasks into the background in order to make your Notes applications snappier. <br /> <br />Come and join us on <strong>Wednesday from 3:00pm - 4:00pm in DL S. Hemisphere III</strong> ! <br /> <br />And please also join us on <strong>Thursday from 7:00am - 8:00am in SW Toucan 1</strong> to share our experiences with <strong>Application Architecture based on Composite Application</strong> (BOF206). <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/20.01.2010002624KLE8E3.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/20.01.2010002624KLE8E3.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Lotusphere announcement: LS2Eclipse - Leverage Eclipse/Expeditor features in your Lotusscript code!</title>
<pubDate>Mon, 11 Jan 2010 13:53:17 +0200</pubDate>
<description>
<![CDATA[ 
If one of the following questions sound familiar to you, this blog article may be interesting for you:
-You have Notes applications and want to bring them to the 21st century without rewriting everything in Java/JavaScript?
-Your users often sit at their desk waiting for your Notes application because of a long running Lotusscript operation?
-Composite Application technology looks interesting, but the Lotusscript APIs are not dynamic / powerful enough?
-As a Lotusscript developer, you always hated it to hear those Java guys saying "That's easy. All you have to do is call this Eclipse API..." :-)  ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/11.01.2010135317KLEH5D.htm</link>
<category>Lotusphere 2010</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/11.01.2010135317KLEH5D.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/11.01.2010135317KLEH5D.htm</guid>
<content:encoded><![CDATA[ If one of the following questions sound familiar, this blog article may be interesting for you: <ul> <li>You have Notes applications and want to bring them to the 21st century without rewriting everything in Java/JavaScript? </li><li>Your users often sit at their desk waiting for your Notes application because of a long running Lotusscript operation? </li><li>Composite Application technology looks interesting, but the Lotusscript APIs are not dynamic / powerful enough? </li><li>As a Lotusscript developer, you always hated it to hear those Java guys saying "That's easy. All you have to do is call this Eclipse API..." :-) </li></ul>During our own Notes/Domino development in the past years, we often needed Eclipse API functionality in places where it was not available, like a classic view action, a form or an agent. <br />New features always got added to the "outside world", the Eclipse/Expeditor framework, but the classic Notes client and the Lotusscript language nearly stayed the same over the years. <br />While Java development for Eclipse/Expeditor has many advantages compared to classic form/view development of Lotus Notes, it surely makes development more complex and you loose the rapid application development approach that Lotus Notes made so successful. <br />In addition, long-time Notes users have an existing code base of thousands of lines of code, that they cannot simply rewrite in Java/JavaScript to create a new Java UI or XPages based application. <br /> <br /> <br />We think that there is a missing piece between classic Notes and the Expeditor framework of Lotus Notes R8.x. This is our main use case for <strong>Mindoo LS2Eclipse</strong>. <br /> <br /><strong>Mindoo LS2Eclipse is a bridging technology that makes Eclipse APIs accessible from Lotusscript code.</strong> <br /> <br />The following image is a rough overview of the LS2Eclipse architecture: <br /> <div align=center> <br /><img  alt="Image:Lotusphere announcement: LS2Eclipse - Leverage Eclipse/Expeditor features in your Lotusscript code!" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/11.01.2010135317KLEH5D.htm/content/M2?OpenElement" /></div> <br />The installation kit contains an Eclipse plugin (packaged as a widget for easy deployment) and a set of Lotusscript libraries. <br />Those libraries with a rich set of about 50 object-oriented Lotusscript classes give you access to many powerful Eclipse features, divided into the following 7 areas:  <br /> <br /><span style="text-decoration:underline">JobTools</span> <br />The JobTools area is a key feature of the LS2Eclipse API. It is the key to running your application code in multiple threads, thus making it possible to keep the user interface responsive even if a long-running operation (e.g. storing an email in a CRM system on a Domino server) is active. <br />Your Lotusscript code runs as a so called Eclipse Job, a background process that can optionally display a progress dialog with status/progress information.  <br /> <br />Feature overview: <ul> <li>Bridge between the Eclipse job framework and Notes agents </li><li>schedule the execution of an agent as an Eclipse background job </li><li>pass parameters to the job </li><li>jobs can report progress and can be cancelled on user request </li><li>Notes UI is responsive when job is running, job may change the UI during execution (e.g. to present the result)</li></ul><span style="text-decoration:underline">PlatformUI</span> <br />The PlatformUI area let's you read and interact with the Eclipse workbench, which is the graphical framework that is displaying the Lotus Notes client.  <br /> <br />Feature overview: <ul> <li>Read the structure of open windows, tabs and their contents (Eclipse views) </li><li>focus tabs, show/hide/minimize/maximize views </li><li>Access the side shelf, show/hide shelf views and toggle the shelf between collapsed, thin and expanded </li><li>show text in the status bar of the Notes client and show message boxes (e.g. to display information from a background agent job)</li></ul><span style="text-decoration:underline">ComponentTools</span> <br />The ComponentTools contain a set of tool classes to make Composite Applications more dynamic. <br /> <br />Feature overview: <ul> <li>call Composite Application actions of components manually without a CA wire </li><li>dynamically create and show content like Notes data or a web browser view  </li><li>modify the properties of components </li><li>read and modify the structure of a Composite Application (component/page preferences) </li><li>toggle between CA pages in your code (e.g. to create a custom navigator) </li><li>locate open views in the workbench based on their internal ids</li></ul><span style="text-decoration:underline">NotesUITools</span> <br />This area contains features of the new Java UI API in Lotus Notes 8.5.1. With it you can interact with the Notes client user interface, even if your code is running in a background job, where the standard NotesUIWorkspace is not available. In addition, you are no longer restricted to the active area of the screen to read/write data from/to a view or a document.  <br /> <br />Feature overview: <ul> <li>gives you access to the Notes UI even when your code is running in a background job </li><li>get a NotesUIDocument/NotesUIView handle for any area (IWorkbenchPart) of the screen, not just the active one </li><li>modify the NotesUIDocument's content, read the current selection from a NotesUIView </li><li>activate a view/document in the current page</li></ul><span style="text-decoration:underline">PerspectiveTools</span> <br />In the Notes client, an Eclipse perspective is the content of a main tab. The perspective tools give you access to all registered tabs in the system and they even allow for the creation of completely new tab layouts. <br /> <br />Feature overview <ul> <li>get list of registered Eclipse perspectives (IPerspectiveRegistry) </li><li>clone existing perspectives </li><li>create and display your own Eclipse tab layouts (IPerspectiveFactory/IPageLayout etc.) on the fly</li></ul><span style="text-decoration:underline">ProgramTools</span> <br />The program tools contain platform independent APIs to registered file extensions in the OS. <br /> <br />Feature overview <ul> <li>find associated programs by file extension </li><li>get list of registered file extensions in the system </li><li>launch files and urls</li></ul><span style="text-decoration:underline">ExtensionRegistryTools</span> <br />Experts can use the ExtensionRegistryTools to add new Eclipse extensions to the IExtensionRegistry of the Eclipse framework. <br /> <br /><strong>How does the code look like?</strong> <br /> <br />We tried to name the Lotusscript objects similar to their corresponding Eclipse API objects. That way, you already know most of the important Eclipse APIs if you start coding in Java later on and searching for code snippets on the internet is made easier. <br />To get a feeling for the API, here is a small code snippet: <br /> <br />To create a new API connection, you use this syntax: <br /> <br /><tt>Dim connection As EclipseConnection</tt> <br /><tt>Set connection=EclipseConnectionManager.createConnection()</tt> <br /> <br />To access the PlatformUI, type in this: <br /> <br /><tt>Dim platfUI As PlatformUI</tt> <br /><tt>Set platfUI=PlatformUIFactory.getInstance(connection)</tt> <br /> <br />The IPartService is a class to get the currently active area (IWorkbenchPart) of the screen: <br /> <br /><tt>Dim partService As IPartService</tt> <br /><tt>Dim part As IWorkbenchPart</tt> <br /><tt>Dim vpart as IViewPart</tt> <br /><tt>Dim classes as EclipseAPIClasses</tt> <br /><tt>Dim partTitle as String</tt> <br /><tt>Dim partId as String</tt> <br /><tt>Dim partSecondaryId as String</tt> <br /> <br /><tt>Set classes=connection.EclipseAPIClasses <font color="#008000">'helper to cast an object to another API object</font></tt> <br /><tt>Set partService=platfUI.getWorkbench().getActiveWorkbenchWindow().getPartService()</tt> <br /><tt>Set part=partService.getActivePart()</tt> <br /><tt>If classes.IViewPart.isInstance(part) then</tt> <br /><tt>&nbsp; &nbsp; &nbsp; &nbsp; <font color="#008000">'part is a IViewPart; this gives us additional properties</font></tt> <br /><tt>&nbsp; &nbsp; &nbsp; &nbsp; Set vpart=classes.IViewPart.cast(part)</tt> <br /><tt>&nbsp; &nbsp; &nbsp; &nbsp; partTitle=vpart.getTitle() &nbsp; &nbsp; &nbsp; &nbsp;</tt> <br /><tt>&nbsp; &nbsp; &nbsp; &nbsp; partId=vpart.getId()</tt> <br /><tt>&nbsp; &nbsp; &nbsp; &nbsp; partSecondaryId=vpart.getViewSite().getSecondaryId()</tt> <br /><tt>End If</tt> <br /> <br /> <br /><strong>Where to get the API</strong> <br /> <br />The API is feature complete, but we still have some documentation to write. For example, I'm currently working on a database with test cases that may be handy to learn about the new features. <br />It currently contains the following 12 cases: <ul> <li>Case 1 - Workbench information </li><li>Case 2 - PartService, get information about the active viewpart </li><li>Case 3 - Viewparts in the current page </li><li>Case 4 - Schedule background agent jobs </li><li>Case 5 - Change the UIDocument in another viewpart </li><li>Case 6 - Get the selection from a Notes view in another viewpart </li><li>Case 7 - Create new NSF viewparts in the current page </li><li>Case 8 - Create new NSF viewparts in a different tab </li><li>Case 9 - Manually call actions of CA components (change content of a document container) </li><li>Case 10 - Create a new Eclipse perspective layout with placeholders for new views </li><li>Case 11 - Compare selected documents in a new Eclipse perspective </li><li>Case 12 - Toggle the sidebar mode between collapsed/expanded/thin</li></ul>If you are interested and will be attending Lotusphere next week, <strong>come to our session about the new Java APIs of Lotus Notes 8.5.1 (BP203)</strong> on Wednesday from 3:00 until 4:00 pm or wake up early on Thursday to <strong>join us in our birds-of-a-feature session about "Application Architecture based on Composite Application technology" (BOF206)</strong> from 7:00 until 8:00 am. <br /> <br />I will post an info in this blog, when a trial version of LS2Eclipse is available. <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/11.01.2010135317KLEH5D.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/11.01.2010135317KLEH5D.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Our Birds-of-a-Feather session has been selected by the Lotusphere attendees!</title>
<pubDate>Thu, 10 Dec 2009 16:32:54 +0200</pubDate>
<description>
<![CDATA[ 
Good news from IBM today: Our BoF has been approved for Lotusphere 2010. That's our second approved session and particularly great because the BoF sessions were voted by the Lotusphere attendees.
Our session is one of those that they would most like to see on the agenda.

This is IBM's description for this kind of session:

Audience: Any and all Lotusphere attendees
Description: Come one, come all! Birds-of-a-Feather sessions are a popular feature of Lotusphere, bringing together communities and individuals with similar interests. These sessions are informal, interactive discussion groups for like-minded attendees to share ideas and experiences in an small group, open forum setting.


And here is our session abstract:

Application Architecture based on Composite Application technology

Composite Application technology builds a bridge between several worlds. With it you can transfer information between programming languages like Java and Lotusscript, fill Symphony spreadsheets with the contents of a Notes view, sent commands to host applications and even automate Windows applications.
With the introduction of XPages for the Notes client, CA technology gains additional momentum, because they are the way to go, if you need interaction between your XPages application and the surrounding Notes client platform.
We would like to share our experiences with Composite Application technology and discuss how an application architecture based on Composite Application technology could look like if you start designing it from scratch.

We are really looking forward to Lotusphere and are heavily working on cool demos for our session about the new Java API's of Lotus Notes 8.5.1. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/10.12.2009163254KLEL95.htm</link>
<category>Lotusphere 2010</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/10.12.2009163254KLEL95.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/10.12.2009163254KLEL95.htm</guid>
<content:encoded><![CDATA[ Good news from IBM today: Our BoF has been approved for Lotusphere 2010. That's our second approved session and particularly great because the BoF sessions were voted by the Lotusphere attendees. <br />Our session is one of those that they would most like to see on the agenda. <br /> <br />This is IBM's description for this kind of session: <br /> <br /><span style="text-decoration:underline">Audience:</span> Any and all Lotusphere attendees <br /><span style="text-decoration:underline">Description:</span> Come one, come all! Birds-of-a-Feather sessions are a popular feature of Lotusphere, bringing together communities and individuals with similar interests. These sessions are informal, interactive discussion groups for like-minded attendees to share ideas and experiences in an small group, open forum setting. <br /> <br /> <br />And here is our session abstract: <br /> <div align=center> <br /><strong>Application Architecture based on Composite Application technology</strong></div> <br /> <br />Composite Application technology builds a bridge between several worlds. With it you can transfer information between programming languages like Java and Lotusscript, fill Symphony spreadsheets with the contents of a Notes view, sent commands to host applications and even automate Windows applications. <br />With the introduction of XPages for the Notes client, CA technology gains additional momentum, because they are the way to go, if you need interaction between your XPages application and the surrounding Notes client platform. <br />We would like to share our experiences with Composite Application technology and discuss how an application architecture based on Composite Application technology could look like if you start designing it from scratch. <br /> <br />We are really looking forward to Lotusphere and are heavily working on cool demos for our <a href="http://www.mindoo.com/web/blog.nsf/dx/17.11.2009203805KLER2D.htm" title="Add-ons for Client/Designer leveraging new Java APIs of Lotus Notes 8.5.1" target="_blank">session about the new Java API's of Lotus Notes 8.5.1</a>.  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/10.12.2009163254KLEL95.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/10.12.2009163254KLEL95.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>One Lotusphere 2010 session approved!</title>
<pubDate>Tue, 17 Nov 2009 20:38:06 +0200</pubDate>
<description>
<![CDATA[ 
We just received an email from IBM telling us that one of our session submissions for Lotusphere 2010 has been approved.
The title is:

Add-ons for Client/Designer leveraging new Java APIs of Lotus Notes 8.5.1

This is really cool, because it's our favorite topic. Those new APIs can be used for many small useful Notes and DDE add-ons and I'm sure we will have some nice giveaways for the session.

See you in Orlando!
 ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/17.11.2009203805KLER2D.htm</link>
<category>Lotusphere 2010</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/17.11.2009203805KLER2D.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/17.11.2009203805KLER2D.htm</guid>
<content:encoded><![CDATA[ We just received an email from IBM telling us that one of our session submissions for Lotusphere 2010 has been approved. <br />The title is: <br /> <div align=center> <br /><strong>Add-ons for Client/Designer leveraging new Java APIs of Lotus Notes 8.5.1</strong></div> <br /> <br />This is really cool, because it's our favorite topic. Those <a href="http://www.mindoo.com/web/blog.nsf/dx//web/blog.nsf/dx/11.10.2009174606KLELHE.htm?opendocument&amp;comments" target=_blank>new APIs</a> can be used for many small useful Notes and DDE add-ons and I'm sure we will have some nice giveaways for the session. <br /> <br />See you in Orlando! <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/17.11.2009203805KLER2D.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/17.11.2009203805KLER2D.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #8: Dynamically creating the UI of an XPage in Java</title>
<pubDate>Tue, 10 Nov 2009 23:11:23 +0200</pubDate>
<description>
<![CDATA[ 
This 8th part of the XPages series is more or less a link to a great blog posting that was just published my Tommy Valand.

It demonstrates how you can create a dynamic web user interface by leveraging JSF features in your XPages application. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/10.11.2009231122KLEU27.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/10.11.2009231122KLEU27.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/10.11.2009231122KLEU27.htm</guid>
<content:encoded><![CDATA[ This 8th part of the <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>XPages series</a> is more or less a link to a great blog posting that was just published my Tommy Valand. <br /> <br /> It demonstrates how you can create a dynamic web user interface by leveraging JSF features in your XPages application. <br /> In his example, Tommy produces a data table UIComponent with a snippet of Java code that is executed with the click on a button. <div align=center> <br /><img  alt="Image:XPages series #8: Dynamically creating the UI of an XPage in Java" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/10.11.2009231122KLEU27.htm/content/M2?OpenElement" /></div> <br />I'm currently working on something similar for a customer project, but unfortunately I cannot say much about technical details at the moment. <br /> Basically, it's about dynamic application UI creation based on an abstract UI description. The system produces a dual-output: it dynamically creates the UI of an XPage, but it also creates a Java UI (e.g. a set of Swing components) with a similar form layout. <br /> Write once, run anywhere. :-) <br /> <br /> The concept includes its own data layer that works independent from Lotus Notes and has some fancy features like transaction logging (even for storing in Lotus Notes databases). <br /> <br /> I recommend that you take a look at <a href="http://dontpanic82.blogspot.com/2009/11/xpages-creating-data-table.html" target=_blank>Tommys posting</a> and start thinking about your personal use case for this. Anything is possible. <br /> <br /> In my next blog series posting I'm going to write about my own bean manager for managed beans that I needed as a workaround for <a href="http://www.mindoo.com/web/blog.nsf/dx//web/blog.nsf/dx/21.10.2009142550KLEGL7.htm?opendocument&amp;comments" target=_blank>security limitations when running an XPages application in the Lotus Notes client</a>.   ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/10.11.2009231122KLEU27.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/10.11.2009231122KLEU27.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Today Mindoo joined IBM&#8217;s Design Partner program for Quickr 8.5</title>
<pubDate>Wed, 4 Nov 2009 13:42:02 +0200</pubDate>
<description>
<![CDATA[ 
We are now active participants in IBM's Design Partner programs for Notes/Domino and for Quickr 8.5. I'm currently installing the first Quickr 8.5 code drop on one of our development servers. 

We would like to thank IBM for letting us participate!  ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/04.11.2009134201KLEGWC.htm</link>
<category>Quickr</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/04.11.2009134201KLEGWC.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/04.11.2009134201KLEGWC.htm</guid>
<content:encoded><![CDATA[ We are now active participants in IBM's Design Partner programs for Notes/Domino and for Quickr 8.5. I'm currently installing the first Quickr 8.5 code drop on one of our development servers. <br /> <br /> We would like to thank IBM for letting us participate!   ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/04.11.2009134201KLEGWC.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/04.11.2009134201KLEGWC.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Speaking at Notesusertage 2009 (Notes user days, German conference) on the 5th of November - register until the 25th of October!</title>
<pubDate>Thu, 22 Oct 2009 21:49:23 +0200</pubDate>
<description>
<![CDATA[ 
Actually I'm not part of the main program, but demoing two applications that we are developing for our partner Haus Weilgut in a parallel customer track.
The first one is a pretty large XPages application framework (about 10 Java projects combined into one NSF). Let's call it an "UI generator", but it's actually a lot more than that.
The second application is a quite powerful relational reporting engine for Lotus Notes data. Something like "NotesSQL^2". :-) ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/22.10.2009214922KLER9E.htm</link>
<category>Notesusertage 2009</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/22.10.2009214922KLER9E.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/22.10.2009214922KLER9E.htm</guid>
<content:encoded><![CDATA[ Actually I'm not part of the main program, but demoing two applications that we are developing for our partner <a href="http://www.weilgut.de" target="_blank">Haus Weilgut</a> in a parallel customer track. <br />The first one is a pretty large XPages application framework (about 10 Java projects combined into one NSF). Let's call it a "UI generator", but it's actually a lot more than that. <br />The second application is a quite powerful relational reporting engine for Lotus Notes data. Something like "NotesSQL<sup>2</sup>". :-) <br /> <br />The Notesusertage conference is an annual German Notes conference located in Karlsruhe, Germany. <br /> <br />Registration is open until the 25th of October. Conference fee is 69 Euro. <br /> <br />Here is the German conference description from the <a href="http://www.notesusertage.de" target="_blank">Notesusertage website</a>: <br /> <br /><hr>Warum in die Ferne schweifen, wo das Gute doch so nah. <br /> <br />Erfahren Sie, wie Sie konsequent Ihre Lotus Notes- und Domino-Plattform im Unternehmen ausbauen und tauschen Sie sich mit Gleichgesinnten aus. <br /> <br />Die Notes Usertage treffen den Nerv der Zeit: <br />Anhand praktischer Beispiele aus großen und mittelständischen Unternehmen lernen Sie neue Erweiterungsmöglichkeiten kennen, mit denen Sie Investitionen in neue Systeme und Schnittstellen vermeiden. Dabei bringen Sie Ihre Infrastruktur auf den Stand, den die aktuelle Rechtslage erfordert. <br /> <br />Mehrwert mit Lotus Notes, das bedeutet: <ul> <li>unternehmensweites CRM </li><li>Wissens- und Projektmanagement </li><li>wirtschaftliche und rechtskonforme Archivierung von E-Mails </li><li>Kopplung mit ERP-Systemen </li><li>Ressourcenplanung </li><li>Optimierung mit Blackberry </li><li>schneller Zugriff auf Informationen </li><li>Reporting, Business Intelligence </li><li>... und vieles mehr!</li></ul>Neue Funktionen, Module und moderne Technologien machen Ihr Unternehmen leistungsfähiger und helfen Ihnen, vorhandene Ressourcen besser zu nutzen.  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/22.10.2009214922KLER9E.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/22.10.2009214922KLER9E.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #7: Running under a restricted Java context - or: Why doesn&#8217;t my XPages application work in the Notes Client?!</title>
<pubDate>Wed, 21 Oct 2009 14:25:51 +0200</pubDate>
<description>
<![CDATA[ 
As an experienced XPages developer, Lotus Notes 8.5.1 user and reader of this XPages blog series, you may already have tried to use your XPages applications in the new Lotus Notes Client. 
As long as they only contain program code in JavaScript and a few simple Java routines, you will probably have succeeded. This article helps you for the other cases.
 ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/21.10.2009142550KLEGL7.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/21.10.2009142550KLEGL7.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/21.10.2009142550KLEGL7.htm</guid>
<content:encoded><![CDATA[ As an experienced XPages developer, Lotus Notes 8.5.1 user and reader of this XPages blog series, you may already have tried to use your XPages applications in the new Lotus Notes Client. <br /> As long as they only contain program code in JavaScript and a few simple Java routines, you will probably have succeeded. Your application looks quite the same as on the web and you can now begin to tweak the UI with a client-specific theme and enhance the application features by <a href="http://www.mindoo.com/web/blog.nsf/dx/14.09.2009175508KLELNZ.htm" title="XPages in the client: How to use XPages as components in Composite Applications" target="_blank"/>integrating it into a Composite Application</a>. <br /> <strong><br /> Any visual issues?</strong> <br /> If there are any visual issues (for instance I heard about dojo dialog boxes not resizing as expected, but haven't tested yet), keep in mind that the 8.5.1 Notes Client uses <strong>Xulrunner version 1.8.1.3</strong> to display the XPages, which is the <strong>render engine of Firefox 1.5</strong> as far as I know. So make sure to have everything you do compatible with that "nearly recent" Firefox version. ;-) <br /> (the Xulrunner executable is located in the folder <notesdir>\framework\rcp\eclipse\plugins\com.ibm.rcp.xulrunner.runtime.win32.x86_6.2.1.20090925-1604\xulrunner) <br /> It should be possible to do that (1.5 was already quite powerful), although I'm a bit confused because <a href="http://www.dojotoolkit.org/tags/browser-compatibility" target="_blank">this page</a> says that the dijit widgets are only supported in Firefox 2+x. But I saw at least the dijit tabbedpane work without problems in one of my apps. <br /> <strong><br /> Java execution errors?</strong> <br /> Let's say that you followed this blog series and did your homework. You have tried to use JSF managed beans in your application, understood the concept and like it. <br /> Well, then you may have already seen this Java exception thrown in a few methods, for example in those that call our JSF managed bean helper class: <br /> <br /> <code>javax.faces.FacesException: java.lang.SecurityException: ECL Permission Denied <br />  &nbsp; &nbsp;com.sun.faces.application.ApplicationAssociate.createAndMaybeStoreManagedBeans(Unknown Source) <br />  &nbsp; &nbsp;com.sun.faces.el.VariableResolverImpl.resolveVariable(Unknown Source) <br />  &nbsp; &nbsp;com.ibm.xsp.el.VariableResolverImpl.resolveVariable(Unknown Source) <br />  &nbsp; &nbsp;com.sun.faces.el.impl.NamedValue.evaluate(Unknown Source) <br />  &nbsp; &nbsp;com.sun.faces.el.impl.ExpressionEvaluatorImpl.evaluate(Unknown Source) <br />  &nbsp; &nbsp;com.sun.faces.el.ValueBindingImpl.getValue(Unknown Source) <br />  &nbsp; &nbsp;com.sun.faces.el.ValueBindingImpl.getValue(Unknown Source) <br />  &nbsp; &nbsp;com.acme.tools.JSFUtil.getBindingValue(Unknown Source)</code> <br /> <br /> When I first saw this, I yelled something comparable to "Interesting! How fascinating! A welcome challenge for me!". Ok, maybe less polite ;-). <br /> <br /> That was 2-3 days ago. Since then, I did some research and testing to find out what is causing this problem and how to deal with it. <br /> I'd like to share it with you. <br /> <strong><br /> The Domino Server - a secure environment</strong> <br /> So far, we did our Xpages development on a Domino server. We were allowed to do this, because our administrator granted us developer rights on a database on the server, and he gave us the power to execute our code on that machine. He does not allow anybody to do this. He knows us and trusts us. <br /> <strong><br /> Controlling access in the Notes Client</strong> <br /> It's a slightly different situation for the Notes client. A Notes user could download a Notes database with malicious code from anywhere on the internet. <br /> That's the reason why there is an <strong>Execution Control List</strong> (ECL) in the client to restrict what applications may do on the user's workstation. Critical operations like accessing the machine's filesystem need to be confirmed (trusted) by the user - and the administrator can prevent Notes users from easily trusting anyone. <br /> The ECL is not a new invention. It's been in the client for many years and controlled the program code of forms, views, agents and other design elements. <br /> <br /> For Eclipse plugins extending the Lotus Notes Standard client, there is no such thing as an ECL (because Eclipse does not have it), only the installation of plugins can be controlled by policy. <br /> This has produced a lot of discussion about the security of Eclipse plugins. <br /> <strong><br /> Security for local Xpages</strong> <br /> For the first implementation of XPages in the Notes client, IBM chose a more conservative security model. The Java programming language has a built-in security system, called the SecurityManager, that IBM connected to the ECL system of Lotus Notes. <strong>Everything that is not connected to the ECL system of Lotus Notes, is considered insecure and is therefore denied</strong>. <br /> <br /> Java developers may already know the impact of the SecurityManager when they try to do restricted operations (like accessing files) in Java applets. They just don't work. <br /> <br /> So that's what happens behind the scenes in our method "JSFUtil.getBindingValue(String)". It calls JSF functions and deep in the calling tree, there is a restricted method and the JVM says "no". <br /> <strong><br /> The good news</strong> <br /> The administrator does not have to worry about end users that download and open XPages applications from the web. <br /> <strong><br /> The bad news</strong> <br /> The developers and ISVs have to worry about what their application code is allowed to do and how to deal with the restrictions. <br /> <strong><br /> What is allowed?</strong> <br /> Here is a table with the available classes of allowed Java operations and their equivalent ECL levels in Notes 8.5.1: <br /> <br /> <table border="1"><tr><th>Java Permission</th><th>Note Client ECL Access (Workstation)</th></tr><tr><td>java.util.PropertyPermission</td><td>Environment variables</td></tr><tr><td>java.io.FilePermission</td><td>File system</td></tr><tr><td>java.net.SocketPermission</td><td>Network</td></tr></table><br>(plus using the Notes Java API) <br /> <br /> Calling a Java operation that needs one of these permissions results in a Notes ECL confirmation dialog if the XPage's signer is not trusted. <strong>Any other restricted Java operation that is not listed in the table will fail for Xpages in the Notes Client 8.5.1.</strong> <br /> <strong><br /> What is not allowed?</strong> <br /> Ok, this is the "not so funny" part of this blog posting. I did a few tests. I don't have a complete list, but I have some of the things that hurt the most:  <ul> <li>using java.net.URLConnection, e.g. to easily connect to a web server  </li><li>XML parsing with javax.xml.parsers.DocumentBuilder  </li><li>Loading Java resources with Class.getResourceAsStream()</li></ul>All three are prohibited because java.net.NetPermission is not connected to the ECL system. <br /> Regarding the URLConnection: Please note that you <em>can</em> use networking. I have a working demo of an XPages application in the client that downloads a HTML file from a web server (by using Java's <a href="http://java.sun.com/javase/6/docs/api/java/net/Socket.html" target="_blank">Socket</a> class and the HTTP protocol) and analyzes it in an XPages application in the client. Actually, at the moment, it's not 100% working any more, because I just upgraded to a new version of <a href="http://jtidy.sourceforge.net/" target="_blank">JTidy</a> which now internally loads Java resources with <em>Class.getResourceAsStream()</em>. Ouch... ;-) <br /> <strong><br /> Workaround for developers</strong> <br /> Add the grant command shown below to the java.policy file under the Notes directory and restart the client. <br /> <br /> <code>grant { <br />  &nbsp; &nbsp; &nbsp;permission java.security.AllPermission; <br /> };</code> <br /> <br /> This completely disables the security restrictions of the platform. That's why it's <strong><em><span style="text-decoration:underline">an extremely bad idea to do this on a user's machine</span></em></strong>. :-) <br /> But it makes it easy for you to work on your Java code and test it in the client. <br /> <strong><br /> Workaround for customer installations</strong> <br /> This is not really a workaround. <span style="text-decoration:underline">It's the only thing we have</span>. ;-) <br /> <br /> You can put all your restricted code in a JAR file and store it in the jvm/lib/ext directory of the Notes Client. That code then has the right to run with a higher security level and may do the things that your XPages Java code is not allowed to. <br /> Please note that you need a special syntax in your code to ask Java for that higher privilege level: <br /> <br /> <code>public class ExternalWorkaroundClass { <br />  &nbsp; &nbsp;public String tryWorkaround(final String anArgument) throws Exception { <br /> <br />  &nbsp; &nbsp; &nbsp; &nbsp;String result = AccessController.doPrivileged( <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new PrivilegedExceptionAction<String>() { <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;public String run() throws Exception { <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;String result=null; <br /> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//do some restricted operations here to compute result <br /> <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return result, <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <br />  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <br />  &nbsp; &nbsp; &nbsp; &nbsp;); <br />  &nbsp; &nbsp; &nbsp; &nbsp;return result; <br />  &nbsp; &nbsp;}</code> <br /> <strong><br /> How should I automatically deploy this to a few hundred customers???</strong> <br /> Don't ask me. Be creative. ;-). IBM dev is working on a better solution and more supported Java permissions in a future version (<strong><span style="text-decoration:underline">hopefully 8.5.2 or some kind of 8.5.1 fix pack</span></strong>). <br /> Looks like they thought that most of the XPages developers do not use those restricted (or any) Java classes at all. So the impact of this would not be too big. <br /> <br /> And they were probably right. But for us, this really hurts. <br /> <strong><br /> What about managed Java beans?</strong> <br /> I guess the JSF method that produces the Java exception shown at the beginning of this article either wants to load the JSF configuration XML file faces-config.xml as a Java resource or it wants to parse it using the JVM's XML parser. <br /> But hey, remember I said something similar to "A welcome challenge for me!"? :-) <br /> <br /> I'm currently writing my own bean manager. The whole bean concept is about creating a bean, feeding it with default values and storing it in the right scope. Who needs the JSF bean manager for that? :-)   ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/21.10.2009142550KLEGL7.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/21.10.2009142550KLEGL7.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Notes 8.5.1: The new Java UI classes and Domino Designer extensibility API</title>
<pubDate>Sun, 11 Oct 2009 17:46:06 +0200</pubDate>
<description>
<![CDATA[ 
I haven't read any blog articles yet about the new extensibility APIs that come with Lotus Notes 8.5.1. Since we participated in the discussion with IBM (at Lotusphere 2009 and later on in the Design Partner Program) about what needs to be part of a first official API version, I would like to give you some hints where to find these new APIs and what they are about. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/11.10.2009174606KLELHE.htm</link>
<category>Lotus Notes 8.5.1</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/11.10.2009174606KLELHE.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/11.10.2009174606KLELHE.htm</guid>
<content:encoded><![CDATA[ <em>Disclaimer: IBM Lotus Notes/Domino 8.5.1 is prerelease code and there are no guarantees from IBM that the functionality presented or discussed will be in the final shipping product.</em> <br />  <br /> <br />I haven't read any blog articles yet about the new extensibility APIs that come with Lotus Notes 8.5.1. Since we participated in the discussion with IBM (at Lotusphere 2009 and later on in the Design Partner Program) about what needs to be part of a first official API version, I would like to give you some hints where to find these new APIs and what they are about. <br /> <br />Two new extensibility APIs will ship with Lotus Notes 8.5.1: <br /> <br /><strong><span style="text-decoration:underline">Domino Designer Extensibility API</span></strong> <br />With this API, an experienced Eclipse Java developer is able to track the user's selection in DDE (e.g. the Note ID/Notes URL of the selected design elements) in order to apply his own design modifications (e.g. via DXL import) and let DDE catch up with the modified design elements afterwards. <br />It contains functions to convert a standard Eclipse <tt>IProject</tt> into something called <tt>DesignerProject</tt> that provides additional information for a NSF database project in DDE. You get the basic NSF data like server/filepath/replica-id, some design related infos (template names, design hidden flag) and a few interaction methods, for example to open a database in DDE and to initialize/refresh the whole NSF project or single design elements in case you applied some changes to the backend Notes database. <br /> <br /><strong><span style="text-decoration:underline">Notes Client Java UI API</span></strong> <br />The Java UI API lets you get a handle on the currently opened UI document and UI view, called <tt>NotesUIDocument</tt> / <tt>NotesUIView</tt>: <br /> <br /><code>NotesUIWorkspace ws=new NotesUIWorkspace(); <br />NotesUIDocument uidoc=ws.getCurrentDocument(); <br />NotesUIView uiview=ws.getCurrentView();</code> <br /> <br />You do not have all the methods in Java yet that you know from the Lotusscript NotesUIDocument/NotesUIView, so don't expect too much for round nr 1. <font color="#ff0000">(<em>But read on until the last paragraph to see why this is not a real problem</em>)</font> <br /> <br /><span style="text-decoration:underline">NotesUIDocument</span> <br />With the Java based <tt>NotesUIDocument</tt> you are able to<em> modify fields</em> in the backend document. It provides refresh methods to make those changes visible in the front end. <br />Please note, that I said "<em>modify fields</em>", not "<em>get the backend document</em>". There are technical reasons (for example running in different threads and the Client's memory management) that make it impossible to get a full handle on the backend document, but the functionality of the API should be enough for most of the use cases. <br /> <br />You can get information about the currently focused field (including tracking focus changes with a <tt>DocumentFieldListener</tt>), toggle edit mode on/off, cut/copy/paste/insert text in the UI and detect that a document has been modified. <br /> <br /><span style="text-decoration:underline">NotesUIView</span> <br />The NotesUIView class gives you access to the view's name/UNID/URL. There is a method to print the view. <br /> <br />That not much for the NotesUIView, but by using the available Eclipse selection APIs you were already able to grab the selected documents in earlier Lotus Notes versions. <br /> <br /><span style="text-decoration:underline">NotesUIWorkspace</span> <br />In addition to the methods <tt>getCurrentDocument()</tt> and <tt>getCurrentView()</tt>, NotesUIWorkspace contains various methods to open Notes contents, like views, framesets or pages. There are also a few <tt>compose(...)</tt> methods that open a form to create a document in the Notes client. You can optionally specify a <tt>Document</tt> as an argument that contains fields that should be set as default field values in the form (this document can be a temporary document created with <tt>NotesUIWorkspace.getTemporaryDocument(Session)</tt>that is automatically deleted when the Notes client shuts down). <br /><tt>NotesUIWorkspace.addDatabase(...)</tt> adds a database to the workspace of the Notes client. <br />And finally, there is a <tt>NotesUIWorkspace.prompt(...)</tt> method that works like the corresponding method in Lotusscript. That means it displays different forms of selection dialogs with the style of the Notes client.  <br /> <br /><strong><span style="text-decoration:underline">Need more information?</span></strong> <br />So, how do you know the exact syntax of the available classes and methods?  <br />You can find the complete Javadoc documentation for the two new APIs in the help system of the Lotus Notes client: <div align=center> <br /><img  alt="Image:Notes 8.5.1: The new Java UI classes and Domino Designer extensibility API" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/11.10.2009174606KLELHE.htm/content/M2?OpenElement" /></div> <br /><strong><span style="text-decoration:underline">There is one more thing :-)</span></strong> <br />Oh wait, I forgot one method. Actually, it's my favorit one. <br />When we saw the first draft of the Java UI API at the end of last year, we thought of many things that we would like to add. <br />But you know, you quickly realize that you can only concentrate on a few features or even a single one, that is the most important to you and needs to be available for round nr 1. <br /> <br />Together with a few other design partners, we <em>desperately</em> asked/begged IBM to add one method, that is mission critical for the success of the API release. <br /> <br />The basic question was: What would you do if a feature is not available in Java, but you know that it's there in Lotusscript? You write a Lotusscript agent and call it from Java. <br />Something like <br /> <br /><code>Database db=session.getDatabase(server, filepath); <br />Agent myAgent=db.getAgent("MyLotusscriptAgent"); <br />myAgent.run();</code> <br /> <br />That's nothing new. A standard function in the Notes Java API sind R5 or R6. <br /> <br />Ever tried that with an agent that should do something in the UI, like changing a form's field values or open a selection dialog? <br />It does not work. <br /> <br />That's because Lotus Notes only executes that code in the backend, you do not have any UI access. <br /> <br /><strong>Here is the solution:</strong> <br /> <br /><tt><code><strong>public void runAgent(NotesAgentData agentData, NotesDocumentDataCallback callback, boolean runOnUIContext)</code></strong></tt> <br /><span style="font-size:10px;">From the javadoc: <br />Runs the agent represented by the agent data. Pass in false for runOnUIContext to run your agent on a temporary document. Pass in true for runOnUIContext to run your agent on the current selected document in the UI. Values added to the NotesAgentData object, using the addItem method, will be added to the temporary document. Also note with this method you can run an agent from one database on a completely different database. In other words, the agent you are running does not have to run on documents from the same database. While this gives the user more flexibility it also may break some assumptions of the agent, for example what fields are on the document.  <br /> <br />When running an agent on a temporary document it is recommended that you set the Target in the properties dialog of the agent to be 'None'. You can do this while editing the agent in Domino Designer. This allows you to run the agent without having anything selected in the UI. To access the temporary document from your agent, you can use Session.DocumentContext in LotusScript, or Session.getAgentContext().getDocumentContext() in Java. The note id of the temporary document is returned to you in the NotesDocumentDataCallback object.  <br />&#91;...&#93; <br />Parameters: <br />agentData - data about the agent to run <br />callback - callback to run when agent is done running <br />runOnUIContext - true to run the agent on the current UI context false to run the agent on the temporary document</span> <br /> <div align=center> <br />This new method is <font color="#ff0000"><strong>incredibly great<span style="text-decoration:underline"></font></span></strong>.</div> <br />It means that you can put all the code that is missing in this first Java UI API release into a Lotusscript or formula agent and use <tt>NotesUIWorkspace.runAgent()</tt> to execute it - <em>&nbsp;</em>in <em>any </em>database. And even better, there is a <em>callback mechanism</em> that you can use to get notified when the code is done to grab some results from a parameter document or the Notes.ini. <br /> <br /> <br /><strong>Tomorrow is Notes 8.5.1 release day. Have fun playing with the new APIs!</strong> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/11.10.2009174606KLELHE.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/11.10.2009174606KLELHE.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages in the client: How to use XPages as components in Composite Applications</title>
<pubDate>Mon, 14 Sep 2009 17:55:08 +0200</pubDate>
<description>
<![CDATA[ 
Today two interesting videos have been posted to the Domino Designer wiki that demonstrate how XPages in the Lotus Notes client 8.5.1 can be integrated with other components by using them as components of a Composite Application. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/14.09.2009175508KLELNZ.htm</link>
<category>Composite Application</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/14.09.2009175508KLELNZ.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/14.09.2009175508KLELNZ.htm</guid>
<content:encoded><![CDATA[ <em>Disclaimer: IBM Lotus Notes/Domino 8.5.1 is prerelease code and there are no guarantees from IBM that the functionality presented or discussed will be in the final shipping product.</em> <br /> <br /> <br />Today two interesting videos have been posted to the <a href="http://www-10.lotus.com/ldd/ddwiki.nsf/dx/XPage_Components_in_Notes_851_Videos.htm" target=_blank>Domino Designer wiki</a> that demonstrate how XPages in the Lotus Notes client 8.5.1 can be integrated with other components by using them as components of a Composite Application. <br /> <br /><strong><span style="text-decoration:underline">Component definition for XPages</span></strong> <br />The first video shows how to transform an XPage into a new design element type called <em>Component</em>, that can then be used in a Composite Application. For a <em>Component</em>, you can define your own properties in order to configure the referenced XPage for a specific use case. <br />In the video, this is used to alter the theme of the XPage and to show and hide elements within the XPage's UI depending on the property value. By defining component properties, your XPages become much more reusable and configurable. The purpose is to reuse the same XPage in many different contexts (inside Composite Applications) without the need to change a line of code. <div align=center> <br /><a href="http://download.boulder.ibm.com/ibmdl/pub/software/dw/lotus/XPages/Components/XPage_Components_in_Notes_851_Part1.html" target="_blank"><img  alt="Image:XPages in the client: How to use XPages as components in Composite Applications" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/14.09.2009175508KLELNZ.htm/content/M2?OpenElement" /> <br />XPage of the discussion database as a component in a Composite Application (click to watch the video)</a></div> <br /> <br /><strong><span style="text-decoration:underline">Wiring XPages components to other components</span></strong> <br />In the second video, the XPage is wired to a mail database component and a web browser component. They communicate in both directions by sending Composite Application properties: <br />Clicking on links in the XPage changes the search query on the web and generates a new email with pre-filled fields. In the other direction, clicking on an email in the inbox opens the mail sender's article list in the XPage discussion database. <div align=center> <br /><a href="http://download.boulder.ibm.com/ibmdl/pub/software/dw/lotus/XPages/Components/XPage_Components_in_Notes_851_Part2.html" target="_blank"><img  alt="Image:XPages in the client: How to use XPages as components in Composite Applications" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/14.09.2009175508KLELNZ.htm/content/M3?OpenElement" /> <br />Composite Application of an XPage, a Notes Java view and a browser component (click to watch the video)</a></div> <br />The video contains pretty simple examples, but when you understand the idea behind the whole concept, a lot more can be achieved with this technology. It's a great opportunity to extend the functionality of "XPages in the client". <br />In Lotus Notes 8.5.1, the pure XPages runtime will only provide basically the same as in the web browser. But by using Composite Application technology, you can easily add features to your application that are not yet available for XPages. <br /> <br />Let's take a look at another use case: <br />You could produce a formatted text in the code of your CRM XPages application (e.g. your own XML format from the user's selection) and publish it through a CA wire. Either you or any other developer can then build a CA component to receive and process this content. <br />They could e.g. develop it in Lotusscript to produce some fancy Notes richtext output or write an Eclipse plugin in Java to automate the Symphony office suite that is build inside Lotus Notes to create a new document, like a letter or even a complete report spreadsheet. <br />In this use case, the components that take care of the content output to richtext/Symphony, could also be hidden helper components without UI contribution to the Composite Application. <br /> <br /><strong><span style="text-decoration:underline">Summary</span></strong> <br />Although the first XPages implementation for the Lotus Notes client 8.5.1 is basically more or less a portable web application container, you can use Composite Application technology to add more functionality. <br /> <br />The benefit of the Composite Application architecture is to mix a lot of technologies for the purpose of a business use case without the need to redevelop cross-technology interfaces over and over again. Composite Applications have a simple data exchange system: The CA components use simple strings to send and receive data to other components. Components are connected through so called Composite Application wires to exchange this data. <br /> <br />Hopefully, the integration into the Notes client will be further improved in later Lotus Notes releases. The JSF technology that the XPages runtime is build upon, provides a technology called <a href=http://java.sun.com/javaee/javaserverfaces/reference/docs/customRenderKit.html target=_blank><em>custom render kits</em></a>. They can be used to create alternative output formats of a JSF application, e.g. native Java rendering in SWT or Swing or maybe solutions for mobile phone. <br />Although developing a custom render kit is a lot of work, this <em>might </em>be a way to enrich the XPages experience with native controls (like Java views and the native Notes richtext editor) in a later Lotus Notes version. Another approach could be to extend the <a href=https://developer.mozilla.org/en/XULRunner target=_blank>XULRunner</a> that the XPages runtime uses in the client to render the UI. <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/14.09.2009175508KLELNZ.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/14.09.2009175508KLELNZ.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>Augmented reality on the iPhone - a cool new concept with great potential</title>
<pubDate>Mon, 31 Aug 2009 13:52:02 +0200</pubDate>
<description>
<![CDATA[ 
A little sign of life, one week after the last vacation and one week before the next one. :-)

Our main work at the moment has to do with a completely new MindPlan version for our partner Haus Weilgut. There already is a standalone MindPlan application on the market that stores its data in Lotus Notes and one version that is directly integrated into the Lotus Notes 8.x client as a Composite Application component.
This new version is somehow different. Still using Notes/Domino technologies, but with a very innovative approach. Watch the MindPlan blog for announcements in the next weeks.

I will continue the XPages development and blogging after the next vacation (had to concentrate on MindPlan to produce an alpha test version).

For now, I've just come across a very cool new concept, called "Augmented reality" for the iPhone that I would like to share with you.

Here is an article about a sample application that integrates tourist information into the camera image of an iPhone:
The future is now? Augmented reality comes to the iPhone

I think the technology has a great potential, not only for tourist information. I think of very funny geo caching and virtual reality shooter games when I the demo video.
For example something like this on the iPhone: http://www.youtube.com/watch?v=Cix3Ws2sOsU  :-) ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/31.08.2009135201KLEFX3.htm</link>
<category>iPhone</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/31.08.2009135201KLEFX3.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/31.08.2009135201KLEFX3.htm</guid>
<content:encoded><![CDATA[ A little sign of life, one week after the last vacation and one week before the next one. :-) <br /> <br />Our main work at the moment has to do with a completely new <a href=http://www.mindplan.com target=_blank>MindPlan</a> version for our partner Haus Weilgut. There already is a standalone MindPlan application on the market that stores its data in Lotus Notes and one version that is directly integrated into the Lotus Notes 8.x client as a Composite Application component. <br />This new version is somehow different. Still using Notes/Domino technologies, but with a very innovative approach. Watch the <a href=http://blog.mindplan.com target=_blank>MindPlan blog</a> for announcements in the next weeks. <br /> <br />I will continue the XPages development and blogging after the next vacation (had to concentrate on MindPlan to produce an alpha test version). <br /> <br />For now, I've just come across a very cool new concept, called "Augmented reality" for the iPhone that I would like to share with you. <br /> <br />Here is an article about a sample application that integrates tourist information into the camera image of an iPhone: <br /><a href=http://www.macworld.com/article/142503/2009/08/augmented_reality.html target=_blank>The future is now? Augmented reality comes to the iPhone</a> <br /> <br />I think the technology has a great potential, not only for tourist information. I think of very funny geo caching and virtual reality shooter games when I the demo video. <br />For example something like this on the iPhone: <a href="http://www.youtube.com/watch?v=Cix3Ws2sOsU" target=_blank>http://www.youtube.com/watch?v=Cix3Ws2sOsU</a> &nbsp;:-)  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/31.08.2009135201KLEFX3.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/31.08.2009135201KLEFX3.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #6: Tracking data changes</title>
<pubDate>Wed, 22 Jul 2009 17:52:10 +0200</pubDate>
<description>
<![CDATA[ 
We will change and add a lot of code in our XPages/JSF sample implementation in this blog posting, because our current Movie Actor application does note handle data changes very well.

Remember part 4 of this series, when we introduced the Actor and ActorList implementation:
Our ActorList Java bean is the so called backing bean behind the ActorList XPage, which means that it is used to provide the data and application logic needed by that XPage.
Moving all the code from the XPage to the backing bean helps us to separate the UI from the business logic. It improves code reuse and testing/debugging.

In part 4 I described how to show your own Java objects in a data table control and in a repeat control. We used this technology to display a list of Actor objects in read-only mode.
As I said in the article, you can replace the computed fields in the data table by edit boxes to make the Actor object list editable. JSF then calls the setter methods of the Actor objects with the new values.

That works, but the architecture isn't really smart that way.

In this article, I would like to add a data store to our little scenario, that we will use to store the data changes to a persistent data storage.
That way we can
-check whether the current user is allowed to change the data
-write the changes and the previous values to a log file (e.g. for auditing purpose)
-do data transformation, like storing the information of one data object in two places (e.g. two Notes documents or Notes and SQL)
-trigger additional data changes, like inheriting field values to/from other documents

In short: We get complete control over the data that is written to disk.
 ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/22.07.2009175255KLELM7.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/22.07.2009175255KLELM7.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/22.07.2009175255KLELM7.htm</guid>
<content:encoded><![CDATA[ We will change and add a lot of code in our XPages/JSF sample implementation in this blog posting, because our current Movie Actor application does note handle data changes very well. <br /> <br />Remember <a href="http://www.mindoo.com/web/blog.nsf/dx//web/blog.nsf/dx/16.07.2009095816KLEBCY.htm?opendocument&amp;comments#anc1" target=_blank>part 4 of this series</a>, when we introduced the <em>Actor</em> and <em>ActorList</em> implementation: <br />Our ActorList Java bean is the so called <strong>backing bean</strong> behind the ActorList XPage, which means that it is used <strong>to provide the data and application logic needed by that XPage</strong>. <br />Moving all the code from the XPage to the backing bean helps us to separate the UI from the business logic. It improves code reuse and testing/debugging. <br /> <br />In part 4 I described how to show your own Java objects in a data table control and in a repeat control. We used this technology to display a list of Actor objects in read-only mode. <br />As I said in the article, you <em>can</em> replace the computed fields in the data table by edit boxes to make the Actor object list editable. JSF then calls the setter methods of the Actor objects with the new values. <br /> <br />That works, but the architecture isn't really <em>smart </em>that way. <br /> <br />In this article, I would like to add a data store to our little scenario, that we will use to store the data changes to a persistent data storage. <br />That way we can <ul> <li>check whether the current user is allowed to change the data </li><li>write the changes and the previous values to a log file (e.g. for auditing purpose) </li><li>do data transformation, like storing the information of one data object in two places (e.g. two Notes documents or Notes and SQL) </li><li>trigger additional data changes, like inheriting field values to/from other documents</li></ul> <br />In short: <strong>We get complete control over the data that is written to disk</strong>. <br /> <br />Our today's result will look like this: <div align=center> <br /><img  alt="Image:XPages series #6: Tracking data changes" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/22.07.2009175255KLELM7.htm/content/M2?OpenElement" /> <br /> <br />(we concentrate on the functionality first, this is not a web design series ;-) )</div> <br /> <br />It's the data table of part 4, but with edit boxes and a button "Save changes". That button triggers the save operation to store the modified Actor table row entries into our own data store. <br />The logging field at the bottom contains a list of data comparison results (I had changed the comment property of the first Actor in the list and pressed the save button). <br /> <br /><strong>Our data store</strong> <br /> <br />Let's start with a simple Java interface definition of our data store: <br /> <br /><code>package com.acme.actors.model; <br />import java.util.List; <br /> <br /><span style="color:#008000">/** <br />&nbsp;* Interface for a CRUD-based Data Store <br />&nbsp;*/</span> <br />public interface DataStore { <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* The method creates a new Actor instance <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return new Actor <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public Actor createActor(); <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* The method searches for an Actor by its ID in the data store <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param id Actor ID <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return Actor or null <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public Actor findActorById(String id); <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Writes changes made to the specified Actor instance to the data store <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* to store them permanently. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param changedActor Changed Actor instance <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public void updateActor(Actor changedActor); <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* The method delete an Actor from the data store <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param id Actor ID <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public void deleteActor(String id); <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* The method returns a list of Actor objects, ordered by the lastname property. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* This list cannot be modified. Use the DataStore methods instead. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return List <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public List<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />Actor<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> getActorsByLastname(); <br />}</code> <br /> <br />That's a data store interface for our Actor objects following the <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" target=_blank>CRUD</a> pattern. CRUD stands for <strong>C</strong>reate, <strong>R</strong>ead, <strong>U</strong>pdate and <strong>D</strong>elete. <br />It's not a concrete implementation. A Java interface acts like a blueprint for the implementations: they have to implement all the methods of the interface. <br /> <br />Our implementation, using an in-memory list of objects can be found here: <ul> <li><a href="http://www.mindoo.com/web/blog.nsf/dx/MyDataStore.java/$file/MyDataStore.java" target="_blank" title="MyDataStore.java">MyDataStore.java - com.acme.actors.model.mydb.MyDataStore</a><br /> (I inserted a link to the file to make this article more readable)</li></ul>The first interesting thing is how we tell JSF about this concrete data store implementation. We use a new managed bean for that, <nobr>called <em>DataStoreManager</em>:</nobr> <br /> <br /><code>package com.acme.actors.model; <br /> <br />import javax.faces.FacesException; <br />import com.acme.tools.JSFUtil; <br /> <br /><span style="color:#008000">/** <br />&nbsp;* The DataStoreManager manages the {@link DataStore} instance that is <br />&nbsp;* used for the data storage of the application. <br />&nbsp;*/</span> <br />public class DataStoreManager { <br />&nbsp; &nbsp; &nbsp; &nbsp; private String m_storageClass; <br />&nbsp; &nbsp; &nbsp; &nbsp; private DataStore m_store; <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; public DataStoreManager() {} <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* This method is used by JSF to set the class name of the <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* {@link DataStore} to be used. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param className class name <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; @SuppressWarnings("unchecked") <br />&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#ff0000">public void setStorageClass(String className) {</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_storageClass=className; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //try to initialize the data store using Java reflection <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Class<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />? extends DataStore<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> storageClazz=(Class<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />? extends DataStore<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>) getClass().forName(className); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_store=(DataStore) storageClazz.newInstance(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (ClassNotFoundException e) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new FacesException(e); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (IllegalAccessException e) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new FacesException(e); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InstantiationException e) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new FacesException(e); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Returns the class name of the {@link DataStore} to be used. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return class name <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public String getStorageClass() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m_storageClass; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Returns the data store instance for the data access. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return data store <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public DataStore getStore() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m_store; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Convenience method to access the instance of the DataStoreManager for <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* the current user from the session scope. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return DataStoreManager instance <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#ff0000">public static DataStoreManager getManager() {</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (DataStoreManager) JSFUtil.getBindingValue("#{DataStoreManager}"); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />}</code> <br /> <br />Take a look at two methods in particular: <em>setStorageClass(String)</em> and the static method <em>getManager()</em>. <br /> <br />We use <em>setStorageClass(String)</em> to tell the DataStoreManager bean which implementation of the DataStore interface it should use. It then tries to instantiate the concrete data store, for our test implementation the class is "com.acme.actors.model.mydb.MyDataStore". <br /> <br />The static method <em>getManager()</em> uses one of the helper functions of <a href="http://www.mindoo.com/web/blog.nsf/dx//web/blog.nsf/dx/18.07.2009191738KLENAL.htm?opendocument&amp;comments#anc1" target=_blank>series part 5</a> to return the session scope instance of the DataStoreManager. <br /> <br />So in our Java code, we can quickly do data store operations like this <br /> <br /><code>DataStore ds=DataStoreManager.getManager().getStore(); <br />ds.deleteActor("12345"); <br /> <br />Actor newActor=ds.createActor(); <br />newActor.setFirstname("Humphrey"); <br />newActor.setLastname("Bogart"); <br />newActor setComment("Casablanca"); <br />ds.updateActor(newActor);</code> <br /> <br />JSF will take care that the DataStoreManager bean is created when we call <em>getManager()</em>. We can even call <em>getManager()</em> before the bean is used anywhere in an XPage. <br /> <br />Please note that the code above <strong>does not contain any Lotus Notes specific code</strong> like bindings to Notes documents and views, just our own simple Java classes and interfaces. <br />Data handling is done <span style="text-decoration:underline">in our code</span>. <br /> <br /><strong>Setting default bean properties</strong> <br /> <br />How do we know when to tell the DataStoreManager the class name of our data store? <br />That's easy: <em>We let JSF do it automatically</em>. By adding a small piece of code in the faces-config.xml, we can define default values that should be set when a bean is created by JSF. <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" />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; <<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; <<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" />>DataStoreManager<<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; <<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.acme.actors.model.DataStoreManager<<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; <<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" />>session<<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 /><span style="color:#ff0000"> &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; <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />property-name>storageClass<<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; <<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.acme.actors.model.mydb.MyDataStore<<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; <<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" />></span> <br />&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 /> <br />&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; <<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" />>ActorList<<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; <<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.acme.actors.controller.ActorList<<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; <<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" />>session<<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; <<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 /> <br />&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; <<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" />>Log<<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; <<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.acme.logging.Log<<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; <<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" />>session<<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; <<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 /><<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 />You can set more than just string properties. For example, you can fill a Map with key/value pairs or predefine the values of a Java List. Please refer to the JSF documentation I mentioned in <a href="http://www.mindoo.com/web/blog.nsf/dx//web/blog.nsf/dx/15.07.2009152504KLEHR8.htm?opendocument&amp;comments#anc1" target=_blank>part 2 of this series</a> for the exact syntax. <br /> <br /><strong>Detecting object property changes</strong> <br /> <br />There are certainly many ways to track property changes for the data objects. For this example, I chose to store a list of <em>ObjectPropertyChangeEvent</em>s in my data objects. Such a change event basically is a container for the name of the property (like "Firstname", "Lastname", "Comment"), its old and its new value. We will generate such events in the setter methods of our new <em>Actor</em> class implementation like this: <br /> <br /><code>public void setFirstname(String newFirstName) { <br />&nbsp; &nbsp; &nbsp; &nbsp; if (!StringUtil.isEqual(m_firstName, newFirstName)) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#008000">//first name has changed. Store old and new value in a change event</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#ff0000">ObjectPropertyChangeEvent evt=new ObjectPropertyChangeEvent(FLD_ACTOR_FIRSTNAME, m_firstName, newFirstName); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_firstName=newFirstName; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addChangeEvent(evt);</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />}</code> <br /> <br />Here is the base implementation of a data object. It contains all the property change management methods. Our <em>Actor</em> class will now be a subclass of <em>DataObject</em> &nbsp;to leverage those methods. <br /> <br /><code>package com.acme.actors.model; <br /> <br />import java.util.Hashtable; <br /> <br /><span style="color:#008000">/** <br />&nbsp;* Abstract base object for a data store object that provides an internal list <br />&nbsp;* of changed object properties. The purpose is to quickly get information <br />&nbsp;* in a data source what property changes have to be transferred to <br />&nbsp;* persistent storage. <br />&nbsp;*/</span> <br />public abstract class DataObject { <br />&nbsp; &nbsp; &nbsp; &nbsp; private boolean m_initialized=false; <br />&nbsp; &nbsp; &nbsp; &nbsp; private Hashtable<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />String, ObjectPropertyChangeEvent<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> m_changeEvents; <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; public DataObject() {} <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; protected void init() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!m_initialized) { <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//lazy creation of member variables</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_changeEvents=new Hashtable<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />String, ObjectPropertyChangeEvent<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; m_initialized=true; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Method to check whether properties in this object have been changed. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>true<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> if there are changed properties <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public boolean hasChanges() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init(); <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return !m_changeEvents.isEmpty(); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Returns the property change events for this object <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return change events or an empty list <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public ObjectPropertyChangeEvent&#91;&#93; getChanges() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init(); <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m_changeEvents.values().toArray(new ObjectPropertyChangeEvent&#91;m_changeEvents.size()&#93;); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Adds a change event to the internal list. If the property has been changed <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* before, the old and new change event will be merged into one. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param evt change event <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; protected void addChangeEvent(ObjectPropertyChangeEvent evt) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init(); <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String fieldId=evt.getFieldId(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ObjectPropertyChangeEvent oldEvt=m_changeEvents.get(fieldId); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (oldEvt==null) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_changeEvents.put(fieldId, evt); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else { <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//merge old and new event</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Object oldValue=oldEvt.getOldValue(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_changeEvents.put(fieldId, new ObjectPropertyChangeEvent(fieldId, oldValue, evt.getNewValue())); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Method to clear the change event list <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public void resetChanges() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_initialized=false; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init(); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />}</code> <br /> <br />Here is the new Actor implementation and the source code of the <em>ObjectPropertyChangeEvent</em>: <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/Actor.java/$file/Actor.java" title="Actor.java" target="_blank">Actor.java - com.acme.actors.model.Actor</a> <br /><a href="http://www.mindoo.com/web/blog.nsf/dx/ObjectPropertyChangeEvent.java/$file/ObjectPropertyChangeEvent.java" title="ObjectPropertyChangeEvent.java" target="_blank">ObjectPropertyChangeEvent.java - com.acme.actors.model.ObjectPropertyChangeEvent</a> <br /> <br />Our data store is now ready to use and our Actor data objects are prepared to write a change event log when somebody calls the setter methods. <br /> <br /><strong>Adding the "save changes" operation</strong> <br /> <br />At first, we now have to produce code in our <em>ActorList</em> backing bean that handles the save operation: It grabs the changed Actor objects from the data table and sends them to the persistent data store. <br />We use another of our helper function for this purpose: <em>JSFUtil.findComponent(String)</em>. It traverses the JSF component tree of the current XPage to give us access to the data table (like the getComponent() method does in XPages JavaScript). <br /> <br />This is our new ActorList backing bean: <br /> <br /><code>package com.acme.actors.controller; <br /> <br />import java.util.List; <br />import javax.faces.component.UIComponent; <br />import javax.faces.component.UIData; <br />import com.acme.actors.model.Actor; <br />import com.acme.actors.model.DataStoreManager; <br />import com.acme.tools.JSFUtil; <br /> <br />public class ActorList { <br />&nbsp; &nbsp; &nbsp; &nbsp; public ActorList() {} <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; public List<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />Actor<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> getActorsByLastname() { <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//delegate call to the new data store</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return DataStoreManager.getManager().getStore().getActorsByLastname(); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#ff0000"> &nbsp; &nbsp; &nbsp; &nbsp;public void save() { <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//grab the data table content and send it to the data store</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIComponent table=JSFUtil.findComponent("actorTable"); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (table instanceof UIData) { <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//the table is a subclass of UIData, which gives us access to the row values of the table</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIData tableData=(UIData) table; <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int rows=tableData.getRowCount(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int oldRowIndex=tableData.getRowIndex(); <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i=0; i<rows; i++) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tableData.setRowIndex(i); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Object currObj=tableData.getRowData(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (currObj instanceof Actor) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Actor currActor=(Actor)currObj; <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//send the Actor object to the data store to write changes <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //to the persistent storage</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DataStoreManager.getManager().getStore().updateActor(currActor); <br />&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; } <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tableData.setRowIndex(oldRowIndex); <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; Log.getInstance().println("Could not find table with id=actorTable"); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; }</span> <br />}</code> <br /> <br />Finally, we need to add the "Save changes" button to the XPage UI with the following JavaScript onClick code: <br /> <br /><code>var actorList=com.acme.tools.JSFUtil.getBindingValue("#{ActorList}"); <br />actorList.save();</code> <br /> <br />Here is a list of remaining files that have been used or changed in this article: <ul> <li>Full source of the ActorList XPage<br /> <a href="http://www.mindoo.com/web/blog.nsf/dx/ActorList.xsp.txt/$file/ActorList.xsp.txt" title="ActorList.xsp.txt">ActorList.xsp.txt</a> </li><li>Helper class for logging (bean implementation)<br /> <a href="http://www.mindoo.com/web/blog.nsf/dx/Log.java/$file/Log.java" title="Log.java" target="_blank">Log.java - com.acme.logging.Log</a> </li><li>Helper class for string comparison<br /> <a href="http://www.mindoo.com/web/blog.nsf/dx/StringUtil.java/$file/StringUtil.java" title="StringUtil.java" target="_blank">StringUtil.java - com.acme.tools.StringUtil</a></li></ul> <br />Ok, guys... the worst part of this series is over ;-). It has become a really long article, even longer than part 4. <br /> <br />But it's easier than it looks like. Believe me. :o) <br /> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/22.07.2009175255KLELM7.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/22.07.2009175255KLELM7.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #5: Helper classes to access the JSF environment and Lotus Notes data</title>
<pubDate>Sat, 18 Jul 2009 19:17:37 +0200</pubDate>
<description>
<![CDATA[ 
In this weekend posting, I would like to introduce two helper classes that you will probably need for your first steps. 

After I had found out how to declare and bind Managed Java Beans in XPages, I tried to produce a small sample application. 
Soon, three questions came up, that I needed to solve, before I could go on: 
How do I access global JavaScript variables and my declared Java beans?
How can I access fields in the current XPage?
Calling NotesFactory.createSession() to create a Notes session throws a security exception.
Is there a way to access Notes API from my bean code?

Here is the first helper class that has an answer for all three questions. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/18.07.2009191738KLENAL.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/18.07.2009191738KLENAL.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/18.07.2009191738KLENAL.htm</guid>
<content:encoded><![CDATA[ In this weekend posting, I would like to introduce two helper classes that you will probably need for your first steps. <br /> <br /> After I had found out how to declare and bind Managed Java Beans in XPages, I tried to produce a small sample application. <br /> Soon, three questions came up, that I needed to solve, before I could go on:  <ul> <li><strong>How do I access global JavaScript variables and my declared Java beans?</strong> </li><li><strong>How can I access fields in the current XPage?</strong> </li><li><strong>Calling NotesFactory.createSession() to create a Notes session throws a security exception.<br /> Is there a way to access Notes API from my bean code?</strong></li></ul>Here is the first helper class that has an answer to all three questions: <br /> <br /><code>package com.acme.tools; <br /> <br />import javax.faces.application.Application; <br />import javax.faces.context.FacesContext; <br />import javax.faces.el.ValueBinding; <br /> <br />public class JSFUtil { <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* The method creates a {@link javax.faces.el.ValueBinding} from the <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* specified value binding expression and returns its current 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" />> <br />&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<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;* If the expression references a managed bean or its properties and the bean has not <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* been created yet, it gets created by the JSF runtime. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param ref value binding expression, e.g. #{Bean1.property} <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return value of ValueBinding <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* throws javax.faces.el.ReferenceSyntaxException if the specified <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>ref<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> has invalid syntax <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public static Object getBindingValue(String ref) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FacesContext context=FacesContext.getCurrentInstance(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Application application=context.getApplication(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return application.createValueBinding(ref).getValue(context); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* The method creates a {@link javax.faces.el.ValueBinding} from the <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* specified value binding expression and sets a new value for it.<<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" />> <br />&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<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;* If the expression references a managed bean and the bean has not <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* been created yet, it gets created by the JSF runtime. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param ref value binding expression, e.g. #{Bean1.property} <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param newObject new value for the ValueBinding <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* throws javax.faces.el.ReferenceSyntaxException if the specified <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>ref<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> has invalid syntax <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public static void setBindingValue(String ref, Object newObject) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FacesContext context=FacesContext.getCurrentInstance(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Application application=context.getApplication(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ValueBinding binding=application.createValueBinding(ref); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; binding.setValue(context, newObject); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* The method returns the value of a global JavaScript variable. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param varName variable name <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return value <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @throws javax.faces.el.EvaluationException if an exception is thrown while resolving the variable name <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public static Object getVariableValue(String varName) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FacesContext context = FacesContext.getCurrentInstance(); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return context.getApplication().getVariableResolver().resolveVariable(context, varName); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Finds an UIComponent by its component identifier in the current <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* component tree. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param compId the component identifier to search for <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return found UIComponent or null <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @throws NullPointerException if <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>compId<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> is null <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public static UIComponent findComponent(String compId) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return findComponent(FacesContext.getCurrentInstance().getViewRoot(), compId); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Finds an UIComponent by its component identifier in the component tree <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* below the specified <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>topComponent<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> top component. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param topComponent first component to be checked <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param compId the component identifier to search for <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return found UIComponent or null <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @throws NullPointerException if <<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>compId<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />/code<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> is null <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public static UIComponent findComponent(UIComponent topComponent, String compId) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (compId==null) <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new NullPointerException("Component identifier cannot be null"); <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (compId.equals(topComponent.getId())) <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return topComponent; <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (topComponent.getChildCount()>0) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List<UIComponent> childComponents=topComponent.getChildren(); <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (UIComponent currChildComponent : childComponents) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIComponent foundComponent=findComponent(currChildComponent, compId); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (foundComponent!=null) <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return foundComponent; <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; return null; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />}</code> <br /> <br /><strong>How to access other beans and bean properties</strong> <br />You can use the methods <em>JSFUtil.getBindingValue()</em> and <em>JSFUtil.setBindingValue()</em> to do that: <br /> <br /><code><span style="color:#008000">//Returns our previously declared session scope bean ActorList. The bean is created if it does not exist yet</span> <br />ActorList actors=(ActorList) JSFUtil.getBindingValue("#{ActorList}"); <br /> <br /><span style="color:#008000">//Get the value of a bean property</span> <br />List<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />Actor<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> actorList=(List<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />Actor<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>) JSFUtil.getBindingValue("#{ActorList.actors}"); <br /> <br /><span style="color:#008000">//Set the value of a bean property</span> <br />JSFUtil.setBindingValue("#{ActorList.actors}", new ArrayList<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />Actor<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />>());</code> <br /> <br /><span style="text-decoration:underline">Hint:</span> <br />The expression language is more powerful than you might think. An expression like <br /> <br /><code>#{ActorList.actorsById&#91;"12345"&#93;.firstname}</code> <br /> <br />could for example return the firstname of the actor with the unique identifier "12345" from the ActorList bean. <br /> <br />What the expression resolver does internally is grab your declared <em>ActorList</em> bean from the session scope, look out for a method "getActorsById()" and check its return value. If the return value is of type <em>java.util.Map</em> (like a List in Lotusscript), if would then call its <em>get</em> method with the hash key "12345" (<em>like Map.get("12345")</em>) to get the Map entry for that key. In our case, this could be an Actor object. <br />Finally, the resolver then searches for a method <em>getFirstname()</em> in the object and returns its value. <br /> <br /><strong>How to access fields in the current XPage</strong> <br />An XPage (like any JSF page) consists of a tree of <em>UIComponent</em> objects. The top element of that tree can be retrieved with <br /> <br /><code>UIViewRoot view=FacesContext.getCurrentInstance().getViewRoot();</code> <br /> <br />Our helper function <em>JSFUtil.findComponent(String)</em> traverses the whole component tree and searches for an UIComponent with the specified identifier. <br />That's basically what the XPage JavaScript function <em>getComponent(String)</em> does. <br /> <br />So the following code <br /> <br /><code>UIComponent comp=JSFUtil.findComponent("actorTable");</code> <br /> <br />would for example give us access to the table of actors that we created in the previous article of this series. <br />It depends on the component type, how much we can do with the components. UIComponent is just the base class that all the various UI components extend. We will see an example use case for accessing the component tree in a later article. <br /> <br /><strong>How to access global JavaScript variables / How to get the current Lotus Notes Session</strong> <br />It you know the answer to the first question, you know the answer to the second. That's because the current Lotus Notes session and database are stored in global JavaScript variables. <br /> <br />So here is helper class number two, that leverages the new <em>JSFUtil.getVariableValue(String)</em> function to grab a global JavaScript variable: <br /> <br /><code>package com.acme.model.notes; <br /> <br />import lotus.domino.Database; <br />import lotus.domino.Session; <br />import com.acme.tools.JSFUtil; <br /> <br />public class DominoAccess { <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Returns the current Notes session instance of the Javascript engine. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return Session <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public static Session getCurrentSession() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (Session) JSFUtil.getVariableValue("session"); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br /><span style="color:#008000"> &nbsp; &nbsp; &nbsp; &nbsp;/** <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Returns the current Notes database instance of the Javascript engine. <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return Database <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; public static Database getCurrentDatabase() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (Database) JSFUtil.getVariableValue("database"); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />}</code> <br /> <br />Sample usage: <br /><code>Session session=DominoAccess.getCurrentSession(); <br />String userName=session.getUserName();</code> <br /> <br />This returns the user name of your Lotus Notes ID if you are logged in and the name of the Domino server ID if you are not logged in. <br /> <br /><span style="text-decoration:underline">Hint</span> <br />Please note that the session and all child Notes objects like databases or documents are disposed (by calling their <em>recycle()</em> method) quite often. I haven't figured out so far when this exactly happens. <br />So do not store Notes objects locally in your code. Instead, grab a fresh session, transfer the Notes data into your own objects and do not forget to call <em>recycle()</em> on Notes objects that you don't need any more (like for normal Notes Java API coding) to avoid high memory allocation. <br /> <br /> <br />That's it for today. A very technical article without a screenshot or real-life example. Sorry about that. But it's necessary to have this knowledge base for the next articles. <br />I'm curious if anybody has already started to build his own sample application. Feel free to write a comment! <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/18.07.2009191738KLENAL.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/18.07.2009191738KLENAL.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #4: Backing Bean Management with XPages</title>
<pubDate>Thu, 16 Jul 2009 09:58:16 +0200</pubDate>
<description>
<![CDATA[ 
In this part of the XPages series about an alternative application architecture, I'm going to talk about Backing Bean Management.

At the end of this blog entry, you should get the trick how the XPages user interface can be connected to backend Java Beans. I will follow up with another article that contains code snippets you might need after you start working with this technology in a real-life project.

And I promise to show an example at the very end of this series, to not leave you alone, totally confused with Java, Beans, Bindings, Expression Language and other things. :-)

Warning! This article is looooong ;-). ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/16.07.2009095816KLEBCY.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/16.07.2009095816KLEBCY.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/16.07.2009095816KLEBCY.htm</guid>
<content:encoded><![CDATA[ In this part of the XPages series about an alternative application architecture, I'm going to talk about Backing Bean Management. <br /> <br />At the end of this blog entry, you should get the trick how the XPages user interface can be connected to backend Java Beans. I will follow up with another article that contains code snippets you might need after you start working with this technology in a real-life project. <br /> <br />And I promise to show an example at the very end of this series, to not leave you alone, totally confused with Java, Beans, Bindings, Expression Language and other things. :-) <br /> <br /><strong><span style="color:#ff0000">Warning! This article is <span style="text-decoration:underline">looooong</span> ;-).</span></strong> <br /> <br /><strong>Separation of UI and application logic</strong> <br />A Backing Bean is a Java Bean that is associated with UI components used in a page. The purpose of Backing Beans is to separate the definition of UI components from objects that perform application-specific processing and hold data. That way your XPage will contain more or less just the UI, while the application logic is stored in the bean. <br /> <br />To continue with our Movie Actor database, we start with a pretty simple Java class that is a container for the data of an actor: <br /> <br /><code>package com.acme.actors.model; <br /> <br />public class Actor { <br />&nbsp; &nbsp; &nbsp; &nbsp; private String m_id; <br />&nbsp; &nbsp; &nbsp; &nbsp; private String m_firstName; <br />&nbsp; &nbsp; &nbsp; &nbsp; private String m_lastName; <br />&nbsp; &nbsp; &nbsp; &nbsp; private String m_comment; <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; public Actor() {} <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; public Actor(String id, String firstName, String lastName, String comment) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_id=id; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_firstName=firstName; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_lastName=lastName; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_comment=comment; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; public String getId() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m_id; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; public void setId(String newId) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_id=newId; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; public String getFirstname() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m_firstName; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; public void setFirstname(String newFirstName) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_firstName=newFirstName; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; public String getLastname() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m_lastName; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; public void setLastname(String newLastname) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_lastName=newLastname; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; public String getComment() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m_comment; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; public void setComment(String newComment) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_comment=newComment; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />}</code> <br /> <br />Well, pretty self-explanatory. The class will be is used to store the firstname, lastname, a comment and a unique identifier of an actor. Notice, that the class is completely independent from Lotus Notes. The identifier field might be later on used for a Notes document's universal id (in case we load Notes data), but it could just as well be something completely different like a primary key of table rows in a SQL database. <br /> <br />Let's take a look at our first Backing Bean. It will be used to provide the backend logic of our actor list XPage: <br /> <br /><code>package com.acme.actors.controller; <br /> <br />import java.util.ArrayList; <br />import java.util.List; <br />import java.util.UUID; <br />import com.acme.actors.model.Actor; <br /> <br />public class ActorList { <br />&nbsp; &nbsp; &nbsp; &nbsp; private List<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />Actor<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> m_actors; <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; public ActorList() {} <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; private void init() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (m_actors==null) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#008000">//list is empty and needs to be filled</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors=new ArrayList<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />Actor<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; m_actors.add(new Actor(createNewId(), "Sean", "Connery", "James Bond")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors.add(new Actor(createNewId(), "Daniel", "Craig", "James Bond")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors.add(new Actor(createNewId(), "Catherine", "Zeta-Jones", "Ocean's Twelve")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors.add(new Actor(createNewId(), "Tobey", "Maguire", "Spiderman")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors.add(new Actor(createNewId(), "Kirsten", "Dunst", "Spiderman")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors.add(new Actor(createNewId(), "John", "Travolta", "Pulp Fiction")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors.add(new Actor(createNewId(), "Bruce", "Willis", "Die Hard")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors.add(new Actor(createNewId(), "Christopher", "Lee", "Dracula")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors.add(new Actor(createNewId(), "Patrick", "Stewart", "Star Trek")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors.add(new Actor(createNewId(), "Charlton", "Heston", "Planet of the Apes")); <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; private String createNewId() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#008000">//create a new unique identifier for a list entry</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return UUID.randomUUID().toString(); <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; public List<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />Actor<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> getActors() { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#008000">//init() initializes the actor list the first time it is called</span> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init(); <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m_actors; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br /> <br />&nbsp; &nbsp; &nbsp; &nbsp; public void setActors(List<<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />Actor<img  src="http://www.mindoo.com/web/blog.nsf/dx//icons/ecblank.nsf/$file//icons/ecblank.nsf" width="1" height="1" />> newActors) { <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m_actors=newActors; <br />&nbsp; &nbsp; &nbsp; &nbsp; } <br />}</code> <br /> <br />Our class does not contain any real business logic at the moment. It contains a list of ten actors that are written into the internal variable "m_actors", which is returned by the method "getActors()". <br />We will use this method in our XPage, to feed the rows of a table. <br /> <br /><strong>Bean declaration in faces-config.xml</strong> <br />Next we need to tell the JavaServer Faces runtime about our new bean. <br />To do this, modify the faces-config.xml file and add the following <<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" />> section: <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" />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; <<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; <<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" />><span style="color:#ff0000">ActorList</span><<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; <<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" />><span style="color:#ff0000">com.acme.actors.controller.ActorList</span><<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; <<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" />><span style="color:#ff0000">session</span><<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; <<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 /><<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 />With this information, the JSF runtime is able to resolve an expression language construct like "#{ActorList}" to find our bean. It knows that the bean has the classname "com.acme.actors.controller.ActorList" and can create a new instance of it. <br />We also tell the runtime something about the bean's life span, called "scope", in this line: <br /> <br /><code><<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" />><span style="color:#ff0000">session</span><<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" />></code> <br /> <br />The scope <em>"application"</em> means that there will be only one instance of the bean in the whole application (=one bean for all users, useful for translation dictionaries). With<em>"session"</em>, one bean is created for the whole session of a single user, e.g. to hold personal profile information. With the scope<em>"request"</em> you can create a bean that is only valid for a single HTTP request (to pass data from one page to the other) and the scope <em>"none" </em>&nbsp;lets the JSF runtime dispose the bean after every HTTP request. In that case, it is stored nowhere automatically. <br /> <br /><strong>And now, the end is near</strong> <br />To bring all the pieces together, we now create our ActorList XPage and insert a data table control with three columns: <div align=center> <br /><img  alt="Image:XPages series #4: Backing Bean Management with XPages" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/16.07.2009095816KLEBCY.htm/content/M2?OpenElement" /></div> <br />For the table's binding, we click on "Advanced", select "Expression Language (EL)" from the combo box and enter the following text: <em>ActorList.actors</em>. <br />This produces the string "#{ActorList.actors}" in the source code of the XPage. When the JavaServer Faces runtime resolves this expression to retrieve the row data for the table, it fetches/creates our ActorList Java Bean from the sessionScope and searches for a method "getActors" in it. This is our method that returns the List of actors. <br /> <br />The table will now display each List entry in its own table row. By entering the string "currentActor" in the Collection name field (see #2 in the screenshot above), the row data (the current Actor objects) can be accessed in the row controls (in my case three computed fields for the firstname, lastname and comment): <div align=center> <br /><img  alt="Image:XPages series #4: Backing Bean Management with XPages" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/16.07.2009095816KLEBCY.htm/content/M3?OpenElement" /></div> <br />Here is the full source code of the ActorList XPage: <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:dataTable rows="5" id="actorTable" var="currentActor" <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; style="width:50%" value="<span style="color:#ff0000">#{ActorList.actors}</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:this.facets<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:pager layout="Previous Group Next" xp:key="header" id="pager1"<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:pager<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:pager layout="Previous Group Next" xp:key="footer" id="pager2"<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:pager<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.facets<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:column id="firstnameColumn"<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:text escape="true" id="firstnameField" value="<span style="color:#ff0000">#{currentActor.firstname}</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; &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<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:column<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:column id="lastnameColumn"<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:text escape="true" id="lastnameField" value="<span style="color:#ff0000">#{currentActor.lastname}</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; &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<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:column<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:column id="commentColumn"<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:text escape="true" id="commentField" value="<span style="color:#ff0000">#{currentActor.comment}</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; &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<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:column<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:dataTable<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 /><strong>And finally:</strong> <br />This is how our example looks like. It's a table with our in-memory Actor Java objects: <div align=center> <br /><img  alt="Image:XPages series #4: Backing Bean Management with XPages" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/16.07.2009095816KLEBCY.htm/content/M4?OpenElement" /></div> <br />Instead of a data table, you could of course also use a repeat control to have full control over the generated code. To make the table cells editable, just use an edit box instead of the computed fields. The XPages/JavaServer Faces runtime will automatically inform you about the new values by calling the set-methods of the Actor objects. <br /> <br /><span style="text-decoration:underline">Hint #1</span> <br />The method "getActors()" is called on every page refresh and also when the user switches from page 1 of the table to page 2. So you should make sure that you do some caching in your bean and avoid CPU intensive data lookups on every call. <br /> <br /><span style="text-decoration:underline">Hint #2:</span> <br />Please note that we return a Java List (java.util.List) implementation in our method "getActors()". <br /><strong>Nobody said that all the data needs to be in-memory when the data table component calls "getActors()"</strong>. When you develop your own List implementation, you have full control, which data really has to be loaded from your (external) data store. The table/pager only needs the currently visible rows of the active page. <br /> <br /><span style="text-decoration:underline">Hint #3</span> <br />You should avoid to return a Java Collection (java.util.Collection) instead of the Java List in the "getActors()" method. <br />That does works, but the pager around the data table needs to know how many elements there are, to calculate the amount of pages for the navigation. Since a Java Collection does not return the total number of entries, the pager calls Collection.toArray(), which grabs the whole data list as an array into memory. That might kill the server for large amounts of data. <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/16.07.2009095816KLEBCY.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/16.07.2009095816KLEBCY.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #3: How to use version control systems in DDE</title>
<pubDate>Wed, 15 Jul 2009 18:02:40 +0200</pubDate>
<description>
<![CDATA[ 
Ok, in my previous posting of the XPages series, I said I'm going to talk about faces-config.xml next, but I just wanted to add a sidenote, because the topic "Version Control in Domino Designer on Eclipse" seems to be quite interesting for the developer community. 

As you might know, DDE 8.5 is not able to do proper version control for your Notes database, because the CVS/SVN plugins of the underlying Eclipse platform do not support a virtual filesystem (like DDE uses it).

But there is a workaround, at least for the Java code that will contain our application backend logic.  ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/15.07.2009180240KLELTQ.htm</link>
<category>DDE</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/15.07.2009180240KLELTQ.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/15.07.2009180240KLELTQ.htm</guid>
<content:encoded><![CDATA[ Ok, in my <a href="http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm" title="Article: XPages series #2: Setting up the database" target="_blank"/>previous posting</a> of the XPages series, I said I'm going to talk about faces-config.xml next, but I just wanted to add a side note, because the topic "Version Control in Domino Designer on Eclipse" seems to be quite interesting for the developer community. <br /> <br />As you might know, DDE 8.5 is not able to do proper version control for your Notes database, because the CVS/SVN plugins of the underlying Eclipse platform do not support a virtual filesystem (like DDE uses it). <br />But there is a workaround, at least for the Java code that will contain our application backend logic. <br /> <br />In my posting, I showed how to add a folder to the classpath of the NSF project. The Java content was stored in the "WebContent/WEB-INF/source" folder of the database project. <br /> <br />Actually, there were two buttons to add content to the build path in the project properties dialog: <div align=center> <br /><img  alt="Image:XPages series #3: How to use version control systems in DDE" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/15.07.2009180240KLELTQ.htm/content/M2?OpenElement" /></div> <br />One is "Add Folder" to add a folder of the NSF project. Now we click on the other button "Link Source" instead: <div align=center> <br /><img  alt="Image:XPages series #3: How to use version control systems in DDE" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/15.07.2009180240KLELTQ.htm/content/M3?OpenElement" /></div> <br />You can use this "Link Source" feature of Eclipse to include external folders to your project. The external folders can then be part of any version control system you like. <br /> <br />Simply press "Refresh" on that folder in DDE to let it catch any changes you make in external editors. DDE will also notice changes automatically when a Java file is already open in the editor. <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/15.07.2009180240KLELTQ.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/15.07.2009180240KLELTQ.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #2: Setting up the database</title>
<pubDate>Wed, 15 Jul 2009 15:25:05 +0200</pubDate>
<description>
<![CDATA[ 
Before we begin coding, let me point you to a book that I'm using here to search what is left from JavaServer Faces in the XPages runtime:
It's called "The Complete Reference JavaServer Faces" from Chris Schalk and Ed Burns.
I don't know if I should recommend you buying it, because IBM has changed most of the original JSF code syntax. So you will not be able to simply copy&paste snippets from the book to the XPages editor, but it's useful to understand the bean management concept and the syntax of the Expression Language (EL) that you can also use in XPages to bind UI components like fields with backend data (beans and Notes documents).

For me it looks like redefining the JSF tag syntax and directly binding UI fields to Notes document items have been done to create a "new XPages product" from JavaServer Faces and to make it easier for the classic Notes developers to work with it. Unfortunately, this make it unnecessarily hard for experienced JSF coders to jump over to XPages. And no existing JSF applications can run in XPages without being rewritten.

Let's get started. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm</guid>
<content:encoded><![CDATA[ Before we begin coding, let me point you to a book that I'm using here to search what is left from JavaServer Faces in the XPages runtime: <br />It's called "<a href="http://books.google.com/books?id=vwzk3dRtEhcC&amp;lpg=PP1&amp;dq=The%20Complete%20Reference%20JavaServer%20Faces&amp;hl=de&amp;pg=PP1" target=_blank>The Complete Reference JavaServer Faces</a>" from Chris Schalk and Ed Burns. <br />I don't know if I should recommend you buying it, because IBM has changed most of the original JSF code syntax. So you will not be able to simply copy&amp;paste snippets from the book to the XPages editor, but it's useful to understand the bean management concept and the syntax of the Expression Language (EL) that you can also use in XPages to bind UI components like fields with backend data (beans and Notes documents). <br /> <br />For me it looks like redefining the JSF tag syntax and directly binding UI fields to Notes document items have been done to create a "new XPages product" from JavaServer Faces and to make it easier for the classic Notes developers to work with it. Unfortunately, this make it unnecessarily hard for experienced JSF coders to jump over to XPages. And no existing JSF applications can run in XPages without being rewritten. <br /> <br />Let's get started. <br /> <br />Although we do most of our XPages development on the Design Partner program 8.5.1 prebetas, we made sure that everything that will be demonstrated in the following articles has been created and tested using a 8.5 client and server. <br /> <br /><strong>Creating a new database</strong> <br />Our first goal is to create a database with an XPage that contains a list of our favorite actors. An actor should have a firstname, lastname and a comment property for the beginning, all three are of type string. <br />Our data will not come from Notes documents, but from our own (simulated) in-memory data store. <br /> <br />We start by creating a new database on the Domino server. Let's call it "Movie Actors". <br /> <br />In DDE, open the database and switch to the Java Perspective, either by using "Window/Open Perspective/Other..." and selecting "Java" in the selection dialog, or by simply clicking on <a href="http://www.mindoo.com/web/blog.nsf/dx/09.07.2009160821KLEJLA.htm" title="Article: Free tool to quickly change perspectives in Domino Designer on Eclipse (DDE)" target="_blank"/>our new DDE toolbar icon</a>. <br /> <br />The database looks like this: <div align=center> <br /><img  alt="Image:XPages series #2: Setting up the database" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm/content/M2?OpenElement" /></div> <br />Domino Designer on Eclipse (DDE) is based on the Eclipse framework. What you see in the picture is the Eclipse project representation of our database (Eclipse uses a virtual filesystem, so most of these files do not exist on your disk, and only some of them are stored in the NSF file). <br />There are two interesting folders for our upcoming development: "Local" and "WebContent/WEB-INF".  <br /> <br /><span style="text-decoration:underline">Local</span> <br />The Local folder is what it's called - a local repository where Lotus Notes creates necessary Java classes like a dummy Activator.java file which is needed to be able to treat the NSF project as an Eclipse plugin. <br />You should not mess around in the "Local" folder and add your own code! It's created only on your machine or on the server. It does not replicate and DDE will probably overwrite your changes. <br />Instead, we're gonna add our own source code folder later on. <br /> <br /><span style="text-decoration:underline">WebContent/WEB-INF</span> <br />The content of the WEB-INF folder is part of the NSF file. JSF coders will already recognize the content in the screenshot above. The "faces-config.xml" is the central definition file in the JavaServer Faces world. <br />One purpose of the faces-config.xml is to define the Java Beans that your application may use, e.g. as a backend class for the user interface (so called backing beans) to get/set form field values and provide code for action button and command links. <br /> <br /><strong>Adding a source folder</strong> <br />As I have said before, the "Local" folder cannot be used to store your own Java code. So we need to add a folder to the build path of the project. <br />To do this, right click on the project name and select "Properties" from the context menu. Then navigate to the "Build path" section of the properties dialog: <div align=center> <br /><img  alt="Image:XPages series #2: Setting up the database" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm/content/M3?OpenElement" /></div> <br />Here you see the "Local" folder as part of the build path. We will add another one. Please click on "Add Folder", then navigate to the "WEB-INF" folder in the tree and press "Create New Folder": <div align=center> <br /><img  alt="Image:XPages series #2: Setting up the database" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm/content/M4?OpenElement" /></div> <br />We call the new folder "source". After closing the dialogs, you can see your new Java coding playground in the tree: <div align=center> <br /><img  alt="Image:XPages series #2: Setting up the database" border="0" src="http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm/content/M5?OpenElement" /></div> <br />Everything you do in this folder and its subfolders will be stored in the NSF file of your database and replicated to the server. <br /> <br /><span style="text-decoration:underline">Hint #1</span> <br />If DDE 8.5 shows error dialogs like "Resource is out of sync" when you edit files inside the project tree, please right click on the parent folder and use the "Refresh" function in the context menu, then double click again on the file. <br />This seems to be an intermittent issue in DDE with the virtual filesystem. <br /> <br /><span style="text-decoration:underline">Hint #2</span> <br />Even if you do pure XPages/Domino data store development, adding a source folder might be interesting for you. In SSJS (Server-side JavaScript), you can now access your new Java code like this, for example in a computed field or label on an XPage: <br /> <br /><span style="color:#008000">//create an instance of our class</span> <br />var myObj=new com.acme.test.MyClass(); <br /><span style="color:#008000">//let it produce a string and return it as the value of the computed field</span> <br />return myObj.produceSomething(); <br /> <br /><strong>We're done with part 2</strong> <br />Your Java environment is now set up. In the next posting, we're gonna take a look at the faces-config.xml file. <br /> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/15.07.2009152504KLEHR8.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/15.07.2009152504KLEHR8.htm?opendocument&amp;comments</wfw:comment>
</item>
<item>
<title>XPages series #1: The vision of a better XPages architecture</title>
<pubDate>Wed, 15 Jul 2009 11:45:36 +0200</pubDate>
<description>
<![CDATA[ 
Well, when I look at all the blog postings and tutorials that have been written so far about XPages, I get the feeling, nobody really asks for some kind of "advanced architecture" for XPages applications. Something that goes beyond just plugging a new UI on top of Notes documents, something with a kind of "master plan" in mind with reusable pieces of code and a clear separation of the UI and the backend logic.

Maybe that's because it's a Notes technology and therefore Rapid Application Development driven, maybe because XPages is just too new, so most of the developers are happy to simply achieve somehow what they want to do. And of course, the already existing benefits they get from their code compared to classic Domino web development makes them feel that this is already a giant step forward.

Yes, it is already a great progress. But there is more under the XPages surface than you think. ...
 ]]>
</description>
<link>http://www.mindoo.com/web/blog.nsf/dx/15.07.2009114536KLEDG4.htm</link>
<category>XPages</category>
<dc:creator>Karsten Lehmann</dc:creator>
<comments>http://www.mindoo.com/web/blog.nsf/dx/15.07.2009114536KLEDG4.htm?opendocument&amp;comments</comments>
<guid isPermaLink="true">http://www.mindoo.com/web/blog.nsf/dx/15.07.2009114536KLEDG4.htm</guid>
<content:encoded><![CDATA[ Well, when I look at all the blog postings and tutorials that have been written so far about XPages, I get the feeling, nobody really asks for some kind of "advanced architecture" for XPages applications. Something that goes beyond just plugging a new UI on top of Notes documents, something with a kind of "master plan" in mind with reusable pieces of code and a clear separation of the UI and the backend logic. <br /> <br /> Maybe that's because it's a Notes technology and therefore Rapid Application Development driven, maybe because XPages is just too new, so most of the developers are happy to simply achieve <span style="text-decoration:underline">somehow</span> what they want to do. And of course, the already existing benefits they get from their code compared to classic Domino web development makes them feel that this is already a giant step forward. <br /> <br /> Yes, it is already a great progress. But there is more under the XPages surface than you think. <br /> <br /> My motivation for digging deeper into the XPages architecture and the underlying JavaServer Faces technology was driven by the following facts:  <ul> <li>our development goal was to <strong>use the same business logic API for both the XPages UI and backend processes</strong> to modify the application data  </li><li>we wanted to have more control of the data storage, like <strong>monitoring/logging data changes</strong>  </li><li>we needed <strong>support</strong> <strong>for large amounts of none-Notes data</strong>  </li><li>we wanted <strong>CVS support for the code we produce in Domino Designer on Eclipse</strong>  </li><li>maybe later on, most of the <strong>code should also run in a different environment</strong>, like a none-Notes data store  </li><li>and finally: I personally absolutely do not like JavaScript as a development language for server-side scripting at all.<br /> I'm a Java guy. I like <strong>type-safety of the code</strong> and I love <strong>being able to debug</strong> what I do. &nbsp;;-)</li></ul>So the following XPages series postings will show you a completely alternative way to develop XPages applications. We still use the XPages design element, but we do not bind it to Notes documents. <br /> Most of our code will be developed in backend Java classes, using a technology called "<strong><span style="text-decoration:underline">Managed Beans</span></strong>".  <br /> <br /> <br />Click here to see a list of all the articles published so far: <a href="http://www.mindoo.com/web/blog.nsf/dx//web/blog.nsf/archive?openview&amp;title=XPages&amp;type=cat&amp;cat=XPages">XPages articles</a> <br />  ]]></content:encoded>
<wfw:commentRss> http://www.mindoo.com/web/blog.nsf/dxcomments/15.07.2009114536KLEDG4.htm</wfw:commentRss>
<wfw:comment> http://www.mindoo.com/web/blog.nsf/dx/15.07.2009114536KLEDG4.htm?opendocument&amp;comments</wfw:comment>
</item>
</channel></rss>
