hcOPF is Released!

June 25th, 2009

I have been working towards this for a long time now.  Initially I was undecided what license to use, then it was a matter of wanting to complete some code improvements.  Finally I just decided it was never going to be perfect, especially since I don’t have that much time to work on it at present, so I finally kicked it out of the door.

The framework certainly works.   I have numerous applications and success stories that testify to that.  It does however have some holes.  The biggest of which is Unit Test coverage.  I started writing the framework long before Agile methodology became the rage, and although I see the value of writing tests first, it’s a little harder to write them afterwards.  It’s also very challenging to write tests for GUI elements.

I am also in the process of changing the way the framework deals with Object IDs aka primary keys.  Initially I used an Attribute property to specify if a column was involved in the primary key (apPrimaryKey).  I later introduced the concept of a ThcOID class to encapsulate primary key handling in order to better facilitate keys consisting of multiple attributes, natural keys, and keys made up of non-integer data types.  Currently you have to use both methods for the framework to function correctly since the conversion to ThcOID is not complete.

The design-time aspects of the framework have also undergone an evolution and are no longer complete.  I used to only support Attribute/UI Control Name/UI Control Property Name elements in the UIObjectBinder and used RTTI to set and get the values from the UI Control.  Then I introduced the MGM pattern, providing a much more flexible framework capable of supporting almost any non data-aware control.  If you use a ThcMediator descendant with the ObjectBinder, you must establish the bindings in code.  The same applies to design-time functionality for the DevXGrid.  All column bindings for a view must be created in code.  I typically use a previously written method as a template for a new one.  At some point I would like to have design-time support implemented, or at the very least have some sort of wizard to generate the code.

The project is hosted on SourceForge at http://sourceforge.net/projects/larryhengensopf/.  If you have any issues with the framework, pop me an email.

hcOPF an ORM for Delphi

June 25th, 2009

What is an OPF?

An object persistence framework is essentially a library of pre-written code that takes care of the details of persisting, or permanently storing an object. The object may be persisted to a text file, XML file etc., but in the business world it will most likely be to an RDBMS and for this reason they are sometimes referred to as an ORM (Object Relational Mapper).  Object databases have been around for some time, but they are not used as prominently as RDBMS products so programmers still have to be able to write their objects into a RDBMS, and the easiest way to do that is create an Object Persistence Framework, or layer, that can perform all the CRUD (Create, Read, Update and Delete) operations developers normally have to code by hand.  This enables developers to focus on implementing better UIs, and addressing the problems the application is meant to solve.

The concept of an OPF is nothing new.  Java has TopLink, Hibernate, etc, .NET has a partial port of Hibernate called oddly enough, NHibernate, CSLA, Castle Record and numerous other implementations.  One of the major impediments to an OPF for Delphi is the lack of complete RTTI aka Reflection, and the development environment itself.  Delphi’s IDE is geared to creating RAD applications using it’s component technology.  While this means you can create Object Oriented applications quickly, the benefits of OOP are for the most part lost, because the data is not being manipulated in an object oriented fashion.  As a result code becomes harder to maintain and understand because data validation code is scattered throughout form and data modules.  The use of events on TDataSets can create a spider web of event sequences that produce obscure bugs that are difficult to trace, and more database activity is usually required in a typical RAD application than a truly object oriented one.

How it All Began

My interest in OPFs began when working for a company that developed their own OPF as the foundation for a suite of hospital medical applications written in Delphi 3.  That company went bankrupt, but the validity of their vision of a using an OPF as a foundation for applications was proven to me every time I wrote a database application afterwards.  The more complicated the application, or the more closely it modeled the real world, the more sense it made to use an OPF and write a fully object oriented application.  Eventually, I started working on my own OPF, ensuring that I didn’t make the same design mistakes that were made in the other framework which was later sold as ObjectSight.  I wrote a basic requirements document, and proceeded to develop the OPF, reworking it over time as I came across other ideas from Seleqt, Techinsite, Phillip Brown, Thomas Buxton, Frank Shearer, Chris Lichti, and participants of the Obiwan project and Object Oriented Design discussion groups.

