
December 31 2007 by

Andrew Powell
When building Flex applications, I always use
Service Capture to help debug remoting calls. Well, it turns out that with SC version 1.2.22, it will not read the AMF data coming from BlazeDS. It will read the data sent to BlazeDS, but not the data coming out. I am sure this will be fixed soon, but a head's up to anyone else running into this problem.
Posted in Flex | BlazeDS | ESRI | IIS | Adobe | Training |
4 comments

December 27 2007 by

Andrew Powell
Do not try to understand Cairngorm; that's impossible. Instead only try to realize the truth: There is no framework. Then you'll see, that it is not Cairngorm that bends, it is only yourself.
Posted in Cairngorm | Flex | General | Adobe |
2 comments

December 24 2007 by

Andrew Powell
The watch is officially on! NORAD is now tracking Santa Claus.
See it here
Posted in General |
0 comments

December 12 2007 by

Andrew Powell
With ColdFusion 8 came interfaces. Anyone who has developed in Java with Spring will tell you that the crux of the Spring framework and its IOC container is the ability to define your dependencies as interfaces. ColdFusion didn't have the ability to use interfaces until the latest release, CF8. Interfaces, mixed with ColdSpring, give us the ability to apply loose coupling between our services and their dependencies.
Our service:
<cfcomponent output="false">
<cffunction name="init" access="public" returntype="net.infoaccelerator.stockWatcher.services.StockService">
<cfset variables.TO = structNew()/>
<cfreturn this/>
</cffunction>
<cffunction name="setStockDAO" access="public" returntype="void">
<cfargument name="stockDAO" type="net.infoaccelerator.stockWatcher.business.dao.IStockDAO" required="true"/>
<cfset variables.TO.stockDAO = arguments.stockDAO/>
</cffunction>
.
.
.
</cfcomponent>
Notice that the service takes, as an argument to the setStockDAO method, the IStockDAO interface. This means that we can pass in any CFC that implements the IStockDAO interface.
The Interface CFC:
<cfinterface>
<cffunction name="create" output="false" returntype="net.infoaccelerator.stockWatcher.vo.StockVO">
<cfargument name="stockVO" type="net.infoaccelerator.stockWatcher.vo.StockVO" required="true"/>
</cffunction>
<cffunction name="read" output="false" returntype="net.infoaccelerator.stockWatcher.vo.StockVO">
<cfargument name="symbolString" type="string" required="true"/>
</cffunction>
<cffunction name="update" output="false" returntype="Boolean">
<cfargument name="stockVO" type="net.infoaccelerator.stockWatcher.vo.StockVO" required="true"/>
</cffunction>
<cffunction name="delete" output="false" returntype="Boolean">
<cfargument name="stockVO" type="net.infoaccelerator.stockWatcher.vo.StockVO" required="true"/>
</cffunction>
</cfinterface>
Now, let's look at the implementation:
<cfcomponent output="false" implements="net.infoaccelerator.stockWatcher.business.dao.IStockDAO">
<cffunction name="init" access="public" returntype="net.infoaccelerator.stockWatcher.business.dao.StockDAO">
<cfreturn this/>
</cffunction>
<cffunction name="create" output="false" returntype="net.infoaccelerator.stockWatcher.vo.StockVO">
<cfargument name="stockVO" type="net.infoaccelerator.stockWatcher.vo.StockVO" required="true"/>
<cfset var serializedCFC = ""/>
<cfset var fileOut = CreateObject("java", "java.io.FileOutputStream")>
<cfset var objOut = CreateObject("java", "java.io.ObjectOutputStream")>
<cfset fileOut.init(expandPath('/DATA_FILES/') & arguments.stockVO.getSymbol() & '.scfc')>
<cfset objOut.init(fileOut)>
<cfset objOut.writeObject(arguments.stockVO)/>
<cfset objOut.close()>
<cfreturn arguments.stockVO/>
</cffunction>
<cffunction name="read" output="false" returntype="net.infoaccelerator.stockWatcher.vo.StockVO">
<cfargument name="symbolString" type="string" required="true"/>
<cfset var stockVO = ""/>
<cfset var fileIn = CreateObject("java", "java.io.FileInputStream")>
<cfset var objIn = CreateObject("java", "java.io.ObjectInputStream")>
<cfif fileExists(expandPath('/DATA_FILES/') & arguments.symbolString & '.scfc')>
<cfset fileIn.init(expandPath('/DATA_FILES/') & arguments.symbolString & '.scfc')>
<cfset objIn.init(fileIn)>
<cfset stockVO = objIn.readObject()>
<cfset objIn.close()>
<cfelse>
<cfset stockVO = createObject('component','net.infoaccelerator.stockWatcher.vo.StockVO').init()/>
</cfif>
<cfreturn stockVO/>
</cffunction>
<cffunction name="update" output="false" returntype="Boolean">
<cfargument name="stockVO" type="net.infoaccelerator.stockWatcher.vo.StockVO" required="true"/>
<cfset var serializedCFC = ""/>
<cftry>
<cffile action="delete" file="#expandPath('/DATA_FILES/')##arguments.stockVO.getSymbol()#.scfc"/>
<cfset create(arguments.stockVO)/>
<cfreturn true/>
<cfcatch type="any">
<cflog file="StockWatcher" text="#cfcatch.message#"/>
<cfreturn false/>
</cfcatch>
</cftry>
</cffunction>
<cffunction name="delete" output="false" returntype="Boolean">
<cfargument name="stockVO" type="net.infoaccelerator.stockWatcher.vo.StockVO" required="true"/>
<cftry>
<cffile action="delete" file="#expandPath('/DATA_FILES/')##arguments.stockVO.getSymbol()#.scfc"/>
<cfreturn true/>
<cfcatch type="any">
<cflog file="StockWatcher" text="#cfcatch.message#"/>
<cfreturn false/>
</cfcatch>
</cftry>
</cffunction>
</cfcomponent>
ColdSpring Config:
<beans>
<bean id="stockService" lazy-init="true" class="net.infoaccelerator.stockWatcher.services.StockService">
<property name="stockDAO">
<ref bean="stockDAO"/>
</property>
</bean>
<bean id="stockDAO" lazy-init="true" class="net.infoaccelerator.stockWatcher.business.dao.StockDAO"/>
<bean id="stockVO" lazy-init="true" singleton="false" class="net.infoaccelerator.stockWatcher.vo.StockVO"/>
<bean id="quoteVO" lazy-init="true" singleton="false" class="net.infoaccelerator.stockWatcher.vo.QuoteVO"/>
</beans>
What does this mean? As long as we wire in a DAO that implements the IStockDAO interface, we're good to go. We can create any type of DAO, but as long as it implements that IStockDAO interface, it doesn't matter. We can easily swap a file-based DAO for a database DAO, as long as the new DAO properly implements the interface. It's that simple.
The full code is attached as a zipped CFEclipse project.
Posted in ColdFusion | General | ColdSpring | Universal Mind | Hibernate |
5 comments

December 11 2007 by

Andrew Powell
As everyone who is running Leopard and ColdFusion know by now, Leopard shipped with Java 5, and not Java 6. The performance improvements in Java 6 are too great to be left behind on the Mac. Fortunately, there is a solution:
SoyLatte: Java 6 for OS X
A simple change to the "java.home" variable in your jvm.config file and you'll be all set. Binaries are available, so you do not have to compile your own. I am currently running, in a development environment, under the 64-bit version with CF8 and it is smooth. Of course, YMMV.
Posted in Java | ColdFusion | Apple | General | Universal Mind |
5 comments