"10 Things Every Software Architect Should Know" webcast

In the 10 Things Every Software Architect Should Know webcast (and slide deck) Richard Monson-Haefel weaves a thoughtful exposition and good examples around the (almost banal) ten things a senior development project contributor should know. Worth 50 minutes of your life. The ten things are
  • People are the platform
  • All solutions are obsolete
  • Data is forever
  • Flexibility breeds complexity
  • Nothing works as expected
  • Documentation is the universal source code
  • Know the business
  • Maintain the vision
  • Software architects should also be coders
  • There is no substitute for experience

Coffee & Code in South Kingstown

I will be heading to South Kingstown's Brewed Awakenings for Coffee & Code this Monday, Tuesday, and Wednesday between 10:30 and 11:30 AM. See you there.

Where was that click?

I have used many kinds of UI toolkits over the years. To greater and lesser extents I have used Macintosh (pre-Cocoa), Win32, Motif, Qt, Swing, Xlib, wxWindows, Tk, Andrew, and some others that I don't remember their names. Today, I needed a little dynamic HTML widget to hold an image and respond to clicks. Piece of cake! Hum, but where is the API call to get the location of the mouse relative to the image? As far as I can tell there is none. Perhaps the new CANVAS element is kinder to developers but to do this without it requires many more lines of code than I would have expected. Luckily, Re:morse.nl in conjunction with prototype already figured it out and, better still, figured it out right.

Designing Web Interfaces webcast

Bill Scott's O'Reilly Webcast Designing Web Interfaces is well worth time watching. Lots of current examples.

"integrating social networking is like failed love"

I still get folks asking for social networking features for their sites. I generally try to tell them to integrate with an existing one. I enjoyed this comment from Burningbird about Amazon's Kindle discussion board's fall
Amazon has just discovered what many other companies are discovering: integrating social networking is like failed love, amazingly wonderful at first, but eventually evolving into an urge to gnaw your own arm off in order to escape.

I want my Kindle 2

Man! I just got an iPhone 3G and now my technology-lust has attached itself to the Kindle 2.

PDF page images

I am in the middle of building a web application for commenting on PDF documents. My plan is to use it to allow South Kingstown, RI residents to comment on the upcoming operations budget. The software will be open sourced for others to use -- assuming it actually turns out to be useful.

On the tools I needed was to be able to rasterize the PDF's pages. I really don't want to depend on a plugin (Acrobat, Foxit Reader, etc) for such a public site. Having images of the pages allows me to do a number of other interactions that I would have no control to do within the plugin. So, I need pictures.

After struggling with a number of other rasterizers (mostly around fonts (still!) or unknown library dependencies) I found the LGPLed PDFRenderer at java.net. And it works. And it works very well with very little effort. Here is my test program for creating readable and thumbnail images of every page.


Update: I forgot to include the build.xml

"may the police always be as friendly"


"May you visit many more Wright houses. And may the police always be as friendly when you arrive." Found written on a bookmark in a used Frank Lloyd Wright book.

Unix utilities for Windows.

Continuing to re-configure my Windows XP box I installed the excellent set of Unix utilities from unxutils at SourceForge. One command line tool that is missing from unxutils is bash. After some digging around I found a standalone version of bash at www.steve.org.uk.

Microsoft has Windows Services for UNIX. The one time I installed this (a few years ago) the installer failed and left my machine in a broken state. The set of tools and services in the Microsoft package is comprehensive and so I would like to use it. However, I don't want to take the risk of breaking my machine again. Anyone know if the installation issues have been fixed?

OpenOffice and basic collaboration

I use OpenOffice as my office tools suite. For my needs -- letters, documentation, and budgets -- it is more than adequate. The one area where it is not nearly as good as Microsoft Office during collaborative writing and editing. Word's balloon comments really makes it easy to add and review comments and maintain the integrity of the original document.

I did find one feature in OpenOffice recently that helps collaboration though and that is line numbers. OpenOffice will automatically add and maintain line numbers in the left margin. This feature makes referencing the content in text -- email, IM, etc -- and in person -- meetings, phone, skype, etc -- straigh forward. I wish Word had this feature. Then again, perhaps it does and just have not yet found it.

Using inline HTML as templates

I was tired of embeding HTML inside Javascript: How many times have you gotten right on the first try
var template = '<p id="'+base_id+'-a">This is the template. ' + 
  '<b id="'+base_id+'-b">And this is the tempalate, too.</b></p>';

Where as we always seem to get right
<p id="xxx-a">
  This is the template. <b id="xxx-b">And this is the tempalate, too.</b>
</p>

So, instead I wanted to place the HTML inline in the document and clone it from Javascript when needed. This allowed me to more easily code and then syntactically and visually check the HTML by rendering in the browser.

Unfortunately, there is no deep clone for DOM elements. And even if there was one I suspect it would not handle ID attributes as I wanted. So I wrote my own clone_dom and clone_dom_element functions.