I am happy to say that I licensed an earlier version of this framework to a client, and have used it on numerous projects myself, including one for the company at which I currently work.  I love the fact that I don’t have to write SQL and the more I use the framework, the better it gets.  The latest improvements include support for practically any non-data aware control via the MGM pattern.  It also supports the DevX suite of controls including their very powerful grid by way of a custom datasource.  I have dubbed the framework hcOPF where hc stands for Hengen Computing.

X Platform Development in Delphi

April 9th, 2009

In order for Delphi to maintain and grow it’s market share it, IOW, continue to be successful, it needs retain current developers and attract new ones.  To do so, it must become the only development platform capable of X platform development in either native code, or .NET CIL.  To support this goal, the IDE itself must be X platform, demonstrating the capabilities of the compiler, VCL and supporting tools. This premise is supported by the efforts of Borland in the Kylix days.  Although much of the Kylix effort was the result of market hype and a non-validated developer survey, the underlying reason for X platform support is even stronger today.  

Developers want to make money, wherever and whenever they can.  The question is how?  Developers would rather spend less time learning new languages and technologies and more time writing applications that may make them money.  Unfortunately, learning new technologies is often required to produce unique and better applications, especially when it comes to the Web.  Also, Microsoft seems to love changing the development technologies platform substantially every 5 or so years, and maybe that is how they have maintained dominance.  While everyone else is trying to figure out how the new APIs work, and when to use them, Microsoft continues to write software and make money at it.  It’s not as if their software is necessarily better, they just know how to market it.  Interestingly enough, they continue to develop native code solutions for more than low level solutions such as the OS.

How can Delphi continue to grow their market share when .NET is the predominant platform?  The answer is leverage.  Now, to maximize leverage you have to be able to produce X platform applications.  Why?  Well for one, there are competitors who have been doing so for quite some time using Widget libraries like Qt. Now there is also .NET which may actually deliver on Java’s promise to Write Once Run Anywhere/Everywhere (WORA) or (WORE).  .NET is not only a major threat  to Embarcadero’s Developer Tools specifically, but also the Object Pascal language as well.  .NET supports multiple languages, and the premier language, C# is cleaner in many respects than OP.  Add to that, the ease of integration with third party .NET libraries, the plethora of open source projects most of which are in C#, and the number of jobs requiring .NET expertise and you have a very compelling argument to go with C# .NET.  Somehow CodeGear has to ensure the survival of OP to ensure the survival of the VCL and it’s RAD Studio IDE.  One major way to ensure the survival of OP is to facilitate X platform support.  Another would be to open the language and the VCL.  Today Firebird is a very successful open source project with a large community.

The mere existence of Lazarus and the Free Pascal Compiler’s Delphi compatibility directive is a testament to the fact there are many developers who want to use Delphi for X platform development.  As of January 2009, you can even use the Free Pascal compiler to target the iPhone!   

Embarcadero may want to pay some attention to Apple.  Apple knows how to commercialize open source projects and contribute back to the community.  If Embarcadero followed Apple’s lead, we would not only have a much better Windows product, but we would also likely have Delphi for the Mac, Linux and the iPhone as well.  

Time to quit following Microsoft and carve your own niche…that’s just my 2 cents.

First Impressions of ODI

February 25th, 2009

At work we have purchased ODI (Oracle Data Integrator) 10.1.3.5 as our latest ETL/ELT tool.   ODI was previously known as the Sunopsis Data Conductor before it was purchased by Oracle in October 2006.  Before buying ODI, we had used Oracle stored procedures, straight C# .NET code and SSIS 2005 for integrations.  If I had been blogging at the time we started using SSIS, I no doubt would have posted along the lines of this.  I hated SSIS.  The worst part was having to write VB script in a seperate IDE environment.  I doubt the product ever underwent any usability testing before release.  I understand SSIS 2008 is a much better beast, but we never considered using it because of the bitter taste left in our mouth.

ODI’s UI

ODI is written in Java.  As a windows user, The UI is not as intuitive as I have come to expect.  Beyond the distinctive Java appearance and lack of speed, ODI has some particular behaviours I find annoying.  If you use Alt + Tab to switch between running applications, the icon shown for any ODI thick client application is the steaming cup of Java and if you click the close button in any of these applications, say the Topology Manager for instance, you get the following confirmation dialog:

