Simple proof of concept - UML Generator

I was talking with Brian Kotek recently about a particular design issue when he suggested I make use of yUML. This is an online service that allows you to dynamically generate UML documents. UML is not something that I'm really into. I can see the benefits of it, but I just haven't felt the need yet to make it part of my development process. That being said, I thought it was pretty cool how yUML allowed you to generate a UML picture straight from a URL. If you look at their samples page, you can see how they go from a simple URL "api" to a generate graphic.

Based on that, I decided to see if I could whip up some code to examine a CFC and generate the URL. While this isn't completely useful (it only works with one CFC and doesn't handle relationships), it was fun and I thought someone may be able to play with it more. Here is the script I came up with:

<cfset meta = getComponentMetadata("test")> <cfdump var="#meta#" expand="false">

<cfset modifiers = {public="+",protected="##",private="-",package="~",remote="+"}>

<cfset rooturl = "http://yuml.me/diagram/scrufy/class/">

<!--- Name ---> <cfset rooturl &= "[" & urlEncodedFormat(meta.name) & "|">

<!--- Properties ---> <cfloop index="x" from="1" to="#arrayLen(meta.properties)#"> <cfset p = meta.properties[x]> <!--- all properties are public ---> <cfset rooturl &= "#urlEncodedFormat(modifiers.public)##p.name#;"> </cfloop>

<!--- Methods---> <cfif arrayLen(meta.functions)> <cfset rooturl &= "|"> </cfif>

<cfloop index="x" from="1" to="#arrayLen(meta.functions)#"> <cfset f = meta.functions[x]> <cfif not structKeyExists(f, "access")> <cfset f.access = "public"> </cfif> <cfset rooturl &= "#urlEncodedFormat(modifiers[f.access])##f.name#();"> </cfloop>

<cfset rooturl &= "]">

<cfoutput> #rooturl#<br/> <img src="#rooturl#"> </cfoutput>

Going from top to bottom, you can see I get the metadata for a CFC called test. If this code were converted into a UDF you would want to simply make that portion dynamic. I create a structure that maps ColdFusion's access modifiers into the symbols that yUML will use to generate the UML graphic. Since remote doesn't make sense in this context, I mapped it to public.

After that, it's simply then a matter of looping over the metadata. I start off with the properties and then handle the methods. Given this input:

<cfcomponent persistent="true">

<cfproperty name="foo" ormtype="string"> <cfproperty name="goo" ormtype="string"> <cfproperty name="aaa" ormtype="string">

<cffunction name="privatetest" access="private"> </cffunction>

<cffunction name="publictest" access="public"> </cffunction>

<cffunction name="packagetest" access="package"> </cffunction>

<cffunction name="remotetest" access="remote"> </cffunction>

</cfcomponent>

The output is:

It would probably be nice to sort the values (one thing I wish cfdump would do for CFCs). Handling relationships should - in theory - be possible. You just want to ensure you don't get into an infinite recursion loop with bidirectional relationships.

Archived Comments

Comment 1 by Ryan posted on 12/14/2009 at 8:40 PM

I love stuff like this. Were you able to break it ;).

Comment 2 by Raymond Camden posted on 12/14/2009 at 8:45 PM

You know, I'm pretty offended you would think I would try to muck with someone's URL params to see if I could "break" a site.

Geeze. ;)

Ok, no, I didn't actually. On a real quick test just now it seems as if you screw things up bad enough, they just return a blank image. No error.

Comment 3 by Mark Mandel posted on 12/15/2009 at 3:32 AM

You know I'm working on an extension to ColdDoc to allow you to generate complex UML diagrams from CFC meta data...? ;o)

Great minds must think alike.

yUML is a cool tool though! :D

Comment 4 by Raymond Camden posted on 12/15/2009 at 3:54 AM

@Mark: Hey, I'd be happy to be in the same timezone, mentally, with you. Thanks. :)