UDF: pcase() - Captilize first letter of each word in a string

ColdFusion, Tips and Tricks, Technology, CFML, UDF
This is a UDF that I keep on hand for converting strings to "proper case", such as a person's name.  For instance, in a database we might have a name stored like DAVID B. SHUCK, but when they log into our site and we welcome them, we don't necessarily want to shout it at them!   Saying "Hello David B. Shuck..." would hopefully be a bit less abrasive. 

Enter the user-defined function pcase().  Through the use of regular expressions we are doing a search for word patterns and capitalizing the first letter in each word.  Enjoy!




<cffunction name="pcase" access="public" output="false" returntype="string">
    <cfargument name="string" type="string" required="true" />
    <cfreturn REReplaceNoCase(LCase(arguments.string),"(^[a-z*]|[ *][a-z*])","\U\1\E","all") />
</cffunction>

Implicit constructor and CF9 style implicit accessors without ColdFusion 9

ColdFusion, Tips and Tricks, Technology, CFML
One of the broadly welcomed features of ColdFusion 9 has been the addition of implicit getters and setters to CFCs.  What this means is that you no longer have to hand code the repetitive boiler plate getXXX() and setXXX() methods for each property in your model objects. However, you don't need ColdFusion 9, (or even ColdFusion for that matter) to enjoy the benefits of the new implicit accessors with the version 9 release.  Since ColdFusion 8, developers have had access to the OnMissingMethod() method which makes tasks like this very simple to implement on your own.  The OnMissingMethod is also available in current versions of OpenBlueDragon and Railo.

For my implementation of this, I use a standard BaseBean class in a number of my projects which is extended by all of my model class objects.  By leveraging the OnMissingMethod() in this BaseBean, I create these implicit accessors, in addition to an implicit constructor init() method as well.

There are multiple examples on the internet that show how you can use OnMissingMethod(), but for the most part, the examples that I have come across do not protect the class from being having infinite previously undefined properties added to it from the outside.  For instance, I could have a class named Person.cfc with define properties of "firstName" and "lastName", but nothing would stop someone from doing Person.setThisIsNotAProperty(true) and that value would be dynamically added to the Person instance.  While some might argue that the flexibility that this approach offers is a positive thing, I prefer to lock my classes down just a bit more.  For instance I like the fact that I can open up a model class and see exactly what properties it can contain with clearly defined <cfproperty/> tags.   From a maintainability standpoint the idea of "mystery" dynamic properties strike me as just wrong.

For my implicit constructor, I take an approach where I loop through any named arguments that were passed, and if the name matches a property that I have defined with <cfproperty/>, then it will be passed to a setter method.  Any arguments that are passed that are not defined as a property are discarded.

So let's take a look at what this looks like.  First I will paste the entire BaseBean, and below we will break it apart to discuss what is going on.
<cfcomponent output="false">
	
		
	<cffunction name="init" access="public" output="false" returntype="BaseBean">
		<cfset var i = "" />
		<cfset initializePropertyList() />
		<cfloop list="#this.propertyList#" index="i">
			<cfif StructKeyExists(arguments,i)>
				<cfset set(i,arguments[i]) />
			</cfif>
		</cfloop>		
		<cfreturn this />
	</cffunction>
	
	
	<cffunction name="initializePropertyList" access="private" output="false" returntype="void">
		<cfset var i = "" />
		<cfif NOT StructKeyExists(this,"propertyList")>
			<cfset this.propertyList = "" />
			<cfif ArrayLen(GetMetadata(this).properties)>
				<cfloop from="1" to="#ArrayLen(GetMetadata(this).properties)#" index="i">
					<cfset this.propertyList = ListAppend(this.propertyList,GetMetadata(this).properties[i].name)>
				</cfloop>
			</cfif>
		</cfif>		
		<cfreturn />	
	</cffunction>


	
	<cffunction name="onMissingMethod" access="public" output="false" returntype="any">
		<cfargument name="missingMethodName" type="string" required="true" />
		<cfargument name="missingMethodArguments" type="struct" required="true" />
		
		<cfset var property = "" />
								
		<cfif ReFindNoCase("^[gs](et)",arguments.missingMethodName)>
			<cfset property = ReReplaceNoCase(arguments.missingMethodName,"^[gs](et)","") />
			<cfset initializePropertyList() />

			<cfif ListFindNoCase(this.propertyList,property)>
				<cfif StructIsEmpty(arguments.missingMethodArguments)>
					<cfreturn get(property) />
				<cfelse>
					<cfset set(property,arguments.missingMethodArguments[1]) />
					<cfreturn this />
				</cfif>	
			<cfelse>
				<cfthrow message="The class #GetMetadata(this).name# does not have a property named #property# so the implicit #arguments.missingMethodName#() method is not available." />		
			</cfif>

		</cfif>	
		<cfreturn />	
	</cffunction>
	
	<cffunction name="get" access="public" output="false" returntype="any">
		<cfargument name="property" type="string" required="true" />
		<cfset var value = "" />
				
		<cfset value = variables[arguments.property] />
			
		<cfreturn value />	
	</cffunction>
	
	<cffunction name="set" access="public" output="false" returntype="void">
		<cfargument name="property" type="string" required="true" />
		<cfargument name="value" type="any" required="true" />
		
		<cfset variables[arguments.property] = arguments.value />
		
		<cfreturn />
	</cffunction>
	
