Archive for November, 2010

Looping over lines in a file with cfscript

Monday, November 22nd, 2010

So the question I recently raised with myself was how would I go about looping over the contents of a file line by line using Coldfusion scripting? Well it turns out that it’s not too difficult although I did run into a small snag. First let’s look at how to loop over the lines in a file using cfscript. What I’m going to do is try to locate any ‘<cfinclude’ tags in the file being looped over and return the results.

Looping over lines

var loc_delimiter = chr(10);

var loc_numOfLines = listLen(arguments.fileData, loc_delimiter);

for(var i = 1; i <= loc_numOfLines; i = i + 1)
{
	loc_matches = {};

	loc_thisLine = listGetAt(arguments.fileData, i, loc_delimiter);

	loc_matches.line = i;
	loc_matches.matches = reMatchNoCase("<cfinclude", loc_thisLine);

	if(!arrayIsEmpty(loc_matches.matches))
	{
		arrayAppend(loc_allMatches, loc_matches);
	}
}

This assumes that file data has been read into memory using fileRead().

So our delimiter is chr(10) which means look for a new line feed. You can also use this in conjunction with the ‘return’ chr(13) to be safe. The key is to turn the file into a list delimited by the new line character and/or the carriage return character (these are the hidden characters you may have seen show up in your Word document by accidentally pressing some unknown key combination). Once we have a list we can loop through the length. For each loop we want to use the listGetAt() function to get the data on that line. Essentially and index is equal to a line in this context. We can then use a regular expression to look for any ‘<cfinclude’ matches and append them to an array if we find one.

(more…)

Using Java to compare Coldfusion objects

Monday, November 22nd, 2010

This past weekend I was building some unit tests when I came across a situation where I needed to compare two Coldfusion objects for equality. If I had a way to simply assert true the equality of two objects would make the test infinitely more simple than what it need be.

I have never really had a need to do this before and am not aware of any way in coldfusion to compare complex objects against one another. However, since CF is built on the very powerful Java libraries it didn’t take much digging to turn up the Java equals() function that accepts an object to be compared against. It essentially works with something like:

isequal = object1.equals(object2);

Pretty straight forward. Let’s look at an example illustrating how to grab this function and utilize it using Coldfusion on Coldfusion objects.

Java Equals() in Coldfusion

<!--- get the Java Comparator class --->
<cfset variables.comparator = createObject("java", "java.util.Comparator") />

<!--- build the first object --->
<cfset variables.objectOne = structNew() />
<cfset variables.objectOne.name = "matt" />
<cfset variables.objectOne.lastname = "cook" />

<!--- build the second object --->
<cfset variables.objectTwo = structNew() />
<cfset variables.objectTwo.name = "matt" />
<cfset variables.objectTwo.lastname = "cook" />

<!--- compare the objects --->
<cfset variables.isEqual = variables.objectTwo.Equals(variables.objectOne) />

<!--- output the boolean --->
<cfdump var="#variables.isEqual#" />

(more…)

Ordering an array of Objects

Monday, November 15th, 2010

So we all know that if we have an array of simple values sorting that array according to those values in Coldfusion couldn’t be easier. Using the arraySort() function will handle sorting the array fairly effortlessly on the developer’s part. However, what if you have an array of objects. Each object in the array contains a value that you want to sort by. Here things get slightly more complicated as the arraySort() function will not work in this case. However, sorting the array is still fairly simple. Before getting into this, let’s take a quick look at an array containing a set of objects with index values that need to be sorted.

Build an array with objects

<cfset variables.model = structNew() />

<cfset variables.model.data = arrayNew(1) />

<cfset variables.model.data[1] = structNew() />
<cfset variables.model.data[1].Index = 2 />

<cfset variables.model.data[2] = structNew() />
<cfset variables.model.data[2].Index = 4 />

<cfset variables.model.data[3] = structNew() />
<cfset variables.model.data[3].Index = 1 />

<cfset variables.model.data[4] = structNew() />
<cfset variables.model.data[4].Index = 3 />

This produces the following visually:

unordered array

Unordered Array of Objects

(more…)

Using the structNew() and structClear() functions

Monday, November 15th, 2010

While the structNew() and structClear() functions do relatively the same thing, one thing to keep in mind is that the structNew() function creates a new struct and the structClear() function clears a single existing struct and all of its instances. While this may seem obvious, the last part mentioned (all existing instances of a struct) can create some fairly weird scenarios if not careful.

