Thanks Bruce!

QuickImage Category OpenNTF Personal

Bruce Elgort has stepped down as chairman of OpenNTF

I have known Bruce for many years. I could go on about how I met him and how we became close, but that not something I'm willing to share. He is a good and kindly man, he is a caring an loving individual, and he is a friend.

Bruce has worked his ass off over the years as a major contributor to our little yellow community. He has been a huge disruptive change agent and has helped shaped the way I look at the world.

For all you have done Bruce, and for all you continue to do, I want to say thank you.



Installing and Configuring IBM Domino 9 Social Edition on CentOS 6 Enterprise Linux

QuickImage Category IBM Domino CentOS Linux Admin Articles Technical Show-n-Tell Thursday

I realize it is been a while since I posted, I'm hoping this blast of content will make up for my absence.

Since the official release of IBM Notes and Domino 9.0 Social Edition a few weeks ago, I have been "chomping at the bit" wanting to release a set of instructions / videos on how to install it on a Linux machine.

During the beta program I had the opportunity to "play" with it quite a bit, and let me tell you this release is exceptionally good. It is also by far the easiest and most hassle-free version I have ever installed on a Linux machine -but there are still a few gotchas and watch-outs to be wary of.

I have written an instructional document entitled Installing and Configuring IBM Domino 9 Social Edition on CentOS 6 Enterprise Linux and posted it to dropbox. I hope it helps alleviate some of the fear and confusion with regards to using Linux as your Domino server platform. The document is aimed at YellowHeads (having some experience with Domino installations on Windows) who are thinking about stepping into the world of Linux. The document is focused on 64 bit Linux, but calls out differences from 32 bit installations where necessary. Even though it is aimed specifically at CentOS 6, the instructions should work for any RHEL or Debian-based (with some changes to handle DEB vs. RPM) linux version -although I must point out that the only supported Linux distributions are RHEL 6 and SUSE 11.

I have also cut a series of 9 videos wherein I walk through the instructions step-by step and demonstrate how easy it really is to perform the installation. They are available on my YouTube channel, although I'm hoping I can talk David Leedy into including them on Notes In 9.

Hope this helps!



Disk Inventory X

Category Technical Tools Reviews Mac

Ok, here is a real quick review

I have been using Disk Inventory X for about 6 months now, and I couldn't imagine not having it in my tool kit.

If you are a Mac user and do anything more complicated or technical than surf facebook, then you should go get this tool.

I don't always recommend a product, but when I do you should pay attention

Hope this helps!



Returning to the Real World

Category Lotusphere Life  Presonal

I've been pretty heads down over the last few months leading up to Lotusphere IBM Connect 2013. Nothing to apologize for, I've just been focused on other things.

I will leave it to others to provide detailed post-conference analysis. Let me just say that it was, through no fault of IBM, one of the worst weeks of my life. It was also one of the better weeks of my life. We lost a friend, but also made some new ones. I drew much closer to many existing friends as well.

Gents (and Ladies), I will not embarrass you by calling you out by name. You know who you are. I do want to say though that I really needed you this week, and you all came through in spades. I love all of you, thank you for your friendship and support. If you need me to talk to or cry with or scream at the moon, all you have to do is call.




Birth of the Marine Corps

QuickImage Category History


(Philadelphia) Friday, November 10, 1775

Resolved, That two Battalions of marines be raised, consisting of one Colonel, two Lieutenant Colonels, two Majors, and other officers as usual in other regiments; and that they consist of an equal number of privates with other battalions; that particular care be taken, that no persons be appointed to office, or enlisted into said Battalions, but such as are good seamen, or so acquainted with maritime affairs as to be able to serve to advantage by sea when required; that they be enlisted and commissioned to serve for and during the present war between Great Britain and the colonies, unless dismissed by order of Congress: that they be distinguished by the names of the first and second battalions of American Marines, and that they be considered as part of the number which the continental Army before Boston is ordered to consist of.

Ordered, That a copy of the above be transmitted to the General.

"One, two, three, four......I LOVE the Marine Corps!"
-Drill Instructor Corporal Petrovitch (on the Parade Deck at MCRD San Diego in July, 1982)

