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]

Reply via email to