<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lotushints &#187; Basic</title>
	<atom:link href="http://www.lotushints.com/category/basic/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lotushints.com</link>
	<description>Lotus Notes tips &#38; tricks you always hoped you will not need</description>
	<lastBuildDate>Wed, 14 Jul 2010 06:00:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Design patterns &#8211; Part 10: Builder pattern</title>
		<link>http://www.lotushints.com/2009/05/design-patterns-part-10-builder-pattern/</link>
		<comments>http://www.lotushints.com/2009/05/design-patterns-part-10-builder-pattern/#comments</comments>
		<pubDate>Mon, 18 May 2009 06:00:47 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Code optimization]]></category>
		<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[Lotus Domino]]></category>
		<category><![CDATA[Object-oriented development]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[absract factory]]></category>
		<category><![CDATA[builder]]></category>
		<category><![CDATA[custom classes]]></category>
		<category><![CDATA[LotusScript]]></category>
		<category><![CDATA[maintenance]]></category>
		<category><![CDATA[object-oriented]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=349</guid>
		<description><![CDATA[In part 10 of Design pattern series we will take look at Builder design pattern. Albeit much similarity, this pattern it is not to be mistaken with Abstract factory pattern. As Abstract Factory emphasizes a family of products and returns the product immediately, Builder focuses on constructing complex object step by step, returning product in [...]]]></description>
			<content:encoded><![CDATA[<p>In part 10 of <a href="/category/design-patterns/">Design pattern series</a> we will take look at Builder design pattern. Albeit much similarity, this pattern it is not to be mistaken with Abstract factory pattern. As Abstract Factory emphasizes a family of products and returns the product immediately, Builder focuses on constructing complex object step by step, returning product in final step.</p>
<blockquote><p>The intention of the <strong>The Builder pattern</strong> is to abstract steps of construction of objects so that different implementations of these steps can construct different representations of objects.</p></blockquote>
<p><span id="more-349"></span></p>
<p><strong>Huh?</strong></p>
<p>The best way to explain how builder pattern works is to look at the example. Imagine you have to build product presentation for a company that sells built PCs. For clarity&#8217;s sake, let&#8217;s pretend that they sell only two types of computers. One for basic office needs, running Linux OS and one for pro gaming needs running Windows.</p>
<p><strong>Let&#8217;s go!</strong></p>
<p>First, you need a product class. This class will be able to store product type, add components and display itself when needed. This allows you to build product with as many components as needed.</p>
<pre>Class CBuilderProduct
	Private m_strProductName As String
	Private m_strLParts List As String

	Sub New (productName As String)
		m_strProductName = productName
	End Sub

	Sub Add (part As String, desc As String)
		m_strLParts (part) = desc
	End Sub

	Sub Show ()
		Dim strDisplay As String

		strDisplay = "Product: " &amp; m_strProductName
		Forall part In m_strLParts
			strDisplay = strDisplay &amp; Chr(13) &amp;_
                      Listtag (part) &amp; ": " &amp; part
		End Forall
		Messagebox strDisplay
	End Sub
End Class</pre>
<p>Next, you need a builder class. This is an abstract class, only specifying methods and variables used by end product classes that inherit from it.</p>
<pre>Class CBuilder
	Private m_Product As CBuilderProduct

	Property Get Product As CBuilderProduct
		Set Product = m_Product
	End Property

	Sub AddOS()
	End Sub

	Sub AddPC()
	End Sub
End Class</pre>
<p>Now, you are ready to create real product classes. In our case, this classes will represent Basic and Pro products.</p>
<pre>Class CBuilderProductBasic As CBuilder
   Sub New()
      Set m_Product = New CBuilderProduct ("Basic Package")
   End Sub

   Sub AddOS()
      Call m_Product.Add ("Operating system", "Fedora Core 10")
   End Sub

   Sub AddPC()
      Call m_Product.Add ("Computer", "Basic home computer")
   End Sub
End Class

Class CBuilderProductPro As CBuilder
   Sub New()
      Set m_Product = New CBuilderProduct ("Pro Package")
   End Sub

   Sub AddOS()
      Call m_Product.Add ("Operating system", "Windows 7")
   End Sub

   Sub AddPC()
      Call m_Product.Add ("Computer", "Pro gaming computer")
   End Sub
End Class</pre>
<p>You are almost done. But first, you need a catalogue (or shop) class. This class will actually contain algorithm for building desired products. Beware that<em> builder</em> parameter of <em>Create </em>method must be of type <em>Variant </em>(it should be <em>CBuilder</em>) or you will get an error while compiling your code that will use this design pattern!</p>
<pre>Class CBuilderCatalog
	Sub Create (builder As Variant)
		Call builder.AddPC()
		Call builder.AddOS()
	End Sub
End Class</pre>
<p>To test the code, I wrote a simple agent that simply outputs two message boxes. One for each product.</p>
<pre>Sub Initialize
	Dim builder As CBuilder
	Dim shop As CBuilderCatalog

	Set shop = New CBuilderCatalog ()

	Set builder = New CBuilderProductBasic ()
	Call shop.Create (builder)
	Call builder.Product.Show()

	Set builder = New CBuilderProductPro ()
	Call shop.Create (builder)
	Call builder.Product.Show()
End Sub</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/05/design-patterns-part-10-builder-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom web forms &#8211; Part 3: User input form</title>
		<link>http://www.lotushints.com/2009/04/custom-web-forms-part-3-user-input-form/</link>
		<comments>http://www.lotushints.com/2009/04/custom-web-forms-part-3-user-input-form/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 08:00:25 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Custom forms]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[form]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=297</guid>
		<description><![CDATA[In parts 1 and 2, we looked at exporting forms to DXL and then importing them back. In this short article,we will look at a simple form that will allow users to assemble their own web form. So what do I need? First, we need to assmble list of fields user needs to add. Each [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.lotushints.com/category/custom-forms/">parts 1 and 2</a>, we looked at exporting forms to DXL and then importing them back. In this short article,we will look at a simple form that will allow users to assemble their own web form.<br />
<span id="more-297"></span><br />
<strong>So what do I need?</strong></p>
<p>First, we need to assmble list of fields user needs to add. Each field usually has a label that describes to a user what information should he enter. Then, some fields are plain text, rich text, checkboxes, etc. Also, fields can have a default value.</p>
<p>Keeping that in mind, a basic web form usually has a field named $$Return, that specifies what happens on document submit. Also, it would be nice, if we allowed our users to enter name of the form and some short description that will be presented in web form.</p>
<p><strong>The implementation</strong></p>
<p>For basic forms, we don&#8217;t need anything fancy. No rich text for short description, probably only simplest field formats (plain text, rich text, radiobutton and checkbox) and probably not more than 10 fields. Since this example is here just to prove a case, I will limit it to 5 different fields.</p>
<p>So, our list of fields now looks like this:</p>
<ul>
<li>form name</li>
<li>form description</li>
<li>return page</li>
<li>5x field that will hold field name</li>
<li>5x field that will be used for field type</li>
<li>5x field with value (in case of radiobutton and checkbox)</li>
<li>5x field with default value</li>
<li>5x field with label</li>
</ul>
<p>The &#8220;finished&#8221; form is displayed in picture below.</p>
<div id="attachment_299" class="wp-caption aligncenter" style="width: 300px"><img class="size-medium wp-image-299" title="myclientform" src="http://www.lotushints.com/wp-content/uploads/2009/04/myclientform-300x158.png" alt="Filled user's form" width="300" height="158" /><p class="wp-caption-text">Filled user&#39;s form</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/04/custom-web-forms-part-3-user-input-form/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Banner animator v1.1</title>
		<link>http://www.lotushints.com/2009/03/banner-animator-v11/</link>
		<comments>http://www.lotushints.com/2009/03/banner-animator-v11/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 08:00:30 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[animator]]></category>
		<category><![CDATA[banner]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=276</guid>
		<description><![CDATA[In order to display multiple banners in single spot (and to keep web site from becoming tacky), you will need some sort of client side script that will display first one banner, then the second one etc. This is called banner animator (or even ad animator). In this case, the functionality is written in JavaScript, [...]]]></description>
			<content:encoded><![CDATA[<p>In order to display multiple banners in single spot (and to keep web site from becoming tacky), you will need some sort of client side script that will display first one banner, then the second one etc. This is called banner animator (or even ad animator). In this case, the functionality is written in JavaScript, with some help of HTML (for element positioning) and CSS (for element appearance).<br />
<span id="more-276"></span><br />
<strong>What does that have to do with Lotus Notes?</strong></p>
<p>Absolutely nothing. The only connection to Lotus Notes is, when you integrate this functionality into your database. It is a simple and trivial solution. I needed to create a form that will represent one single banner. This form contains name, URL, image, sort order etc. Look-up view for obtaining sorted banner list was created and some web forms that are already in &#8220;production&#8221; had to be altered, for loading of JavaScript class etc.</p>
<p><strong>Prerequisites</strong></p>
<p>This functionality depends heavily on <a href="http://jquery.com/">jQuery library</a>. It can be obtained <a href="http://docs.jquery.com/Downloading_jQuery">here</a>. I recommend minified version if you plan on hosting it yourself or, you can use <a href="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js">Google Code link</a> to link it from Google.</p>
<p>Next you need to obtain the <em>adPlayer </em>library. It is located <a href="http://dl.getdropbox.com/u/599331/jslibs/adPlayer.js">here</a>. I would ask you to not link the library directly from this link, but download it to your server and link it from there.</p>
<p><strong>Getting started</strong></p>
<p>In order to implement this application, you will first need to make a small HTML adjustment in the place where you want banner animator to be implemented.</p>
<pre>&lt;ul id="adPlayer"&gt;
    &lt;li&gt;&lt;a href=""&gt;&lt;img src="images/ad1.jpg" /&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=""&gt;&lt;img src="images/ad2.jpg" /&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=""&gt;&lt;img src="images/ad3.jpg" /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div id="adPlayerNav"&gt;&lt;/div&gt;</pre>
<p>Obviously you should insert link of your desire. The same goes for image <em>src </em>and <em>alt</em> parameters. Also, number of <em>li</em> elements can vary.</p>
<p>Next, at the bottom of the page (where your JS libraries are loaded and on load events are set), you need to load both .js files  (<em>jQuery </em>and <em>AdPlayer</em>) , if you do not already have them. Next, add following (or if you already have onload event loader, just call loadPlayer() function).</p>
<pre>&lt;script type="text/javascript" language="javascript"&gt;
    $(document).ready(function() {
        loadPlayer();
    });
&lt;/script&gt;</pre>
<p><strong>Now add some style<br />
</strong></p>
<p>It is necessary to add styling to content thus far. CSS excerpt below will give you some idea as to how you can style things. Beware that #adPlayer height property must be set to height of a banner space. Also, some tweaking to .js file will have to be done, but nothing major (this will definitely be changed in future releases).</p>
<pre>/* layout */
#adPlayer { list-style: none; height: 220px; margin-left: 0;
margin-bottom: 0; overflow: hidden; padding: 0; }
#adPlayer li { margin: 0; padding: 0; }
#adPlayerNav { position: relative; top: -1em; right: 1em;
text-align: right; }
#adPlayerNav ul { list-style: none; margin: 0; padding: 0; }
#adPlayerNav li { display: inline; margin: 0 0 0 0.1em;
padding: 0; }
#adPlayerNav li.adPlay, #adPlayerNav li.adPause {
margin-left: 1em; }
#adPlayerNav li a { cursor: pointer; padding: 0 0.5em; }

/* typography */
#adPlayerNav li { font-size: 1.2em; }

/* color */
#adPlayerNav li { border: solid 1px rgb(213, 213, 217); }
#adPlayerNav li a { background-color: white; padding: 0.5em; }</pre>
<p>You now have fully functional banner animator.</p>
<p><strong>Optimization</strong></p>
<p>Loading 3+ 50K+ images in the middle of the page can never be a good thing. Thus, <em>adPlayer</em> library has a <strong>dynamic mode</strong> that can be used. This mode loads images after the page is loaded, which is a good thing. However, you cannot leave your banner space empty until then. A compromise solution is to load first banner in-line and all others after the document is loaded. Your HTML file must now look somewhat like this:</p>
<pre>...
&lt;ul id="adPlayer"&gt;
    &lt;li&gt;&lt;a href=""&gt;&lt;img src="images/ad1.jpg" /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div id="adPlayerNav"&gt;&lt;/div&gt;
...
&lt;script type="text/javascript" language="javascript"&gt;
    $(document).ready(function() {
        loadPlayer( true );
        adplayer.add ("", "images/ad2.jpg", "");
        adplayer.add ("", "images/ad3.jpg", "");
        adplayer.generatePlayer();
    });
&lt;/script&gt;</pre>
<p>Loading <em>loadPlayer</em> method with <em>true </em>as parameter value will enable <strong>dynamic mode</strong>. Now you can add banners in desired sort order. First parameter is <em>link</em>, second image <em>src </em>and third image <em>alt</em>. After you are done, just call <em>generatePlayer</em> method.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/03/banner-animator-v11/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom web forms &#8211; Part 2: Importing Form from DXL</title>
		<link>http://www.lotushints.com/2009/03/custom-web-forms-part-2-importing-form-from-dxl/</link>
		<comments>http://www.lotushints.com/2009/03/custom-web-forms-part-2-importing-form-from-dxl/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 08:00:47 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Custom forms]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[dxl]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[import]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=260</guid>
		<description><![CDATA[In the second part of Custom web forms series I will try to cover import of simple form to Notes database from DXL file. If you wonder how to export a form to DXL, please check Part 1: Exporting Form into DXL. Requirements As mentioned, you will need a DXL file like the result of [...]]]></description>
			<content:encoded><![CDATA[<p>In the second part of <a href="/category/custom-forms/">Custom web forms series</a> I will try to cover import of simple form to Notes database from DXL file. If you wonder how to export a form to DXL, please check <a href="/2009/03/custom-web-forms-part-1-exporting-form-into-dxl/">Part 1: Exporting Form into DXL</a>.<br />
<span id="more-260"></span></p>
<p><strong>Requirements</strong></p>
<p>As mentioned, you will need a DXL file like the result of <a href="/2009/03/custom-web-forms-part-1-exporting-form-into-dxl/">Part 1</a>. Beware that, if you have altered the file and removed the DOCTYPE tag, you will not be able to import DXL and you will either need to add correct DOCTYPE tag back or export the form again.</p>
<p><strong>The code</strong></p>
<p>The code itself is pretty straightforward. You need to open a DXL file as a NotesStream object and then use NotesDXLImporter class to import a DXL to your database. There is a catch. You need to set <strong>DesignImportOption</strong> property of NotesDXLImporter object to create design element. These options are specified in Notes Designer Help.</p>
<pre>Dim session As New NotesSession
Dim dbCurr As NotesDatabase
Dim docForm As NotesDocument
Dim stream As NotesStream
Dim dxlImporter As NotesDXLImporter
Dim strFile As String

Set dbCurr = session.CurrentDatabase
Set stream = session.CreateStream ()

strFile = "c:\download\templateform.xml"
If (Not stream.Open (strFile, "utf-8")) Then
   Exit Sub
End If

Set dxlImporter = session.CreateDXLImporter (stream, dbCurr)
dxlImporter.DesignImportOption =_
DXLIMPORTOPTION_REPLACE_ELSE_CREATE
Call dxlImporter.Process ()</pre>
<p>Just in case you don&#8217;t want to check Notes help for values, here are DXL import options:</p>
<ul>
<li> DXLIMPORTOPTION_CREATE (1)</li>
<li> DXLIMPORTOPTION_IGNORE (2)</li>
<li> DXLIMPORTOPTION_REPLACE_ELSE_IGNORE (5)</li>
<li> DXLIMPORTOPTION_REPLACE_ELSE_CREATE (6)</li>
<li> DXLIMPORTOPTION_UPDATE_ELSE_IGNORE (9)</li>
<li> DXLIMPORTOPTION_UPDATE_ELSE_CREATE (10)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/03/custom-web-forms-part-2-importing-form-from-dxl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom web forms &#8211; Part 1: Exporting Form into DXL</title>
		<link>http://www.lotushints.com/2009/03/custom-web-forms-part-1-exporting-form-into-dxl/</link>
		<comments>http://www.lotushints.com/2009/03/custom-web-forms-part-1-exporting-form-into-dxl/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 08:00:12 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Custom forms]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[dxl]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[form]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=248</guid>
		<description><![CDATA[The one thing that in my opinion always lacked in Lotus Notes was the ability for users without designer access (and much knowledge of HTML) to build their own custom forms. One might argue that it is not that big of a deal and that it would take an experienced developer approximately one hour to [...]]]></description>
			<content:encoded><![CDATA[<p>The one thing that in my opinion always lacked in Lotus Notes was the ability for users without designer access (and much knowledge of HTML) to build their own custom forms. One might argue that it is not that big of a deal and that it would take an experienced developer approximately one hour to create and test such a form. However, developers usually have more important work to do and this is an hour unnecessary spent.</p>
<p><span id="more-248"></span></p>
<p><strong>How to get around&#8230;</strong></p>
<p>I am positive that different developers would handle this differently. For sure, the easiest thing to do would be to add designer access to a person wishes to create a form. I would advise against it. Not only it creates severe security issue, but it also enables inexperienced user to poke about the database design.</p>
<p>I am positive every designer till now at least heard of DXL. Some of us even used it. I did it for exporting entire database to our internal wiki and to create atom rss for another database. However, most developers, in my experience, look at DXL as a bit of a Notes voodoo.</p>
<p><strong>Let&#8217;s remove this tag!</strong></p>
<p>In several parts, I will try to show how to export and import a simple HTML form that one can use on the web. Also at the very end, I will try to create a form that will enable a user with less than developer access to create a web form.</p>
<p><strong>Onward, to the point &#8211; Exporting Form to DXL<br />
</strong></p>
<p>It is quite simple. You create or already posses a form. For exporting it to DXL, you will need to know it&#8217;s name or you can enable for to be available in Create menu and add a shared action onto it, that will do the work for you. I decided for the later.</p>
<div id="attachment_250" class="wp-caption aligncenter" style="width: 479px"><img class="size-full wp-image-250" title="myform" src="http://www.lotushints.com/wp-content/uploads/2009/03/myform.png" alt="Form with shared action as viewed in Notes client" width="469" height="282" /><p class="wp-caption-text">Form with shared action as viewed in Notes client</p></div>
<p style="text-align: left;">Figure above displays a simple form previewed in Notes client with shared action &#8220;Export form&#8221;in action bar. Upon clicking on this action, a file will be saved on your disk to path c:\download\my_form_name.xml. And below is the code that does all this.</p>
<pre>Sub Click(Source As Button)
   Dim ws As New NotesUIWorkspace
   Dim s As New NotesSession
   Dim db As NotesDatabase
   Dim nc As NotesNoteCollection
   Dim doc As NotesDocument
   Dim docForm As NotesDocument
   Dim stream As NotesStream
   Dim dxlExporter As NotesDXLExporter
   Dim bFound As Boolean
   Dim n As Integer
   Dim strId As String
   Dim strFormName As String

   Set db = s.CurrentDatabase
   Set doc = ws.CurrentDocument.Document
   Set nc = db.CreateNoteCollection (False)
   nc.SelectForms = True
   Call nc.BuildCollection ()

   bFound = False
   strId = nc.GetFirstNoteId ()
   For n = 1 To nc.Count
      Set docForm = db.GetDocumentByID (strId)
      strFormName = docForm.GetFirstItem ("$title").values(0)
      If (doc.Form (0) = strFormName) Then
         bFound = True
         Exit For
      End If
      strId = nc.GetNextNoteId (strId)
   Next

   If (Not bFound) Then Exit Sub

   Set stream = s.CreateStream ()
   Call stream.Open("c:\download\" &amp; strFormName &amp; ".xml","utf-8")
   Call stream.Truncate ()

   Set dxlExporter = s.CreateDXLExporter (docForm, stream)
   Call dxlExporter.Process
   Call stream.Close ()
End Sub</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/03/custom-web-forms-part-1-exporting-form-into-dxl/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Rules of engagement</title>
		<link>http://www.lotushints.com/2009/03/rules-of-engagement/</link>
		<comments>http://www.lotushints.com/2009/03/rules-of-engagement/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 07:00:08 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[development rules]]></category>
		<category><![CDATA[story]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=222</guid>
		<description><![CDATA[There are two rules I always respect and usually follow: If a code compiles and seems to work in first try, there is something terribly wrong with it. Never, ever, under no circumstances, move anything in production on Friday. I urge you not to break one of these rules, no matter how confident you feel [...]]]></description>
			<content:encoded><![CDATA[<p>There are two rules I always respect and usually follow:</p>
<ol>
<li>If a code compiles and seems to work in first try, there is something terribly wrong with it.</li>
<li>Never, ever, under no circumstances, move anything in production on Friday.</li>
</ol>
<p>I urge you not to break one of these rules, no matter how confident you feel and under no circumstances.</p>
<p>Let me tell you a little story. I have developed a new feature for our renewed web site. This was over two weeks ago and on test system, it was working like a charm. Everyone liked it and there was no bugs found. So, I moved my code to production system. All fine and well, as without content and proper linkage, this feature would not be visible to web users until we decided to allow it. As I said, the thing missing was a content. That wasn&#8217;t my job and I paid no heed to it. So on Friday, a co-worker assigned for content gave me a green light. Now, I was feeling overconfident and despite warnings in my head and by my fellow developers, I decided to go with it.</p>
<p>Big mistake. I spent next 4 hours (and some overtime as well), working feverishly to remove bugs that were result of the content. It is not that content was wrong, but rather that it was not tested enough. And for a cherry on a cake, I received a call from project manager on my way home. Apparently he wasn&#8217;t aware we are going live. Well not on Friday anyway.</p>
<p>Lesson learned. Never, ever, under no circumstances, move anything in production on Friday. Moving on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/03/rules-of-engagement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design patterns &#8211; Part 6: Observer pattern</title>
		<link>http://www.lotushints.com/2009/02/design-patterns-part-6-observer-pattern/</link>
		<comments>http://www.lotushints.com/2009/02/design-patterns-part-6-observer-pattern/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 08:00:33 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Code optimization]]></category>
		<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[Object-oriented development]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[custom classes]]></category>
		<category><![CDATA[LotusScript]]></category>
		<category><![CDATA[object-oriented]]></category>
		<category><![CDATA[observer]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=183</guid>
		<description><![CDATA[One of the most used patterns is also a pattern that hears by the name Observer. What does it do? Well, imagine you have a stock portfolio and you need to notify your investors every time the value of their stock changes. First, your investors need to subscribe to the stock they would like to [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most used patterns is also a pattern that hears by the name Observer. What does it do? Well, imagine you have a stock portfolio and you need to notify your investors every time the value of their stock changes. First, your investors need to <strong>subscribe</strong> to the stock they would like to be notified about. Next, whenever new stock value is <strong>published</strong>, subscribers are notified. Much like RSS subscription. But what about definition:</p>
<blockquote><p><strong>The Observer pattern</strong> defines a one-to-many dependency between objects so that when one object changes state, all of its dependants are notified and updated automatically.</p></blockquote>
<p><span id="more-183"></span><br />
<strong>Fine, but what can I do with that?</strong></p>
<p>We will build an above mentioned example of a stock and it&#8217;s investors. First, you will need to create an observer abstract class:</p>
<pre>Class CObserver
	m_strName As String

	Property Get ObserverName As String
		ObserverName = Me.m_strName
	End Property

	Sub New (strName As String)
		Me.m_strName = strNAme
	End Sub

	Sub Update()
	End Sub
End Class</pre>
<p>As you can see, it contains a name, which will be used as unique id, a constructor, where the name is set and subroutine called Update that will be called when new value of our stock will be set.</p>
<p>Now, that we have an observer, we can create a subject class that will be an abstract class used by our stock.</p>
<pre>Class CObserverSubject
	m_oList List As CObserver

	Sub Attach (observer As CObserver)
	  If (Not Iselement (m_oList (observer.ObserverName))) Then
	     Set m_oList (observer.ObserverName) = observer
	  End If
	End Sub

	Sub Detach (observer As CObserver)
	  If (Iselement (m_oList (observer.ObserverName))) Then
	     Erase m_oList (observer.ObserverName)
	  End If
	End Sub

	Sub Notify ()
		Forall observer In m_oList
			Call observer.Update()
		End Forall
	End Sub
End Class</pre>
<p>The class contains list of all investors (observers) and operations to add (Attach ()) or remove (Detach ()) them. There is also routine Notify, that will update each and every investor.</p>
<p>Framework is now set. Moving on to concrete classes. First, we will create a concrete subject class called ObserverStock.</p>
<pre>Class CObserverStock As CObserverSubject
	m_strName As String
	m_dValue As Double

	Property Get StockName As String
		StockName = Me.m_strName
	End Property

	Property Get Value As Double
		Value = Me.m_dValue
	End Property

	Property Set Value As Double
		Me.m_dValue = Value
		Call Notify()
	End Property

	Sub New (strName As String, dValue As Double)
		Me.m_strName = strName
		Me.m_dValue = dValue
	End Sub
End Class</pre>
<p>The class inherits from ObserverSubject class. Also, it has a property for obtaining stock name and properties for obtaining and setting stock value. However, when setting stock value, not only value is set, but there is also a call to Notify method, specified in ObserverSubject class. This will notify all subscribers of new value.</p>
<p>The only thing missing now is observer concrete class called ObserverInvestors.</p>
<pre>Class CObserverInvestor As CObserver
	m_Stock As CObserverStock

	Property Get Stock As CObserverStock
		Set Stock = Me.m_Stock
	End Property

	Property Set Stock As CObserverStock
		Set Me.m_Stock = Stock
	End Property

	Sub New (strName As String)
	End Sub

	Sub Update()
		Messagebox Me.m_strName &amp; ": " &amp;_
		m_Stock.StockName &amp; " value is " &amp; m_Stock.Value
	End Sub
End Class</pre>
<p>And it is simple enough. It needs a constructor with name as parameter (due to his parent class), a property that ties stock to the class and Update () function that will ideally send an e-mail to investors, but in this case just pops up a message with investor and stock info.</p>
<p><strong>Usage of previous classes</strong></p>
<p>To use previously stated classes, I wrote an agent that will create a stock, add three investors to it, and change value. Then, last observer will be removed from notification list and value will be updated again. When running this agent, you should first get three pop up messages and then only two.</p>
<pre>Sub Initialize
	Dim observer As CObserverInvestor
	Dim stock As CObserverStock

	Set stock = New CObserverStock ("MyStock", 120.0)

	Set observer = New CObserverInvestor ("Investor 1")
	Set observer.Stock = stock
	Call stock.Attach (observer)

	Set observer = New CObserverInvestor ("Investor 2")
	Set observer.Stock = stock
	Call stock.Attach (observer)

	Set observer = New CObserverInvestor ("Investor 3")
	Set observer.Stock = stock
	Call stock.Attach (observer)

	stock.Value = 100.0

	Call stock.Detach (observer)
	stock.Value = 102.5
End Sub</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/02/design-patterns-part-6-observer-pattern/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Version control and bug tracking</title>
		<link>http://www.lotushints.com/2009/01/version-control-and-bug-tracking/</link>
		<comments>http://www.lotushints.com/2009/01/version-control-and-bug-tracking/#comments</comments>
		<pubDate>Sat, 24 Jan 2009 12:51:10 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bug tracking]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[maintenance]]></category>
		<category><![CDATA[organization]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=169</guid>
		<description><![CDATA[In my years of developing software, I come to realize that what every software development department needs is: some sort of IDE with a compiler version control and bug tracking. Usually you get stuck with IDE with a compiler. Everything else is up to you. But how are things in Lotus Notes? Version control As [...]]]></description>
			<content:encoded><![CDATA[<p>In my years of developing software, I come to realize that what every software development department needs is:</p>
<ul>
<li>some sort of IDE with a compiler</li>
<li>version control</li>
<li>and bug tracking.</li>
</ul>
<p>Usually you get stuck with IDE with a compiler. Everything else is up to you. But how are things in Lotus Notes?<br />
<span id="more-169"></span><br />
<strong>Version control</strong></p>
<p>As expected Lotus Designer doesn&#8217;t have an integrated version control software. Not yet anyway. They are planing to build subclipse to work in new 8.5 designer, but that still needs some time. Also most people are probably still stuck at R7.</p>
<p>Well, one of the things you could use is Teamstudio Ciao!. This is a payed software meaning that either it becomes your department policy to use it or you will never use it. I had a chance of working with Ciao and I have to say that I was less than impressed. But that is just me. I know a lot of people using it without any drawbacks and with lack of tools out there, this is probably the way to go.</p>
<p>Next widely used option is to use separate templates for each and every version of your application. There are two things wrong with this. One is that there is no way any developer would do a new template just for fixing one single agent. Second one is that I am yet to see a consistent template policy.</p>
<p>Another possibility is to copy your database locally and then import it into Subversion (SVN) or perhaps write a script that would periodically do that for you. The thing is that you won&#8217;t be able to just revert to desired version of the database without deleting the existing one. There is one other option. You could export objects (agents, views etc.) as DXL, import it into SVN and then when needed import DXL back to the database. However, DXL is not 100% representation of design elements. Thus I wouldn&#8217;t recommend it.</p>
<p>As mentioned there is a subclipse project that would enable subclipse in Domino Designer 8.5. Subclipse is Eclipse plug-in for Subversion. And since Domino Designer 8.5 is built on Eclipse framework, this would finally solve most of our version control issues.</p>
<p><strong>Bug Tracking</strong></p>
<p>Why bug tracking? Well, I am yet to see software without bugs. And the thing that helps the most is some sort of bug tracking engine. However, oddly enough, this is the part rarely seen and used. Typical bug tracking process should go like this:</p>
<ul>
<li>someone reports a bug</li>
<li>developer is assigned to the bug</li>
<li>developer fixes the bug</li>
<li>third person (inside a company and related to project the bug was reported for) tests the fixed code</li>
<li>bug report is completed.</li>
</ul>
<p>Now, show of hands. How many of you have this process implemented in your development cycle? I thought so. But being a Notes developer, what are your options?</p>
<p>There is a great open source project at openntf.org called <a href="http://www.openntf.org/Projects/pmt.nsf/ProjectLookup/BugTracker">BugTracker</a>. Another option is to use some commercial product like <a href="http://www.trackersuite.com/frame_help_desk_software.html">Trackersuit Help Desk Software</a> or similar.</p>
<p>If you are not attached to domino apps only, there are tons of open source applications for bug tracking. Probably most known amongst them are <a href="http://www.mantisbt.org/">Mantis BugTracker</a> and <a href="http://www.bugzilla.org/download/">Bugzilla</a>.</p>
<p>The most inappropriate systems for bug tracking I have seen thus far are internal forum and wiki. These applications are not meant to be bug trackers. So, please, don&#8217;t use them as such.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/01/version-control-and-bug-tracking/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Design patterns &#8211; Part 5: Adapter pattern</title>
		<link>http://www.lotushints.com/2009/01/design-patterns-part-5-adapter-pattern/</link>
		<comments>http://www.lotushints.com/2009/01/design-patterns-part-5-adapter-pattern/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 08:00:29 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Code optimization]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[adapter]]></category>
		<category><![CDATA[custom classes]]></category>
		<category><![CDATA[LotusScript]]></category>
		<category><![CDATA[object-oriented]]></category>
		<category><![CDATA[Object-oriented development]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=162</guid>
		<description><![CDATA[Another quite useful pattern is Adapter pattern. Adapters represent an interface between two different classes. For example imagine being a continental EU citizen travelling to UK. For you to plug in to UK power plug, you need an adapter that will take the interface your connector has and output the interface UK power plug demands. [...]]]></description>
			<content:encoded><![CDATA[<p>Another quite useful pattern is Adapter pattern. Adapters represent an interface between two different classes. For example imagine being a continental EU citizen travelling to UK. For you to plug in to UK power plug, you need an adapter that will take the interface your connector has and output the interface UK power plug demands.<span id="more-162"></span><br />
Definition of Adapter pattern is:</p>
<blockquote><p>The<strong> Adapter pattern</strong> converts the interface of a class into an interface the client expects. Adapter lets classes work together even if they couldn&#8217;t otherwise due to incompatible interfaces.</p></blockquote>
<p><strong>So how does this work in practice?</strong></p>
<p>You will mostly need adapters when you will obtain code from someone else. But just for the sake of simplicity, we will look into unlikely scenario, when you will get a code that prints &#8220;Hello World!&#8221; and write an adaptor that displays &#8220;Hello adapters!&#8221; in message box using the same interface.</p>
<p>First you need a client class and it&#8217;s interface. As we know, interfaces are not implemented in LotusScript. Thus, an abstract class will be used instead. Then we&#8217;ll need a client class. Both are pasted below:</p>
<pre>Class CHelloWorldInterface
	Sub printText ()
	End Sub
End Class

Class CHelloWorld As CHelloWorldInterface
	Sub printText ()
		Print "Hello World!"
	End Sub
End Class</pre>
<p>Now, we need to create our interface that displays &#8220;Hello adapters!&#8221; in message box.</p>
<pre>Class CHelloAdaptersInterface
	Sub msgboxText ()
	End Sub
End Class

Class CHelloAdapters As CHelloAdaptersInterface
	Sub msgboxText ()
		Messagebox "Hello Adapters!"
	End Sub
End Class</pre>
<p>All we need now is an adapter.</p>
<pre>Class CHelloAdpatersAdapter As CHelloWorldInterface
	m_helloAdapter As CHelloAdaptersInterface

	Sub new (helloAdapter As CHelloAdaptersInterface)
		Set Me.m_helloAdapter = helloAdapter
	End Sub

	Sub printText()
		Call m_helloAdapter.msgboxText()
	End Sub
End Class</pre>
<p>And to bind it together, here is an agent that will output both results.</p>
<pre>Sub Initialize
	Dim hw As CHelloWorld
	Dim ha As CHelloAdapters
	Dim haa As CHelloWorldInterface

	Set hw = New CHelloWorld ()
	Set ha = New CHelloAdapters ()
	Set haa = New CHelloAdaptersAdapter (ha)

	'test HelloAdapters
	Call ha.msgboxText()

	'test HelloWorld
	Call testHello (hw)

	'test HelloAdaptersAdapter
	Call testHello (haa)
End Sub

Sub testHello (hello As CHelloWorldInterface)
	Call hello.printText()
End Sub</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/01/design-patterns-part-5-adapter-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding content to Rich Text field in a document using QOA</title>
		<link>http://www.lotushints.com/2008/12/adding-content-to-rich-text-field/</link>
		<comments>http://www.lotushints.com/2008/12/adding-content-to-rich-text-field/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 08:00:33 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Basic]]></category>
		<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[LotusScript]]></category>
		<category><![CDATA[Rich Text Item]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=154</guid>
		<description><![CDATA[I have found an interesting challenge last week. For some reason, I had to have a document on web that would show a computed table of products and there would be some content before and after. The trick however is, that we use some sort of CRM database for our web content and documents use [...]]]></description>
			<content:encoded><![CDATA[<p>I have found an interesting challenge last week. For some reason, I had to have a document on web that would show a computed table of products and there would be some content before and after. The trick however is, that we use some sort of CRM database for our web content and documents use one rich text item to store document content.</p>
<p>Now, I didn&#8217;t want to create another form or change the existing one and there was way to complicated to do a computed value in rich text for table display. And we already had a web <abbr title="Query open Agent">QOA</abbr> for this type of document.<span id="more-154"></span>So what did I do? I added following custom code to rich text field:</p>
<pre>&lt;$$myTable&gt;</pre>
<p><strong>But how would that do you any good?</strong></p>
<p>Now all I had to do is add the following code to <abbr title="Query open Agent">QOA</abbr>:</p>
<pre>Dim rti As NotesRichTextItem
dim rtr As NotesRichTextRange
...
Set rti = docWeb.GetFirstItem ("Body")
Set rtr = rti.CreateRange
Call rtr.FindAndReplace ({&lt;$$myTable&gt;}, strHtml)
Call rti.Compact ();
...</pre>
<p>First I obtain a Rich Text field where my identifier is. Then, I created a range and used <a href="http://publib-b.boulder.ibm.com/lotus/c2359850.nsf/f4b82fbb75e942a6852566ac0037f284/34518440ca28e24d8525731b004a59f1?OpenDocument">FindAndReplace</a> method to replace identifier with HTML (stored in strHtml variable), that will display required table.</p>
<p><strong>That is all?</strong></p>
<p>Yes. Mind you, there is a catch. All in-line images in Rich Text field will not display on web. Image resources will display normally.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2008/12/adding-content-to-rich-text-field/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