Essentially, if a loop is created and in each loop a struct is created and stored in an array, structClear() cannot be used to refresh the struct on each loop without clearing all instances of the struct. What happens is on loop one, the struct is created and assigned a value. On loop two the struct is cleared and a new value is inserted and appended to the array. This is great except now you do not have two independent structs. Instead you have two instances of the same struct. The result is that clearing the struct not only empties both structs, but when the new value is assigned it is assigned to both structs. Now you have two structs that are identical (this is of course appropriate if all the structs should be identical and better form as they can all be updated much more efficiently). On the eighth loop you will have eight instances of the same struct.

What we want is a new struct with a different value for each loop. As such there does need to be something that resets or creates a new struct for each loop iteration. If not, you will end up with eight structs with every value assigned to them.

To do this you need to use the structNew() function as this will create a whole new struct independent of the struct created in the previous loop. This allows the variable assignment to change (in this case to a new struct) without effecting the previously stored struct. At this point only pin pointing the struct manually will allow it to be manipulated because we’re now working with a new struct in a new array index. To better understand let’s look at a couple examples of each instance.

(more…)

Case-sensitivity with Coldfusion and XML

Sunday, November 14th, 2010

This is really just a note about intermingling a case-insensitive language like Coldfusion with a case-sensitive language like XML. Sometimes I get so used to not having to pay attention to case when something goes wrong, that figuring out a simple issue that does have to do with case-sensitivity really throws me for a loop. The issue I ran into involved using the xmlSearch() function.

I used this function to search on an XML doc and the search kept returning an empty array. For a moment I thought for sure my xPath was incorrect, but further research showed it to be accurate. For some reason I just couldn’t get to a certain node. Of course, the issue turned out to be that I simply didn’t case my xPath correctly. For example my xPath may have looked like “//root/mynode”. The actual node I was trying to get in the XML doc was myNode.

Because I deal so much with Coldfusion I feel my immediate reaction to an xPath issue was that it was either wrong, or there was a misspelling. It really took a few minutes to realize that the path was correct as well as the spelling. What was incorrect was the case. Correcting the case, of course, resolved the issue.

So something to keep in mind, that while working within the world of Coldfusion case is meaningful only in terms of readability and following standards. However, when using Coldfusion with other (possibly case-sensitive) languages like XML we have to switch our brains into a different mode and start troubleshooting with character case in mind.

Using SoapUI to work with SOAP and WSDL request / responses

Tuesday, November 9th, 2010

My use of the software SoapUI has so far been minimal although I intend to further explore its capabilities, and a quick look at their website indicates that there are many. Currently I have been working with some Web Services Description Language (WSDL) documents utilizing SOAP for the service messaging. While true, a WSDL will contain all that one needs to know to invoke the web service, what if – you may ask, there was a program that could take that WSDL and create mock SOAP requests and responses based on the guidelines laid out in the WSDL.

Well, this is where the SoapUI comes into play (and as I previously stated it appears to do many other awesome things). A colleague of mine recommended using it, and it is certainly a program I will continue to utilize as it does create an easy to read set of mock requests and responses that significantly reduces the amount of time it takes to plan out a program utilizing a complex set of web services to perform.

Anyways you can read all about SoapUI on their website. Also, there is a free open source version for download at sourceforge. Enjoy!

My First CF Builder Extension

Monday, November 8th, 2010

So I decided this evening to jump on the CF Builder Extension bandwagon and give it a shot myself. A quick look at the docs and a review of some of the pre-installed extensions that come with CF Builder and I was off and running.

I decided to start simple and create an extension that will allow the user (currently me) to select a set of characters and validate it as JSON.

Setting up a new extension is as simple as creating a new project, copying one of the existing extension configuration files (ide_config.xml) and creating a/some handlers. Extensions can be managed from the Extensions view in CF Builder. So my directory structure for my extension looks like the following.

/jsonValidator
/jsonValidator/ide_config.xml
/jsonValidator/handlers
/jsonValidator/handler/validateJson.cfm
/jsonValidator/handler/cfcs
/jsonValidator/handler/cfcs/handleValidation.cfc

That is the entire directory/file structure of my extension. Actually the handleValidation.cfc is not really needed as that code could be put inside of the validateJson.cfm file, but that wouldn’t be very good practice would it??

Let’s first take a look at the ide_config.xml file.

(more…)

Note on building CF Builder Extensions

Monday, November 8th, 2010

This is just a quick note concerning how you as a developer can approach the installation process of a CF Builder extension during development. Of course, while what you will eventually distribute to the world is a zip file containing your extension it doesn’t make much sense that you would need to zip and install the extension yourself with each update that you make during the development process.

