Feeds:
Posts
Comments

Modern Day Love Note


	words = [
		'more',
		'very much',
		'more every day',
		'still',
		'infinitly',
		'deeply',
		'passionitly'];
	desc = [
		'is amazing',
		'is Awesome',
		'is Blithesome',
		'is Excellent',
		'is Fabulous',
		'is Fantastic',
		'is Favorable',
		'is Fortuitous',
		'is Great',
		'is Incredible',
		'is Ineffable',
		'is Mirthful',
		'is Outstanding',
		'is Perfect',
		'is Propitious',
		'is Remarkable',
		'is Smart',
		'is Spectacular',
		'is Splendid',
		'is Stellar',
		'is Stupendous',
		'is Super',
		'is Ultimate',
		'is Unbelievable',
		'is Wondrous'];
	sentance = [];
	string = [];
	for (i=1; i LTE arrayLen(words); i++) {
		arrayAppend(string, 'I love you ');
		arrayAppend(string,words[i]);
		arrayAppend(string,'! ');
		writeOutput(arrayToList(string, '') );
		arrayClear(string);
	}
	for (i=1; i LTE arrayLen(desc); i++) {
		arrayAppend(string, 'My love for you is ');
		arrayAppend(string,desc[i]);
		arrayAppend(string,'! ');
		writeOutput(arrayToList(string, '') );
		arrayClear(string);
	}

This afternoon, I am writing some JavaScript for a CMS system and FireFox was not allways fetching the new scripts from the development server. I ran across this helpful FireFox tip and wanted to share and save on my blog.

How to force FireFox to reload the page and ignore cache

  • You can use Ctrl + F5 for a single use basis, or if you want firefox to always reload the page then type this into the address bar: about:config
  • Type this into the filter: browser.cache.check_doc_frequency
  • Change the value to: 1

Additional Values

  • 3 – only check if it seems outdated (Default Value)
  • 2 – always use cached version
  • 1 – always check for newer version
  • 0 – check for newer version once per session

This morning the 2010 Adobe Community Professionals List was posted on the Adobe Community Manager Blog. I made a quick matrix and chart of the data to answer some questions of my own and thought I would share with the community. Continue Reading »

Just a simple command that helped me today.

$ sudo rm -rf `find . -type d -name .svn`

This afternoon I encountered an error ‘A CFC with entityname X could not be found’ as I was working on a new campaign entity for our Adwords campaign. For GCA.net, we are preparing to launch a AdWord campaign related to the new RedHat JBoss Bootcamp Training classes that are almost public. We also happen to be in the middle of the SugarCRM release to the Sales staff which is causing lots of interruptions. Continue Reading »

Hyrule, by Dan Vega, is pretty cool. Using some simple metadata in your ORM Entities or CFCs you can enable Hyrule validation. It is quite an elegant object data validator and I have switched to it on my newest project. If you are using ColdFusion 9 and rapidly developing applications with the new ORM Hybernate features then I highly recommend you take advantage of Dan’s generosity and adopt use of Hyrule.

When evaluating the code I discovered two minor bugs and sent the corrections to the author, Dan Vega (who has some sweet projects). The biggest issue was that the validation results where stored in the instance of Hyrule which made it unsafe to persist in a non request specific scope. Since I am a big ColdBox Framework fan, which makes caching objects so much fun, I just can’t allow a utility like like Hyrule to exist and not be a singleton. So, I made some changes and e-mailed them to Dan Vega two weeks ago.

Tonight, I made some additional changes to Hyrule. This time, I added some recursive crawling to the object being validated to support extended properties (the second bug I found). Hyrule can now validate the object passed into it and the properties set into the instance of the extended objects. I have yet to hear back from Dan Vega from my code suggestion a few weeks ago so I thought I’d post the code here for consumption and for safe keeping in case I suffer some SVN meltdown.

ValidatorResults.cfc
This is a new file which must be passed into the Hyrule Validate method.

/**
 * @displayname Hyrule Validator Errors
 * @hint I am the thread safe error component. I am intended to be created in a thread safe scope such as local or request
 * @accessors true
 * @output false
 */
component {

	/**
	* @hint The array which will contain errors found by Hyrule
	*/
	property array errors;

	public function init(){
		setErrors([]);
		return this;
	}

	/**
	 * @hint A way to see if the validate method produced any errors.
	 */
	public boolean function hasErrors(){
		return arrayLen( getErrors() ) > 0;
	}

	/**
	 * @hint adds an error to the errors array
	 */
	public void function addError(String property,String Message,String display){
		var s = {property=arguments.property,message=arguments.message,display=arguments.display};
		arrayAppend(getErrors(),s);
	}

}

Validator.cfc
This is the primary method for Hyrule

/**
 * @displayname Hyrule Validator
 * @hint I am the main component for the Hyrule Validation Framework
 * @accessors true
 * @output false
 */
