22 March 2010
The introduction of ColdFusion Builder has the potential to be a real game-changer for ColdFusion developers, and for me, self-updating extensions are an exciting part of it. As the first dedicated ColdFusion IDE since ColdFusion Studio many years back, ColdFusion Builder offers the ability to further improve the speed and efficiency with which developers create their CFML applications.
In my opinion, the single most compelling feature currently in ColdFusion Builder is the ability to create extensions using standard CFML templates. Now every ColdFusion developer has the power to customize and enhance their Eclipse-based development environment in a language that they are comfortable in and share these across their workplace or with the ColdFusion community.
In this article I will introduce a library I have written that allows you to easily enable your ColdFusion extension to detect newer versions, download them, and install them. This is a common feature in IDE extensions but is not a built-in functionality for ColdFusion extensions. While this is an initial release and the library isn't what I would yet consider feature complete (see Where to go from here for some of its current limitations), the goal is to allow you to easily add this feature to any extension via minimal code changes and a simple configuration.
Although it isn't a requirement, some knowledge of creating ColdFusion Builder extensions will be helpful in understanding this article. If you haven't yet built an extension, this article touches on some of the basics, but its intent isn't to teach you about building extensions. If you are looking for a more in-depth tutorial on building extensions, read Simon Free's article Building extensions for Adobe ColdFusion Builder.
In addition, this library is based upon a proof-of-concept project that I previously wrote about on my blog. While this isn't required reading, it offers some background on some of the concepts discussed here. To offer credit where it’s due, this library was inspired in large part by the auto-updating functionality contained in Laura Arguello's Mango Blog project.
To illustrate how the auto-update library works, I will modify one of my own prior extensions called the Skeleton Application Generator (available on RIAForge). Despite its complex sounding name, this is a very simple extension that unzips the application skeleton of your chosen framework into the selected folder. This article includes examples of the two allowed configuration options: hosting the extension updates on your own and hosting an extension on RIAForge.
One of my primary goals for the auto-update library was to make it extremely easy to integrate. While I chose to use this particular extension for its simplicity, modifying more complex extensions should be just as easy since I boiled integration of the auto-update library down to two simple steps:
The first thing you need to do in either configuration, of course, is download cfbuilder_extension_updater.zip and unzip the files of the auto-update library. Your extension is typically organized with the ide_config.xml in the root and a handlers folder containing the code and templates. After unzipping, place the auto-update library files in your handlers folder. There are six required files:
onApplicationStartmethod to initialize the library and in
onRequestto intercept requests when an update is available or has been downloaded.
cfzipdoesn't implement this tag yet.
First, consider a scenario in which you are hosting your own updates and want to enable auto-updating of your extension. This might be your preferred option if your extension isn't necessarily for public consumption, as it would be on RIAForge. For example, you might create an extension specific to your workplace and want to make sure updates are pushed out whenever they are available.
If you open the Settings.ini file you will notice some basic settings for
lastDateChecked. In a hosted update scenario, the only option you need to set is
urlToCheck. You do not specify the version number in Settings.ini; it is set automatically by the library based on the version number you specify in your extension’s ide_config.xml file. (It is important to note, however, that the version number in your ide_config.xml file must be numeric.) Here is the configuration file for my Application Skeleton Generator:
[main] version=0.1 urlToCheck=http://www.remotesynthesis.com/projects/Application Skeleton Generator/ApplicationSkeletonGenerator.zip riaForgeProjectName= lastDateChecked=
urlToCheck specifies the hosted ZIP file that will contain the most recent version of your extension. At this time, you must place a copy of the ide_config.xml for your update alongside your ZIP file in the same hosted folder location (so, in this case, it would be located at http://www.remotesynthesis.com/projects/Application Skeleton Generator/ide_config.xml). This is done so that the auto-update library does not need to download and unzip the update in order to determine its version number.
As with the hosted configuration, you don't need to set the version in the Settings.ini configuration file to enable RIAForge updates because it is pulled from the ide_config.xml file. Note, however, that the version you specify in your project settings at RIAForge.org must be numeric. This allows the library to determine if an update is required. I considered using the last updated date for your project to determine if an update is needed, but this changes even if you simply modify the description or other settings of your project, so I didn't feel it was a reliable gauge.
In the RIAForge configuration, your
urlToCheck should be your project XML on the RIAForge site. You can obtain this XML URL by logging in to RIAForge and clicking the View Your Projects link. The
riaForgeProjectName setting should be, as the name implies, exactly what you place in the Project Name field on RIAForge. Here is the RIAForge configuration file for my Skeleton Application Generator:
[main] version=0.1 urlToCheck=http://www.riaforge.org/index.cfm?event=xml.userprojects&uid=8 riaForgeProjectName=Skeleton Application Generator lastDateChecked=
For both the hosted and the RIAForge update configurations, the Application.cfc of your extension must extend the BaseApplication.cfc sample file. Your extension’s Application.cfc must call
onRequest(). If you already have an existing Application.cfc that implements these methods, simply add the calls to
onRequest()respectively. For example, here is the Application.cfc for my Skeleton Application Generator; note that
onRequestStart() is included but not required by my library, it simply ensures that no debugging information is shown that could cause the result XML to be malformed:
<cffunction name="onApplicationStart"> <cfset super.onApplicationStart() /> <cfreturn true /> </cffunction> <cffunction name="onRequestStart"> <cfsetting showdebugoutput="false"> </cffunction> <cffunction name="onRequest"> <cfargument name="targetPage" type="string" required="true" /> <cfset super.onRequest(arguments.targetPage) /> <cfinclude template="#arguments.targetPage#" /> </cffunction>
By implementing the library this way, it can intercept requests without requiring you to modify your templates in any way. When an update is available or when the update has been downloaded and installed, the library simply captures the request and serves up its own XML response to display in the Eclipse UI.
As I noted, this project is still in its infancy. There may be some unforeseen bugs, and it isn't feature complete. For example, I plan on allowing you to configure how frequently the software checks for updates; currently it is hard-coded to check daily. I also want to offer developers the ability to let the user decide not to be notified of automatic updates. I hope to add many more features in future iterations of this project. You can look for upcoming project updates (free and open source) on RIAForge. I encourage you to contribute to the project if you find it useful.
Even with its limited current feature set, I think this library can add a very powerful feature to your already awesome ColdFusion extensions. In fact, without much effort, you could easily borrow much of the code and concepts to implement an auto-updater function for any of your ColdFusion projects, not just extensions.