<html>
<head>
<script type="text/javascript" src="http://prototypejs.org/javascripts/prototype.js"></script>
<script type="text/javascript">

  /*
   * clone_dom
   *
   * clone's the DOM element tree starting at template_id and appends to
   * element at target_id. The id_map is a simple hash that maps an id in
   * the template elements to an id in the cloned elements.
   */
  function clone_dom( template_id, target_id, id_map ) {
    var clone_template = clone_dom_element( $(template_id), id_map );
    $(target_id).appendChild( clone_template );
  }

  /*
   * clone_dom_element
   *
   * Clone's and returns the DOM element tree. The id_map is a simple hash
   * that maps an id in the template elements to an id in the cloned elements.
   */
  function clone_dom_element( element, id_map ) {
    var clone_element = element.cloneNode(false);
    if ( clone_element.getAttribute ) {
      var id = clone_element.getAttribute('id');
      if ( id != null ) {
        if ( id_map[id] ) {
          clone_element.setAttribute('id', id_map[id]);
        }
        else {
          clone_element.removeAttribute('id')
        }
      }
    }
    var child_nodes = element.childNodes
    for( var i = 0; i < child_nodes.length; i++ ) {
      var clone_node = clone_dom_element( child_nodes[i], id_map );
      clone_element.appendChild( clone_node );
    }
    return clone_element;
  }

</script>
</head>
<body>

  <!-- Place the templates in a non-displaying part of the document. Since the
     templates will be used in building the document keep them near the top.
     (When debugging the templates display them.)
  -->
  <div id="templates" style="display: none">

    <p id="template-a">
      This is the template. <b id="a-b">And this is the tempalate, too.</b>
    </p>

    <p id="template-x">
      <table border="1">
        <tr><th>Column 1</th><th>Column 2</th></tr>
        <tr><td>Value 1</td><td>Value 2</td></tr>
      </table>
    </p>

  </div>


  <p>Something before the cloned elements</p>

  <!-- There is where the templated DOM will be placed when cloned
  -->
  <div id="location-m"></div>

  <p>Something after the cloned elements</p>

  <!-- We are going to clone template-a and template-x into location-m
  -->
  <script type="text/javascript">
    clone_dom( 'template-a', 'location-m', { 'template-a': 'foo1', 'a-b': 'bar1' } );
    clone_dom( 'template-x', 'location-m', { 'template-x': 'foo2'                } );
    clone_dom( 'template-a', 'location-m', { 'template-a': 'foo3', 'a-b': 'bar3' } );
    clone_dom( 'template-x', 'location-m', { 'template-x': 'foo4'                } );
  </script>

</body>
</html>

What is the right framework for modern application development?

Everyone I know who might have contract work is getting an email from me these days! In my email to David Ascher of Mozilla Messaging I wrote
[...] my time at the start up was all Ruby on Rails .. which I grew to like .. but it is still the wrong language and framework for modern development.
to which David said
Can you explain your last bit?
Here is my attempt to do so.

Google Maps and then GMail significantly raised the expectations of web applications. Today, tools like GWT are raising it even higher. Tools on the web are in one of two classes:

1) sequential data access or
2) compound data use.

Rails and its imitators deal well with sequential data access. They are the GUI of REST. You have a canonical URL that represents the state of the application and the UI. For compound data use, however, you don't always have a canonical URL that represents the state of the application.

Ask the question "What is the URL for the state of my Thunderbird use right now?". As engineers we can imagine a nastly URL composed of very many parameters. A veritable URL maze. But we also know that this is not what is needed.

So, what is needed for modern development?

1) Rich GUI front-end tools as good as Apple's Interface Builder or at least as good as NetBean's Matisse and what Visual Studio has in it today. Apple, Microsoft, Sun and Qt Software (TrollTech) all have the advantage (today) of have an established user interface toolkit (the look) and user interface guidelines (the feel). For web applications this is missing today. There are lots of players attempting to provide this at the DHTML level (css + html + javascript), but I think what is really needed is a new browser standard akin to XUL, and, perhaps, Java Faces, Java Portlets, and even the "widget" ecology.

2) SOA and RESTful backend support of the GUI. This can be done today with all the web application toolkits like Rails, Grails, Django, Joomla, JSTL, etc. and workflow tools like BEPL. Most of this backend support can be stateless and so scale using common techniques and tools.

3) The last item is just the stuff that connects the GUI and the backend. While the developer should always be aware of the network between the two, I don't think the developer need be concerned about how data is marshaled and transmitted. I am not sure how this would be manifested. What Interface Builder and Qt have -- slots, channels, interface points, etc -- would be a useful line of inquiry.

I am generally out of the loop these days when it comes to cutting-edge UI frameworks. What I see in the open-source world though is inadequate. GWT is the torchbearer today but even here the tool pales in comparison to Interface Builder and what the SmallTalk and Lisp worlds have had for decades!

I realize I did not answer the question about language. I am sure Ruby is not it but it is better than many other languages in its language category.

