One of the cool new features of ColdFusion 9 is CFaaS, or ColdFusion as a Service. I'll be honest, I hate the abbreviation. It makes me think of a disease. But - I'll get over it since the feature itself is so impressive. During the ColdFusion Meetup (recording here), ColdFusion Evangelist Terry Ryan demonstrated using CFDOCUMENT remotely via Flex. In his demo, he enters some text, clicks a button, and gets the URL to download a PDF. This reminded me that many moons ago, earlier in the ColdFusion 9 beta, I had created a simple demo called DeadBike. (I'll buy you a beer at CFUNITED if you can guess why.) Here is a quick video showing it in action (clicking will take you to a full screen view, so I'd recommend 'open in new tab'):

So the code behind this is very similar to what Terry showed. Note that I've been lazy and hard coded all the security information within Flex.

<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:cf="coldfusion.service.mxml.*" layout="absolute" viewSourceURL="srcview/index.html">

<cf:Config id="conf" cfServer="127.0.0.1" cfPort="8502" serviceUserName="service" servicePassword="service" />

<cf:Document id="doctestnow" action="generate" format="pdf" result="handleResult(event)" fault="handleError(event)" />

<mx:Script> <![CDATA[ import mx.rpc.events.ResultEvent;

public var res:String = new String();

private function renderSourceAsPDF():void { var source:String = sourceText.text; if(source.length == 0) return doctestnow.content = source; doctestnow.execute(); }

private function handleResult(event:ResultEvent):void {
res=event.result.toString(); pdfviewer.location=res; }

private function handleError(event:Event):void { mx.controls.Alert.show(event.toString()); }

]]> </mx:Script>

<mx:HDividedBox width="100%" height="100%">

<!-- source side --> <mx:VBox width="50%" height="100%">

<mx:Panel title="Source" width="100%" height="100%"> <mx:TextArea id="sourceText" width="100%" height="100%" /> </mx:Panel>

<mx:HBox horizontalAlign="right" width="100%"> <mx:Button label="Render PDF" click="renderSourceAsPDF()" /> </mx:HBox>

</mx:VBox>

<!-- render side --> <mx:Panel title="PDF" width="50%" height="100%">

<mx:HTML id="pdfviewer" width="100%" height="100%" />

</mx:Panel>

</mx:HDividedBox>

</mx:WindowedApplication>

Let's focus on the interesting bits first. You can find the connection/service information here:

<cf:Config id="conf" cfServer="127.0.0.1" cfPort="8502" serviceUserName="service" servicePassword="service" />

<cf:Document id="doctestnow" action="generate" format="pdf" result="handleResult(event)" fault="handleError(event)" />

CFaaS has two special security requirements. First, you must go to User Management and specifically create a user and then give them access to particular services. In this case I gave the user, service, access to the Document service. Secondly, you have to specify which IP addresses are allowed to use the service. Now - I have to say - this is a bit troubling. I get the idea behind it - but it's going to be a problem for an intranet. I can't imagine you would need to enter each and every single IP address of your corporation by hand. But - that seems to be the case for right now. Hopefully that will change before release.

The code handling rendering is about as simple as it gets:

private function renderSourceAsPDF():void { var source:String = sourceText.text; if(source.length == 0) return doctestnow.content = source; doctestnow.execute(); }

Essentially - if I ttyped something, execute the CF service. My services result handler then simply uses the HTML component to render the PDF.

private function handleResult(event:ResultEvent):void { res=event.result.toString(); pdfviewer.location=res; }

Note that I had gotten a URL back, like Terry's demo, but I went ahead and loaded the result in the component.

I was going to package up the demo, but it's usability by the public is very limited. I'd recommend simply copying my code into a new Flex Builder project. Remember to include the cfservices.swc file with your project!