Listing 1.

<cfcomponent displayname="Base Object" hint="I provide the base methods for Iterating Business Objects (IBOs). DO
 NOT EDIT.">

<cffunction name="init" returntype="BaseObject" access="public" output="false" hint="I initialize the base object
 with application specific parameters.">
	<cfscript>
		variables.IteratorRecord = 1;
		variables.gettableAttributeList = "*";
		variables.settableAttributeList = "*";
	</cfscript>
	<cfreturn This>
</cffunction>

<cffunction name="get" returntype="any" access="public" output="false" hint="I am a generic getter that handles
 getting of all attributes. I confirm they are gettable, try to use a custom method, and if that fails, I just ask
  access() to get the attribute value directly.">
	<cfargument name="AttributeName" type="string" required="yes" hint="The name of the attribute to get">
	<cfscript>
		var Local = StructNew();
		If (ListFindNoCase(variables.gettableAttributeList,arguments.AttributeName) OR variables.gettableAttributeList
		 EQ "*")
		{
			// The method should be run
			if (structKeyExists(variables,"get#arguments.AttributeName#"))
			{
				// There is a custom method, use it
				Local.ReturnValue = evaluate("variables.get#arguments.AttributeName#()");
			}
			Else
			{
				// Otherwise just pull the attribute using private "access" method
				Local.ReturnValue = variables.access(arguments.AttributeName);
			};
		}
		Else
		{
			// The attribute is private (or invalid)
			Local.ReturnValue = "";
		};
	</cfscript>
	<cfreturn Local.ReturnValue>
</cffunction>

<cffunction name="set" returntype="any" access="public" output="false" hint="I am a generic setter that handles
 setting of all attributes. I confirm they are settable, try to use a custom method, and if that fails, I just ask
  mutate() to set the attribute value directly.">
	<cfargument name="AttributeName" type="string" required="yes" hint="The name of the attribute to set">
	<cfargument name="AttributeValue" type="any" required="yes" hint="The value of the attribute to set">
	<cfscript>
		var Local = StructNew();
		If (ListFindNoCase(variables.settableAttributeList,arguments.AttributeName) OR variables.settableAttributeList
		 EQ "*")
		{
			// The method should be run
			if (structKeyExists(variables,"set#arguments.AttributeName#"))
			{
				// There is a custom method, use it
				Local.ReturnValue = evaluate("variables.set#arguments.AttributeName#(arguments.AttributeValue)");
			}
			Else
			{
				// Otherwise just set the attribute using private "mutate" method
				Local.ReturnValue = variables.mutate(arguments.AttributeName,arguments.AttributeValue);
			};
		}
		Else
		{
			// The attribute is private (or invalid)
			Local.ReturnValue = "";
		};
	</cfscript>
	<cfreturn Local.ReturnValue>
</cffunction>

<cffunction name="access" returntype="any" access="private" output="false" hint=" I encapsulate access to the
 attribute values within this object, accepting an attribute name and returning the appropriate attribute value.">
	<cfargument name="AttributeName" type="string" required="yes" hint="The name of the attribute to get">
	<cfset var Local = StructNew()>
	<cftry>
		<cfscript>
			// Just pull the attribute
			Local.ReturnValue = variables.Data[variables.IteratorRecord][arguments.AttributeName];
		</cfscript>
		<cfcatch>
			<cfset Local.ReturnValue = "">
		</cfcatch>
	</cftry>
	<cfreturn Local.ReturnValue>
</cffunction>

<cffunction name="mutate" returntype="any" access="private" output="false" hint=" I encapsulate access to the
 attribute values within this object, accepting an attribute name and setting it to the provided attribute value.">
	<cfargument name="AttributeName" type="string" required="yes" hint="">
	<cfargument name="AttributeValue" type="string" required="yes" hint="">
	<cfset var Local = StructNew()>
	<cftry>
	<cfscript>
		// Just set the attribute
		variables.Data[variables.IteratorRecord][arguments.AttributeName] = arguments.AttributeValue;
	</cfscript>
		<cfcatch>
			<cfset Local.ReturnValue = "">
		</cfcatch>
	</cftry>
	<cfreturn Local.ReturnValue>
</cffunction>

<cffunction name="loadQuery" returntype="numeric" access="package" output="false" hint="I take a query and use it to
 load the business object with its data.">
	<cfargument name="Recordset" type="query" required="yes" displayname="Recordset" hint="I am the query that needs
	 to be loaded.">
	<cfscript>
		// Based on code by Peter J. Farrell (pjf@maestropublishing.com) via cflib.org
	 	var theQuery = arguments.Recordset;
		var theStructure = StructNew();
		var cols = ListToArray(theQuery.columnlist);
		var row = 1;
		var thisRow = "";
		var col = 1;
		If (theQuery.recordcount LT 1)
		{
			theStructure[row] = variables.setDefaultValues(theQuery.columnlist);
			THIS.Recordset = theStructure[row];
		}
		Else
		{
			for(row = 1; row LTE theQuery.recordcount; row = row + 1)
			{
				thisRow = StructNew();
				for(col = 1; col LTE arraylen(cols); col = col + 1)
				{
					thisRow[cols[col]] = theQuery[cols[col]][row];
				}
				theStructure[row] = Duplicate(thisRow);
				THIS.Recordset = arguments.Recordset;
			}
		};
		variables.Data = theStructure;
		variables.NumberofRecords = Row;
		THIS.PropertyNameList = theQuery.columnlist;
		THIS.NumberofRecords = Row - 1;
	</cfscript>
	<cfreturn variables.NumberofRecords>
</cffunction>

<cffunction name="First" returntype="void" access="public" output="false" hint="I set the business object to point
 to the first record as part of the iterator functionality.">
	<cfscript>
		variables.IteratorRecord = 1;
	</cfscript>
</cffunction>

<cffunction name="Next" returntype="boolean" access="public" output="false" hint="I increment the position of the
 business object iterator, returning success or failure as a boolean. If failure (already on final record), I leave the
  count the same.">
	<cfscript>
		// Declare a local structure for all local variables
		var Local = StructNew();
		If (variables.IteratorRecord GTE variables.NumberofRecords)
		{
			Local.ReturnBoolean = false;
			variables.IteratorRecord = variables.NumberofRecords;
		}
		Else
		{
			Local.ReturnBoolean = false;
			variables.IteratorRecord = variables.IteratorRecord + 1;
		};
	</cfscript>
	<cfreturn Local.ReturnBoolean>
</cffunction>

<cffunction name="isLast" returntype="boolean" access="public" output="false" hint="I return whether the business
 object is displaying the last record or not as part of the iterator functionality.">
	<cfscript>
		// Declare a local structure for all local variables
		var Local = StructNew();
		If (variables.IteratorRecord EQ variables.NumberofRecords)
			Local.ReturnBoolean = true;
		Else
			Local.ReturnBoolean = false;
	</cfscript>
	<cfreturn Local.ReturnBoolean>
</cffunction>

</cfcomponent>