Listing 1: EmployeeCollection.cfc

<cfcomponent displayname="employeeCollection">

<cfproperty name="My" type="struct"
hint="Protected and Inheritable Instance Structure"
required="yes" default="StructNew()">
<cfproperty name="My.DSN" type="any"
hint="The DSN being queried to fill the collection"
required="no" default="Employees">
<cfproperty name="My.resultSet" type="any"
hint="The resultSet being iterated through"
required="yes" default="">

<!--- PSEUDO CONSTRUCTOR CODE --->
<cfset My = structNew()>
<cfset My.DSN = "Employees">
<cfset My.resultSet = "">

<!--- BEGIN // INITIALIZATION FUNCTIONS --->
<cffunction name="init"
access="public"
output="false"
Hint="Initializes Query object // always returns this for method chaining"
returntype="struct">
<cfargument name="department" required="false" type="string" default="">
<cfargument name="sortOrder" required="false" type="string" default="">
<!--- This is the actual implemntation!!!!
<cfquery name="qInit" datasource="#My.DSN#">
Select *
FROM Employees
<cfif arguments.department neq "">
WHERE Department = '#arguments.department#'
</cfif>
<cfif arguments.sortOrder neq "">
ORDER BY #arguments.sortOrder#
</cfif>
</cfquery>
// This is a demo implemntation!!!! --->
<cfset var qInit = querynew("location,firstName,lastName")>
<cfset queryaddrow(qInit, 3)>
<cfset QuerySetCell(qInit, "location", "Philadelphia", 1)>
<cfset QuerySetCell(qInit, "firstName", "Dave", 1)>
<cfset QuerySetCell(qInit, "lastName", "Duncan", 1)>
<cfset QuerySetCell(qInit, "location", "Louisville", 2)>
<cfset QuerySetCell(qInit, "firstName", "Elmo", 2) >
<cfset QuerySetCell(qInit, "lastName", "Smiggins", 2) >
<cfset QuerySetCell(qInit, "location", "San Diego", 3) >
<cfset QuerySetCell(qInit, "firstName", "Rita", 3) >
<cfset QuerySetCell(qInit, "lastName", "Morebeno", 3) >
<cfset My.resultSet = qInit>
<cfreturn this>
</cffunction>


<cffunction name="Iterator"
access="public"
returntype="struct">
<cfset var myIterator = createObject("component","com.myCompany.QueryIterator")>
<cfinvoke component="#myIterator#"
method="init"
collection="#my.resultset#" />
<cfreturn myIterator />
</cffunction>

</cfcomponent>



Listing 2: AbstractIterator.cfc

<cfcomponent displayname="AbstractIterator">

<cfproperty name="My" type="struct"
hint="Protected and Inheritable Instance Structure"
required="yes" default="StructNew()">
<cfproperty name="My.collection" type="any"
hint="The collection being iterated through"
required="yes" default="">
<cfproperty name="My.index" type="numeric"
hint="The current index of the my.collection"
required="no" default="0">
<cfproperty name="My.length" type="numeric"
hint="The length of my.collection"
required="no" default="0">
<cfproperty name="My.currentItem" type="any"
hint="The item at the current index of my.collection"
required="no" default="">

<cfset my = structNew()>
<cfset my.collection = "">
<cfset my.index = 0>
<cfset my.length = 0>
<cfset my.currentItem = "">

<cffunction name="init" 
access="public"
output="false"
Hint="Initializes Iterator object // always returns this">
<cfabort showerror="Error: This Method is Abstract and must be overridden">
</cffunction>

<cffunction name="hasNext"
access="public"
returntype="boolean">
<cfif my.length GTE my.index + 1>
<cfreturn true>
<cfelse>
<cfreturn false>
</cfif>
</cffunction>

<cffunction name="next"
access="public"
returntype="any">
<cfabort showerror="Error: This Method is Abstract and must be overridden">
</cffunction>

</cfcomponent>




Listing 3: ListIterator.cfc

<cfcomponent displayname="ListIterator" extends="AbstractIterator">

<cfset my.delimiters = "">

<cffunction name="init"
access="public"
output="false"
Hint="Initializes ListIterator object // always returns this for method chaining"
returntype="struct">
<cfargument name="collection" type="string" required="true">
<cfargument name="delimiters" type="string" required="false" default=",">
<cfset my.collection = arguments.collection>
<cfset my.delimiters = arguments.delimiters>
<cfset my.length = listlen(my.collection, my.delimiters)>
<cfreturn this>
</cffunction>

<cffunction name="next"
access="public" output="true">
<cfif this.hasNext()>
<cfset my.index = my.index + 1>
<cfset my.currentItem = ListGetAt(my.collection, my.index , my.delimiters)>
</cfif>
<cfreturn my.currentItem>
</cffunction>