</cfcomponent>

Before we walk through the actual flow, I would like to point out the method initializePropertyList() that you see here:
<cffunction name="initializePropertyList" access="private" output="false" returntype="void">
	<cfset var i = "" />
	<cfif NOT StructKeyExists(this,"propertyList")>
		<cfset this.propertyList = "" />
		<cfif ArrayLen(GetMetadata(this).properties)>
			<cfloop from="1" to="#ArrayLen(GetMetadata(this).properties)#" index="i">
				<cfset this.propertyList = ListAppend(this.propertyList,GetMetadata(this).properties[i].name)>
			</cfloop>
		</cfif>
	</cfif>		
	<cfreturn />	
</cffunction>

By using the GetMetadata() function, we are able to introspect our instance and create a list of property names which we can reference in our other methods.  This is what enables us to enforce the rules that I described above in which we make sure that a property exists before setting it in the constructor or through an implicit accessor.  You will see in both the init() and OnMissingMethod() methods that we call this method to ensure the list of properties is available before testing against it.

With that established, let's take a look at the init() constructor method:
<cffunction name="init" access="public" output="false" returntype="BaseBean">
	<cfset var i = "" />
	<cfset initializePropertyList() />
	<cfloop list="#this.propertyList#" index="i">
		<cfif StructKeyExists(arguments,i)>
			<cfset set(i,arguments[i]) />
		</cfif>
	</cfloop>		
	<cfreturn this />
</cffunction>

After making sure that our propertyList has been initialized, we loop through that list and if there is a matching named argument, we call the set() method which sets that value into the variables scope.

So with the object initialized, let's take a look at our accessors.  For our example, let's say that we have a Person object and we are doing to set our firstName property like this: person.setFirstName("Dave").  Since that setter method doesn't exist in our Person class, the OnMissingMethod() below will be invoked. 
<cffunction name="onMissingMethod" access="public" output="false" returntype="any">
	<cfargument name="missingMethodName" type="string" required="true" />
	<cfargument name="missingMethodArguments" type="struct" required="true" />
	
	<cfset var property = "" />
							
	<cfif ReFindNoCase("^[gs](et)",arguments.missingMethodName)>
		<cfset property = ReReplaceNoCase(arguments.missingMethodName,"^[gs](et)","") />
		<cfset initializePropertyList() />

		<cfif ListFindNoCase(this.propertyList,property)>
			<cfif StructIsEmpty(arguments.missingMethodArguments)>
				<cfreturn get(property) />
			<cfelse>
				<cfset set(property,arguments.missingMethodArguments[1]) />
				<cfreturn this />
			</cfif>	
		<cfelse>
			<cfthrow message="The class #GetMetadata(this).name# does not have a property named #property# so the implicit #arguments.missingMethodName#() method is not available." />		
		</cfif>

	</cfif>	
	<cfreturn />	
</cffunction>

We are then doing a regular expression test to see if the missing method names starts with either "get" or "set".  If so, we derive the name of the target property by stripping the "get" or "set" off of the string.  After making sure that our propertyList has been defined, we then look in that list to see if the target property actually exists in the instance.  If it does, the request is then routed on to either the getter or the setter depending on whether arguments were passed to it.  Otherwise an exception will be thrown to let the developer know that he or she has attempted to access an undefined property.

