Using CF With Flex2
Using CF With Flex2
Trademarks
1 Step RoboPDF, ActiveEdit, ActiveTest, Authorware, Blue Sky Software, Blue Sky, Breeze, Breezo, Captivate, Central,
ColdFusion, Contribute, Database Explorer, Director, Dreamweaver, Fireworks, Flash, FlashCast, FlashHelp, Flash Lite,
FlashPaper, Flash Video Encoder, Flex, Flex Builder, Fontographer, FreeHand, Generator, HomeSite, JRun, MacRecorder, Adobe
Systems Incorporated, MXML, RoboEngine, RoboHelp, RoboInfo, RoboPDF, Roundtrip, Roundtrip HTML, Shockwave,
SoundEdit, Studio MX, UltraDev, and WebHelp are either registered trademarks or trademarks of Adobe Systems Incorporated
and may be registered in the United States or in other jurisdictions including internationally. Other product names, logos,
designs, titles, words, or phrases mentioned within this publication may be trademarks, service marks, or trade names of Adobe
Systems Incorporated or other entities and may be registered in certain jurisdictions including internationally.
Third-Party Information
This guide contains links to third-party websites that are not under the control of Adobe Systems Incorporated, and Adobe
Systems Incorporated is not responsible for the content on any linked site. If you access a third-party website mentioned in this
guide, then you do so at your own risk. Adobe Systems Incorporated provides these links only as a convenience, and the inclusion
of the link does not imply that Adobe Systems Incorporated endorses or accepts any responsibility for the content on those third-
party sites.
Speech compression and decompression technology licensed from Nellymoser, Inc. (www.nellymoser.com).
Opera ® browser Copyright © 1995-2002 Opera Software ASA and its suppliers. All rights reserved.
Copyright © 2006 Adobe Macromedia Software LLC. All rights reserved. This manual may not be copied, photocopied,
reproduced, translated, or converted to any electronic or machine-readable form in whole or in part without written
approval from Adobe Systems Incorporated Notwithstanding the foregoing, the owner or authorized user of a valid copy
of the software with which this manual was provided may print out one copy of this manual from an electronic version of
this manual for the sole purpose of such owner or authorized user learning to use such software, provided that no part of
this manual may be printed out, reproduced, distributed, resold, or transmitted for any other purposes, including,
without limitation, commercial purposes, such as selling copies of this documentation or providing paid-for support
services.
Acknowledgments
Project Management: Randy Nielsen
Writing: Anne Sandstrom
Editing: Linda Adler
Production Management: Adam Bernett
Media Design and Production: Masayo Noda
Special thanks to Linda Adler, Randy Nielsen, Bill Sahlas, Farah Gron, Bob Powelll, Mike Nimer., Dean Harmon, and
Tom Jordhal
3
Chapter 5: Using the ColdFusion Extensions for
Flex Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
About the ColdFusion Extensions for Flex Builder . . . . . . . . . . . . . . . . 74
Installing the ColdFusion Extensions for Flex Builder . . . . . . . . . . . . . . 74
Eclipse RDS Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
ColdFusion/Flex Application wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
ActionScript to CFC wizard. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
CFC to ActionScript wizard. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
RDS CRUD wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Services Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4 Contents
CHAPTER 1
Contents
About Flash Remoting Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Using Flash Remoting Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5
Using Flash Remoting Update
To specify a CFC to connect to, you do one of the following:
■ Specify the CFC, including the path from the web root, in the MXML.
■ Create a named resource for each CFC that you connect to. This is similar to registering a
data source.
To create a named resource for each CFC that you connect to:
1. Edit the services-config.xml file by adding an entry for each CFC that you connect to, for
example:
<destination id="CustomID">
<channels>
<channel ref="my-cfamf"/>
</channels>
<properties>
<source>dot_ path_to_CFC</source>
<lowercase-keys>true</lowercase-keys>
</properties>
</destination>
The source attribute specifies the dot notation to the CFC from the web root (the
classpath to the CFC).
2. Restart the ColdFusion server.
In this example, when a user presses a button, the Click event calls the CFC method
getUsers.
5. Specify a handler for the return result of the CFC method call for the <mx:RemoteObject>
tag, as the following example shows.
private function my_CFC_handler( event:ResultEvent )
{
// Show alert with the value that is returned from the CFC.
mx.controls.Alert.show(ObjectUtil.toString(event.result));
}
Flash Remoting Update supports the same authentication mechanism as any HTTP request
from the browser, including getting and setting cookies. This mechanism allws you to take
advantage of the same authentication systems you use for any normal HTTP request. To take
advantage of this functionality in a Flash application, you need to set the HTTP authorization
headers by specifying the user’s username and password with the RemoteObject
setRemoteCredentials method. When ColdFusion receives the Flash Remoting /http
request, ColdFusion populates the cflogin.name and cflogin.password variables (inside the
cflogin tag) with these values. For more information, see the documentation for the
cflogin tag.
Example application
The following sample application lets you test authentication. It consists of a Flex application,
and a ColdFusion application that consists of an Application.cfm file and the ColdFusion
component that the Flex application calls.
The Flex application appears as follows:
The Flex application above lets you enter a username and password. It creates a remote object
to the CFC. Because the application creates a remote object that is managed by a CFC, you
can set a username and password for the authentication mechanism of the remote service.
When you click the Login button, the application calls the setRemoteCredentials method,
using the username and password entered in the text boxes. This sets the properties in the
mx:RemoteObject tag, which are passed in all future requests.
<cflogin>
<cfif isDefined("cflogin.name") or isDefined("cflogin.password")>
<cfloginuser name="#cflogin.name#" password="#cflogin.password#"
roles="flexadmin">
</cfif>
</cflogin>
To make communication between the Flex application and the CFC secure, you can
specify that the AMF channel in the ColdFusion destination definiton be secure in the
WEB-INF\flex\services-config.xml file.
Data translation
The following table lists the ColdFusion data types and the corresponding ActionScript data
type:
Array [] = Array
Struct {} = untyped Object
Contents
About Flex and ColdFusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Configuring a Flex Messaging event gateway . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Enabling communication with Flex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Sending outgoing messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Handling incoming messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Using session and client variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Data translation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
13
About Flex and ColdFusion
ColdFusion includes the Flex Messaging event gateway, which uses the ColdFusion Event
Gateway Adapter to send messages to and receive messages from Adobe Flex Data Services.
This means that ColdFusion applications and Flex applications can publish to and consume
events from the same event queue.
NO T E
To use the Flex Messaging event gateway to interact with a Flex application, the Flex
application must be running on Flex Data Services.
The RMI registry, which facilitates communication between the ColdFusion Event
Gateway Adapter and the Flex Messaging event gateway uses port 1099, which is the
default port for Java RMI. You cannot change this port number. To ensure that the RMI
registry provides registry service for both Flex Data Services and ColdFusion, start Flex
first, and then start ColdFusion. If you stop Flex, you must restart Flex, and then restart
the gateway.
Property Description
destination A hard-coded destination. If you specify this value, any destination
information in the message is ignored.
host The host name or IP address of the Flex Data Services server.
allowedIPs A comma- delimited list of IP addresses from which the Flex Messaging
event gateway accepts messages. If you do not specify a list of allowed IPs,
only processes on the local computer can send messages to the gateway.
If you create a configuration file, save it in the {cf.rootdir}/gateway/config/ directory, with the
extension .cfg.
Name Contents
body Body of the message. This is required.
Headers If the message contains any headers, the CFML structure that contains
the header names as keys and values.
LowercaseKeys If the value is set to yes, the structure keys are converted to lowercase
during creation of ActionScript types.
TimeToLive Number of milliseconds during which this message is valid.
In addition, the Flex Messaging event gateway automatically provides values for the following
Flex message fields:
Name Contents
MessageID A UUID that identifies the message
A single instance of the Flex Messaging event gateway can send messages to any
destination that is registered with the ColdFusion Event Gateway Adapter. However, if
the destination is configured in the Flex Messaging gateway configuration file, the
destination in the message is ignored.
Name Contents
body Body of the message.
ClientID ID of the client that sent the message.
The incoming message data structure also includes the values of messageID and timeToLive
from the Flex message.
<cfset mailfrom="#messageheader.sentfrom#">
<cfset mailto="#messageheader.sendto#">
<cfset mailsubject="#messageheader.subject#">
<cfset mailmessage ="#messageheader.mailmsg#">
Restricting IP addresses
To restrict the IP addresses from which your ColdFusion application accepts messages, you
must use a confiugration file, as specified in “Configuring a Flex Messaging event gateway”
on page 15. In addition to specifying the destination and host, you specify the comma-
delimited list of IP addresses from which your ColdFusion application accepts messages.
Also, you can specify the allowed IPs for when you send messages from Flex to ColdFusion.
You do so in the destination definition in the messaging-config.xml file on the server on
which your Flex application is running. The following example is a sample destination:
<destination id="ColdFusionGateway">
<adapter ref="cfgateway"/>
<properties>
<gatewayid>*</gatewayid>
<gatewayhost>10.60.1.7</gatewayhost>
<allowedIPs>10.60.1.7,10.60.1.8,10.60.1.9</allowedIPs>
</properties>
<channels>
<channel ref="my-rtmp"/>
<channel ref="my-polling-amf"/>
</channels>
</destination>
N OT E
The local machine is not included in the list of allowed IPs by default.
Data translation
The following table lists the ColdFusion data types and the corresponding Adobe Flash or
ActionScript data type:
Data translation 23
24 Using the Flex Messaging Event Gateway
CHAPTER 3
25
Set up your development environment
The ColdFusion Event Gateway Adapter lets you create applications in which Flex Data
Services and ColdFusion MX 7.0.2 communicate. Flex Data Services includes the
ColdFusion Event Gateway Adapter. ColdFusion MX 7.0.2 includes the Flex Messaging event
gateway.
To complete this tutorial, you must have the following products installed:
■ Flex Data Services
■ ColdFusion MX 7.0.2
The example ColdFusion application uses the cfmail tag. You must set up an e-mail
server in the ColdFusion MX Administrator before testing the application.
To become familiar with the messaging-config.xml file, view it in an XML editor so that
you can expand and collapse sections.
</mx:Application>
]]>
</mx:Script>
2. Directly below the <![CDATA[ tag, add the following ActionScript import statements:
import mx.messaging.events.*;
import mx.messaging.Producer;
import mx.messaging.messages.AsyncMessage;
3. Save the file.
msg.headers.gatewayid = "Flex2CF2";
msg.body = new Object();
msg.body.emailto = emailto.text;
msg.body.emailfrom = emailfrom.text;
msg.body.emailsubject = emailsubject.text;
msg.body.emailmessage = emailmessage.text;
pro.send(msg);
messagestatus.text = "Message sent to ColdFusion.";
}
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="initApp()">
<mx:Script>
<![CDATA[
import mx.messaging.events.*;
import mx.messaging.Producer;
import mx.messaging.messages.AsyncMessage;
msg.headers.gatewayid = "Flex2CF2";
msg.body = new Object();
msg.body.emailto = emailto.text;
msg.body.emailfrom = emailfrom.text;
msg.body.emailsubject = emailsubject.text;
msg.body.emailmessage = emailmessage.text;
pro.send(msg);
messagestatus.text = "Message sent to ColdFusion.";
}
</mx:Application>
To make debugging easier, you may want to start ColdFusion in a console by going to
the CFusionMX7\bin directory and entering cfstart.
Contents
About Flex and ColdFusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Application development and deployment process . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Enabling SSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Data translation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Example application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
35
About Flex and ColdFusion
The Flex Data Service assembler lets ColdFusion developers use ColdFusion components
(CFCs) to provide the back-end data management for a Flex application that uses the Data
Management Service.
N OT E
To use the Flex Data Service assembler, the Flex application must be running on Flex
Data Services 2.0.
1. A Flash client requests data that is handled by the Flex Data Management Service.
2. Flex calls a fill, sync, get, or count method in the Data Service.
3. The ColdFusion Data Service adapter sends the request to the Flex Data Service assembler
by using Java Remote Method Invocation (Java RMI).
4. The Flex Data Service assembler and the ActionScript translator convert ActionScript 3.0
data types to the appropriate ColdFusion values.
5. The ColdFusion server invokes the fill, sync, get, or count method of the assembler
CFC, which invoke the appropriate methods in the DAO CFC.
6. The ColdFusion application creates an array of Value Objects or appropriate return value,
which it sends to the ColdFusion server.
The RMI registry, which facilitates communication between the ColdFusion Data
Service assembler and the Flex Data Management Service uses port 1099, which is the
default port for Java RMI. You cannot change this port number.
To make creating the CFCs easier, ColdFusion MX 7.0.2 includes wizards that you
can use in Flex Builder. For more information, see Chapter 5, “Using the ColdFusion
Extensions for Flex Builder”.
<!--
Use the ColdFusion configured channels which have
the instantiate-types flag set to false.
-->
<channels>
<channel ref="cf-dataservice-rtmp"/>
<channel ref="cf-polling-amf"/>
</channels>
<properties>
<!-- The component name or path on the CF server -->
<component>samples.contact.ContactAssembler</component>
<!--
This is the ID of the ColdFusion Data Management server as configured
in the ColdFusion Administrator.
Only needed if you have more than one instance of CF on a machine.
<identity>default</identity>
-->
<!--
Credentials to pass to the assembler CFC for all clients
Generally better to use setRemoteCredentials() API on client
<remote-username></remote-username>
<remote-password></remote-password>
-->
<!-- Define the resolution rules and access level of the cfc being
invoked -->
<access>
<metadata>
<identity property="contactId"/>
</metadata>
<network>
<!-- Add network elements here -->
</network>
<server>
<!--
The method declarations are ignored for CFC Assemblers,
with the exception of the fill-method settings.
Method names are fixed: fill, sync, get, count.
No parameters are defined here, unlike Java.
Any arguments provided via the AS call are passed along to the CFC,
just use optional arguments when defining the CFC.
-->
<fill-method>
<!--
Does the assembler have a "fill-contains" method?
This method is used to determine whether to refresh the fill.
If the specified method returns true the fill is re-executed
after a create or update.
Auto-refresh determines if the fill is always refreshed if not
specified.
May only be used when auto-refresh is true.
Optional. Default is false.
-->
<use-fill-contains>false</use-fill-contains>
<!--
Determines whether to refresh the fill on updates or creates.
Optional. Default value is true.
<!--
Determines whether order is important for this filled
collection. Allows for
performance optimization when order is not important.
Optional. Default value is true.
-->
<ordered>true</ordered>
</fill-method>
</server>
</properties>
</destination>
To enable the Data Services adapter:
1. Copy the following ColdFusion-specific <channel-definiton> sections (cf-dataservice-rtmp
and cf-polling-amf) from the sample services-config.xml file to the <channels> section of
the web application flex-messaging-service.xml file:
<!-- ColdFusion specific HTTP channel -->
<channel-definition id="cf-polling-amf"
class="mx.messaging.channels.AMFChannel">
<endpoint
uri="http://{server.name}:{server.port}
/{context.root}
/messagebroker/cfamfpolling"
class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
<serialization>
<!-- This must be turned off for any CF channel -->
<instantiate-types>false</instantiate-types>
</serialization>
<polling-enabled>true</polling-enabled>
<polling-interval-seconds>8</polling-interval-seconds>
</properties>
</channel-definition>
<!-- ColdFusion specific RTMP channel -->
<channel-definition id="cf-dataservice
-rtmp"class="mx.messaging.channels.RTMPChannel">
<endpoint uri="rtmp://{server.name}:2048"
class="flex.messaging.endpoints.RTMPEndpoint"/>
<properties>
<idle-timeout-minutes>20</idle-timeout-minutes>
<serialization>
<!-- This must be turned off for any CF channel -->
<instantiate-types>false</instantiate-types>
</serialization>
</properties>
</channel-definition>
For more information, see “Configuring the Data Service” in Developing Flex Applications,
which is included in the Flex documentation.
NO TE
The ColdFusion MX Administrator lets you enable or disable Flex Data Management
support. If you are running more than one instance of ColdFuison, you must use a unique
ID to specify each instance of ColdFusion for which you want to enable Flex Data
Management support. You do so by specifying the identity in the <identity> element of the
data-management-config.xml file.
Managing fills
To determine whether to refresh a fill result after an item is created or updated, you include a
fillContains method in the assembler and set both use-fill-contains and auto-refresh to true
in the <fill-method> section of the data-management-config.xml file. A sample <fill-
method> section appears as follows:
<fill-method>
<use-fill-contains>true</use-fill-contains>
<auto-refresh>true</auto-refresh>
<ordered>false</ordered>
</fill-method>
In this example, ordered is set to false because the fill result is not sorted by any criteria.
However, if the fill result is sorted, you set ordered to true. When an item changes in a fill
result that is ordered, you must refresh the entire fill result.
The fillContains method tells the Flex application whether it is necessary to run the fill
again after an item in the fill result has changed. The fillCcontains method returns a value
that indicates how the fill should be treated for that change. When the fillContains
method returns true, the fill is executed after a create or update operation.
The fillContains method signature is as follows:
<cffunction name="fillContains" output="no" returnType="boolean"
access="remote">
<cfargument name="fillArgs" type="array" required="yes">
<cfargument name="item" type="[CFC type object]" required="yes">
<cfargument name="isCreate" type="boolean" required="yes">
Authentication
To authenticate users when using the Flex Data Service Assembler, you use the Flex
setRemoteCredentials() method on the DataService object. The credentials, which are in
the FlexSession object, are passed to the ColdFusion application, where you can use the
cflogin tag to perform authentication. Alternatively, you can set credentials in the Flex
destination, although this is not the recommended way to do so.
Enabling SSL
You can encrypt communication between ColdFusion and Flex by enabling Secure Sockets
Layer (SSL). To use SSL, you must create a keystore file. The keystore is a self-signed
certificate. (You do not need a certificate signed by a Certificate Authority, although if you do
use one, you do not need to configure Flex as indicated in the steps below.) The information
in the keystore is encrypted and can be accessed only with the password that you specify. To
create the keystore, you use the Java keytool utility, which is included in your Java Runtime
Environment (JRE).
Enabling SSL 45
To enable SSL, you do the following:
■ Create the keystore
■ Configure Flex
■ Enable SSL in the ColdFusion MX Administrator
The following table describes the parameters of the keytool utility that you use:
Parameter Description
-alias The name of the keystore entry. You can use any name for this, as long
as you are consistent when referring to it.
-dname The Distinguished Name, which contains the Common Name (cn) of
the server.
Next, you place the certificate you created in the file that the JVM uses to decide what
certificates to trust. The file in which you put the certificate, (usually named cacerts), is
located in the JRE, under the lib/security folder.
To configure Flex:
1. Export the keystore to a certificate by using the keytool utility, with a command similar to
the following:
keytool -export -v -alias FlexAssembler -keystore cf.keystore -rfc -file
cf.cer
2. Import the certificate into the JRE cacerts file for your server by using the keytool utility,
with a command similar to the following:
keytool -import -v -alias FlexAssembler -file cf.cer -keystore
C:\fds2\UninstallerData\jre\lib\security\cacerts
Data translation
The following table lists the ColdFusion data types and the corresponding Adobe Flash or
ActionScript data type: [arrays become lists - which are AS arrayCollections; ask mike]
Data translation 47
Example application
This section describes creating a Flex application that uses the ColdFusion Data Service
adapter and Flex Data Service assembler so that a ColdFusion component handles the back-
end database management.
You can download the source code for the files that are included in the Flex sample Contact
application from “Using ColdFusion with Flex – Part 1: Creating and Running a Contact
Manager Application.” In addition, you can view the code for the Flex sample Contact
appliation in “The Flex Contact Manager Application” on page 62.
To use ColdFusion instead of the Java adapter:
1. Create the assembler CFC.
2. Create the DAO CFC.
3. Create the Value Object CFC.
NO TE
To make creating the CFCs easier, ColdFusion MX 7.0.2 includes wizards that you
can use in Flex Builder. For more information, see Chapter 5, “Using the ColdFusion
Extensions for Flex Builder”.
<cftry>
<cfset dao = CreateObject("component","samples.contact.ContactDAO")>
<!--- If the SQL failed, mark this change with the error. --->
<cfcatch type="database">
<cfset msg = "Error during fill: " & cfcatch.queryError &
". SQL was :" & cfcatch.sql>
</cfcatch>
<!--- If anything else happened, mark this change with --->
<!--- the error. --->
<cfcatch type="any">
<!--- <cfset co.fail(cfcatch.message & " " & cfcatch.detail)> --->
</cfcatch>
</cftry>
</cffunction>
Example application 49
The sync method calls the private methods doCreate, doUpdate, and doDelete. If an error
occurs, the method updates the change object with the failure to inform the Flex application
that the change was not processed. The ChangeObject has two APIs, processed() and
fail(). The fail() API takes an optional string argument, which contains the description
of what went wrong. The doCreate, doUpdate, and doDelete methods appear as follows:
<cffunction name="doCreate" access="private" output="no">
<cfargument name="co" required="yes" hint="The change object.">
<cftry>
<cfset dao = CreateObject("component", "samples.contact.ContactDAO")>
<!--- Create the record; create returns with the identity fields
set --->
<cfset dao.create(new)>
<!--- Set the new version in to the change object. --->
<cfset co.setNewVersion(new)>
<!--- Mark this change as processed successfully. --->
<cfset co.processed()>
<!--- If the SQL failed, mark this change with the error. --->
<cfcatch type="database">
<cfset msg = "Error during create: " & cfcatch.queryError &
". SQL was :" & cfcatch.sql>
<cfset co.fail(msg)>
</cfcatch>
<!--- If anything else happened, mark this change with the error. --->
<cfcatch type="any">
<cfset co.fail(cfcatch.message & " " & cfcatch.detail)>
</cfcatch>
</cftry>
</cffunction>
<cftry>
<cfset dao = CreateObject("component", "samples.contact.ContactDAO")>
<!--- Update the record. --->
<!--- If the SQL failed, mark this change with the error. --->
<cfcatch type="database">
<cfset msg = "Error during update: " & cfcatch.queryError &
". SQL was :" & cfcatch.sql>
<cfset co.fail(msg)>
</cfcatch>
<!--- If anything else happened, mark this change with the error. --->
<cfcatch type="any">
<cfset co.fail(cfcatch.message & " " & cfcatch.detail)>
</cfcatch>
</cftry>
</cffunction>
<cftry>
<cfset dao = CreateObject("component", "samples.contact.ContactDAO")>
<!--- Delete the record. --->
<cfset dao.delete(old)>
<!--- Mark this change as processed successfully. --->
<cfset co.processed()>
<!--- If the SQL failed, mark this change with the error. --->
<cfcatch type="database">
<cfset msg = "Error during delete: " & cfcatch.queryError &
". SQL was :" & cfcatch.sql>
<cfset co.fail(msg)>
</cfcatch>
<!--- If anything else happened, mark this change with the error. --->
<cfcatch type="any">
<cfset co.fail(cfcatch.message & " " & cfcatch.detail)>
</cfcatch>
</cftry>
</cffunction>
Example application 51
Creating the count method
The count method returns the number of records that would be returned by the fill method.
The return type of the count method is numeric. It appears as follows:
<cffunction name="count" output="no"
returntype="samples.contact.Contact[]" access="remote">
<cfargument name="param" type="string" required="no">
<cftry>
<cfset dao = CreateObject("component", "samples.contact.ContactDAO")>
<cfif structKeyExists(arguments, "param")>
<cfreturn dao.count(param=arguments.param)>
<cfelse>
<cfreturn dao.count()>
</cfif>
<!--- If the SQL failed, mark this change with the error. --->
<cfcatch type="database">
<cfset msg = "Error during count: " & cfcatch.queryError &
". SQL was :" & cfcatch.sql>
<cfset co.fail(msg)>
</cfcatch>
<!--- If anything else happened, mark this change with the error. --->
<cfcatch type="any">
<cfset co.fail(cfcatch.message & " " & cfcatch.detail)>
</cfcatch>
</cftry>
</cffunction>
<cftry>
<!--- This is the user to look up. --->
<cfset key = uid.contactId>
<cfset ret="">
<cfset ret=dao.read(id=key)>
<!--- If the SQL failed, mark this change with the error. --->
<cfcatch type="database">
<cfset msg = "Error during get: " & cfcatch.queryError & ". SQL
was :" & cfcatch.sql>
<cfset co.fail(msg)>
</cfcatch>
<!--- If anything else happened, mark this change with the error. --->
<cfcatch type="any">
<cfset co.fail(cfcatch.message & " " & cfcatch.detail)>
</cfcatch>
</cftry>
</cffunction>
Example application 53
Creating the DAO CFC
You create the DAO CFC to perform direct manipulations of the back-end database. The
DAO CFC appears as follows:
<cfcomponent output="false" >
<cfloop query="qRead">
<cfscript>
obj = createObject("component", "samples.contact.Contact").init();
obj.setcontactId(qRead.contactId);
obj.setFirstName(qRead.FirstName);
obj.setLastName(qRead.LastName);
obj.setAddress(qRead.Address);
obj.setCity(qRead.City);
obj.setState(qRead.State);
obj.setZip(qRead.Zip);
obj.setphone(qRead.phone);
<cftransaction isolation="read_committed">
<cfquery name="qCreate" datasource="contacts">
insert into Contacts(FirstName, LastName, Address, City,
State, Zip, phone)
values (
<cfqueryparam value="#localFirstName#"
cfsqltype="CF_SQL_VARCHAR" />,
<cfqueryparam value="#localLastName#"
cfsqltype="CF_SQL_VARCHAR" />,
<cfqueryparam value="#localAddress#" cfsqltype=
"CF_SQL_VARCHAR" />,
<cfqueryparam value="#localCity#" cfsqltype="CF_SQL_VARCHAR" />,
<cfqueryparam value="#localState#" cfsqltype=
"CF_SQL_VARCHAR" />,
<cfqueryparam value="#localZip#" cfsqltype="CF_SQL_VARCHAR" />,
<cfqueryparam value="#localphone#" cfsqltype="CF_SQL_VARCHAR" />
)
</cfquery>
Example application 55
and City = <cfqueryparam value="#localCity#"
cfsqltype="CF_SQL_VARCHAR" />
and State = <cfqueryparam value="#localState#"
cfsqltype="CF_SQL_VARCHAR" />
and Zip = <cfqueryparam value="#localZip#"
cfsqltype="CF_SQL_VARCHAR" />
and phone = <cfqueryparam value="#localphone#"
cfsqltype="CF_SQL_VARCHAR" />
order by contactId desc
</cfquery>
</cftransaction>
<cfscript>
arguments.Contacts.setcontactId(qGetID.contactId);
</cfscript>
</cffunction>
<cfreturn qRead.totalRecords>
</cffunction>
</cfcomponent>
Example application 57
Creating the Value Object CFC
To create the Value Object to return to Flex, you create a CFC by using the cfproperty tag
and including get and set methods. The Value Object CFC appears as follows:
<cfcomponent output="false" alias="samples.contact.Contact">
<!--- These are properties that are exposed by this CFC object. --->
<!--- These property definitions are used when calling this CFC --->
<!--- as a web services, passed back to a Flash application, --->
<!--- or when generating documentation. --->
<cfscript>
//Initialize the CFC with the default properties values.
this.contactId = 0;
this.firstName = "";
this.lastName = "";
this.address = "";
this.city = "";
this.state = "";
this.zip = "";
this.phone = "";
</cfscript>
Example application 59
<cfreturn this.state>
</cffunction>
</cfcomponent>
Example application 61
<sync-method>
<name>sync</name>
</sync-method>
<get-method>
<name>get</name>
</get-method>
<count-method>
<name>count</name>
</count-method>
</server>
</properties>
</destination>
contactmgr.mxml
The contactmgr.mxml file contains the following:
<?xml version="1.0" encoding="utf-8"?>
<!--
///////////////////////////////////////////////////////////////////////////
/////
//
// Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
// All Rights Reserved.
<mx:Script>
<![CDATA[
import mx.controls.*;
import mx.collections.ArrayCollection;
import mx.data.Conflict;
import mx.data.Conflicts;
import mx.data.DataService;
import mx.data.IManaged;
import mx.data.events.*;
import mx.messaging.events.*;
import mx.rpc.*;
import mx.rpc.events.*;
import samples.contact.*;
[Bindable]
public var contacts:ArrayCollection;
[Bindable]
public var contact:Contact;
Example application 63
private function resultHandler(event:ResultEvent):void
{
Hourglass.remove();
if (event.token.kind == "create")
{
dg.selectedIndex = contacts.length - 1;
}
else if (event.token.kind == "delete" && contacts.length>0)
{
var index:int = event.token.index < contacts.length ?
event.token.index : contacts.length -1;
dg.selectedIndex = index;
contact = contacts[index];
}
else if (event.token.kind == "fill" && contacts.length>0)
{
dg.selectedIndex = 0;
contact = contacts[0];
}
}
if (!contacts.contains(contact))
{
Hourglass.show(this);
ds.createItem(contact);
token = ds.commit();
token.kind = "create";
}
else if (ds.commitRequired)
{
Hourglass.show(this);
token = ds.commit();
token.kind = "update";
}
}
]]>
</mx:Script>
Example application 65
<mx:Binding source="state.text" destination="contact.state"/>
<mx:Binding source="zip.text" destination="contact.zip"/>
<mx:Binding source="phone.text" destination="contact.phone"/>
<mx:ControlBar>
<mx:Button label="{dg.selectedIndex!=-1?'Update':'Add'}"
click="updateContact()" width="60"/>
<mx:Button label="Delete" click="deleteContact()"
visible="{dg.selectedIndex!=-1}" width="60"/>
<mx:Button label="New" click="newContact()"
visible="{dg.selectedIndex!=-1}" width="60"/>
</mx:ControlBar>
</mx:Panel>
</mx:HDividedBox>
</mx:Application>
hourglass.mxml
The hourglass.mxml file contains the following:
<?xml version="1.0" encoding="utf-8"?>
<!--
///////////////////////////////////////////////////////////////////////////
/////
//
// Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
// All Rights Reserved.
// The following is Sample Code and is subject to all restrictions on such
code
// as contained in the End User License Agreement accompanying this product.
// If you have received this file from a source other than Adobe,
// then your use, modification, or distribution of it requires
// the prior written permission of Adobe.
//
///////////////////////////////////////////////////////////////////////////
/////
-->
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="220" height="60">
<mx:Script>
<![CDATA[
Example application 67
import mx.managers.PopUpManager;
import mx.core.IFlexDisplayObject;
]]>
</mx:Script>
<mx:Image source="@Embed('wait.png')"/>
</mx:VBox>
mini.mxml
The mini.mxml file contains the following:
<?xml version="1.0" encoding="utf-8"?>
<!--
///////////////////////////////////////////////////////////////////////////
/////
//
// Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
// All Rights Reserved.
// The following is Sample Code and is subject to all restrictions on such
code
// as contained in the End User License Agreement accompanying this product.
// If you have received this file from a source other than Adobe,
// then your use, modification, or distribution of it requires
// the prior written permission of Adobe.
//
///////////////////////////////////////////////////////////////////////////
/////
-->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"
creationComplete="dataService.fill(contacts)">
<mx:ArrayCollection id="contacts"/>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.data.Conflict;
import mx.data.Conflicts;
import mx.data.events.DataConflictEvent;
import mx.rpc.events.FaultEvent;
import samples.contact.Contact;
</mx:Application>
Example application 69
contact.as
The contact.as file contains the following:
///////////////////////////////////////////////////////////////////////////
/////
//
// Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
// All Rights Reserved.
// The following is Sample Code and is subject to all restrictions on such
code
// as contained in the End User License Agreement accompanying this product.
// If you have received this file from a source other than Adobe,
// then your use, modification, or distribution of it requires
// the prior written permission of Adobe.
//
///////////////////////////////////////////////////////////////////////////
/////
package samples.contact
{
[Managed]
[RemoteClass(alias="samples.contact.Contact")]
public class Contact
{
public function Contact() {}
Example application 71
72 Using the Flex Data Service Assembler
CHAPTER 5
Contents
About the ColdFusion Extensions for Flex Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Installing the ColdFusion Extensions for Flex Builder . . . . . . . . . . . . . . . . . . . . . . . . . 74
Eclipse RDS Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
ColdFusion/Flex Application wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
ActionScript to CFC wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
CFC to ActionScript wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
RDS CRUD wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Services Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
73
About the ColdFusion Extensions for Flex
Builder
To make some common coding tasks easier, the ColdFusion Extensions for Flex Builder
include the following:
■ Eclipse RDS Support plug-in, which lets you access files and data sources on a ColdFusion
server.
■ ColdFusion/Flex Application wizard, which lets you create master and detail pages in an
application to create, read, update, and delete records in a database.
■ RDS CRUD wizard, which lets you dynamically create a ColdFusion component (CFC)
based on a table that is registered in the ColdFusion Administrator on a ColdFusion server
■ ActionScript to CFC wizard, which lets you create a CFC based on an ActionScript class
file
■ CFC to ActionScript wizard, which lets you create an ActionScript file based on a CFC
Value Object
■ Services Browser, which lets you browse CFCs, manage a list of web services, and generate
the CFML code to invoke a web service.
To configure any ColdFusion servers that you want to connect to using RDS:
1. In Flex Builder or Eclipse, select Window > Preferences > RDS Configuration.
2. To configure the default localhost server, select localhost and specify the following:
■ Description
■ Host name (127.0.0.1)
■ Port number (8500 if you are using the built-in web server)
■ Context root, if necessary (For more information about the context root, see Installing
and Using ColdFusion MX.)
■ Password, which is the RDS password
3. To specify additional servers, click New, and specify the following:
■ Description, which can be any name you want
■ Host name (IP address or machine name)
■ Port number (8500 if you are using the built-in web server)
■ Context root, if necessary (For more information about the context root, see Installing
and Using ColdFusion MX .)
■ Password, which is the RDS password
4. To remove a server definition, select the server and click Remove.
5. To test a connection, select the server and click Test Connection.
NO T E
If you are using ColdFusion MX 7.0 or earlier, the message “The RDS server was
successfully contacted, but your security credentials were invalid,” appears. The
message indicates that the password was not validated, even if it is correct. Click OK
to close the message.
Once you have configured the RDS connection to your CF servers, you can view the files,
folders and data sources on RDS servers. Each RDS server appears as a node in the RDS
Fileview and Dataview, with the name you specified when you configured the RDS server.
Button Action
Refresh the active RDS server.
RDS Eclipse Support does not support file operations such as copy and paste, drag and
drop, and changing file attributes. However, delete, save, save as, and rename are
supported. In addition, on ColdFusion servers after ColdFusion 5, the date last modified
field does not appear.
You can build queries using either the RDS Query Viewer or the Visual Query Builder. The
RDS Visual Query Builder is similar to the ColdFusion Report Builder Query Builder and
the HomeSite Query Builder.
To build a SQL statement using the Table pane and the Properties panel:
1. Expand a data source.
2. Double-click the columns to be named in the SELECT statement.
As you select columns, the Query Builder creates the SELECT statement in the area at the
lower edge of the pane.
3. If you select columns from more than one table, you must specify the column or columns
used to join them by dragging a column from one table to the related column in the second
table.
If you specify selection criteria, the Query Builder creates a WHERE clause. To
use an INNER JOIN or other advanced selection criteria instead, you must code
the SQL manually.
You code SQL manually to use an INNER JOIN instead of a WHERE clause, use an
OUTER JOIN, or use a database stored procedure.
master/detail master
master/detail
Services Browser
The ColdFusion Services Browser lets you view all of the CFCs and web services on your
computer.
Services Browser 87
Browsing components
The Service Browser lists the following components:
■ Components that the ColdFusion component browser lists
The ColdFusion component browser is located at cf_root/wwwroot/CFIDE/
componentutils/componentdoc.cfm.
■ Components that are located in any directories specified in the ColdFusion MX
Administrator Mappings page
■ Components that are located in any directories specified in the ColdFusion MX
Administrator Custom Tag paths page
You can restrict the list of CFCs according to whether the functions in a CFC are remote,
public, or private.
A sample element of the list appears as follows:
The first line of the listing contains the path. The second line includes the name of the CFC.
The next two lines contain the names of the functions in the CFC. The function name is
followed by any argument, a colon, then the type of the return value. The listing
echo(echoString):STRING indicates that the echo function has an argument named
echoString, and that it returns a string. The myCFC CFC appears as follows:
<cfcomponent>
<cffunction name="echo" output="No" returntype="string">
<cfargument name="echoString" required="Yes">
<cfreturn "echo: #arguments[1]#">
</cffunction>
Services Browser 89
To create a web service object in ColdFusion:
1. Place your mouse pointer where you want to insert the code.
2. View the list of web services.
3. Highlight a web service or a method in a web service and right-click.
4. Select Insert CFInvoke.
The code that the Service Browser generates appears in the ColdFusion file. The following is
an example of the code that the Service Browser generates:
createObject("webservice", "http://arcweb.esri.com/services/v2/
MapImage.wsdl").convertMapCoordToPixelCoord(mapCoord, viewExtent,
mapImageSize);