Confirm Exit

Shouldn’t this say “Topology Manager”?  Apparently, each thick client is considered part of ODI and you have a single login to access any of them.  On the toolbar of each application there are icons for the other thick clients you can use to launch them.  When you try to close the last thick client application you get the confirmation dialog essentially informing you that if you close the application you will have to login the next time you run one of the clients.

There are also some localization issues.  Being unfamiliar with ODI and Java, when it came to creating a connection to a repository I didn’t populate the User and Password edit controls because I had already included the user and password in the thin JDBC connection url.  I got the following error message:

ODI's Localized Error Messages

which translated into English is “the user name of the database can not be null or empty”, but unfortunately I only understand the language specified by the regional setting on my computer which is English.  How would you ever guess that ODI was written by a French company called Sunopsis?

UI cues are very subtle in many cases, and standard behaviour is a little different.  For instance, when selecting objects in the Flow tab of the Interface properties, you must click on the title bar of the diagram element (red circles below) to select it, not anywhere else within the element.

Getting into the Flow

Z Ordering is not handled properly.  If you attempt to import a knowledge module, popup the browse dialog and switch to another application, upon making ODI the active application again, you don’t get the browse dialog, but the dialog from which that was launched.  You have to select the “Select a folder” application with the Java icon using Alt + Tab (it does not appear as a window on the Taskbar).

There is no way to increase the size of the text in the ODI help system, and it’s pretty small even by my standards.  Context sensitive help is not all that sensitive, and much of the help is “click here, select this” which doesn’t help the moment you go off the beaten track or something does not work as expected.  The help is woefully incomplete as is the ODI documentation in general, but we shall get to the nitty gritty in future posts.

Why an iPhone?

February 21st, 2009

Prior to buying an iPhone I used a Palm Tungsten T3.  IMHO, this was the best model Palm ever produced, even if it lacks Wifi.  The lack of good Wifi support even with an SD Wifi B card, was one of the primary reasons I bought an iPhone.  I didn’t actually plan to buy an iPhone, but when I was attending WWDC 2008 I was frustrated that I couldn’t use my Palm for sending email or browsing the web because I kept getting Fatal Exceptions.  It worked fine at home, although it wasn’t the quickest web browsing experience, and sometimes web pages just didn’t look all that great. 

In contrast the web browsing experince on the iPhone is amazing.  I used my buddy’s iPhone at the conference to pickup my mail and was amazed at how close web pages are rendered to the desktop.  It was the consolidation of a cell phone, which I only occasionally use and could not justify, and as Jobs put it “a break through Internet device”,  that prompted me to fork over the money for an iPhone without a contract.  I opted not to get a data plan for the phone, because I couldn’t justify the cost since as a Canadian I would be paying some of the highest cell phone rates in the world.  The only thing I miss about not having data is being able to use the GPS with google maps while travelling.  Instead I have to use a map program that downloads all the map data for a pre-selected area.  I also miss not having data a little while at work, since they don’t provide or allow Wifi on the network.

The iPhone hasn’t completely replaced my Palm yet, because I don’t want to license and use Outlook at home, and Apple doesn’t supply ToDo list management to the same extent it’s available on my Palm.  Eventually I’m sure the iPhone will become my only PDA, even though Apple doesn’t market or support the iPod Touch or iPhone as such, especially if you’re using a PC.

My Take on Palm and their Pre

February 21st, 2009

I have been a big Palm user ever since I bought my first HandSpring Visor about 10 years ago.  Although Palm has had an excellent product for many years, they missed the boat on many things:

1) Pushing the Palm as a Media Player for both Music and Video.  Ever since Palm started using the XScale processor (2003) the Palm became capable enough to act as a PMP, but needed software bundled with it.  Palm only licensed a basic version of RealPlayer, and provided Kinoma for video.  They never really marketed this aspect of the Palm, subsequently the iPod took the majority of the market.

2) Incorporating a Camera into the Palm.  One model, the Zire 71, had a VGA resolution camera, but it never became a mainstream feature and the capabilities of the camera where never updated.