</cfcomponent>




Listing 4: ArrayIterator.cfc

<cfcomponent displayname="ArrayIterator" extends="AbstractIterator">

<cffunction name="init"
access="public"
output="false"
Hint="Initializes ArrayIterator object // always returns this for method chaining"
returntype="struct">
<cfargument name="collection" type="array" required="true">
<cfset my.collection = arguments.collection>
<cfset my.length = arraylen(my.collection)>
<cfreturn this>
</cffunction>

<cffunction name="next"
access="public">
<cfif this.hasNext()>
<cfset my.index = my.index + 1>
<cfset my.currentItem = my.collection[my.index]>
</cfif>
<cfreturn my.currentItem>
</cffunction>

</cfcomponent>





Listing 5: QueryIterator.cfc 

<cfcomponent displayname="QueryIterator" extends="AbstractIterator">

<cffunction name="init"
access="public"
output="false"
Hint="Initializes QueryIterator object // always returns this for method chaining"
returntype="struct">
<cfargument name="collection" type="query" required="true">
<cfset my.collection = duplicate(arguments.collection)>
<cfset my.length = my.collection.recordcount>
<cfset my.currentItem = structNew()>
<cfreturn this>
</cffunction>

<cffunction name="next"
access="public">
<cfif this.hasNext()>
<cfset my.index = my.index + 1>
<cfset Columns = listToArray(my.collection.columnList)>
<cfloop from="1" to="#arraylen(Columns)#" index="field">
<cfset my.currentItem[Columns[field]] = my.collection[Columns[field]][my.index]>
</cfloop>
</cfif>
<cfreturn my.currentItem>
</cffunction>

</cfcomponent>





Listing 6: EmployeeCollection_InitOnly.cfc

<cfcomponent displayname="employeeCollection">

<cfproperty name="My" type="struct"
hint="Protected and Inheritable Instance Structure"
required="yes" default="StructNew()">
<cfproperty name="My.DSN" type="any"
hint="The DSN being queried to fill the collection"
required="no" default="Employees">
<cfproperty name="My.resultSet" type="any"
hint="The resultSet being iterated through"
required="yes" default="">

<!--- PSEUDO CONSTRUCTOR CODE --->
<cfset My = structNew()>
<cfset My.DSN = "Employees">
<cfset My.resultSet = "">

<!--- BEGIN // INITIALIZATION FUNCTIONS --->
<cffunction name="init"
access="public"
output="false"
Hint="Initializes Query object // always returns this for method chaining"
returntype="struct">
<cfargument name="department" required="false" type="string" default="">
<cfargument name="sortOrder" required="false" type="string" default="">
<!--- This is the actual implemntation!!!!
<cfquery name="qInit" datasource="#My.DSN#">
Select *
FROM Employees
<cfif arguments.department neq "">
WHERE Department = '#arguments.department#'
</cfif>
<cfif arguments.sortOrder neq "">
ORDER BY #arguments.sortOrder#
</cfif>
</cfquery>
// This is a demo implemntation!!!! --->
<cfset var qInit = querynew("location,firstName,lastName")>
<cfset queryaddrow(qInit, 3)>
<cfset QuerySetCell(qInit, "location", "Philadelphia", 1)>
<cfset QuerySetCell(qInit, "firstName", "Dave", 1)>
<cfset QuerySetCell(qInit, "lastName", "Duncan", 1)>
<cfset QuerySetCell(qInit, "location", "Louisville", 2)>
<cfset QuerySetCell(qInit, "firstName", "Elmo", 2) >
<cfset QuerySetCell(qInit, "lastName", "Smiggins", 2) >
<cfset QuerySetCell(qInit, "location", "San Diego", 3) >
<cfset QuerySetCell(qInit, "firstName", "Rita", 3) >
<cfset QuerySetCell(qInit, "lastName", "Morebeno", 3) >
<cfset My.resultSet = qInit>
<cfreturn this>
</cffunction>

</cfcomponent>





Listing 7: IteratorExamples.cfm

<!--- Calling an Iterator for a Collection of Employees--->
<cfset SalesPeople = CreateObject("Component","com.myCompany.EmployeeCollection") />
<cfset SalesPeople.init("Sales","lastName") />
<cfset SalesPeopleIterator = SalesPeople.Iterator()>
<cfoutput>
<cfloop condition="#SalesPeopleIterator.hasNext()#">
<cfset salesPerson = SalesPeopleIterator.next()>
#salesPerson.location#: #salesPerson.firstName# #salesPerson.lastName#<br>
</cfloop>
</cfoutput>