CF Builder makes this process very simple in that it re-compiles the files with each save so that you don’t even need to use the Extensions view in CF Builder (although you should do an actual overwrite using the Extensions view when you have something complete). Anyways, just wanted to make sure that it was clear that you can develop and test your extension as if you were developing and testing in the browser. It may not seem like much, but it’s actually a really cool feature that makes our lives that much easier.

Focusing on application configurability and data portability

Tuesday, November 2nd, 2010

The past half year or so of developing for a company within the boundaries of a large application that spans multiple teams and multiple languages was quite a departure from my previous few years of experience freelancing. While freelancing I happily kept within the confines of the Adobe products, and probably 95% of the time within Coldfusion. Sure I would use Javascript, HTML, and CSS, but my applications were built with Coldfusion and Coldfusion alone for the dynamic portion.

As a freelancer I built code with Coldfusion knowing it could be executed by Coldfusion. Now I have to build code that is capable of transcending development languages, as well as performing optimally in the transition. While not all code moves between the languages we work with, I have to assume that it could at some point.

Applications should be configurable to some point, and when I performed Coldfusion centric development I most likely would have built my configuration in CF. This isn’t bad if your application utilizes CF and CF alone. In fact, it is certainly the best route for performance. However, as I now know, we don’t always get to develop CF centric applications. So the question arises – how can I build a configuration and data objects that can be passed to most any language and still work?

I began to, and still primarily, use XML to build configuration settings for an application. XML is a well defined and portable format that can cross most any boundary you want it to. XML can also have transformation objects (XSLT) and schema validation (XSD) applied to it for further control. It allows the configuration options to be externalized from the core components of the application. This means that Coldfusion, .net, Java, etc. can tap into that configuration for their own use. It also means that an application does not necessarily need to be regression tested in the case that data or configuration is manipulated.

Beyond configurability, we sometimes need to maintain a log of complex data that can be read across systems. For this purpose I’ve found JSON to be most useful. It’s light-weight, super portable, and is more than capable of handling objects as character strings. Here an application built with Java can log complex objects as JSON strings. A customer-facing Coldfusion application could then parse through the logs evaluating the JSON string objects and displaying appropriately.

Lastly, using JSON or XML allows complex data to be stored in a language that is more clear than the dynamic languages. For example, I probably couldn’t just jump right into a .net object and start parsing through it and utilizing the data the same way a .net developer probably couldn’t jump into a Coldfusion object and do the same. However, it is highly likely that both the CF and .net developers both understand XML, and maybe a little less likely JSON. This means that if the object structure or data needs to change the Java, .net, or Coldfusion developer can easily make the necessary changes to the externalized XML file and assume that the processing language will be capable of handling the change.

So, just some thoughts on architecting an application in a cross-language environment, while also possibly adding externalized application configurability that certainly reduces core functionality regression testing when changes need to be made.

Switch/Case statement constants

Tuesday, November 2nd, 2010

This is more of a note than anything else concerning an error that throws when trying to run a switch case against a variable. Before analyzing this I want to simply display a function that illustrates a working switch statement, and then the same switch statement replacing the case value with a variable. Let’s take a look.

Working switch statement

public boolean function dynamicSwitch()
{
	var data1 = "matthew";
	var data2 = "cook";

	var expression = data1;

	switch(expression)
	{
		case "matthew":
		{
			return true;
		}

		default:
		{
			return false;
		}
	}
}

Throws an error

public boolean function dynamicSwitch()
{
	var data1 = "matthew";
	var data2 = "cook";

	var expression = data1;

	switch(expression)
	{
		case data1:
		{
			return true;
		}

		default:
		{
			return false;
		}
	}
}

So the second example uses the variable ‘data1′ as the value for the case. This throws a Coldfusion error indicating that case values must be constants (a hard-coded value). This makes sense, and maybe you’re wondering why a variable would ever need to be used for the case value. Admittedly, it certainly makes no sense in the above example, but I do personally like to declare all component constants at the top of my component by storing them in a ‘constant’ namespace and prefixing the variable name with a ‘c_’. Coldfusion doesn’t literally support constant variables, so having some rules around how to syntactically declare constant variables in Coldfusion makes sense to me.

So in my case I had set some constant variables in my component, and in a function needed to compare a passed in argument against them. It was a scenario where the value either would or would not equal the value of one of my constants. Hard-coding those values again for a switch statement would have been plain old bad practice. Nonetheless, it was also in this scenario that I learned I could not use a variable for my case value.

The result was that I used an if-else statement instead. It works fine. The switch statement would have been more appropriate, but take what you can get I guess.