3) Wifi - the Palm Tungsten C was the first to come out with Wifi, but again it was always a matter of selecting one of the few models offered with this feature at the expense of CPU speed, or voice memo recording, or a camera.  Palm never incorporated all features into a single device, and kept the features current.  For example, even though Wifi G was becoming available in 2003, Palm released a plethora of models seemingly without any coherent strategy, and those with Wifi used the older B specification.  Palm has never updated their Wifi support since to either the G or N specification. 

4) Cell phone.  After 3Com bought Palm, many of the original founders left to form HandSpring and came out with the first SmartPhone.  Once again Palm had the market, but let it slip from it’s grasp by not continuing to innovate after acquiring HandSpring.  They seemed to have mistakenly believed that their customers would wait forever for their nextgen SmartPhone based on the PalmOS replacement.

5) Support.  Not only has Palm not provided hardware updates to their devices to keep them current (so they could read higher capacity SD cards, use faster Wifi etc), Palm has also failed to provide updates to their software.  The Palm desktop did not support Vista for about a year and a half, and the Mac version of the Palm desktop still uses PPC code, relying on the compatibility layer that Apple will be shortly removing from Mac OS/X. 

Palm is still selling their devices at unreasonably high prices despite the fact that they are dated, and lacking in support.  That’s personally one of the primary factors in my decision to not consider the Palm Pre.  If the company has chosen repeatedly to ignore the needs of it’s existing customers, then why should those customers remain loyal to the company?

The Palm Pre looks very promising as an iPhone competitor.  It is remarkably similar in many respects to the iPhone.  I guess imitation is the sincerest form of flattery, but I personally don’t like the idea of a thumb board, or writing applications using web based technologies.  I think Apple discovered that developers need the capability to write native device code, and that giving them this capability can make or break your device.  Palm has a long way to go in getting developers onto their platform, and getting the device out.  I hope they succeed because competition is always good for the consumer, but I’ve chosen the iPhone and for me, Palm’s history of indifference to it’s existing customers doesn’t make me want to become one again.

Customizing TApplication Without Helpers

February 18th, 2009

Have you ever wished you could create a TApplication descendant to incorporate some core functionality you wanted across all your applications?  We did, and this post describes how we accomplished it in Delphi 7 which does not support class helpers.

One of the fundamental features Delphi lacks for “out of the box” enterprise application development is the ability to determine whether the current logged in user belongs to an Active Directory group directly, or indirectly through memberships in other groups.  This is essential for determining if the user is allowed to run the application at all, and if so, what subset of the application’s features they are allowed to access.

At work, we maintain a DEV, TEST and PROD database environment.  Our applications accept this environment specifier as a command line parameter.  We dynamically change our database connections at run-time, and restrict access to the applications on the file system using AD groups.  Some of our applications used Oracle database tables in the application’s schema for security, and to record their usage.  Since there was no consistent schema used for all applications, this was difficult to maintain and any applications with security were usually accompanied by a “Security Manager” companion application.  The development group wanted to off load all the user provisioning support calls we received, to the service desk, so we had to provide a uniform security mechanism they could administrate - AD.

The Requirements

My experience has taught me that full blown requirements gathering just doesn’t work, nor does diving into code.  I prefer a middle of the road approach.  I like to create a point form list of application requirements, and then prototype it to see how well it works, driving out more ideas.

My requirements for this effort were:

  • prevent users from running the application if they did not belong to the appropriate group(s)
  • provide easy access to AD Membership information for securing application features
  • must be easily incorporated into existing applications with minimal changes (including apps not requiring security)
  • incorporate our standard About box
  • provide some basic roles and allow developer defined ones
  • provide application version information

The Implementation

Initially I started by developing components that could provide AD Group membership information.  Then we standardized on a group naming convention, taking into account the multiple database environments we needed to support:

Format(’%s - %s - %s’,[ApplicationName,Environment,RoleName]);  //i.e.: ‘HierarchyMgr - DEV - PowerUsers’

TApplication was never really meant to be used as an ancestor class.  None of it’s methods are virtual, it’s presence in the Forms unit and tight coupling to TForm and other classes speak to this.  So I traced through the sequence of code excecuted on application startup and found that the only way I could load my own application object instead of TApplication was to make my unit the first one in the uses clause of a project.  Then in my initialization I can free the existing application object, replacing it with my own using the following code:

initialization
if assigned(Forms.Application) then
Forms.Application.Free;

Application := TEnApplication.Create(nil);
Application.ShowHint := True;
//in case any units access the Forms.Application global variable explicitly, assign it to the same instance
Forms.Application := Application;

finalization
//Application object will be destroyed by native Delphi VCL

If you’re interested in the actual code, send me an email…

Delphi on My Mac with VMWare 2.01

February 14th, 2009

This summer a friend of mine convinced me to go to the Apple Developer conference with him.  He had purchased an original iPhone and convinced me we should find out how to write applications for the next generation iPhone.  It was shortly after the conference that I bought my first Mac - a Macbook Pro.  I bought a Mac laptop because I have been traveling more frequently and have often missed being able to cut a little Delphi code and keep in touch with the world via the Net.  Since I had to buy a Mac for iPhone development, I thought it was the perfect time to see if a laptop was right for me.  So far, I’m liking the ability to code anywhere and any time.

Initially I thought about using BootCamp to load windows onto my MacBook Pro, but decided against it because I only had a 100Gb hard drive, since I unwittingly bought an older version of the MacBook Pro on eBay (it’s only a 2 Ghz Core Duo MacBook Pro 1,1), making the trade off for a smaller but faster HD.  This model also didn’t have an external Firewire 800 port so running Windows off an external drive wasn’t a good option both for performance and the portability impediment of an external device.

After looking at other options such as replacing the HD with a larger version I opted to buy VMWare’s Fusion 2 for 50% off, a mere $40USD.  It’s amazing to me the complexity of the software you can buy for cheap these days.  As a programmer it’s also disturbing, since I understand the time and effort that goes into writing such a piece of software.

After working now with Delphi 7 on Fusion, I have concluded that Delphi 7 under VMWare on my older laptop is actually faster than running it on my AMD X2 4400+ Windows PC with a 10K rpm HD.   It’s been a little difficult getting used to a laptop keyboard, but I think my PC is going to be relegated to acting as my server in the near future.

One major issue that I encountered with Delphi on my MacBook Pro was the lack of an Insert key.  Although I own Rad Studio 2007, I am still actively using Delphi 7.  This is in part to the component libraries that I own, and CodeRush.  For those of you out there who don’t know about CodeRush, it’s an IDE add-in written by Mark Miller when he owned Eagle Software, prior to selling his IP and joining DevExpress.  CodeRush was a great productivity tool.  I especially like the code navigation and code template features.  Unfortunately it has some bugs, one of which is that Insert mode is occasionaly turned off, and the code templates start to overwrite other code.  As I understand it,  a lot of these kind of problems are due to bugs in the Editor itself and a lack of documentation and support from Borland for third party vendors.  Each release of Delphi involved a significant rework of the product, and with the advent of .NET with a much larger market and a vendor encouraging developers to write IDE add-ins, Mark left the Delphi community and halted maintenance on CodeRush for Delphi.

Today, I figured out how toggle Insert mode in Delphi 7.  VMWare is supposed to have a menu option to send special key codes to the guest OS, but for some reason Insert was not on my Send Key sub menu as shown in the VMWare docs.  To get around it, I went to VMWare Preferences for keyboard and mouse, enabled the key mappings and then added one.  I chose Alt + X to map to the Insert key and it works now…sort of.  The first time I press Alt+X Insert mode is toggled correctly, but if I continue to hold the Alt key and hit the X, the first or second time I start to get the ‘X’ character in the editor rather than toggling insert mode.  Hopefully this issue will be fixed as well as a couple other UI annoyances in the upcoming 2.02 release.  At any rate I would highly recommend a MacBook Pro with VMWare for all your Delphi development.

Why TPersistent?

November 23rd, 2008

I decided I wanted to blog, to increase my presence in the on-line community.  I wanted a site where I could do more than just blog, and since my opinions are my own it didn’t make any sense for my blog to be part of a corporate site, and I didn’t want to publish under larryhengen.com.

Since one of my primary programming interests is Delphi, I decided to use what IMHO is the most important class in the VCL.  Without TPersistent there would be no DFM streaming, no opportunity for objects to make much of an impact during their short life time….and so it seemed fitting for my blog domain name.