Follow up: JSON value object from Transfer via ColdSpring remote proxy

transfer , ORM , AOP , AJAX , coldspring 1 Comment »

I think I found myself a solution. First, here's the problem.

The Problem

I have Transfer managing my ORM. It works awesome, I love it, and now I want to start building AJAX-based tools to manage the data through Transfer. But Transfer hides all properties of a class behind getter and setter methods, so when I hit a remote CFC to get, say, new("person") or get("person", 42), all that comes back in a JSON string is {}. No properties visible, so nothing comes back.

The Solution

My LTOFactory (Lightweight Transfer Object) is a component that will talk to Transfer, get the object I'm looking for, and then return the product of Transfer-ORM's built in getMemento() method, which is a simple struct that contains all the properties - publicly exposed. Now my JSON string has the properties!

The same concept for the get method can be, with a little elbow grease, made to work also for list, save, and delete if I choose. If I do that, LTOFactory probably isn't a very good name anymore, but I'm talking results here, not semantics.

The Code

Here is my LTOFactory code.



<cfcomponent output="false">



   <cffunction name="init" returntype="Any" output="false">
      <cfargument name="transfer" type="Any" required="true" />
      <cfset variables.instance["oTransfer"] = arguments.transfer />
      <cfreturn this />
   </cffunction>


   <cffunction name="new" output="false">
      <cfargument name="class" type="string" required="true" />
      <cfscript>
         // Feign a local private scope (coming soon in CF9!)
         var local = {};
         // Retrieve the new Transfer Object (TO) from the Transfer factory
         local.o = variables.instance["oTransfer"].new(arguments.class);
         // Return the memento for the new object
         return local.o.getMemento();
      </cfscript>
   </cffunction>


   <cffunction name="get" output="false"><!--- not yet implemented ---></cffunction>


   <cffunction name="list" output="false"><!--- not yet implemented ---></cffunction>



</cfcomponent>


Here is my ColdSpring configuration that sets up Transfer, its factory, the LTOFactory with dependency injection, and the AOP remote bean configuration so I can hit the LTOFactory via AJAX.

<?xml version="1.0" encoding="iso-8859-1"?>
<beans>
   <!-- Transfer -->
    <bean id="transferFactory" class="transfer.TransferFactory">
      <constructor-arg name="datasourcePath"><value>datasource.xml</value></constructor-arg>
      <constructor-arg name="configPath"><value>transfer.xml</value></constructor-arg>
      <constructor-arg name="definitionPath"><value>/definitions</value></constructor-arg>
      <singleton>TRUE</singleton>
    </bean>

   <bean id="transfer" factory-bean="transferFactory" factory-method="getTransfer" />

   <bean id="LTOFactory" class="LTOFactory">
      <constructor-arg name="transfer">
         <ref bean="transfer" />
      </constructor-arg>
   </bean>

   <bean id="remote.LTOFactory" class="coldspring.aop.framework.RemoteFactoryBean">
      <property name="target">
         <ref bean="LTOFactory" />
      </property>
      <property name="serviceName">
         <value>RemoteLTOFactory</value>
      </property>
      <property name="relativePath">
         <value>/remote/</value>
      </property>
      <property name="remoteMethodNames">
         <value>get,list,new</value>
      </property>
      <property name="beanFactoryName">
         <value>bf</value>
      </property>
   </bean>
</beans>

Getting a DTO/VO out of Transfer-ORM via ColdSpring remote proxy

transfer , ORM , JavaScript , AJAX , coldspring 1 Comment »

I'm working awfully hard these days to be a lazy S.O.B. What I'm trying to do right now is figure out how I'm going to send and receive a simple JSON data chunk that represents a business object (a "data transfer object" (DTO), a.k.a. "value object" (VO) or just "transfer object" (TO)) to and from a remote proxy bean (CFC) generated by ColdSpring AOP. This is not hard to do. What's become an unexpected challenge, however, is when that remote proxy bean is a Transfer factory (from the awesome ORM framework by Mark Mandel).

If you don't know already, here is what will happen with a class pulled out of the Transfer factory when slurped down a remote access pipe; as a part of the process of translating it to a JSON string to send back to my AJAX call, ColdFusion will only turn public, visible properties in the ColdFusion component into JavaScript object properties. This doesn't serve me well because Transfer will not expose any data properties. Rather, it makes getter and setter methods for each property - which I love! But I don't love it for trying to bounce objects back and forth via AJAX/JSON.