Poems for a new President

Poems have been flowing from blogs since inauguration day. Perhaps someone will collect them to share with all. In the interim, here are two I know of: David Floyd's Inauguration Day and Rethabile Masilo's RICHARD OF YORK GAVE BATTLE IN VAIN.

Update: Here is Elizabeth Alexander's "Praise Song for the Day".

Somewhere in Texas...

Somewhere in Texas the secret-service is returning the village's missing idiot.

South Kingstown, RI Now blog



I am engaged in changing the way the South Kingstown town and school administration keeps us -- the members of the South Kingstown community -- aware of their activities. I believe that with awareness will come increased participation. Today I created the South Kingstown, RI Now blog to record of ideas and communications.

Creating rooted Windows Explorer windows

I like to use "rooted" Windows Explorer windows. A rooted explorer window does not show a folder's ancestors nor any other drives, Desktop, etc. You just see the folder and its decedents. For example, running "explorer /e,/root,c:\Program Files\Internet Explorer" from the command line (or the start menu's "Run..." menu item) will open a root explorer window. The "Internet Explorer" folder's content is on the right and the folder's decedent folders is on the left. Having many of these rooted explores seems to help me keep my desktop organized.

However, I don't want to have to use the command line to create these rooted explorers. I wanted a little GUI that would present a folder section dialog and then have it run explorer for the selected folder. I did this using Windows Scripting Host (WSH) because I knew it could do what I wanted and that everyone could use the result because everyone with Windows XP (and I assume Vista) has WSH. What I did not know how to do was how to program WSH.

When you don't know how to use a language or toolkit and you want to code something really quickly it is best to find code that does something similar to what you want and then hack it. I was lucky and found some sample code and below is the result. Save the code to the file "explore.vbe" and to run it just open it -- I have a shortcut in my Quick Launch toolbar.

set shell = WScript.CreateObject("WScript.Shell")
shell.run "explorer.exe /e,/root," & BrowseForFolder("Windows Explorer Root")

Function BrowseForFolder(strPrompt)
'Uses the "Shell.Application" (only present in Win98 and newer)
'to bring up a file/folder selection window. Falls back to an
'ugly input box under Win95.
'Shell32.ShellSpecialFolderConstants
Const ssfPERSONAL = 5 'My Documents
Const ssfDRIVES = 17 'My Computer
Const SFVVO_SHOWALLOBJECTS = 1
Const SFVVO_SHOWEXTENSIONS = 2
Dim sh, fol, fs, lngView, strPath
Set sh = CreateObject("Shell.Application")
If Instr(TypeName(sh), "Shell") = 0 Then
BrowseForFolder = InputBox(strPrompt, "Select Folder", CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName))
Exit Function
End If
Set fs = CreateObject("Scripting.FileSystemObject")
lngView = SFVVO_SHOWALLOBJECTS Or SFVVO_SHOWEXTENSIONS
strPath = ""
Set fol = sh.BrowseForFolder(&0, strPrompt, lngView, ssfDRIVES)
Err.Clear
On Error Resume Next
strPath = fol.ParentFolder.ParseName(fol.Title).Path
'An error occurs if the user selects a drive instead of a folder
If Err.Number <> 0 Then
BrowseForFolder = Left(Right(fol.Title, 3), 2) & "\"
Else
BrowseForFolder = strPath
End If
End Function
Wow, this is ugly code. But it does work.

Will code for money

I am looking for full-time or contract work. If you are interested in hiring me or just want to chat please send email to andrew@andrewgilmartin.com.

I left WaveSyndicate, a very early stage startup, because as its product was more solidly defined the product became less interesting to me. When this happens, it is always better to leave as soon as this is clear. I believe WaveSyndicate and its product have a good future and especially so with Jared Rosoff and Bob Chatham at the helm.

What emoticon would your grandfather use?

My grandfather was an iron worker in the ship-yards of Glasgow, Scotland. His job was to bore holes 4in thick steal plates that were used in the ship's boilers. I suspect he would have no use for iChat's emoticons.

Participation starts with awareness

For me participation in South Kingstown municipal government and school administration starts with awareness. What is happening right now in town and school? For example, did you know that the engineering drawings for the bathrooms on main st & bike path are complete and implementation is waiting on state funding (promised but now on hold)? Perhaps you are an avid bike path user and want to see the bathrooms built in place of buying more open land this year. Being aware of bike path activities would empower you to advocate for this construction. (The town, by the way, already has been able to set aside 29% of the available land for open-space.) When you are aware of what is being considered and what is being acted upon as early as possible then you don't feel blind sided when the change happens nor do you feel that nothing is happening.

You need to be able to subscribe to specific issues, categories of issues, and full text searches of issues. When new data is added to an issue -- a fact, a comment, a data set, a PDF, a GIS layer, etc -- you will be automatically notified. For some issues you want just a weekly summary sent in email on Saturday morning. For other issues you want detail emailed ASAP and an text message sent now.