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.