One thing you might notice is that when our conditional block routes the request to the setter, we return an instance of the class itself.  This allows us to do method chaining like this:  person.setFirstName("Dave").setLastName("Shuck").  it should be noted that this is not the approach that Adobe took with ColdFusion 9.

So let's take a look at it in action.  Here is our Person.cfc class.
<cfcomponent output="false" extends="BaseBean">
	
	<cfproperty name="id" type="string" />
	<cfproperty name="firstName" type="string" />
	<cfproperty name="lastName" type="string" />
	
</cfcomponent>

As you can see in the <cfcomponent/> tag, we are extending our BaseBean which is all that we need to have a workable domain class object.

When we put this together and access it in our code, we can do this:
<cfset person = CreateObject("component","Person").init(id=7,firstName="Dave", lastName="Shuck") />

<cfdump var="#person#" />



Once we have an instance, we can modify those properties like so:
<cfset person.setId(8).setFirstName("Johnny").setLastName("Rotten") />



I have not actually tested this on Railo, but I can confirm that it works in OpenBlueDragon (including GAE version), and ColdFusion versions 8 and 9. 


0

Create SSL sites in Apache on Windows with OpenSSL

Tips and Tricks, Servers, Windows, Technology
To get a secure SSL site up and running on Apache under Windows, there are a few hoops to jump through that are not very intuitive.  To that end, I am going to document my approach to setting up SSL using OpenSSL.  This approach assumes that you already have Apache up and running on your machine, so if you have not done that, head over to the HTTPD download page and set that up before continuing.

  • Setting up OpenSSL
    First we need to get OpenSSL setup on our system, which is not included with the Apache Windows binaries.  In fact the OpenSSL project doesn't even provide the binaries themselves, but you can find them at Shining Light Productions.  For this example, I will be choosing the Win32 OpenSSL v0.9.8k Light version.  If you see a message like the one below, you will need to install the Microsoft Visual C++ 2008 Redistributable Package and then attempt the OpenSSL installation again.

     

    Once you have it installed, you can do a quick test to make sure that it is set up properly:



  • Creating Certificates
    Next, we will use the OpenSSL terminal interface to create our self-signed certificates.  To explain a bit about what is going on below, I have a site already existing on my system that can be reached at http://scribble.  What we are doing is creating a secure subdomain of https://secure.scribble.   Typically when I create certificates, I name the files with the host/domain obvious so that they can be easily identified later.  Obviously you will want to replace the domain name to match your setup, but type the following in the terminal in the OpenSSL/bin directory:

    openssl req -new -out secure.scribble.csr -keyout secure.scribble.pem


    That will generate what you see below.



    You may notice that I left a lot of the prompts blank.  Considering this is a dummy certificate in a development environment, that approach makes sense.  You may choose to be more explicit based on your needs.


    If we were to use this key as it is, we would be prompted for the password every time that Apache starts.  Since that is less than ideal, we will now generate a non-protected key from the one we created in the previous step by typing the following:

    openssl rsa -in secure.scribble.pem -out secure.scribble.key





    You can see that I was prompted for a pass phrase.  This is the same password that you created when we generated the certificate above.


    Now we need to need to build the certificate that we will actually import into Apache.  You can do so by typing:

    openssl x509 -in secure.scribble.csr -out secure.scribble.cert -req -signkey secure.scribble.key -days 1000


    This will result in the following output:



    You can see that we now have a .cert, .csr, .key, and .pem file for our domain.  We will use a combination of the .key and the .cert

  • Configuring Apache
    Now we need to make sure that your Apache server is ready to serve SSL requests. 

    First, let's put the .key and .cert files that we created above into a directory under Apache.  In your "conf" directory, create a subdirectory named "ssl" and move secure.scribble.key and secure.scribble.cert into that new directory.

    Next we need to make sure that the mod_ssl module is enabled.  Open up the httpd.conf file for your Apache webserver.  Search for "mod_ssl" and you should find a line that looks like this:



    Yours will likely be commented out with a '#' sign in front of the line.  You will want to delete that '#' so that it looks like the highlighted line above.

    Next you will need to make sure that you have uncommented the line that includes the httpd-ssl.conf file like you see below:



    The last thing we need to do is configure our site.  Open up the conf/extra/httpd-ssl.conf file in an editor.  You will see that there is an amazingly huge and complex site definition in there already that starts with and ends about 150 lines later with .  We need to disable this site.  If you are feeling bold, you can simply delete it.  However, I take the approach of commenting it out entirely so that I still have it as a reference, which is my recommendation as well.   Starting with the line , put a '#' at the start of every line that doesn't already have one and continue until you comment out the line.

    Now it is finally time for us to create the site definition for our https://secure.scribble site.  We will use some of the concepts in the example, but eliminate most of them.  Here is what mine looks like after paring down all the excess:
    <VirtualHost *:443>
    DocumentRoot "C:/www/scribble"
    ServerName secure.scribble:443
    SSLEngine on
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    SSLCertificateFile conf/ssl/secure.scribble.cert
    SSLCertificateKeyFile conf/ssl/secure.scribble.key
    </VirtualHost>    


    In that code you can see where we are pointing to the .key and .cert files that we created above. 

    Now, restart your Apache server and you are now serving up securely!