All that I've said so far makes it difficult to receive object data without some custom service layer nonsense (I'm lazy, remember?) But just as frustrating is that there doesn't seem to be a simple way to pass an argument collection of property name-value pairs to a constructor in the Transfer factory to create a new object or update one. There is a get method which will return a new class of the requested type, but no way to send in a struct full of default values, which is what I would push up to the service layer via AJAX in my RIA.

Am I going to have to write a custom service layer after all this? I've been poking and prodding for hours here trying to avoid this work.  :) Yes, I fully appreciate the irony in this. I'm a geek, it's what I do.

ColdFusion goes case-sensitive with query of query

Database No Comments »

This little gem goes down as another of those "I've been using CF this long and never knew this important thing" scenarios.

When you're performing a query-of-query and using a LIKE operator, the match becomes case sensitive.  Here's an example.  Let's say you have a table, "chores" with these records in it (one column):

IDNAME
1 Wash the dishes
2 Start the washing machine
3 Dish out some justice
4 Play golf

First start with a standard select out of the database.  Of course, this doesn't make sense, it's just for the example.

Now we'll select from that query (the famous query-of-query) but use the LIKE operator.  The objective is to get all the records with some variation of "wash" in them.  We expect to see records with ID 1 and 2, however, the following will only yield ID 2:

<cfquery name="qChores" dbtype="query">
SELECT ID, name
FROM qOriginalQuery
WHERE (name LIKE '%wash%')
</cfquery>

In order to retrieve records with ID 1 and 2, as you might have wanted, you can force everything to upper case to eliminate any value differences:

<cfquery name="qChores" dbtype="query">
SELECT ID, name
FROM qOriginalQuery
WHERE (UPPER(name) LIKE '%#UCase(wash)#%')
</cfquery>

Credit for this answer to my frustrations goes to my Google result, Just Skins.  Thanks!

Custom CFEclipse Dictionary - tweaking the code hints

tools , cftags , IDE 5 Comments »

I'm sure this is information you can get just about anywhere, but the assumption that everyone knows about it is silly.

I loaded up a file in CFEclipse just now and I got the little red "X" on the left margin of my cfstoredproc tag. For some reason I don't have the ColdFusion 8.0.1 dictionary loaded on this machine. I could have gone searching for it and all that, which might well have been just as easy, but instead I felt compelled to manually edit the dictionary file. If for nothing else, it was a good exercise.

Just so you all know, the dictionary files are here:
C:\Program Files\eclipse\plugins\org.cfeclipse.cfml_1.3.2.200901041029\dictionary

Now, of course, the exact path might change based on your preferences and version of CFEclipse. In this directory there is an XML file for each dictionary, and all are loaded up when CEclipse starts. I recently downloaded the XML dictionary for ColdExt (that'll be another blog post before long, I hope!) and dropped it in here.

So, to complete my thoughts for this post, I went into the cf8.xml file and copied the cachedwithin and cachedafter parameters from the cfquery tag to the cfstoredproc tag. After a restart of CFEclipse, WHALA! No more little red "X". Now you know, and that's half the battle!

CFUnited Express Atlanta has Arrived

training , conference , community , coldspring No Comments »

It's the dawn of a brand new day. Here in Atlanta with peers and colleagues to finally get my chance to expand my sphere of knowledge on some things I've been lacking on. I would say a small portion of the content is not immediately relatable to my world, another portion could eagerly be applied to enhance my world, and then another segment is pretty much comprised of some things I've identified as "the road to travel" - and what's funny is that some recent talks about upcoming projects may have had that road arrive even sooner than expected.

What's truly cherishing about this for me - and you'd know this if you follow this blog at all - is that I'm going to have a rare chance to be a small fish in a big pond of ColdFusion experts. I expect to be coming up with questions that delve into deeper aspects of these raging curiosities I have. I must fill the empty spaces which I haven't been able to satiate via "expensive mentor-less epiphanies". This is going to be awesome.

And of course, the best part, and that I don't expect to be waving my wacky gospel and tamborine when I return to the "ranch". This stuff will be evident and appreciated by more than one peer, I'm sure. More to come.

Powered by Mango Blog. Design and Icons by N.Design Studio
RSS Feeds