On 21 October 1921, Major Edwin McClellan, Officer-in-Charge, Historical Section, Headquarters Marine Corps, sent a memorandum to Major General Commandant John A. Lejeune, suggesting that the original birthday on 10 November 1775 be declared a Marine Corps holiday to be celebrated throughout the Corps. McClellan further suggested that a dinner be held in Washington to commemorate the event. Guests would include prominent men from the Marine Corps, Army, and Navy, and descendants of the Revolution. Accordingly, on 1 November 1921, General Lejeune issued Marine Corps Order No. 47, Series 1921. The order summarized the history, mission, and tradition of the Corps, and directed that it be read to every command on 10 November each subsequent year in honor of the birthday of the Marine Corps. This order has been duly carried out.

Read More


Brewer's Breakfast

Category Personal Beer Recipies

Many home-brewers, believing that spent grains are worthless, will throw them out when finished brewing.

This belief is far from the truth.

Spent grain is an excellent source of nutrition. They are packed with proteins, vitamins, fiber, and flavor. When mashing and lautering, the grains are steeped in water heated to somewhere between 150 and 170 degrees. This process draws the sugars, colors, and flavors from the grains into the wort. HOWEVER much of the flavor and all the rest of the healthy goodness remains behind, locked inside the grain.

Some studies have made an association between spent grans and all kinds of health benefits. I don't have the citations right now and I'm too lazy to go look them up -but if you're reading this you probably know how Google works. Eating spent grains (particulary ryes) has been proven to significantly reduce serum cholesterol levels in humans. Other studies have shown that eating grains helps prevent all sorts of really nasty "gut" cancers -liver, pancreatic, colon, bowel, and stomach. Spent grains are loaded with complex carbohydrates and dietary fiber -which is extremely good for your digestion.

Also, spent grains are delicious.

Some people like to bake bread with their spent grains. If you want to try that do NOT use only the spent grains in your baking -you will end up with a wonderful smelling but thoroughly inedible brick. You need some standard all-purpose flour in your recipe.