Photos from the Dallas Adobe User Group Tour event

InstantSpot, Tips and Tricks

We had a great time Friday night with around 170 in attendance!  Terry did a great job and everyone left hungry for the new releases that he teased.  Here are some pics from the night.

 

How to set JAVA_HOME environment variable in Ubuntu

Ubuntu, Tips and Tricks

I am actually creating this blog entry as a bookmark for myself, but since I know that I never remember how to do it, others might benefit as well!

One way that you can set your JAVA_HOME variable and add to your PATH, is be doing the folowing.  As 'sudo' open up /etc/bash.bashrc and add the following to the end of the file.  NOTE: Set the java path to whatever the actual path is on your environment if it does not match /usr/lib/jvm/java

JAVA_HOME=/usr/lib/jvm/java
export JAVA_HOME
PATH=$PATH:$JAVA_HOME/bin
export PATH

When you reboot, try running the following:

$ echo $JAVA_HOME
/usr/lib/jvm/java
 echo $PATH
[probably lots of paths]:/usr/lib/jvm/java/bin

tags:
Ubuntu, JAVA_HOME

Setting up Apache, OpenBD, Railo, and ColdFusion - Part 1

ColdFusion, Tips and Tricks, Servers

This is Part 1 of a muilt-part blog post demonstrating how run OpenBlueDragon, Railo, and ColdFusion all on the same machine, and all using the Apache webserver with individual Virtual hosts using different CFML engines.  But, before we get into it, here is a little background.

For the past several months now I have stepped over to Windows on my laptop after years of not using it regularly.  It was actually the first time I had actually used Vista, actually and was quite an interesting experience.  First, as much as I love the Linux environment, I really expected to loathe being in Windows daily.  I was surprised at how much Vista *didn't* suck.  With all the raging passion against it in general I suppose that I had low expectations, but nevertheless I really thought it was pretty decent in general.  However it has a more sluggish, constricting feel to it in comparison to Linux, so I have decided I have paid my dues and it is time to go back to using an OS that is truly fun to use, rather than one that just wasn't as crappy as I thought it would be. 

After lots of experimentation with various flavors, hands-down Ubuntu is the most painless and most comfortable Linux distros for me personally.  My reasoning for that is vast and probably belongs in another blog entry, so I will attempt to keep from straying any further off the topic!  That said, last night I decided to try gOS which is a really neat distro built off of Ubuntu.  Although the UI is Gnome based, it has more of a Max 10.5.x feel to it.  I think Mac folks would feel right at home taking this environment for a spin.

Immediately after the first boot of my shiny new OS I started trying to put my development environment back together.  I decided that I wanted to have ColdFusion, Railo, and OpenBD all on from the beginning, with all requests first passing through Apache httpd.  Quite some time ago, Aaron Lynch put together some steps to install Smith Project w/Tomcat/Apache, which we have used several times since, primarily setting up Railo. I am not sure I ever would have waded my way through it without his early experimentation and documentation.  On this iteration, I loosely followed those instructions, opting for several packages from the repos, and updated versions of software, and have documented my steps as the are somewhat different in areas. For my current environment, I first installed OpenBD.  I then followed this by installing ColdFusion and setting it up to user the default JRUN connector that is set up during the installation.  Lastly, I installed Railo as another webapp in Tomcat and tied that into Apache as well. 

In the following posts, you will see these steps in detail.


Next:  Part 2 - Installing Tomcat/Apache/OpenBD


Search

Various Links

HikeTheCanyon.org - Rim-to-Rim hike of the Grand Canyon.
Dave Shuck on Twitter - Follow me on Twitter.
Scriptalizer - Minify your Javascript and CSS