Getting to Know Mr. Wizard (Article Reprint)
Posted on Jan 07, 2009
This is a reprint with permission of an article that was originally published in the Fusion Authority Quarterly Update Volume 2 Issue 4 in May 2008 (click here to subscribe).
What was life like before wizards? Can you even remember? It seems that nowadays you won't find a coding
practice that can't be distilled into a multi-step question and answer
process. However, we know from movies and mythology that not all
wizards are good. Look at Gandalf and Saruman. Or, a
wizard can be just a bunch of smoke and mirrors with some old man
behind a curtain, as in Oz. This rings true in the world of software
development as well; wizards can be powerful but must be used with
caution, and the ColdFusion wizards are no exception. The key to using
wizards is to understand what they are doing underneath the covers and
demystify the "magic".
As part of the Flex integration first
released with ColdFusion 7.0.2, Adobe released the ColdFusion
Extensions for Eclipse, which included features like RDS file and dataview support and a number of wizards. These plugins could be used within any Eclipse install, including the standalone Flex Builder.
With ColdFusion 8, these extensions received a nice upgrade, including
some enhancements and new features like the code debugger and a log
viewer. You can download the extensions at
http://www.adobe.com/support/coldfusion/downloads.html and installation
instructions are available at
http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=othertechnologies_11.html.
This article will focus specifically on the wizards that are available through these extensions, including some that can create entire CRUD RIAs based solely upon your data model. I'll take a close look at what they generate and give each wizard a "Wizard Rating", a light-hearted, pop culture reference that reflects my view of the wizard's usefulness, and I'll address any concerns I may have towards using it within a standard development process.
ColdFusion/Ajax Application Wizard
The first wizard we will look at takes advantage of the new integrated Ajax functionality in ColdFusion 8 to build a basic CRUD application (i.e. a form-based application to create, read, update and delete items from a database). To use this wizard, go to the "File" menu and click "New" and "Other". Within the "select a wizard" dialog box, expand the "ColdFusion Wizards" option and choose "ColdFusion/Ajax Application Wizard". Click next to begin the wizard.
Assuming that you are using this
wizard for the first time, you will want to skip the step of loading
previous wizard settings and go straight to choosing which RDS data
source to base your code-generation on. For our samples, we will
utilize the "cfbookclub" Apache Derby data source that comes
pre-installed with ColdFusion. This is located under the "localhost"
RDS Server.
Next, start
adding master and detail pages to your application, using the built-in
"Page Layout and Design" wizard and query wizard. You will create one
master and one detail page for the books table. Begin by clicking the
plus-sign button under available pages to create a new page. Name the
page "Books List" and leave the selected Page Type as "Master".
Finally, click the "Edit Master Page" button, which will open the query
builder dialog.
Figure 1: Creating your master page in the query builder dialog
Once
in the query builder, double click the "APP.BOOKS" table under your
"cfbookclub" data source to add it to the stage. Then double-click the
bookid, title, bookdescription and genre columns to add them to the
query. It is important to select the key column even if it won't be
displaying; otherwise your application will fail. Note that the query
wizard is smart enough to default your bookid as a key and to turn off
the display option. This works for the sample application, as you need to pass the ID to your detail page but the user doesn't need to see it. View the
results of your query by clicking the "Test Query" button. Finally,
click the "save" button. Once back in the "Page Layout and Design"
wizard, be sure to highlight the "Books List" page under "Available
Pages" and click the right-facing arrow next to the list to add it to
your navigation tree.
Next, you will add the detail page. First
click the plus-sign button again under "Available Pages". Name this
page "Book Detail" and give it a page type of "Detail". Go ahead and
add this to your navigation tree under the "Books List" item before
opening the query wizard again. Inside the query wizard, double-click
on the "APP.BOOKS" table to add it to the stage again. Notice that the
wizard has already added the appropriate connections binding the "ID"
parameter to your books table. Next, you will want to edit the column
options for the books table so as to allow you to edit the related
column of authors. Do this by changing the "Input Control" drop-down to
"ComboBox", which will enable the option to create an "Input Lookup
Query". Clicking on the "Input Lookup Query" option will open a new
Query wizard dialog. Simply double-click the "APP.AUTHORS" table to add
it to the stage and then select the authorID, firstname and lastname
columns. This is another place where you must choose the ID column or risk getting an error in your generated application.
Click
on the save button to return to the initial query builder dialog. Here
you will modify the "Input Control" for the isspotlight column, making
it a Combobox, since it accepts the values "Y" and "N" and the checkbox
value is not customizable. To do this,
open the "Input Lookup Query" query builder dialog, select the books
table and then select the "isspotlight" column. Next, check the display
option for the "isspotlight" column and add the "distinct" keyword into
the query dialog so that it reads "SELECT DISTINCT ISSPOTLIGHT FROM
APP.BOOKS". Finally, click save and then save again to return to the
page layout dialog.
Figure 2: Adding a detail page to your Ajax Application
For the purposes of the example, you are done creating pages. Click
on the "Next" button to enter the "Project Information" dialog. I chose
to create a new project and name it "cfajaxwizard", placing it in my
web root. A folder within the web root will be created with the same
name as the project name, so mine is browsable at the folowing local
URL: http://localhost/cfajaxwizard/. If you browse the project, you
should see a page with a menu option to open the "Books List" dialog in
an Ajax window. You can click on a book record and click the detail
button to review/edit the details, noting the drop-downs that we added
above, or you can delete a record by clicking on the trash can icon.
Finally, you can click the plus-sign icon and add a new record to the database.
Wizard Rating: Unfortunately, I am going to have to give this one an Oz. Much like the famed wizard of the Wizard of Oz,
this wizard generates something that looks impressive until the curtain
is pulled back. The wizard itself was difficult to use, with little to
no documentation and a number of unintuitive options that often left me
befuddled as to why the application didn't work. Note that you can
reuse wizard settings that are saved automatically to run through the
wizard without starting over, though, as with any passive generator,
you will not retain any changes you have made to the generated code.
The
application itself works fine but really doesn't look like any
application I have ever used or would ever deploy into production, even
to handle CRUD. The code itself isn't
terrible but has a number of features that I personally am not fond of
including, as it moves needlessly between cfscript and straight tags,
uses tables for certain layouts and seems, at a cursory glance, to be a
bit difficult to modify. Never mind that you can't currently tweak the
templates to your preference. This wizard seems to exist simply to show
off ColdFusion's new Ajax features during a presentation, but is
nothing I, personally, foresee using within a real project.
ColdFusion/Flex Application Wizard
The ColdFusion/Flex Application Wizard is identical to the Ajax wizard except that it generates (surprise!) a Flex application. In fact, all the dialogs and options appear identical until you reach the "Project Information" dialog. Therefore, to create your example application, run through the steps as described in the last section, until that point.
Within
the "Project Information" dialog, you will notice an option to include
a login dialog, which wasn't available on the Ajax wizard. The actual
code to verify a person's credentials is entirely up to you ,since the
generated code includes several unimplemented methods. The Flex
generator also requires that you choose a valid services-config.xml,
which is generally within the [ColdFusion Install]\wwwroot\WEB-INF\flex
directory. Besides these two changes, the Flex wizard is the same as
the Ajax one and the generated application looks nearly identical,
except that it generates a SWF.
Wizard Rating: For almost
identical reasons as stated above, I feel compelled to give this wizard
a less than flattering wizard rating of Tim The Enchanter. Despite its
flashy, "eccentric", performance, this wizard doesn't produce the most
usable or easy-to-modify code. If you're trying to find your way to the
Holy Grail (i.e., learning Flex), this wizard might give you some
direction, but that is the extent of its usefulness.
CFC Wizard
The prior wizards generate code based upon ColdFusion components. However, in most cases you aren't looking to generate an entire application but would like to save some time on developing your components. The CFC wizard lets you generate various types of CFCs based upon database metadata. Begin by right-clicking on a table in the RDS Dataview and choose "ColdFusion Wizards > Create CFC". For this example, you will again be generating on the "APP.BOOKS" table within the cfbookclub data source.
First, choose the project and folder in which to place the generated files. If your CFC is part of a package, you can specify
it here as well. The bookID column should be pre-selected as the
primary key option and grayed-out. Leave all other options at their
default, including the initial choice of generating an "Active Record
CFC". For those unfamiliar with the design pattern popularized by Ruby
and the Rails framework for Ruby, an active record bean (i.e. books.cfc
in this example) will know how to persist itself in the database, negating the need for a booksDAO.cfc (i.e. Data Access Object). I will not
go into any lengthy discussion of this pattern other than to say I am
not a fan of it personally, but it is an option available to you. Click
on the finish button to generate the bean and gateway components.
The "Bean CFC and DAO CFC" option generates similar components,
except that the CRUD queries are removed from the bean and placed
within the Data Access Object component (booksDAO.cfc). The final
option, "LiveCycle Data Services Assembler CFCs" generates a bean and a
DAO as well as an assembler component (booksAssembler.cfc) with the
appropriate methods for working with LiveCycle Data Services (LCDS).
Wizard Rating: Like the Merlin the Magician character in Disney's The Sword in the Stone,
this wizard is well-intentioned and gets the job done, though not
always in the most elegant fashion. Just as in the movie, this wizard's
magic may best be used "for educational purposes," with some caveats.
As with the prior wizards from which it shares code, the coding style
often strays from accepted standards needlessly. For example, the resulting code often sets the argument as "val" within every setter in a bean or names a variable "new".
<cfcomponent output="false">
<cffunction name="getById" output="false" access="remote">
<cfargument name="id" required="true" />
<cfreturn createObject("component", "BOOKSDAO").read(arguments.id)>
</cffunction>
<cffunction name="save" output="false" access="remote">
<cfargument name="obj" required="true" />
<cfscript>
if( obj.getBOOKID() eq 0 )
{
return createObject("component", "BOOKSDAO").create(arguments.obj);
} else {
return createObject("component", "BOOKSDAO").update(arguments.obj);
}
</cfscript>
</cffunction>
<cffunction name="deleteById" output="false" access="remote">
<cfargument name="id" required="true" />
<cfset var obj = getById(arguments.id)>
<cfset createObject("component", "BOOKSDAO").delete(obj)>
</cffunction>
<cffunction name="getAll" output="false" access="remote" returntype="cfajaxwizard.components.cfgenerated.Book_Detail.BOOKSBean[]">
<cfset var qRead="">
<cfset var obj="">
<cfset var ret=arrayNew(1)>
<cfquery name="qRead" datasource="cfbookclub">
select BOOKID
from APP.BOOKS
</cfquery>
<cfloop query="qRead">
<cfscript>
obj = createObject("component", "BOOKSDAO").read(qRead.BOOKID);
ArrayAppend(ret, obj);
</cfscript>
</cfloop>
<cfreturn ret>
</cffunction>
<cffunction name="getAllAsQuery" output="false" access="remote" returntype="query">
<cfargument name="fieldlist" default="*" hint="List of columns to be returned in the query.">
<cfset var qRead="">
<cfquery name="qRead" datasource="cfbookclub">
select #arguments.fieldList#
from APP.BOOKS
</cfquery>
<cfreturn qRead>
</cffunction>
</cfcomponent>
If the templates were editable, you could fix this easily, but, alas, they are not. Truthfully, there
are a number of generators available in the ColdFusion open-source
world that do the job better than this one, whose only real benefit is its Eclipse integration.
AS Class Wizard
This wizard has a very limited but useful purpose. If you have a "bean" style CFC with cfproperty tags, this wizard creates a matching ActionScript class file with corresponding properties. One of the benefits of using ColdFusion with Flex is its ability to automatically translate an ActionScript class to a ColdFusion component and vice-versa. This wizard simplifies that process by allowing you to simply write the CFC and generate the AS class. Simply right-click on your CFC bean, choose "ColdFusion Wizards" and then click on the "Create AS class (based on cfc)" option. This will bring up the "Create AS File" wizard, which is just a single form to specify the location to save the file, the class package and name and the path to the corresponding CFC. Clicking on finish generates a very simple .as file with the properties of the class defined as public variables and properly typed, as well as an empty constructor. No methods other than the constructor are defined, as the translation between ColdFusion and Flex only supports properties and not methods.
Wizard Rating: This wizard forces me to reach deep for our fictional wizard references since, while it is good and generally useful, it isn't all that powerful to begin with. I have found that among the wizards listed here, this is the one I use regularly and, while it does indeed save some time, the limited scope of its purpose also limits its value. Thus, I am giving this wizard a rating of Radagast the Brown, a wizard from J. R. R. Tolkien's The Lord of the Rings, who strayed from his mission to defeat Sauron but in the end inadvertently saved Gandalf from captivity by Saruman. Yes, indeed, it's a stretch.
Conclusion
Despite my generally unfavorable ratings here, I am absolutely in favor of improved integration of ColdFusion within Flex Builder and Eclipse. These wizards would be much more useful if only the templates were editable or customizable, something I hope the ColdFusion team will address in a future release.
Comments
There are currently no comments for this entry...be the first!