component {

	/**
	 * @hint I am the name of the properties file that contains our default messages
	 */
	property string resourceBundle;

	/**
	 * @hint I am the ValidatorMessage Component - I handle the loading and retrieval of messages.
	 */
	property ValidatorMessage validatorMessage;

	public Validator function init(String rb="DefaultValidatorMessages",Boolean isAbsolutePath=false){
		this.setResourceBundle(arguments.rb);
		this.setValidatorMessage(new ValidatorMessage(arguments.rb));
		return this;
	}

	public void function validate(dto, validatorResults){
		var props = getPropertiesRecusivly( arguments.dto );

		/* LOCAL SCOPE */
		var i 	= 0;
		var key = '';

		// for each property in the array
		for(i=1; i <= arrayLen(props); ++i) {

			// the current property struct
			var prop = props[i];
			// the name of the current property
			var name = prop["name"];

			// the value of the property
			//var val = arguments.dto.getPropertyValue(name);
			var val =  evaluate("arguments.dto." & "get#name#()");
			// the display name of the property
			var display = getDisplay(prop);

			if(structKeyExists(prop,"message")){
				var perPropertyMessage = prop.message;
			}

			// loop over each key/pair value in the property
			for(key in prop){

				// based on the type we can grab our default message template from
				// our properties file that was loaded
				var message = isDefined("perPropertyMessage") ? perPropertyMessage : getValidatorMessage().getMessageByType(key);

				switch(key){

					case "NOTNULL" : {
						var notNullValidator = new validator.NotNullValidator();
						if( isNull(val) ){
							// if notnull != true then we are just making sure its not null
							validatorResults.addError(name,notNullValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "NOTEMPTY" : {
						var notEmptyValidator = new validator.NotEmptyValidator();
						if(!notEmptyValidator.isValid(prop,val)){
							validatorResults.addError(name,notEmptyValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "MIN" : {
						var minValidator = new validator.MinValidator();
						if( !minValidator.isValid(prop,val) ){
							validatorResults.addError(name,minValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "MAX" : {
						var maxValidator = new validator.MaxValidator();
						if( !maxValidator.isValid(prop,val) ){
							validatorResults.addError(name,maxValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "RANGE" : {
						var rangeValidator = new validator.rangeValidator();
						if( !rangeValidator.isValid(prop,val) ){
							validatorResults.addError(name,rangeValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "SIZE" : {
						var sizeValidator = new validator.sizeValidator();
						if( !sizeValidator.isValid(prop,val) ){
							validatorResults.addError(name,sizeValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "INLIST" : {
						var inListValidator = new validator.InListValidator();
						if( !inListValidator.isValid(prop,val) ){
							validatorResults.addError(name,inListValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "NOTINLIST" : {
						var notInListValidator = new validator.NotInListValidator();
						if( !notInListValidator.isValid(prop,val) ){
							validatorResults.addError(name,notInListValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "ISMATCH" : {
						var compareto = prop.isMatch;
						//var comparetoValue = arguments.dto.getPropertyValue(prop.isMatch);
						var comparetoValue =  evaluate("arguments.dto." & "get#prop.isMatch#()");
						prop.comparetoValue = comparetoValue;

						var isMatchValidator = new validator.isMatchValidator();
						if( !isMatchValidator.isValid(prop,val) ){
							validatorResults.addError(name,isMatchValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "PAST" : {
						var pastValidator = new validator.PastValidator();
						if( !pastValidator.isValid(prop,val) ){
							validatorResults.addError(name,pastValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "FUTURE" : {
						var futureValidator = new validator.FutureValidator();
						if( !futureValidator.isValid(prop,val) ){
							validatorResults.addError(name,futureValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "PATTERN" : {
						var patternValidator = new validator.PatternValidator();
						if( !patternValidator.isValid(prop,val) ){
							validatorResults.addError(name,patternValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "ASSERTTRUE" : {
						var assertTrueValidator = new validator.AssertTrueValidator();
						if( !assertTrueValidator.isValid(prop,val) ){
							validatorResults.addError(name,assertTrueValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}
					case "ASSERTFALSE" : {
						var assertFalseValidator = new validator.AssertFalseValidator();
						if( !assertFalseValidator.isValid(prop,val) ){
							validatorResults.addError(name,assertFalseValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "UPPERCASE" : {
						var uppercaseValidator = new validator.UpperCaseValidator();
						if( !uppercaseValidator.isValid(prop,val) ){
							validatorResults.addError(name,uppercaseValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "LOWERCASE" : {
						var lowercaseValidator = new validator.LowerCaseValidator();
						if( !lowercaseValidator.isValid(prop,val) ){
							validatorResults.addError(name,lowercaseValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "PASSWORD" : {
						var passwordValidator = new validator.passwordValidator();
						if( !passwordValidator.isValid(prop,val) ){
							validatorResults.addError(name,passwordValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					// the following all validate using isValid but are broken into custom validators
					// in case you want to overwrite or extend thme to provide customer functionality

					case "EMAIL" : {
						var emailValidator = new validator.emailValidator();
						if( !emailValidator.isValid(prop,val) ){
							validatorResults.addError(name,emailValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "CREDITCARD" : {
						var creditCardNumberValidator = new validator.CreditCardNumberValidator();
						if( !creditCardNumberValidator.isValid(prop,val) ){
							validatorResults.addError(name,creditCardNumberValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "SSN" : {
						var ssnValidator = new validator.SSNValidator();
						if( !ssnValidator.isValid(prop,val) ){
							validatorResults.addError(name,ssnValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "PHONE" : {
						var phoneValidator = new validator.PhoneValidator();
						if( !phoneValidator.isValid(prop,val) ){
							validatorResults.addError(name,phoneValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "ZIPCODE" : {
						var zipCodeValidator = new validator.ZipCodeValidator();
						if( !zipCodeValidator.isValid(prop,val) ){
							validatorResults.addError(name,zipCodeValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "DATE" : {
						var dateValidator = new validator.DateValidator();
						if( !dateValidator.isValid(prop,val) ){
							validatorResults.addError(name,dateValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "ARRAY" : {
						var arrayValidator = new validator.ArrayValidator();
						if( !arrayValidator.isValid(prop,val) ){
							validatorResults.addError(name,arrayValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "STRUCT" : {
						var structValidator = new validator.StructValidator();
						if( !structValidator.isValid(prop,val) ){
							validatorResults.addError(name,structValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "BOOLEAN" : {
						var booleanValidator = new validator.BooleanValidator();
						if( !booleanValidator.isValid(prop,val) ){
							validatorResults.addError(name,booleanValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "QUERY" : {
						var queryValidator = new validator.QueryValidator();
						if( !queryValidator.isValid(prop,val) ){
							validatorResults.addError(name,queryValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "URL" : {
						var urlValidator = new validator.URLValidator();
						if( !urlValidator.isValid(prop,val) ){
							validatorResults.addError(name,urlValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "UUID" : {
						var uuidValidator = new validator.UUIDValidator();
						if( !uuidValidator.isValid(prop,val) ){
							validatorResults.addError(name,uuidValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "GUID" : {
						var guidValidator = new validator.GUIDValidator();
						if( !guidValidator.isValid(prop,val) ){
							validatorResults.addError(name,guidValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "BINARY" : {
						var binaryValidator = new validator.binaryValidator();
						if( !binaryValidator.isValid(prop,val) ){
							validatorResults.addError(name,binaryValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "NUMERIC" : {
						var numericValidator = new validator.numericValidator();
						if( !numericValidator.isValid(prop,val) ){
							validatorResults.addError(name,numericValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "STRING" : {
						var stringValidator = new validator.stringValidator();
						if( !stringValidator.isValid(prop,val) ){
							validatorResults.addError(name,stringValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

					case "CUSTOM" : {
						// TODO: We should throw a custom error here if the component was not found
						var customValidator = createObject("component","#prop.custom#");
						if( !customValidator.isValid(prop,val) ){
							validatorResults.addError(name,customValidator.getMessage(prop,message),display);
							break;
						}
						break;
					}

				}
			}

		}
	}

	/**
	 * @hint This utility function will look at a property to determine what the display name should be.
	         If a display attribute is provided it will use that if not it just uses the property name.
	 */
	private string function getDisplay(Struct prop){
		var display = "";
		if(structKeyExists(arguments.prop,"display")){
			display = arguments.prop.display;
		} else {
			display = arguments.prop.name;
		}
		return display;
	}

	private array function getPropertiesRecusivly(required dto) {
		var metadata = getMetaData(arguments.dto);
		var properties = [];
		/*	Create an array of the first level object properties. We need to create our own array too allow us to append
		 *	it in extended objects. The array returned from the getMetaData method does not support growth */

		var p = getMetaData(arguments.dto).properties;

		for (LOCAL.i=1; LOCAL.i <= arrayLen(p); LOCAL.i++) {
			arrayAppend(properties, p[LOCAL.i]);
		}

		activeMetadata = metadata;
		do {
			extensionExists = structKeyExists(activeMetadata, 'extends') AND activeMetadata.extends.name != 'WEB-INF.cftags.component';
			if ( extensionExists ) {
				// Recursivly reassign the active metadata struct
				activeMetadata = activeMetadata.extends;
				for (LOCAL.i = 1; LOCAL.i <= arrayLen(activeMetadata.properties); LOCAL.i++) {
					arrayAppend(properties, activeMetadata.properties[LOCAL.i]);
				}
			}
		} while (extensionExists);

		return properties;
	}
}

Hello World 2.0

My previous host, GearWorx, has failed terribly. In mid-November, my server was taken down and I have yet to receive a response or a restored database. I have sent several e-mails and have not received a response. I have a feeling they are going out of business.

What did I learn?

If it can–it will happen to you. So, always backup your database on a frequent schedule–even for your small personal projects.

I’m now hosting on WordPress and will begin my blog from scratch for 2010.