Here is a great breakfast recipe (in fact I'm eating it while typing this blogpost):

Spanky's Spent Grain Oatmeal

  • 1 1/2 cups cold water
  • 1/2 cup dry oatmeal (I use Quaker Oats)
  • 1/2 cup spent grains
  • 1 tsp. raw honey

Combine the water, oatmeal, and grans in a small saucepan and bring to a boil while stirring. Be careful, it is really easy to overboil and make a huge mess. Turn the heat down (I have a crappy glasstop stove -I turn mine to 1/2) to a gentle simmer. Continue to simmer while stirring occasionally for 10 minutes. Pour into a bowl and serve with the honey (and a bit of cream if you like). A cup of Irish breakfast tea goes great with this.

I'll try to publish some more recipes in the future (including some wonderful hippie "granola" bars), but for now here are a few from the Brooklyn Brew Shop

Q: What if I'm not a home brewer?
You can still get spent grains. Go to your local microbrewery, and bring along a clean container with your name written on it. Ask them for some spent grains, and give them the container. If they don't have any at the moment, they will on brewing day. They will fill your container and give it back to you. In extremely rare cases they will say no or ask you for some money, but ususally they will be happy to just give them to you.

"Spent Grains: They help you go to the bathroom. If you don't eat them you will get cancer and die."

Hope this helps!


Expanding a Names List

QuickImage Category Show-n-Tell Thursday LotusScript

Here is an old helper function I've had laying about in my toolkit for a while. It gets the unique members of a list of names or groups. Anyway, here is the code:

' * function expandNamesList
' * @author: Devin S. Olson
' * @licence: Apache License, Version 2.0
' **/
Function expandNamesList
Gets the unique members for a list of names and groups.
Conditionally recurses to get all individual members of all sub-groups.

@param directory: Source Address Book database within which to search for groups.
@param source: String or Array of Strings containing the members to expand.

@return Variant: Array of Strings containing the expanded unique members of source. Empty String ("") on error.
Function expandNamesList(directory As NotesDatabase, source As Variant) As Variant
Dim extendedInfo As String
Dim result As Variant
On Error GoTo ErrorTrap

Const VIEWNAME = |($VIMGroups)|

Static cachedb As NotesDatabase
Static groupsview As NotesView
Static recursions As Integer

Dim nvent As NotesViewEntry
Dim group As NotesDocument
Dim nongroupnames List As String
Dim subgroupmembers List As Variant
Dim subgroupnongroupnames List As Variant

Dim workingset As Variant
Dim membername As String
Dim sourcetype As String
Dim tag As String
Dim idx As Integer
Dim isRecursive As Boolean

isRecursive = (GetThreadInfo(LIB_LSI_THREAD_PROC) = GetThreadInfo(LIB_LSI_THREAD_CALLPROC))
If isRecursive Then incValue recursions%, 1


sourcetype$ = TypeName(source)
extendedInfo$ = |Source Type: | & sourcetype$
Select Case sourcetype$
workingset = toArray(source)
If (Not isArrayEmpty(workingset)) Then
workingset = atUnique(workingset)
End If

workingset = toArray(source.content)
If (Not isArrayEmpty(workingset)) Then
workingset = atUnique(workingset)
End If

Case Else

End Select ' Case sourcetype$

If (cachedb Is Nothing) Then
Set cachedb = directory
Set groupsview = Nothing
ElseIf (getDatabaseKey(cachedb) <> getDatabaseKey(directory)) Then
Set cachedb = directory
Set groupsview = Nothing
End If ' (cachedb Is Nothing)

If (groupsview Is Nothing) Then
extendedInfo$ = |View: | & VIEWNAME
Set groupsview = cachedb.GetView(VIEWNAME)
If (groupsview Is Nothing) Then Error ERR_MISSING_VIEW,MSG_MISSING_VIEW
End If ' groupsview Is Nothing

If IsScalar(workingset) Then workingset = toArray(workingset)

For idx% = LBound(workingset) To UBound(workingset)
extendedInfo$ = |Idx: | & CStr(idx%)
membername$ = Trim$(workingset(idx%))
extendedInfo$ = extendedInfo$ & Chr(10) & |Member Name: | & membername$
tag$ = UCase$(membername$)

If (Len(membername$) > 0) Then
If (Len IsElement(nongroupnames(tag$))) Then
If (Len IsElement(subgroupmembers(tag$))) Then
Set nvent = groupsview.GetEntryByKey(membername$, True)
If (nvent Is Nothing) Then
' membername is NOT a group
nongroupnames(tag$) = membername$

' membername IS a group
Set group = nvent.Document
subgroupmembers(tag$) = getDocItemValue(group, "Members")
End If ' (nvent Is Nothing)
End If ' (IsElement(subgroupmembers(tag$)))
End If ' (IsElement(nongroupnames(tag$)))
End If ' (Len(membername$) > 0)
Next idx%

' recursively expand all subgroups
ForAll subgroup In subgroupmembers
tag$ = ListTag(subgroup)
subgroupnongroupnames(tag$) = expandNamesList(directory, subgroup)
End Forall ' subgroup In subgroupmembers

' combine all the sub group members
ForAll subgroupnames In subgroupnongroupnames
If IsScalar(subgroupnames) Then
membername$ = Trim$(CStr(subgroupnames))
If (Len(membername$) > 0) Then nongroupnames(UCase$(membername$)) = membername$

ForAll element In subgroupnames
membername$ = Trim$(CStr(element))
If (Len(membername$) > 0) Then nongroupnames(UCase$(membername$)) = membername$
End Forall ' element In subgroupnames
End If ' IsScalar(subgroupnames)
End Forall ' subgroupnames In subgroupnongroupnames

result = atUnique(StringListToStringArray(nongroupnames))

If isRecursive Then incValue recursions%, -1
expandNamesList = result
Exit Function

On Error GoTo 0
If isRecursive Then extendedInfo$ = extendedInfo$ & Chr(10) & |Recursion Level: | & Format(recursions%, FORMAT_WHOLE_THOUSANDS)
enhLogException LIB_PREFIX, extendedInfo$
result = ""
Resume ExitPoint

End Function ' expandNamesList

Hope this helps!


Learning XPages: Extending Tommy Valand’s clearMap

QuickImage Category XPages SSJS scope Map keySet() Iterator scoped variables RegExp

I have posted a utility SSJS funcion at Learning XPages wherein I extend Tommy Valand's clearMap function.



Learning XPages: A little bit of scope...

QuickImage Category XPages Scope Lotus Technical Serialization

I have publised a new blogpost on Learning XPages. It is A little bit of scope will never. Never, ever, ever erase, and is my attempt to explain some scope and serialization issues.




I'm Henry VIII

QuickImage Category Announcements Lotus XPages

One more time, with feeling.

The new blog is up, and accessible. DNS should have propagated by now, and most importantly I have the network cables plugged into the correct devices. DOH!

My first post is:
Episode IV - A New Hope

The Blog itself is called:
Learning XPages




Wowsers! A Tag Cloud!

Techie Stuff



  • No Recent Referers