Here's what I've got, at the moment. So far, it's only Transfer =>
Flex, and I haven't completely fleshed things out, so I'm not sure
what traps I'm about to hit.
Also, the Flex form doesn't have all the right field types, and I've
got an issue with null dates, but it's a start. I'm posting this
because it would have saved me a good deal of stumbling around, and it
might make some things click for somebody coming at this fresh.
(Finally, of course it's an invitation for welcome criticism and insight.)
Thanks,
Jamie
#################### Transfer Decorator ##############################
<cfcomponent displayname="conference" output="false"
extends="transfer.com.TransferDecorator">
<cfproperty name="conferenceID" type="numeric" default="" />
<cfproperty name="organizationName" type="string" default="" />
<cfproperty name="name" type="string" default="" />
<cfproperty name="addressId" type="numeric" default="" />
<cfproperty name="contactfirstName" type="string" default="" />
<cfproperty name="contactLastName" type="string" default="" />
<cfproperty name="contactPhone" type="string" default="" />
<cfproperty name="contactPhoneExtension" type="string" default="" />
<cfproperty name="contactFax" type="string" default="" />
<cfproperty name="contactEmail" type="string" default="" />
<cfproperty name="startDate" type="date" default="" />
<cfproperty name="endDate" type="date" default="" />
<cfproperty name="materialsDueDate" type="date" default="" />
<cfproperty name="sponsor" type="string" default="" />
<cfproperty name="isCigAttending" type="boolean" default="" />
<cfproperty name="isCigExhibiting" type="boolean" default="" />
<cfproperty name="isCigPresenting" type="boolean" default="" />
<cfproperty name="isClosed" type="boolean" default="" />
<cfproperty name="conferenceTypeId" type="numeric" default="" />
<!--- TODO: create validation --->
</cfcomponent>
######## ConferenceService.getConference() ########
<cffunction name="getconference" access="public" output="false"
returntype="any">
<cfargument name="conferenceID" type="numeric" required="true"
/>
<cfreturn
variables.transfer.get("conference.conference",arguments.conferenceID)
/>
</cffunction>
############## FlattenObjectAroundAdvice.cfm (CS Advice) ##################
<cfcomponent name="FlattenObjectAroundAdvice"
extends="coldspring.aop.MethodInterceptor">
<cffunction name="invokeMethod" access="public" returntype="any">
<cfargument name="methodInvocation"
type="coldspring.aop.MethodInvocation" required="true" />
<cfset var local = structNew() />
<cfinvoke
component="#arguments.methodInvocation.getTarget()#"
method="#arguments.methodInvocation.getMethod().getMethodName()#"
argumentcollection="#arguments.methodInvocation.getArguments()#"
returnvariable="local.result" />
<cfif isTransferOrmObject(local.result) ><!--- this is a
transfer
(orm) object --->
<!--- get the flattened object (aka, "memento"
structure) --->
<cfset local.flattenedObject =
local.result.getMemento() />
<!--- make it a typed structure, by adding a special
key with the
value of the class's name --->
<cfset local.flattenedObject["__type__"] =
getMetaData(local.result).name />
<cfdump var="#local.flattenedObject#" output="console"
/>
<!--- return the flattened object --->
<cfreturn local.flattenedObject />
<cfelse><!--- this is not a transfer (orm) object --->
<!--- return the variable as-is --->
<cfreturn local.result />
</cfif>
</cffunction>
<cffunction name="isTransferOrmObject" access="private"
returntype="boolean" output="false">
<cfargument name="variable" type="any" required="true">
<!--- TODO: there probably is a more elegant/reliable way to
test if
something is a Transfer (ORM) object --->
<cfreturn isObject(arguments.variable) and
structKeyExists(arguments.variable, "getMemento") />
</cffunction>
</cfcomponent>
################# ColdSpring Excerpts #######################
<!--define the flattenObjectAroundAdvice -->
<bean id="flattenObjectAroundAdvice"
class="childwelfare.model.aop.FlattenObjectAroundAdvice" />
<!-- now define a NamedMethodPointcutAdvisor, set the advice property
to the bean above, and set its mappedNames property to '*' which will
create a pointcut to match all methods excluding any init method -->
<bean id="flattenObjectAdvisor"
class="coldspring.aop.support.NamedMethodPointcutAdvisor">
<property name="advice">
<ref bean="flattenObjectAroundAdvice" />
</property>
<property name="mappedNames">
<value>get*</value>
</property>
</bean>
<bean id="imsConferenceServiceTarget"
class="childwelfare.model.ims.conference.ConferenceService">
<constructor-arg name="transfer">
<bean id="transfer" factory-bean="transfer"
factory-method="getTransfer" />
</constructor-arg>
<constructor-arg name="conferenceGateway">
<ref bean="imsConferenceGateway"/>
</constructor-arg>
</bean>
<!--
PROXIES
-->
<bean id="ImsConferenceService"
class="coldspring.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="imsConferenceServiceTarget" />
</property>
</bean>
<!--
REMOTE PROXIES
-->
<!-- This is my remote proxy for the imsAddressService
Notice lazy-init="false" which keeps us from having to manually
init
the bean somewhere
-->
<bean id="imsConferenceServiceRemote"
class="coldspring.aop.framework.RemoteFactoryBean" lazy-init="false">
<property name="target">
<ref bean="imsConferenceService" />
</property>
<property name="serviceName">
<value>ImsConferenceService</value>
</property>
<property name="relativePath">
<value>/childwelfare/wwwroot/cfc/</value>
</property>
<property name="remoteMethodNames">
<value>get*</value>
</property>
<property name="beanFactoryName">
<value>sharedBeanFactory</value>
</property>
<property name="interceptorNames">
<list>
<value>flattenObjectAdvisor</value>
</list>
</property>
</bean>
############ (Flex) ConferenceVO.as ############
package vo
{
[Bindable]
[RemoteClass(alias="childwelfare.model.ims.conference.Conference")]
public class ConferenceVO
{
public var conferenceID:Number = 0;
public var organizationName:String = "";
public var name:String = "";
public var addressId:Number = 0;
public var contactFirstName:String = "";
public var contactLastName:String = "";
public var contactPhone:String = "";
public var contactPhoneExtension:String = "";
public var contactFax:String = "";
public var contactEmail:String = "";
public var startDate:Date = null;
public var endDate:Date = null;
public var materialsDueDate:Date = null;
public var sponsor:String = "";
public var isCigAttending:Boolean = false;
public var isCigExhibiting:Boolean = false;
public var isCigPresenting:Boolean = false;
public var isClosed:Boolean = false;
public var conferenceTypeId:Number = 0;
/*
public function ConferenceVO() {
}
*/
public function ConferenceVO(data:Object = null):void {
if (data != null) {
this.conferenceID = data.conferenceID;
this.organizationName =
data.organizationName;
this.name = data.name;
this.addressId = data.addressId;
this.contactFirstName =
data.contactFirstName;
this.contactLastName =
data.contactLastName;
this.contactPhone = data.contactPhone;
this.contactPhoneExtension =
data.contactPhoneExtension;
this.contactFax = data.contactFax;
this.contactEmail = data.contactEmail;
this.startDate = new
Date(data.startDate);
this.endDate = new Date(data.endDate);
this.materialsDueDate = new
Date(data.materialsDueDate);
this.sponsor = data.sponsor;
this.isCigAttending =
data.isCigAttending;
this.isCigExhibiting =
data.isCigExhibiting;
this.isCigPresenting =
data.isCigPresenting;
this.isClosed = data.isClosed;
this.conferenceTypeId =
data.conferenceTypeId;
}
}
}
}
########## Flex MXML ###########
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
creationComplete="init();">
<mx:Script>
<![CDATA[
import vo.ConferenceVO;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
import vo.ConferenceVO;
// the following variable is used as the dataprovider
for the combobox
[Bindable]
private var theconference:ConferenceVO;
// do init right off the bat
private function init():void{
// call our service
conferenceService.getConference(6);
}
private function resultHandler(event:ResultEvent):void{
this.theconference = new
ConferenceVO(event.result);
}
private function faultHandler(event:FaultEvent):void{
// we have a problem, throw an alert
Alert.show("Couldn't hit the service properly."
+event.fault.faultString,"Error");
}
]]>
</mx:Script>
<!-- define our external service(s) -->
<mx:RemoteObject id="conferenceService"
source="cfc.ImsConferenceService"
destination="ColdFusion"
fault="faultHandler(event)">
<mx:method name="getConference" result="resultHandler(event)" />
</mx:RemoteObject>
<mx:HBox>
<mx:Form id="conferenceForm">
<mx:FormItem label="conferenceID">
<mx:TextInput id="conferenceID"
text="{theconference.conferenceID}" />
</mx:FormItem>
<mx:FormItem label="organizationName">
<mx:TextInput id="organizationName"
text="{theconference.organizationName}" />
</mx:FormItem>
<mx:FormItem label="conferenceName">
<mx:TextInput id="conferenceName"
text="{theconference.conferenceName}" />
</mx:FormItem>
<mx:FormItem label="addressId">
<mx:TextInput id="addressId"
text="{theconference.addressId}" />
</mx:FormItem>
<mx:FormItem label="contactFirstName">
<mx:TextInput id="contactFirstName"
text="{theconference.contactFirstName}" />
</mx:FormItem>
<mx:FormItem label="contactLastName">
<mx:TextInput id="contactLastName"
text="{theconference.contactLastName}" />
</mx:FormItem>
<mx:FormItem label="contactPhone">
<mx:TextInput id="contactPhone"
text="{theconference.contactPhone}" />
</mx:FormItem>
<mx:FormItem label="contactPhoneExtension">
<mx:TextInput id="contactPhoneExtension"
text="{theconference.contactPhoneExtension}" />
</mx:FormItem>
<mx:FormItem label="contactFax">
<mx:TextInput id="contactFax"
text="{theconference.contactFax}" />
</mx:FormItem>
<mx:FormItem label="contactEmail">
<mx:TextInput id="contactEmail"
text="{theconference.contactEmail}" />
</mx:FormItem>
<mx:FormItem label="startDate">
<mx:DateField selectedDate="{theconference.startDate}"
/>
</mx:FormItem>
<mx:FormItem label="endDate">
<mx:DateField />
</mx:FormItem>
<mx:FormItem label="materialsDueDate">
<mx:DateField
selectedDate="{theconference.materialsDueDate}" />
</mx:FormItem>
<mx:FormItem label="sponsor">
<mx:TextInput id="sponsor"
text="{theconference.sponsor}" />
</mx:FormItem>
<mx:FormItem label="isCigAttending">
<mx:TextInput id="isCigAttending"
text="{theconference.isCigAttending}" />
</mx:FormItem>
<mx:FormItem label="isCigExhibiting">
<mx:TextInput id="isCigExhibiting"
text="{theconference.isCigExhibiting}" />
</mx:FormItem>
<mx:FormItem label="isCigPresenting">
<mx:TextInput id="isCigPresenting"
text="{theconference.isCigPresenting}" />
</mx:FormItem>
<mx:FormItem label="isClosed">
<mx:TextInput id="isClosed"
text="{theconference.isClosed}" />
</mx:FormItem>
<mx:FormItem label="conferenceTypeId">
<mx:TextInput id="conferenceTypeId"
text="{theconference.conferenceTypeId}" />
</mx:FormItem>
</mx:Form>
</mx:HBox>
</mx:Application>
On Mon, Dec 22, 2008 at 5:31 PM, Jamie Jackson <[email protected]> wrote:
>
> Okay, I'm chipping away at this beast (one pitiful piece at a time).
> Since it seems like AOP is likely going to figure into the solution
> somehow, I've added some simple AOP logging to my app, to dip my toe
> into the AOP water.
>
> Now to try to go from a (Transfer) object to Flex in some unfactored
> way, to try to get my head around how that works. Snippets/samples
> still appreciated, BTW. ;-)
>
> Jamie
>
> On Dec 20, 5:12 pm, Jamie Jackson <[email protected]> wrote:
>> Note to self, read through this a
>> bit:http://groups.google.com/group/transfer-dev/browse_thread/thread/abdb...
>>
>> On Dec 20, 3:46 pm, Jamie Jackson <[email protected]> wrote:
>>
>>
>>
>> > Background:
>>
>> > I've used Transfer, MG, and CS (DI-only) together on a project before,
>> > so I'm familiar with those pieces.
>>
>> > For the project I'm on now, it will require MG and Flex to use the
>> > same model, so I'm planning to use the above stack, as well as some
>> > technology that's new to me, namely CS for Remote Proxy generation (to
>> > remotely expose parts of my internal Services), Flex, and maybe
>> > Conduit. I've got the CS Remote Proxy part working in a rudimentary
>> > sort of way, and I can hit these remote methods from Flex (via Flash
>> > Remoting), but that's about as far as I've gotten on the Flex <=> CFMX
>> > front (which isn't very far).
>>
>> > Here's the part I need help on:
>>
>> > 1. My remote methods currently return Transfer objects, and I need to
>> > learn how to go from those to populate forms in Flex.
>> > 2. I also need to be able to save down Flex forms via my remote
>> > service methods.
>>
>> > I've been reading Mark's recent posts (http://groups.google.com/group/
>> > transfer-dev/browse_thread/thread/d7f650f4a8dd482e) and blogs (http://
>> > compoundtheory.com/?action=displayCategory&ID=58) on Conduit, but I'm
>> > too new to Flex to be able to get my head around it. I could really
>> > use a simple sample Conduit app. Mark, you wouldn't happen to have one
>> > in the works, would you?
>>
>> > Alternatively, it would help me to see a sample Flex app that uses
>> > Transfer on the back-end in the old-school way (pre-Conduit, using
>> > what, DTOs? or something)? (Of course this begs the question that
>> > anybody is actually using Transfer in a Flex back-end.)
>>
>> > Failing that, if anybody could point me to their favorite *modern*
>> > sample application that uses Flex/CFMX, I'd be very appreciative.
>> > There's a pretty decent amount of information about CFMX+Flex, but so
>> > much of it is about the Flex ColdFusion Project Wizard (which I can
>> > only assume from past experience with code generators, and wizard-
>> > generated applications, is not a good long-term solution), "hello
>> > world" level examples, and old articles whose currency/validity is
>> > suspect.
>>
>> > That turned out to be a long and needy post. Maybe you can tell that
>> > I'm struggling. ;-) Anyway, I'd appreciate any discussion whatsoever
>> > that I can drum up.
>>
>> > Thanks,
>> > Jamie
> >
>
--~--~---------~--~----~------------~-------~--~----~
Before posting questions to the group please read:
http://groups.google.com/group/transfer-dev/web/how-to-ask-support-questions-on-transfer
You received this message because you are subscribed to the Google Groups
"transfer-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/transfer-dev?hl=en
-~----------~----~----~----~------~----~------~--~---