Yes that's exactly what I was thinking. Instead of having the direct calls
to getMetaData() on the target CFC, I would create the modified metadata
object and pass that in, or possibly create a custom getMergedMetaData()
function in the utility CFC that would do this and that the other CFCs would
call. I'll kick the tires and let you know what I can figure out. Thanks
Chris.

On 7/12/07, Chris Scott <[EMAIL PROTECTED]> wrote:

Now your talking!! Go for it! Perhaps you can copy and alter the metadata
before passing it into the utilities class to generate the functions. I can
talk to you offlist about the best ways to do this
C

Chris Scott
[EMAIL PROTECTED]
http://cdscott.blogspot.com/
http://www.coldspringframework.org/








On Jul 11, 2007, at 11:09 PM, Barney Boisvert wrote:

On the other hand, if you were to subclass RemoteFactoryBean with
CF8AjaxRemoteFactoryBean and have it take care of the extra crap
(which is specific to CF8's Ajax stuff, not general purpose like the
XML metadata), I'd say it's a sound solution.

That's the kind of extension that more closely follows the Spring
paradigm: something generally useful that is BUILT UPON core
functionality, as opposed to TWEAKS to core functionality.

cheers,
barneyb

On 7/11/07, Chris Scott <[EMAIL PROTECTED]> wrote:


Hmm, I like the idea, but am not 100% sure this is a good thing to add to
the RemoteFactoryBean. It is a big departure from what Spring offers on one
hand, but more importantly, the code example looks to me like fully
metaprogramming your cfcs in xml. All you are missing is your actual method
call. Being able to fully transform one method into basically a totally
different one is really not what AOP is about, it is about introducing a
little code seamlessly across your application logic, maximizing code reuse,
while simplifying your core business logic. This seems too much of major
magical code transformation to me


C





Chris Scott
[EMAIL PROTECTED]

http://cdscott.blogspot.com/
http://www.coldspringframework.org/












On Jul 11, 2007, at 8:32 PM, Brian Kotek wrote:

I wanted to get some input about a hack that I just created in ColdSpring.
First, some background:

I was playing with the new AJAX features in CF8. In particular, I was
messing with the AJAX grid. I created a simple service component that
returns a query, and wanted to use ColdSpring to generate a remote proxy
bean that the grid can call. So far so good.

The first issue I ran into was that the AJAX grid requires a query to be
reformatted using QueryConvertForGrid(). So I created a simple AOP advice
that runs the target method and then returns the result wrapped with
QueryConvertForGrid(). I could also imagine doing this to format data for
use in the AJAX tree component.

Anyway, when I bound my grid to the CFC method, ColdFusion complained
loudly. I seems any method used to update a grid requires several arguments,
such as cfgridpage, cfgridsize, cfgridpagesortcolumn, and
cfgridpagesortdirection. So I specified these arguments in my CFC call from
the grid. CF still complained. It seems that the AJAX to CFC binding uses
CFC metadata and REQUIRES that cfargument tags exist in the target CFC that
match these arguments.

Now you can probably see the problem. My base service component has no
such arguments. It has no idea I'm eventually using the data it returns in
an AJAX grid. And since ColdSpring uses the base CFC metadata when
generating the remote proxy bean, it won't generate any arguments at all for
that remote method. So it looked like I was out of luck on using ColdSpring
for this sort of thing. Which would suck for an app that sent a lot of data
to AJAX grids...I'd have to manually create remote facades for every method.

Unless....

The wheels began turning...

What if I could somehow inject artificial metadata into the system, so
that even though my base service component didn't have these grid-specific
cfargument tags, the generated remote proxy would? Then ColdFusion's AJAX to
CFC binding would be happy, and the AOP advice would have these arguments
available for use in the QueryConvertForGrid() function call that it does.

 Well, I did it. The result is that a bean definition like this will have
extra metadata defined, that will be used the the RemoteFactoryBean to
generate the remote proxy bean:

    <!-- Generate remote facade for Product Service -->
    <bean id="artServiceAJAX" class="
coldspring.aop.framework.RemoteFactoryBean" lazy-init="false">
        <property name="target">
            <ref bean="artService" />
        </property>
        <property name="serviceName">
            <value>ArtServiceAJAX</value>
        </property>
        <property name="relativePath">
            <value>/artstore/components/</value>
        </property>
        <property name="remoteMethodNames">
            <value>get*</value>
        </property>
        <property name="beanFactoryName">
               <value>BeanFactory</value>
        </property>
        <property name="interceptorNames">
            <list>
                <value>AJAXGridAdvisor</value>
            </list>
        </property>
        <metadata>
            <methods>
                <method name="getArtists" returnType="query">
                    <parameter name="cfgridpage" required="yes"
type="numeric" />
                    <parameter name="cfgridpageSize" required="yes"
type="numeric" />
                    <parameter name="cfgridpagesortcolumn" required="no"
type="string" default="" />
                    <parameter name="cfgridpagesortdirection"
required="no" type="string" default="" />
                </method>
            </methods>
        </metadata>
    </bean>

And the resulting ArtServiceAJAX.cfc has this method defined:


    <cffunction name="getArtists" access="remote" returntype="any"
output="false" >
        <cfargument name="cfgridpage" type="numeric" required="yes" />
        <cfargument name="cfgridpageSize" type="numeric" required="yes" />
        <cfargument name="cfgridpagesortcolumn" type="string"
required="no" default="" />
        <cfargument name="cfgridpagesortdirection" type="string"
required="no" default="" />
        <cfset var rtn = callMethod('getArtists', arguments) />
        <cfif isDefined('rtn')><cfreturn rtn /></cfif>
    </cffunction>

It seems to me this could be very useful in any remote proxy bean that
also uses AOP to do something beyond what the base component it is proxying
does. In theory it would work for web service calls too, which are also
obviously highly dependent on the metadata of the proxy to generate WSDL,
etc. Flex apps might benefit less since I don't believe they depend on the
actual metadata/arguments/types of the methods being called, but someone who
knows more might correct me. This proof of concept requires you to spell out
the full method names, but I could easily see changing it to support
wildcards like get*.

 I set it up so that you can alter the return type of the method itself,
alter the type, required, and default attributes of existing arguments, and
add completely artificial arguments as well.

I'm interested to hear what people think. One downside is that it seems to
definitely alter the ColdSpring XML DTD to differ from the Java Spring DTD,
though I know there is already at least one other difference between the two
(in the constructor arg I think).

Is this madness?

Thanks,

Brian





--
Barney Boisvert
[EMAIL PROTECTED]
http://www.barneyb.com/

Got Gmail? I have 100 invites.



<<inline: TeamFusionD.gif>>

Reply via email to