I actually use a genericTO object base class that takes care of some redundant typing for me.
again, this TO is a lightweight TO as Peter describes them so all of the values are in the "this" scope.
but basically I have a private method, "setup" that is called by the init method and moves all the initial arguments into
the this scope.
Now, I'm about to start pasting in some components so hopefully the
indentation will come out OK for everyone. If you have any
comments, (positive or negative, particularly negative, about any of
these please, feel free to share).
<cfcomponent access="public" displayname="genericTO" hint="Tranfer Object" extends="generic">
<cffunction name="init" access="public" >
<cfabort showerror="This Method is Abstract and needs to be overridden">
</cffunction>
<cffunction name="setup" access="private"
returntype="genericTO" output="true" displayname="issueTO Constructor"
hint="I initialize the TO">
<cfscript>
var thisKey = 0;
var keyArray = ListToArray(StructKeyList(arguments));
var keyIndex = 0;
/* place a copy in public scope for display purposes */
for (keyIndex
= 1; keyIndex LTE ArrayLen(keyArray); keyIndex=keyIndex+1){
thisKey = keyArray[keyIndex];
this[thisKey] = arguments[thisKey];
}
return this;
</cfscript>
</cffunction>
</cfcomponent>
There maybe an easier way to do this I dunno - but take an object with a bunch of properties like:
<cfcomponent access="public" displayname="issueTO" hint="Tranfer Object" extends="genericTO">
<cffunction name="init" access="public"
returntype="issueTO" output="true" displayname="issueTO Constructor"
hint="I initialize the TO">
<cfargument
name="projectID"
type="numeric"
required="true" hint="the project
the issue is related to.">
<cfargument
name="ID"
type="numeric"
required="true" hint="the issue.">
<cfargument
name="title"
type="string"
required="true" hint="the title
of the issue.">
<cfargument
name="area"
type="com.sbcs.protask.area.areaTO"
required="true" hint="">
<cfargument
name="addedByUser"
type="com.sbcs.protask.user.userTO"
required="true" hint="">
<cfargument
name="assignedToUser"
type="com.sbcs.protask.user.userTO"
required="true" hint="">
<cfargument
name="oldAssignedUser"
type="com.sbcs.protask.user.userTO"
required="true" hint="">
<cfargument
name="currentUser"
type="com.sbcs.protask.user.userTO"
required="true" hint="">
<cfargument
name="category"
type="string"
required="true" hint="">
<cfargument
name="priority"
type="com.sbcs.protask.priority.priorityTO"
required="true" hint="">
<cfargument
name="estimate"
type="numeric"
required="true" hint="">
<cfargument
name="description"
type="string"
required="true" hint="">
<cfargument
name="note"
type="string"
required="true" hint="">
<cfargument
name="documentRef"
type="string"
required="true" hint="">
<cfargument
name="document"
type="string"
required="true" hint="">
<cfargument
name="documentPath"
type="string"
required="true" hint="">
<cfargument
name="billing"
type="com.sbcs.protask.billing.billingTO"
required="true" hint="">
<cfargument
name="dueDate"
type="string"
required="true" hint="">
<cfargument
name="fromEmail"
type="string"
required="true" hint="">
<cfargument
name="status"
type="string"
required="true" hint="">
<cfargument
name="oldStatus"
type="string"
required="true" hint="">
<cfargument
name="approvedInd"
type="numeric"
required="true" hint="">
<cfargument
name="timeWorked"
type="numeric"
required="true" hint="">
<cfargument
name="history"
type="query"
required="true" hint="">
<cfscript>
setup(argumentCollection=arguments);
return this;
</cfscript>
</cffunction>
</cfcomponent>
this second component could, and probably should, be expanded to
include the IDs of each of those TOs so that it could do "lazy
initialization" something I hadn't really thought much about until
yesterday when Ben mentioned it. So that could add another seven
properties.
You might have noticed that genericTO also extends generic. So,
even though it doesn't really matter to this conversation here is
generic (which provides basic capabilities to copy an object (even one
that contains other complex objects)
<cfcomponent access="public" displayname="generic" hint="Basic
Object, providing some extended functionality to an object">
<cffunction name="copy" access="public" output="false">
<cfscript>
var i = 0; /* counter index */
var params =
getMetaData(this.init).parameters; /* grab our initial guess at the
parameters to look for */
var args =
structNew(); /* this will be the argumentCollection we pass to the new
object */
var basis =
this; /* this is used as the base structure to grab our properties from
*/
var thisKey = ""; /* we use this to reference properties in "basis" */
/**********************************************************************
most of the time we store our instance properties in
a struct called
variables.instance - if so lets grab our property
values from there
if we dont then we assume they are stored in the
"this" scope and we will
grab the values from there instead
**********************************************************************/
if(isDefined("variables.instance")){
params =
ListToArray(StructKeyList(variables.instance));
basis = variables.instance;
}
/**********************************************************************
loop over the basis object and get a copy of each
property
**********************************************************************/
for(i=1;i LTE ArrayLen(params); i=i+1){
thisKey = params[i].name;
args[thisKey] = copyProperty(basis[thisKey]);
}
/* create the
new object and initialize it with the arguments we copied */
return
createObject("component",getMetaData(this).name).init(argumentCollection
= args);
</cfscript>
</cffunction>
<cffunction name="copyProperty" access="private" output="false" returntype="any">
<cfargument name="prop" type="any" hint="property to duplicate">
<cfscript>
var thisVal = arguments.prop;
var keyList = "";
var i = 0;
var tempStruct = structNew();
var tempArray = arrayNew(1);
/* its an object, so "copy" the object */
if(isObject(thisVal)){
thisVal = thisVal.copy();
} else if(isStruct(thisVal)){
/* loop ver the structure and
copy it as appropriate */
keyList =
ListToArray(structKeyList(thisVal));
for(i=1;i LTE
ArrayLen(keyList);i=i+1){
tempStruct[keyList[i]] = copyProperty(thisVal[i]);
}
thisVal = tempStruct;
}else if(isArray(thisVal)){
/* loop over the array and copy
each index as appropriate */
for(i=1;i LTE
ArrayLen(thisVal);i=i+1){
tempArray[i] =
copyProperty(thisVal[i]);
}
thisVal = tempArray;
} else {
/* it is a simple value, so lets
duplicate it */
thisVal = duplicate(thisVal);
}
return thisVal;
</cfscript>
</cffunction>
<cffunction name="dump" access="public" output="true">
<cfargument name="abort" type="boolean" default="0" />
<cfif isDefined("variables.instance")>
<cfdump var="#variables.instance#" />
<cfelse>
<cfdump var="#this#" />
</cfif>
<cfif arguments.abort><cfabort /></cfif>
</cffunction>
</cfcomponent>
----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email to [email protected] with the words 'unsubscribe cfcdev' as the subject of the email.
CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting (www.cfxhosting.com).
CFCDev is supported by New Atlanta, makers of BlueDragon
http://www.newatlanta.com/products/bluedragon/index.cfm
An archive of the CFCDev list is available at www.mail-archive.com/[email protected]
- Re: [CFCDev] Generic Beans (was: LTOs (was: Form Validation... Bill Rawlinson
- Re: [CFCDev] Generic Beans (was: LTOs (was: Form Valid... Bill Rawlinson
