<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-16515669</id><updated>2011-10-16T00:30:21.339-07:00</updated><category term='Flex'/><category term='Swiz'/><category term='AIR'/><title type='text'>Truths and Lies</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>69</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-16515669.post-2822644051692531097</id><published>2011-06-27T19:52:00.000-07:00</published><updated>2011-06-27T19:53:20.277-07:00</updated><title type='text'>Introducing Swiz AOP!</title><content type='html'>A few years back I wrote a series of articles introducing the principles of Aspect Oriented Programming to ColdFusion developers. In this article I will begin a similar series aimed at ActionScript Developers, in support of Swiz’s newly release AOP Framework. AOP can seem like a daunting topic, with unfamiliar terminology and concepts that can be difficult to get your brain around. Instead of simply explaining new terms, I am going to take a gentle approach, and hope that by providing context to why you may employ AOP, you will walk away with an understanding and excitement to give these powerful concepts a try. This article will simply be an introduction, with my next introducing Swiz’s new framework in practice.&lt;br /&gt;&lt;br /&gt;If you are currently using an Inversion of Control container, you have hopefully begun to take advantage of composition in your architecture. There are many articles out there on why IoC tends to favor composition over inheritance, so I won’t get into a long-winded discussion here, but I can say that when I began to use the Spring Framework for Java back in the early 2000s I really enjoyed learning to think of my applications as groups of shared services, composed of simple bits and peaces making up powerful work units. I play guitar and bass, and I like to think of what we call ‘Services’ existing in my application in a similar way as my effects pedals exist in my rig. If you unscrew a few, you will see that they are made up of a bunch of pretty similar components: capacitors, resisters, transistors and so on, but most users never look at that stuff. They see a few knobs, an input and an output or two. These are the effect’s interfaces. Most users don’t care how they work, they only care about the bad ass metal thunder sounds they make. To me this is a great way to think of application development, and IoC containers like Swiz are amazing tools to give you the power to compose your applications without much overhead, instead concentrating on real functional design. IoC is a great tool, but it’s really the power of composition that makes it all so elegant.&lt;br /&gt;&lt;br /&gt;Aspect Oriented Programming in some ways is like composition on powerful mind altering drugs. Going back to my guitar analogy, some players like to add midi into their rigs. They put a special little device in the signal chain that can filter some or all of their sound into a box that, although it looks pretty much like any other guitar effect, can magically transform their guitar into entirely new and some may say interesting instruments.  (Authors note: I do not condone this! There is absolutely nothing bad ass about an electric guitar sounding like a flute!!)  What really interests me, though, is that the altered behavior is highly controlled, at runtime, by the player. This is what AOP does for your applications. It enables developers to selectively brush complex behavior into their applications, in an extremely transparent manner. So code that is already written, tested, and composed into a complete service can all of a sudden take on entirely new behavior. Sounds pretty awesome, no? Negative side? Well, that would be what I just wrote about ‘in an extremely transparent manner’. AOP can be hard to read, and even harder to understand how it’s even functioning in the first place. A core principle is dynamically changing objects in a way that objects using them can never know. It’s powerful, confusing, and wonderful all at the same time. As I said, it’s like an acid trip for your code.&lt;br /&gt;&lt;br /&gt;So why would you ever do this? Let’s get on to what AOP really aims to acomplish. If you look at a complex system, it is often pretty easy to break it down into many, many specialized pieces of functionality, reused in few places, and far less specialized functionality reused in many places. The first group is your core functionality, the business logic you are trying to implement. The later group is stuff you need to redo all the time, and often can look at as being pretty coupled to code all over the place. In the AOP community, this type of functionality is referred to as ‘Cross Cutting Concerns’, because it cuts across so many parts of your app. The prime example of this is logging. Open up any big AS project and you will see either a ton of trace statements or logging statements everywhere. They cut across everything, but do they have anything to do with the actual business logic one line above them? No, because logging is not business logic, it’s simply cross-cutting debug logic. Other great examples are caching and security. Instead of in-line, right when you are about to make a remote object call, making a call to some security component to make sure the user is actually allowed to do whatever they are doing, then needing to write in logic to do whatever you need to do if they actually are not allowed, it would be much nicer to simply declare that method needs to be secured somehow. If you could simply say a component needs to somehow be secured, or have it’s results cached, you could then write code, very generalized and loosely coupled code, that would allow that component to take on a new aspect of behavior. You want that object to ‘be secured’ or ‘be cached’, sometimes, and need a means to configure that behavior instead of blindly inheriting it all the time. This is the primary problem AOP aims to solve. So how does it do that?&lt;br /&gt;&lt;br /&gt;Well, although AOP uses terms like Proxies, Joinpoints, Pointcuts, Aspects, etc, which sound terribly confusing, I like to think about it in terms of Interception and Introduction. If I want to add security to a method, I am not going to actually write any code about security into that method. Instead I can use AOP to intercept that method, then at runtime decide if I would like to introduce the security logic before actually calling the method. The beauty is, you get very readable core business logic, and as long as you understand how the AOP part is configured, very reusable cross cutting logic to implement systems like caching and security. Since this is already a pretty lengthy article, I am going to leave you thinking a bit. In the next article I will provide a functional walk-through of AOP in practice with Swiz, showcasing a simple caching solution, then move on to a full discussion of Swiz AOP’s main principles. Check back, because these articles will come fast, I promise!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-2822644051692531097?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/2822644051692531097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=2822644051692531097&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/2822644051692531097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/2822644051692531097'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2011/06/introducing-swiz-aop.html' title='Introducing Swiz AOP!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-7678779109435376922</id><published>2011-05-03T10:22:00.000-07:00</published><updated>2011-05-03T10:29:13.640-07:00</updated><title type='text'>Swiz 1.1 Released with Flex 4.5 Mobile Support!</title><content type='html'>The Swiz team is very happy to announce today the release of Swiz 1.1!! This new release includes support for mobile development, along with some critical bug fixes and infrastructure support for future development (I'll keep what that could be a small mystery for the moment...)&lt;br /&gt;&lt;br /&gt;We're proud to also include support for some new features included in &lt;a href="http://www.adobe.com/products/flash-builder.html"&gt;Flash Builder 4.5&lt;/a&gt;, which now automatically completes Swiz metadata!&lt;br /&gt;&lt;br /&gt;Swing on over to &lt;a href="http://swizframework.org/"&gt;www.swizframework.org&lt;/a&gt; for details, or grab the download &lt;a href="http://bit.ly/Swiz1dot1"&gt;here&lt;/a&gt;. Congrats to Team Swiz for the new release!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-7678779109435376922?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/7678779109435376922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=7678779109435376922&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/7678779109435376922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/7678779109435376922'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2011/05/swiz-11-released-with-flex-45-mobile.html' title='Swiz 1.1 Released with Flex 4.5 Mobile Support!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-8520427334654570553</id><published>2010-12-15T09:20:00.000-08:00</published><updated>2010-12-15T09:36:28.091-08:00</updated><title type='text'>Swiz 1.0 Released!!! And in honor, may I present FoShizzle!!!</title><content type='html'>In honor of the long awaited Swiz Framework 1.0 release, available from &lt;a href="http://swizframework.org"&gt;swizframework.org&lt;/a&gt;, may I present for your pleasure my snoop approved, 100% chronic extension &lt;a href="http://dl.dropbox.com/u/2642661/foshizzle.swc"&gt;FoShizzle&lt;/a&gt;!!&lt;br /&gt;&lt;br /&gt;How do I use this glorious piece of engineering you may ask?? Just drop the swc into your project, and add the following custom processor configuration to your main Swiz declaration.&lt;br /&gt;&lt;br /&gt;&amp;lt;swiz:customProcessors&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;processor:DispachizzleProcessor/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;processor:EventHandizzleProcessor/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;processor:InjectizzleProcessor/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;processor:PostizzleConstrizzleProcessor/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;processor:PreDestrizzleProcessor/&gt;&lt;br /&gt;&amp;lt;/swiz:customProcessors&gt;&lt;br /&gt;&lt;br /&gt;Snoopified metadata names can be used as following:&lt;br /&gt;&lt;br /&gt;Dispachizzle == Dispatcher&lt;br /&gt;HandizzleThaEventizzle == EventHandler&lt;br /&gt;Injectizzle == Inject&lt;br /&gt;PostizzleConstrizzle == PostConstruct&lt;br /&gt;PreDestrizzle == PreDestroy&lt;br /&gt;&lt;br /&gt;Enjoy!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-8520427334654570553?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/8520427334654570553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=8520427334654570553&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/8520427334654570553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/8520427334654570553'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2010/12/swiz-10-released-and-in-honor-may-i.html' title='Swiz 1.0 Released!!! And in honor, may I present FoShizzle!!!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-8519352595587920705</id><published>2009-01-29T17:52:00.000-08:00</published><updated>2009-01-29T18:02:58.428-08:00</updated><title type='text'>More Swiz features, or Swiz 0.0.5 Part 2!</title><content type='html'>Since my last post was getting a bit long, I said I would get a second installment out 'soon'. It took slightly longer than I hoped to get together, but it gave me a chance to put more into &lt;a href="http://code.google.com/p/swizframework/"&gt;Swiz&lt;/a&gt;, that I can also blog about 'soon'!. I left you hanging a bit after mentioning Swiz's new Prototype bean, so lets get right down to business. If you've used Spring or ColdSpring before, you should be well aware that they manage both singleton and non-singleton beans. Spring 1.0 and ColdSpring provide a 'singleton' attribute for the &lt;bean&gt; element in your config file. The singleton attribute defaults to true, meaning there will only ever be one instance of that bean in the factory's cache, but if you change it to false, the bean definition becomes a prototype for a new instance that is created every time getBean is called. In Spring 2, the semantic was shifted a bit, and now the attribute is called 'scope', setting it to 'prototype' is the same as singleton=false. I like the shift in terminology, it's more expressive of what Spring is actually doing. &lt;br /&gt;&lt;br /&gt;Handling prototypes, or non singletons, is pretty much a core function of an IoC container, but Swiz has a little secret, we've been getting by without it. This has a lot to do with the route I initially followed to build Swiz. Being that Flex already has a built in xml language which you use to define object instances, it seemed very natural to me to leverage MXML for Swiz's configuration. However, when you supply objects to Swiz in a BeanLoader, you are defining instances, which are cached as singletons. Even though this is extremely simple, and I could easily argue the point that 90% of all objects managed by IoC frameworks are in fact singletons, there is also plenty of reasons why you man need a unique instance every time a bean is retrieved from Swiz. For instance, what if you wanted to wire up a separate instance of a controller for each view in a tab navigator. Well, with Swiz's new Prototype bean, you can! Here's an example of the new Prototype bean in action:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;br /&gt;&amp;lt;BeanLoader xmlns="org.swizframework.util.*" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:mx="http://www.adobe.com/2006/mxml"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:swizframework="org.swizframework.*"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:delegates="foo.delegates.*"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:factory="org.swizframework.factory.*"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!-- hello service --&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;mx:RemoteObject id="widgetService" destination="widgetService"/&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!-- delegate for the hello controller --&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;delegates:WidgetDelegate id="widgetDelegate"/&gt;&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;factory:Prototype id="widgetController"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;className="foo.controllers.WidgetController"/&gt;&lt;br /&gt; &lt;br /&gt;&amp;lt;/BeanLoader&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;I've defined three objects, a delegate, a remote object, and a controller, if you've worked with Swiz in the past you can already guess how they are being wired together. However, instead of defining the controller directly in MXML, I have defined a Prototype bean, providing an id and className. This should look very familiar to users of Spring and ColdSpring, there's just one big difference to take note of. In Swiz, a prototype is by default non-singleton. You will always get a new instance anytime this widgetController is injected into a view or another bean. It's important to take note of this difference. Your normal beans are always singletons. Prototypes are by default definitions of non-sigletons. Which makes a whole lot of sense semantically. However, if you would like you, can alternately use Prototype to define singletons, by setting the attribute singleton="true". As a matter of fact, if you took this route, your BeanLoaders would look a whole lot like your Spring or ColdSpring config files! I hope you find some great uses for the new Prototype, and check back for the next installment, Swiz's new IInitializingBean interface! &lt;br /&gt;&lt;br /&gt;Good to end on another cliffhanger, right?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-8519352595587920705?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/8519352595587920705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=8519352595587920705&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/8519352595587920705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/8519352595587920705'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2009/01/more-swiz-features-or-swiz-005-part-2.html' title='More Swiz features, or Swiz 0.0.5 Part 2!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-1756520752532995579</id><published>2009-01-26T18:51:00.000-08:00</published><updated>2009-01-26T19:54:05.152-08:00</updated><title type='text'>A bunch of sci-fi movies I can't wait to watch with my kids</title><content type='html'>Spurred on by a tweet by &lt;a href="http://www.coldfusionjedi.com/"&gt;Ray Camden&lt;/a&gt;, I decided to put together a list of sci-fi / fantasy movies I can't wait to watch with my kids when they get old enough, as well as some great ones I have watched with them recently. They are 5 and 7, so no, we're not watching Alien! So, here's the 'waiting' list:&lt;br /&gt;&lt;br /&gt;1. Blade Runner (probably my all time favorite movie)&lt;br /&gt;2. 5th Element&lt;br /&gt;3. 12 Monkeys&lt;br /&gt;4. Legend&lt;br /&gt;5. Dark City&lt;br /&gt;6. 2001&lt;br /&gt;7,8,9. All three LOTR's.&lt;br /&gt;10. Planet of the Apes&lt;br /&gt;11. Alien(s)&lt;br /&gt;12. Pan's Labyrinth (maybe, it's pretty scary but it's on the appletv)&lt;br /&gt;&lt;br /&gt;And the ones my wife has deemed 'acceptable'. Ok, some are a stretch in the genre...&lt;br /&gt;&lt;br /&gt;1. Narnia&lt;br /&gt;2. The Dark Crystal&lt;br /&gt;3. The Goonies&lt;br /&gt;4. Wall-e&lt;br /&gt;4. Harry Potter 1,2 &amp; 3. We decided 4 and 5 are too heavy&lt;br /&gt;5. All 4 Indiana Jones&lt;br /&gt;6. Of course all Star Wars, we watch the damn Clone Wars cartoon every freaking Saturday. God it SUCKS!&lt;br /&gt;7. skinnyarms comment reminded me, we watched Tron recently. My kids really liked it, but were awfully confused by the 1980s concept of computers. Simon kept looking at my funny, and I know he was thinking, "you don't really make crazy stuff like that at work"!&lt;br /&gt;&lt;br /&gt;Honorable non-sci-fi mention. We just watched The Wiz, that was very funny to watch with them!&lt;br /&gt;&lt;br /&gt;So, what are you watching with yours?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-1756520752532995579?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/1756520752532995579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=1756520752532995579&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/1756520752532995579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/1756520752532995579'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2009/01/bunch-of-sci-fi-movies-i-cant-wait-to.html' title='A bunch of sci-fi movies I can&apos;t wait to watch with my kids'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-1889609192217519497</id><published>2009-01-06T18:49:00.000-08:00</published><updated>2009-01-07T18:37:31.853-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AIR'/><category scheme='http://www.blogger.com/atom/ns#' term='Swiz'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>New Swiz 0.0.5 for the New Year!</title><content type='html'>&lt;span style="font-style:italic;"&gt;Update&lt;/span&gt;: Just wanted to clear up a few typos. You need to call setStrict(true) &lt;span style="font-style:italic;"&gt;before&lt;/span&gt; calling loadBeans([Beans]). The code snippet has been fixed. Also, I misspoke, Sönke's strict flag only supports fully qualified class names or static constants in the format SOME_EVENT (all caps with underscores). I have also made that change.&lt;br /&gt;&lt;br /&gt;Happy New Year all! You may have noticed I've been on a bit of a blogging holiday, but after a productive for Christmas/new years, I've released a new build of &lt;a href="http://code.google.com/p/swizframework/downloads/list"&gt;Swiz&lt;/a&gt; over at our &lt;a href="http://code.google.com/p/swizframework/"&gt;googlecode site&lt;/a&gt;! I was hoping to make a release earlier this week, but decided to take a little extra time to restructure the repository so I could include dependencies and project files to make it easier to build Swiz from source. So what's in this shiny new build? We've got two major features, and a bunch of bug fixes, which I'll list out at the end of the post. Most importantly though is run-time checking of event types for DynamicMediators, which we are supporting through two different approaches. It really only takes one or two times scratching your head over some non functioning code, only to find a misspelled event type, to see the need for run-time checking of event types. The first approach has been added by a new addition to the Swiz team &lt;a href="http://soenkerohde.com/"&gt;Sönke Rohde&lt;/a&gt;. Sönke's been very active on the google groups list, as well as blogging some great articles on Swiz and talking with me quite a bit off list about Swiz enhancements. I've very happy to have him now contributing! But let's get on to this run time event checking...&lt;br /&gt;&lt;br /&gt;If you've read the documentation for DynamicMediator, you know that Swiz looks for the Mediate annotation to essentially create a wrapper for a function to be added as an event listener for any event type. The syntax looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;[Mediate(event="user:SaveUserEvent", properties="user")]&lt;br /&gt;public function saveUser(user : User) : void { ... }&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Swiz will not only look for Mediate annotations in objects in your BeanLoaders, but also in any view it sees added to the stage. It then creates a DynamicMediator for the event type supplied, which passes the event properties listed into the function you have annotated. DynamicMediators can significantly reduce boilerplate code, but do have one major drawback. You can only supply string values in Flex medatada tags. It would be great to be able to write:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;[Mediate(event=com.foo.SaveUserEvent.SAVE_EVENT, properties="user")]&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;and have the Flex compiler understand that you are referring to a property of a class, but unfortunately, it won't. However, Sönke has added a 'strict' flag, which will force Swiz to evaluate the string value of the event type as a fully qualified class name or static constant in that class, and throw an error if the class cannot be found. This will occur as soon as Swiz tried to create the DynamicMediator, effectively giving you runtime checking of your event types. In order to use this in your project, you would change your initialization of Swiz to something like the following, in an event handler for preinitialize:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;private function onInitialize() : void {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Swiz.setStrict(true).loadBeans( [ Beans ] );&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;You may have noticed the method chaining style I used, which is another new change. Static configuration methods on Swiz return the Swiz instance, allowing you to chain method calls. Now if we change the mediate annotation above to:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;[Mediate(event="com.foo.SaveUserEvent.SAVE_EVENT", properties="user")]&lt;br /&gt;public function saveUser(user : User) : void { ... }&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Swiz will first check to make sure that a class named com.foo.SaveUserEvent exists, and has a string property called SAVE_EVENT when it attempts to create the DymanicMediator. Early on, Sönke had told me that he commonly uses a standard in his development of always using fully qualified class names as his event types, so an Event class com.foo.SaveUserEvent would use a call to super("com.foo.SaveUserEvent") in it's constructor. In that case, you could use an annotation such as the following:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;[Mediate(event="com.foo.SaveUserEvent", properties="user")]&lt;br /&gt;public function saveUser(user : User) : void { ... }&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;and Swiz would just make sure the class existed. However, this would enforce that you MUST have a class for every event type, excluding DynamicEvents. By adding adding the ability to resolve a static constant, you can place your event types in any class. Let's say you had a com.foo.EventConsants class, you could use:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;[Mediate(event="com.foo.EventConsants.SAVE_USER_EVENT", properties="user")]&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;for your mediator, and then dispatch a DynamicEvent like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;var e : DynamicEvent = new DynamicEvent(EventConsants.SAVE_USER_EVENT);&lt;br /&gt;e.user = currentUser;&lt;br /&gt;Swiz.dispatchEvent( e );&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;I really like the flexibility of this approach. However, while Sönke was working on his strict checking approach, I was working on a similar solution to the same problem. While attending a Spring User Group meeting, I saw that they were experiencing similar issues with their move to annotation driven configuration, and was very intrigued by their 'expression language'. So I have come up with a simple implementation of my own, which I think will continue show it's use in Swiz elsewhere as time goes on.&lt;br /&gt;&lt;br /&gt;Let's take a look at how you might use the new expression language instead of the strict approach. In my own work, I have gotten into the practice of storing event types in my controllers, for me it's a way of keeping them part of a particular domain. So in the previous example, if I have a UserController with a SAVE_USER_EVENT property, I would reference it directly in my SaveUserEvent type, calling super(UserController.SAVE_USER_EVENT) in the constructor. Since I have added my UserController to BeanLoader, with an id of "userController", I can now use an expression in my Mediator to reference the SAVE_USER_EVENT property, like so:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;[Mediate(event="${userController.SAVE_USER_EVENT}", properties="user")]&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;When Swiz encounters the ant-style syntax I chose for expressions, it evaluates it in the format [beanId].[property]. If a bean with the supplied ID does not exist, you will immediately get a runtime ExpressionError. What's nice about this format is, you can use public static constants or instance variables for your event types,, and you can even nest them! In the earlier example using Sönke's strict flag, I mentioned using a class called EventConstants for event types. Depending on your development style, you could either provide this bean to Swiz and reference it directly in you expression, like I did with the userController, or maybe your controllers could have an instance of it, in an 'eventTypes' property. Then you can use an expression like:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;[Mediate(event="${userController.eventTypes.SAVE_USER_EVENT}", properties="user")]&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;I think that both these styles will be a great improvement for developers using Swiz, providing a flexible model to suit your development standards. Unless I have strong community outcry to adopt one format over the other, I see no reason not to support both. Well, this post has already gotten a bit long in the tooth, so maybe I'll leave this as part one, and let you know that part two will cover, Swiz's new Prototype bean! So go download the new Swiz 0.0.5 library and happy coding!&lt;br /&gt;&lt;br /&gt;Changes / Fixes for Swiz 0.0.5:&lt;br /&gt;&lt;br /&gt;- DynamicChannelSet now contains an 'endPointName' property that can be set to 'flex2gateway' for ColdFusion&lt;br /&gt;- Multiple calls to autowire for an object or view will only create mediators once&lt;br /&gt;- handleAutowireEvent ignores flash.* and mx.* classes&lt;br /&gt;- DynamicMediators allow event properties to be null&lt;br /&gt;- Primitive objects can be added to BeanLoaders&lt;br /&gt;- Autowire now supports by type (with [Autowire] instead of [Autowire(bean="foo")])&lt;br /&gt;- DynamicResponder supports passing an array of values to be passed back into the result handler&lt;br /&gt; * for example to have the original saved object passed in to a save result function&lt;br /&gt;- Refactored all bean factory specific functionality out of Swiz and into BeanFactory&lt;br /&gt;- Added Strict flag and MediatorUtils for event type checking&lt;br /&gt;- Added ExpressionUtils, also or event type checking&lt;br /&gt;- Added Prototype object, for non-singleton bean definitions&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-1889609192217519497?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/1889609192217519497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=1889609192217519497&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/1889609192217519497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/1889609192217519497'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2009/01/new-swiz-005-for-new-year.html' title='New Swiz 0.0.5 for the New Year!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-2210991066827938025</id><published>2008-09-21T11:29:00.000-07:00</published><updated>2008-09-21T11:46:43.713-07:00</updated><title type='text'>Swiz updates and documentation!</title><content type='html'>You may have heard (certainly not here!) about a little Flex framework I have been working on called &lt;a href="http://code.google.com/p/swizframework/"&gt;Swiz&lt;/a&gt;. Although I have been a tiny bit quiet around here, I have been extremely actively developing and using Swiz, as well as traveling out to 360|Flex to do a session, and trying to get the word out on a few &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;podcasts&lt;/span&gt;. Well, today I REALLY need to get cracking on the blogging, and luckily I have a few updates to share. First off, I just added a section to the &lt;a href="http://code.google.com/p/swizframework/wiki/GettingStarted"&gt;Swiz documentation&lt;/a&gt; on &lt;a href="http://code.google.com/p/swizframework/wiki/DynamicMediators"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;DynamicMediators&lt;/span&gt;&lt;/a&gt; as well as updated the &lt;a href="http://code.google.com/p/swizframework/wiki/ProjectSetup"&gt;project setup&lt;/a&gt; page. Here's a quick rundown of the changes for the week.&lt;br /&gt;&lt;br /&gt;At 360|Flex I learned that the Flex 3 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;SDK&lt;/span&gt; will automatically include custom &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;metadata&lt;/span&gt; compiled into a library. So now there is no reason to add the additional compiler arguments unless you are using the Flex 2 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;SDK&lt;/span&gt;. Also, there has been a little confusion between the first &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;swc&lt;/span&gt; I posted and the latest about how to get Swiz properly initialized. The correct method is to call Swiz.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;loadBeans&lt;/span&gt;( [ loaders ] ) in a function that is invoked in your main application on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;preinitialize&lt;/span&gt;. This will allow Swiz to load all of your beans before any views are added to stage and then &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;autowire&lt;/span&gt; your views as they are added.&lt;br /&gt;&lt;br /&gt;The major new addition, however, is the new &lt;a href="http://code.google.com/p/swizframework/wiki/DynamicMediators"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;DynamicMediators&lt;/span&gt;&lt;/a&gt;, which I showed at 360|Flex. Basically this function allows your controllers to respond to event dispatching by just adding an annotation to the function that you would like invoked. Check out the documentation for a full &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_10"&gt;explanation&lt;/span&gt;. In the coming weeks I am going to put together a short series of blog posts walking you through the setup and usage of Swiz, but for now, head on over the the &lt;a href="http://code.google.com/p/swizframework/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;google&lt;/span&gt; code site&lt;/a&gt;, and if you are interested, join &lt;a href="http://groups.google.com/group/swiz-framework"&gt;the user group&lt;/a&gt; and provide feedback to help Swiz grow!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-2210991066827938025?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/2210991066827938025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=2210991066827938025&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/2210991066827938025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/2210991066827938025'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2008/09/swiz-updates-and-documentation.html' title='Swiz updates and documentation!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-265672822732118686</id><published>2008-09-12T06:22:00.000-07:00</published><updated>2008-09-22T15:47:56.707-07:00</updated><title type='text'>Big news from ColdSpring!!</title><content type='html'>I've got big news for everyone on this fine September day! Really big news! I know many of you all have been patiently waiting for the final release of ColdSpring 1.2. Well after a long time of tweaking and testing, the team has delivered! I am proud to announce the public release of ColdSpring 1.2!! But hold on to your hats, that's not the only announcement today! When you head on over to &lt;a href="http://www.coldspringframework.org"&gt;www.coldspringframework.org&lt;/a&gt; to download 1.2, you will be pleasantly greeted with a brand new site!!!&lt;br /&gt;&lt;br /&gt;Congratulation and a huge thank you to everyone involved! I'd like to especially thank &lt;a href="http://rmaxim.blogspot.com/"&gt;Rachel Maxim (Lehman)&lt;/a&gt; for the awesome work on the site design, &lt;a href="http://www.wiersmablog.com/machblog/"&gt;Kurt Wiersma&lt;/a&gt; for the &lt;a href="http://www.mach-ii.com/"&gt;Mach-ii&lt;/a&gt; powered implementation, &lt;a href="http://www.adrocknaphobia.com/"&gt;Adam Lehman&lt;/a&gt; for the hosting, and &lt;a href="http://www.briankotek.com/blog/"&gt;Brian Kotek&lt;/a&gt; for documentation, bug fixes and general leadership in this release process. Awesome work everyone! Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-265672822732118686?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/265672822732118686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=265672822732118686&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/265672822732118686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/265672822732118686'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2008/09/big-new-from-coldspring.html' title='Big news from ColdSpring!!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-1190830504321812540</id><published>2008-07-08T05:27:00.000-07:00</published><updated>2008-07-08T05:29:51.855-07:00</updated><title type='text'>Philadelphia CFUG meeting, this Thursday on Swiz!</title><content type='html'>Sorry for the delayed post, but our next meeting will be THIS thursday, July 10th at Huntsman Hall at Wharton. This week I will be presenting on the Swiz Framework for Flex development at the Philadelphia CFUG. You can read the details &lt;a href="http://www.phillycfug.org/index.cfm/2008/7/8/CFUG-Meeting-THIS-Thursday"&gt;here&lt;/a&gt;, but if you around, drop by to get an introduction into my new Swiz Framework!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-1190830504321812540?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/1190830504321812540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=1190830504321812540&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/1190830504321812540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/1190830504321812540'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2008/07/philadelphia-cfug-meeting-this-thursday.html' title='Philadelphia CFUG meeting, this Thursday on Swiz!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-5238235649292353256</id><published>2008-06-27T19:24:00.000-07:00</published><updated>2008-06-27T19:29:34.330-07:00</updated><title type='text'>Joe Rinehart's Nuts!!</title><content type='html'>OMG, I take one week off the blogsphere to catch up on work after cfUnited (I'll get a wrap up soon, but all I have to say is GREAT conference this year...) and Joe goes CRAZY! I'm still reading but he's posting some seriously good stuff in his aptly titled &lt;a href="http://www.firemoss.com/blog/index.cfm/Hiberailooving"&gt;Hiberailooving&lt;/a&gt; series. That would be Hibernate+Railo+Groovy. VERY good reading! Covers two major things I came away from cfU with this year, must learn Groovy (reading a great book thanks to Joe) and Railo is very sweet!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thanks Joe!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-5238235649292353256?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/5238235649292353256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=5238235649292353256&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/5238235649292353256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/5238235649292353256'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2008/06/joe-rineharts-nuts.html' title='Joe Rinehart&apos;s Nuts!!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-3005036367614576362</id><published>2008-05-05T18:11:00.000-07:00</published><updated>2008-05-05T18:15:55.284-07:00</updated><title type='text'>Post cfObjective decompression</title><content type='html'>Another cfO has come and gone, and once again it was a completely incredible event. I tried to see more sessions this time around, since I usually get caught up in conversations in the halls, but I'm not sure I was entirely successful. Of course, for me all the networking is what it's really all about. Friday night I sat with Sean for a while and had a really interesting conversation about his soon to be release &lt;a href="http://www.corfield.org/blog/index.cfm/do/blog.cat/catid/edmund"&gt;Edmund&lt;/a&gt; framework. I had already marked his cfUnited session as a must see, so now I am really excited. &lt;a href="http://compoundtheory.com/"&gt;Mark Mandel&lt;/a&gt; and I spent quite a bit of time together this time around exchanging clothing and planning world domination, er, I mean further work on coldspring's tools for remoting with Transfer, so hopefully the fruit of those long evenings will come quickly.&lt;br /&gt;&lt;br /&gt;Of course, what I was particularly excited about was the amazing buzz at the conference about my new &lt;a href="http://code.google.com/p/swizframework/"&gt;Swiz Framework&lt;/a&gt; for Flex, which I was able to release to google code on Saturday. Many people asked me to see examples, and a slight oversight with time management in my session gave me the opportunity to show Swiz to a large audience. Overall it seemed very well received. Afterwards I sat with &lt;a href="http://maximporges.blogspot.com/"&gt;Maxim&lt;/a&gt;, &lt;a href="http://www.asfusion.com/"&gt;Laura and Nahuel&lt;/a&gt; looking over each other's source code and sharing ideas. This had to be the top highlight of the conference for me. &lt;a href="http://mate.asfusion.com/"&gt;Mate&lt;/a&gt; looks really interesting, and both Laura and Nahuel are amazing AS programmers. Really awe inspiring work. I have been reading their blog for a long time now, and it was just a real pleasure to share some time with them.&lt;br /&gt;&lt;br /&gt;I am sure it will take quite a bit of time to decompress from cfO this time around. It seems every year Jared and Steven take it up a notch, which continues to amaze me. I went to quite a few conferences this past year, and none come close to cfObjective in terms of the top quality speakers and session. This year really seemed to be exploding at the seems. I'm not sure I can even take it all in. So long to all my friends until the next conference, I am sure I will see many of you at cfUnited in a few months, thanks for a wonderful time!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-3005036367614576362?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/3005036367614576362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=3005036367614576362&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/3005036367614576362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/3005036367614576362'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2008/05/post-cfobjective-decompression.html' title='Post cfObjective decompression'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-3062846953265095750</id><published>2008-04-20T18:02:00.000-07:00</published><updated>2008-04-20T18:04:55.188-07:00</updated><title type='text'>Congratulations Jared and Jenna!!!</title><content type='html'>Elisabeth Pearl Rypka-Hauer ROCKS!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-3062846953265095750?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/3062846953265095750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=3062846953265095750&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/3062846953265095750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/3062846953265095750'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2008/04/congratulations-jared-and-jenna.html' title='Congratulations Jared and Jenna!!!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-3356791258924903093</id><published>2007-11-25T09:53:00.000-08:00</published><updated>2007-11-25T10:03:46.936-08:00</updated><title type='text'>Possibly my last ColdSpring update this weekend...</title><content type='html'>At least I hope so, my fingers are getting tired! This last update is a little on the experimental side, but I have just committed AbstractAutowireTransactionalTests to cvs (&lt;a href="http://code.coldspringframework.org/browse/CSP-89" target="_new"&gt;CSP-89&lt;/a&gt;). Basically this works exactly like AbstractAutowireTests, except that it begins a transaction before each test and rolls it back after the test, unless you call setCommit() somewhere in your test. Like AbstractAutowireTests, you just supply the location of your config file, and setters for any beans you want to test. From there, go crazy inserting, updating and deleting things in your db, after the test everything is rolled back. This is so handy, we use it all the time (I know, I said that about AbstractAutowireTests, but what can I say? They are REALLY useful!).&lt;br /&gt;&lt;br /&gt;Just a few things I need to point out. I took a very, very heavy handed approach to making this work. It's not going to be the fastest because Paul creates a new instance of your test class for each test method. At that time (in setUp()) I am doing some crazy proxying and method injection. I am actually creating a proxy, and then taking it apart, it's a bit on the nuts side. However, if Paul would make a tiny change to cfcUnit, I could clean a lot of that up. Anyway, I hope this one is even more useful than the last, and feel free to send bugs along to the coldspring list. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-3356791258924903093?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/3356791258924903093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=3356791258924903093&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/3356791258924903093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/3356791258924903093'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/11/possibly-my-last-coldspring-update-this.html' title='Possibly my last ColdSpring update this weekend...'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-3595290496705571113</id><published>2007-11-24T13:25:00.000-08:00</published><updated>2007-11-24T13:51:00.992-08:00</updated><title type='text'>Even More ColdSpring Updates!!</title><content type='html'>Ok, this is something my coworker Cliff Meyers has been trying to get me to write for ages. We use the Spring equivalent of this literally every day. Now, unit testing ColdSpring managed beans is not really all that hard, all you need to do is create a bean factory, load your config file, and call getBean() for anything you want to test. But you know what? That's too much work! Enter AbstractAutowireTests, which you will find in the new coldspring.cfcunit package (yes, I do intend to make more!). Here's how it works, extend this class instead of Paul's TestCase, override the getConfigLocations function, and that's it, everything else is handled for you! Oh yeah, this is an Autowired test case too, so just add setters for whatever bean you want to write tests against, VERY handy. Here's an example of a test case using this new component:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent extends=&lt;span class="cfvalue"&gt;"coldspring.cfcunit.AbstractAutowireTests"&lt;/span&gt;&gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"getConfigLocations"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"string"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&gt;&lt;br /&gt;        &amp;lt;cfset var path = GetDirectoryFromPath(getMetaData(this).path) /&gt;&lt;br /&gt;        &amp;lt;cfreturn path &amp;amp; "/testBeans.xml" /&gt;&lt;br /&gt;    &amp;lt;/cffunction&gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"onSetUp"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&gt;&lt;br /&gt;        &amp;lt;!--- this is where my setup would be... ---&gt;&lt;br /&gt;        &amp;lt;cfset variables.sys = CreateObject('java','java.lang.System') /&gt;&lt;br /&gt;        &amp;lt;cfset variables.sys.out.println("onSetUp executed!") /&gt;&lt;br /&gt;    &amp;lt;/cffunction&gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"onTearDown"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&gt;&lt;br /&gt;        &amp;lt;!--- this is where my teardown would be... ---&gt;&lt;br /&gt;        &amp;lt;cfset variables.sys.out.println("onTearDown executed!") /&gt;&lt;br /&gt;    &amp;lt;/cffunction&gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"setStructBean"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&gt;&lt;br /&gt;        &amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"structBean"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"coldspring.tests.structBean"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&gt;&lt;br /&gt;        &amp;lt;cfset variables.structBean = arguments.structBean /&gt;&lt;br /&gt;    &amp;lt;/cffunction&gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"testNothing"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&gt;&lt;br /&gt;        &amp;lt;cfset variables.sys.out.println("some structBean data: " &amp;amp; variables.structBean.getData().intOne) /&gt;&lt;br /&gt;        &amp;lt;cfset AssertNotNull(variables.structBean) /&gt;&lt;br /&gt;    &amp;lt;/cffunction&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/cfcomponent&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;A few things to point out here. Right now setConfigLocations is not 100%, it only works with 1 config file, but I will have that done any time now. Also, paths are difficult with cfcUnit as far as location of your config file. Using GetDirectoryFromPath(getMetaData(this).path) ensures that I can refer to a path relative to the cfc being tested. And finally, I am using setUp and tearDown, which are called by cfcUnit's test runner to preform my own set up and tear down actions, so instead you should use onSetUp and onTearDown, which will be properly called by the AbstractAutowireTests. For me, this has been an incredible time saver at work, so I hope you enjoy and find this useful! Now if Paul Kenney answers my email I have even more to commit. Cough, cough...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-3595290496705571113?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/3595290496705571113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=3595290496705571113&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/3595290496705571113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/3595290496705571113'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/11/even-more-coldspring-updates.html' title='Even More ColdSpring Updates!!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-4751643462696013746</id><published>2007-11-24T05:48:00.000-08:00</published><updated>2007-11-24T06:48:43.273-08:00</updated><title type='text'>More ColdSpring updates!</title><content type='html'>One thing I love about Spring is every once in a while you wish you had some special type of bean only to find that Spring already has it. Collection factory beans are some of these types of objects, which I actually use quite a bit at work. Let's say you have configured a component you use across many of your applications, so you put its configuration in a base file and include it in each application with ColdSpring's &amp;lt;include&amp;gt; tag. This is a great approach for reusability, but if you want to use arrays or structs to define application specific parameters to that component you're stuck. A lot of times we end up creating special 'config beans' so we can use the ref tag, but many times these are just wrappers over structs anyway. Why use that type of component at all, if you could just define a struct in your config file and reference it wherever you need it? Well, that's the point of the collection factories. Here's an example of these two new components at work:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First I have a ListFactoryBean instance, which you need to remember from spring semantics will return an Array.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="list.factory" class="coldspring.beans.factory.config.ListFactoryBean"&gt;&lt;br /&gt;    &amp;lt;property name="sourceList"&gt;&lt;br /&gt;        &amp;lt;list&gt;&lt;br /&gt;            &amp;lt;value&gt;one&amp;lt;/value&gt;&lt;br /&gt;            &amp;lt;value&gt;two&amp;lt;/value&gt;&lt;br /&gt;            &amp;lt;value&gt;three&amp;lt;/value&gt;&lt;br /&gt;        &amp;lt;/list&gt;&lt;br /&gt;    &amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And now here's a MapFactoryBean, which will return a Struct:&lt;/div&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="map.factory" class="coldspring.beans.factory.config.MapFactoryBean"&gt;&lt;br /&gt;    &amp;lt;property name="sourceMap"&gt;&lt;br /&gt;        &amp;lt;map&gt;&lt;br /&gt;            &amp;lt;entry key="one"&gt;&amp;tl;value&gt;hello&amp;tl;/value&gt;&lt;br /&gt;            &amp;lt;entry key="one"&gt;&amp;lt;value&gt;world&amp;lt;/value&gt;&lt;br /&gt;        &amp;lt;/map&gt;&lt;br /&gt;    &amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Now I can use the ref tag for these maps and lists instead of directly defining them.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="testBean" class="coldspring.tests.testBean" lazy-init="false"&gt;&lt;br /&gt;    &amp;lt;property name="myList"&gt;&lt;br /&gt;        &amp;lt;ref bean="list.factory"/&gt;&lt;br /&gt;    &amp;lt;/property&gt;&lt;br /&gt;    &amp;lt;property name="myMap"&gt;&lt;br /&gt;        &amp;lt;ref bean="map.factory"/&gt;&lt;br /&gt;    &amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This may seem like a lot of extra xml, but it can really help with configuration reuse, or providing simpler mechanisms for overriding properties for unit tests. Of course if you find yourself wrapping structs or arrays with components just because you are working with ColdSpring, well, now you don't have to.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-4751643462696013746?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/4751643462696013746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=4751643462696013746&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/4751643462696013746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/4751643462696013746'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/11/more-coldspring-updates.html' title='More ColdSpring updates!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-9031813276649611444</id><published>2007-11-23T17:56:00.001-08:00</published><updated>2007-11-23T18:14:02.148-08:00</updated><title type='text'>Long, long awaited ColdSpring updates!</title><content type='html'>Ok, it's been a while I admit, and I have been pretty damn quiet up in this here blog, however, I have a serious new goal. That goal is a ColdSpring 1.2 release, and it's going to be SOON!. So, to that end, I'm just going to post my activity so you know where we're at. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have committed 2 fixes that should make Mark Mandel and Barney B really happy. &lt;a href="http://code.coldspringframework.org/browse/CSP-84" target="_blank"&gt;CSP-84&lt;/a&gt; has been fixed, which is a problem where setting lazy-init to false does nothing at all. (Ooops it was never implemented, sorry...). You can now define the lazy initialization on a per bean basis with the lazy-init attribute, or set the global default by specifying default-lazy-init on the root bean element. &lt;a href="http://code.coldspringframework.org/browse/CSP-83" target="_blank"&gt;CSP-83&lt;/a&gt; was a semi bug that actually resulted in extraneous try/catching, but basically I had a bug that made it a little difficult to create custom factories. This is different than defining one bean as a factory for another bean with the factory-bean attribute. If you register a bean that extends coldspring.beans.factory.FactoryBean, that bean will automatically have getObject() called on it when you call getBean(). This can really come in handy for some advanced configuration. I know Mark Mandel was working with it, but ran into some bugs. But it is now fixed, happy day!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OK, that's it for right now, there is A LOT more to come...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-9031813276649611444?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/9031813276649611444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=9031813276649611444&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/9031813276649611444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/9031813276649611444'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/11/long-long-awaited-coldspring-updates.html' title='Long, long awaited ColdSpring updates!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-9211672458765910168</id><published>2007-06-11T05:00:00.000-07:00</published><updated>2007-06-11T05:05:31.101-07:00</updated><title type='text'>Flex 3 beta Now on Labs!</title><content type='html'>Well, that pretty much sums it up, Flex 3 aka AIR (not too sure of that codename myself!) is now available on &lt;a href="http://labs.adobe.com/"&gt;Adobe Labs&lt;/a&gt;. It sure looks like the RIA space is really heating up now. I know a lot of Flex developers have had harsh criticism on &lt;a href="http://silverlight.net/"&gt;MS Silverlight&lt;/a&gt;, and based on current tools alone, I would say rightly so. But the fact of the matter is, MS has arrived at the party. There was also a very interesting exchange in the &lt;a href="http://d5.allthingsd.com/20070531/video-steve-jobs-and-bill-gates-together-part-3-of-7/"&gt;interview with Bill Gates and Steve Jobs&lt;/a&gt; where they discussed the importance of RIAs, both clearly stating that their companies where committed to the idea of richer applications connected to what they called the 'swarm', I believe. And today, we have a brand new beta of Flex, Adobe is clearly leading this market right now, it's so exciting to see the technology pick up in pace! So get yourself some air and enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-9211672458765910168?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/9211672458765910168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=9211672458765910168&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/9211672458765910168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/9211672458765910168'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/06/flex-3-beta-now-on-labshttpwwwbloggerco.html' title='Flex 3 beta Now on Labs!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-6774147186721201192</id><published>2007-03-26T18:10:00.000-07:00</published><updated>2007-03-26T18:23:58.177-07:00</updated><title type='text'>cf.Objective() session updates</title><content type='html'>I finally got my sessions to Jared, and he has &lt;a href="http://www.cfobjective.com/conference/index.cfm?event=page.sessions"&gt;posted an updated list&lt;/a&gt;. I'm going to be doing an introduction to AOP as well as a session concentrating on using ColdSpring to power your Flex applications. Don't forget, early bird pricing will end April 1st, so you better &lt;a href="http://www.cfobjective.com/conference/index.cfm?event=page.register"&gt;get on your tickets&lt;/a&gt; quick! Honestly, $395 is an absolute steal for the amazing amount of top notch sessions that your going to be getting. Last year cf.Objective() was no doubt the best CF conference around, and this year it looks to be even better, so go register! Right now!&lt;br /&gt;&lt;br /&gt;I am also bringing my Flex/ColdSpring session to &lt;a href="http://cfunited.com/"&gt;CFUnited&lt;/a&gt;, which is also shaping up to be another great conference, so go &lt;a href="https://secure.teratech.com/cfunited07/register.cfm"&gt;register for CFUnited&lt;/a&gt; too! Honestly, the value of conferences like these cannot be measured. I got my shinny newish job at &lt;a href="http://www.cynergysystems.com/"&gt;Cynergy Systems&lt;/a&gt; through contacts I made at CFUnited last year (along with &lt;a href="http://www.cbetta.com/blog/index.cfm"&gt;Dave Carabetta&lt;/a&gt;). If your looking for the best way to advance your career with marginal expense, these conferences are surely your best bet. See you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-6774147186721201192?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/6774147186721201192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=6774147186721201192&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/6774147186721201192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/6774147186721201192'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/03/cfobjective-session-updates.html' title='cf.Objective() session updates'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-5650370126506434153</id><published>2007-01-29T17:09:00.000-08:00</published><updated>2007-01-29T17:56:55.576-08:00</updated><title type='text'>Unlocking the power of CF Metadata</title><content type='html'>Lately I have been thinking an awful lot about metadata. We have this great metadata object in CF, but I rarely hear anything about it. Funny, even though we use metadata extensively in ColdSpring, I sort of forgot it was there for day to day use. ColdFusion's metadata object is free for the use in almost any way we want, and can provide extremely powerful class or method level annotations. Let's take a quick look at an example so you can see what I'm getting at. Write yourself any cfc, and write a simple cfm page to dump it's metadata:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfset obj = CreateObject('component','com.foo.mycfc').init() /&gt;&lt;br /&gt;&amp;lt;cfdump var="#getMetadata(obj)#" /&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will output a big struct with all sorts of information about your object, like its name, extends, path, and lots of information its functions, like name, access, etc. There's a whole lot of great information for you to use, but what's really cool is, you can put your own stuff in there.  Just make sure you don't try to overwrite any attributes that ColdFusion uses. This can be easily accomplished by using a prefix to create your own namespace. For my examples we'll use 'cs_' for our attributes. So lets add some custom metadata to our cfc. In the cfcomponent tag, lets add an attribute 'cs_metadata="really cool stuff"' (&amp;lt;cfcomponent name="mycfc" cs_metadata="really cool stuff"...) and run the cfm page we made in the previous example. Check out the output, now we have a cs_metadata key with the value "really cool stuff". Really cool, huh? Or are you thinking, so what? The thing that got me all excited about this is, if we use annotations on methods in our cfcs, we can access them in Advice components (you knew I was gonna get to some AOP right?), which is in fact really really cool stuff.&lt;br /&gt;&lt;br /&gt;The great thing about AOP is it gives you the ability to develop abstract systems in an extremely generic manner. But when we apply them to specific components, we want them to take on more concrete functionality. The easiest way to do this is to provide your Aspects with parameters during configuration, enabling them to become more specialized to your components. For example, in the Klondike record store example I have been showing in my sessions, I have a generic caching system which can be configured for each type of component to cache by providing information to the Aspects. But the downfall of this is, I have to configure that Aspect over and over in ColdSpring for each model component. Enter metadata!&lt;br /&gt;&lt;br /&gt;Let's take a look at a super simple system, one that always show up in any AOP conversation, logging. It's pretty easy to write a very general logging system. I like to wrap the logging in a service so we can reuse it anywhere, and provide log level methods, info(message), warn(message), error(message), debug(message), this way I can swap out cflog for log4j and control the log level in one place. Now all we need is an Aspect that will build a log statement from a method call. What if we would like more control, say to only include certain parameters for certain methods. This would be a nightmare if we tried to provide some sort of configuration to the Aspect, but we can easily put this info in the function metadata and read in in the Aspect! Here's how it's done, first we'll add some metadata to a cfc that we want to log method calls, notice I have added a cs_LogFields attribute:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent displayname="EntryService"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;... init method and setters for dependencies ...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name="getEntriesByCategoryID" access="public" returntype="array" cs_LogFields="categoryID" output="false" &gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="categoryID" type="numeric" required="true" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="numToReturn" type="numeric" required="false" default="-1" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="activeOnly" type="boolean" required="false" default="true" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn variables.entryGateway.getEntries(arguments.numToReturn, arguments.activeOnly, arguments.categoryID) /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;... more service methods ...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/cfcomponent&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Next we have our logging service, I've used cflog in this example and added a setter for the log file name.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent displayname="LoggingService"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name="init" returntype="net.litepost.component.logging.LoggingService"  access="public" output="false"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn this /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&gt;&lt;br /&gt;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name="setFilename" access="public" returntype="void" output="false"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="filename" type="string" required="true" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.filename = arguments.filename&amp;nbsp;&amp;nbsp;/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&gt;&lt;br /&gt;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name="info" access="public" returntype="void" output="false"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="message" type="string" required="true" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cflog file="#variables.filename#" type="information" text="#arguments.message#"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;... rest of logging methods ...&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;&amp;lt;/cfcomponent&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So now we will need an Advice class to tie it all together. I am going to use an AfterReturningAdvice for this one, it's going to be a bit more complex, so I'll put some comments in line.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent name="loggingAdvice" extends="coldspring.aop.AfterReturningAdvice"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- setters for the logging service ---&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name="setLoggingService" returntype="void" access="public" output="false"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hint="Dependency: security service"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="loggingService" type="net.litepost.service.LoggingService" required="true"/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.m_loggingService = arguments.loggingService /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&gt;&lt;br /&gt;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name="afterReturning" access="public" returntype="void"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="returnVal" type="any" required="false" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="method" type="coldspring.aop.Method" required="false" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="args" type="struct" required="false" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="target" type="any" required="false" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var arg = '' /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var argString = '' /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var logFields = "" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- first I need the metadata for the target object of the method call ---&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var objMd = getMetadata(arguments.target) /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var objName = objMd.name /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- I also need the name of the method that was called ---&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var methodName = method.getMethodName() /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- I will use a private function to retrieve the metadata for that function ---&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var functionMd = getFunctionMetadata(objMd,methodName) /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- We use StructKeyExist to find our custom attribute, which we use as the logFields. If the attribute is missing, we are going to assume we want to log all the arguments to the method call ---&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif StructKeyExists(functionMd, "cs_LogFields")&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset logFields = functionMd.cs_LogFields&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfelse&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset logFields = StructKeyList(args)/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- now all we need to do is loop over our logFields list, and build out a string from those values (restricting to simpleValues) ---&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfloop list="#logFields#" index="arg"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif StructKeyExists(args, arg) and isSimpleValue(args[arg])&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif len(argString)&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset argString = argString &amp; ', ' /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset argString = argString &amp; arg &amp;amp; '=' &amp; args[arg] &gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfloop&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- Now send it to the logging service! ---&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.m_loggingService.info("[" &amp; objName &amp;amp; "] " &amp; method.getMethodName() &amp;amp; "(" &amp; argString &amp;amp; ") called!") /&gt;&lt;br /&gt;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&gt;&lt;br /&gt;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- here's our private method to retrieve just a particular function metadata from the full metadata from a cfc ---&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name="getFunctionMetadata" access="private" returntype="struct" output="false"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="metadata" type="struct" required="true"/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name="function" type="string" required="true"/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var ix = 0/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var mdFunctions = arguments.metadata.functions/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfloop from="1" to="#ArrayLen(mdFunctions)#" index="ix"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif mdFunctions[ix].name EQ arguments.function&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn mdFunctions[ix]/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfloop&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn StructNew()/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/cfcomponent&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;If you've followed any of my previous AOP posts, you should have no problem setting all this up in your ColdSpring config file. I'll also include those links. This may look a bit complex at first sight, but look what we are gaining now. I could have provided setters to my advice class, allowing the application developer to configure it to specific uses, but that would mean they would need to configure this class over and over again for each different use, as I did for my caching system. By creating my advice class to read metadata, though, I have still provided that same customization, but this time with minimal work for the developers. Plus, we have provided the power of configuration right where the developer is working, in the cfcs themselves. This may not be the best way to go for all systems by any means, I still feel that the real power of ColdSpring AOP is its declarative approach, and it can be argued that this is going in the opposite direction. But the sheer power of this approach can open many doors to designing truly generic systems. For me that is the ultimate goal of AOP.&lt;br /&gt;&lt;br /&gt;Happy programming, and I hope to see some readers at the frameworks conference where I plan to get a lot more in-depth into these concepts both in my session and drinking in the bar! See you!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://cdscott.blogspot.com/2005/09/introduction-to-coldspring-aop.html"&gt;Introduction to ColdSpring AOP&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cdscott.blogspot.com/2005/10/coldspring-aop-tutorial-part-one.html"&gt;ColdSpring AOP Tutorial – Part One&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cdscott.blogspot.com/2005/11/coldspring-aop-tutorial-part-two.html"&gt;ColdSpring AOP Tutorial – Part Two, Around Advice &lt;/a&gt;&lt;br /&gt;&lt;a href="http://cdscott.blogspot.com/2006/02/introducing-auto-magic-remoting-with.html"&gt;Introducing auto-magic Remoting with ColdSpring&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-5650370126506434153?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/5650370126506434153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=5650370126506434153&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/5650370126506434153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/5650370126506434153'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/01/unlocking-power-of-cf-metadata.html' title='Unlocking the power of CF Metadata'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-8671073535935894552</id><published>2007-01-26T10:59:00.000-08:00</published><updated>2007-01-26T11:06:14.630-08:00</updated><title type='text'>I'm the quintessential CF Developer!!</title><content type='html'>WOW! I can't believe it!  I'm actually the quintessential CF Developer, &lt;a href="http://www.buntel.com/blog/index.cfm?mode=entry&amp;amp;entry=54DB3FFD-4E22-1671-5BDCF74737695F12"&gt;as far as Tim Buntel is concerned&lt;/a&gt;! He was a little off on his meme though, so I thought I would update it, make it a little more accurate:&lt;br /&gt;&lt;br /&gt;Chris, the web developer persona&lt;ul&gt;&lt;li&gt;   38 years old&lt;/li&gt;&lt;li&gt;   Married for 7 years, has a 5.5 year old son named Tommy and a 3 year old named Simon. They both are insane about Star Wars Legos&lt;/li&gt;&lt;li&gt;   Drives a 2004 Honda Accord (which the wife stole), 1998 Volvo V70, and 1999 BMW r1100s (which is the greatest feat of engineering ever created. And it's yellow, oooh yellow...)&lt;/li&gt;&lt;li&gt;   Bought a house a 6 years year ago, a 1885 Stone Victorian, slowly renovating. Decorations are partially vintage, but not really.&lt;/li&gt;&lt;li&gt;   Likes the "I'm a Mac, I'm a PC" tv commercials, hates the UPS "Whiteboard" ads. OK, Right on 100%. Except I like the PC guy and the Mac guy is a pompous twit. But I have been a hard core Mac enthusiast my whole life. Hey we had a Lisa for christ's sake!&lt;/li&gt;&lt;li&gt;   Couldn't give a rat's ass about the Oscars&lt;/li&gt;&lt;li&gt;   Into How It's Made, Mythbusters, secretly watches American Chopper even though I hate it, random nature and science stuff&lt;/li&gt;&lt;li&gt;   Likes snowboarding. Wait, really likes snowboarding, really. I actually started when they were planks of wood with a rope on the nose and freaking water ski bindings. (And yeah, we wore an onion on our belt)&lt;/li&gt;&lt;li&gt;   Food? A little bit of everything, especially if it's on the grill&lt;/li&gt;&lt;li&gt;   Music? Let's put it this way. I added American Hardcore to my netflix queue last night, and am giddy as a school girl waiting for that damn movie to actually come out on DVD. Seriously I cannot even believe I missed it in the theater. And the new Slayer is AMAZING&lt;/li&gt;&lt;li&gt;   I lost a lot of hours watching Devo videos on youtube. I do not know why...&lt;/li&gt;&lt;/ul&gt;Help Tim, what's your persona??&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-8671073535935894552?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/8671073535935894552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=8671073535935894552&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/8671073535935894552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/8671073535935894552'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/01/im-quintessential-cf-developer.html' title='I&apos;m the quintessential CF Developer!!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-1837696645285885074</id><published>2007-01-26T10:04:00.000-08:00</published><updated>2007-01-26T10:17:26.928-08:00</updated><title type='text'>Some Excellent Flex articles...</title><content type='html'>Kind of late on this, but in case you missed em, a couple of &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Cynergy&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;coworkers&lt;/span&gt; / Flex super gurus have &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;written&lt;/span&gt; some must read flex articles you probably want to check out.&lt;br /&gt;&lt;br /&gt;First up, Andy Trice did a &lt;a href="http://www.cynergysystems.com/blogs/page/andrewtrice?entry=census_mashups_using_strikeiron_web"&gt;killer &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;mashup&lt;/span&gt;&lt;/a&gt; with Yahoo Maps and &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;StrikeIron's&lt;/span&gt; census web service. Really cool demo, and of course &lt;a href="http://www.cynergysystems.com/blogs/page/andrewtrice"&gt;Andy's blog&lt;/a&gt; is pretty much a must read.&lt;br /&gt;&lt;br /&gt;Andy and &lt;a href="http://www.cynergysystems.com/blogs/page/keunlee"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Keun&lt;/span&gt; Lee&lt;/a&gt; also wrote a great article, second in a series on &lt;a href="http://www.adobe.com/devnet/flex/articles/frontback_pt2.html"&gt;Building &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;RIAs&lt;/span&gt; from front to back&lt;/a&gt; at Adobe's Dev center. Part one was also written by Carson &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Hager&lt;/span&gt; and Dave Wolf, &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Cynergy&lt;/span&gt; execs and killer developers too. Some really great stuff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-1837696645285885074?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/1837696645285885074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=1837696645285885074&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/1837696645285885074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/1837696645285885074'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/01/some-excellent-flex-articles.html' title='Some Excellent Flex articles...'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-5578391912159452729</id><published>2007-01-01T09:45:00.000-08:00</published><updated>2007-01-01T10:15:13.099-08:00</updated><title type='text'>Happy New Year! (From ColdSpring too!)</title><content type='html'>Happy new year everybody! Or should I just list out my limited readership by name? 2006 was a very crazy year for me, good in a lot of ways, completely crazy in others, so good riddens, but only sort of. I thought that today would be a really good day to sit back and relax, but instead I decided to work on some ColdSpring. Oh well. I'll relax later. So does that mean there's something new to announce? You bet! And you can thank Sean for bugging me, too.  ColdSpring now supports the &lt;alias&gt; tag! Here's how it's used:&lt;br /&gt;&lt;br /&gt;Lets say you have a bean defined, perhaps a reactor factory like the following, which you have referenced all throughout a complex configuration file:&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="myReactorFactory" class="reactor.reactorFactory"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;constructor-arg name="configuration"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;/config/reactor.xml&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/constructor-arg&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;br /&gt;&lt;br /&gt;Now let's say you have switched architectures to something like Model-Glue:Unity, and you want to use that same reactor factory. But there is a problem, because Unity wants that bean to be named 'ormService'. Previously you would need to change the bean's id, and then all the bean ref tags, but now can just simply define an alias, like so:&lt;br /&gt;&lt;br /&gt;&amp;lt;alias name="myReactorFactory" alias="ormService"/&gt;&lt;br /&gt;&lt;br /&gt;Walla! Done and done. Now that's just damn handy! This is still a work in progress, so feedback and testing would be great. Happy New Year (again)!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-5578391912159452729?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/5578391912159452729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=5578391912159452729&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/5578391912159452729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/5578391912159452729'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2007/01/happy-new-year-from-coldspring-too.html' title='Happy New Year! (From ColdSpring too!)'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-116295600417038181</id><published>2006-11-07T19:14:00.000-08:00</published><updated>2006-11-07T19:20:04.183-08:00</updated><title type='text'>Thank you Pennsylvania!</title><content type='html'>The concession speech has just ended, and for the first time in many years I can finally again be proud of our political process. Having Santorum for a Senator of the state where I was born and raised has certainly not been something to be proud of, but we can all breath easy and be a little happier. Thanks again PA!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-116295600417038181?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/116295600417038181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=116295600417038181&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/116295600417038181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/116295600417038181'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/11/thank-you-pennsylvania.html' title='Thank you Pennsylvania!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-115776816162252234</id><published>2006-09-08T19:13:00.000-07:00</published><updated>2006-09-08T19:16:01.646-07:00</updated><title type='text'>New Job's Resolution...</title><content type='html'>Rock! I simply could not help myself, isn't she a beauty?&lt;br /&gt;&lt;br /&gt;&lt;img src="http://static.flickr.com/96/238046029_57d711326d.jpg" width="375" height="500" alt="Bring on the metal..." /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-115776816162252234?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/115776816162252234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=115776816162252234&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115776816162252234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115776816162252234'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/09/new-jobs-resolution.html' title='New Job&apos;s Resolution...'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-115566475276041319</id><published>2006-08-15T10:52:00.000-07:00</published><updated>2006-08-15T10:59:32.203-07:00</updated><title type='text'>Congratulations Paul and Adam!</title><content type='html'>In case you haven't heard, Adobe has aquired two great members of our community, Paul Kenney and Adam Way[ne Lehman]. Read about &lt;a href="http://corfield.org/blog/index.cfm/do/blog.entry/entry/Paul_Kenney_to_join_Adobe"&gt;Paul's job&lt;/a&gt; with Sean, and &lt;a href="http://http://www.buntel.com/blog/index.cfm?mode=entry&amp;amp;entry=0E32EA10-4E22-1671-5A32FF89F738E4AB"&gt;Adam's new job&lt;/a&gt; as North America's new ColdFusion Specialist (that's a hell of a title Adam!).&lt;br /&gt;&lt;br /&gt;Best of luck to both of you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-115566475276041319?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/115566475276041319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=115566475276041319&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115566475276041319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115566475276041319'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/08/congratulations-paul-and-adam.html' title='Congratulations Paul and Adam!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-115534321421001590</id><published>2006-08-11T17:21:00.000-07:00</published><updated>2006-08-11T17:40:14.250-07:00</updated><title type='text'>One ColdFusion 8 wish...</title><content type='html'>There's a lot of good lists out there, and sure I've got a few wishes, many of which have been said before. But there's one in thing I don't think anyone has mentioned that I really think would be incredibly useful. I would like to see better packaging options in CF 8. We can package up applications along with CF and deploy them as ears, which is great, but I'm more talking for library code. What I would really like to do is just have modelglue or cfcunit as a .jar file, drop it in a mapping or custom tags directory and be all set. This has nothing to do with trying to 'lock' the code mind you. Take cfcUnit for instance, Paul has a packaging structure of org.cfcunit.*, which is all fine, except for I have a client who's packages also start with org. So I can either create a mapping for org, and put both sets of code in there, or make a specific mapping for org.cfcunit. Personally I think it would be a hell of a lot more flexible to just be able to use .jar files and skip the mappings. CF should be able to figure out what's where by the manifest files.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-115534321421001590?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/115534321421001590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=115534321421001590&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115534321421001590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115534321421001590'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/08/one-coldfusion-8-wish.html' title='One ColdFusion 8 wish...'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-115465156380551741</id><published>2006-08-03T17:25:00.000-07:00</published><updated>2006-08-03T17:32:43.816-07:00</updated><title type='text'>Going to MAX 2006?</title><content type='html'>I'm trying to get my travel plans together quick so I can get a decent price on a flight, but even though the discount on rooms is very good, they still don't come cheap! So I'm looking to share a room, any takers?? If you're interested, post a comment, or hit me up on IM (my gmail address is on my resume, check the hire me link). &lt;br /&gt;&lt;br /&gt;I like to stay up very late and I think I like beer, so take that into account...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-115465156380551741?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/115465156380551741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=115465156380551741&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115465156380551741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115465156380551741'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/08/going-to-max-2006.html' title='Going to MAX 2006?'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-115431099540014923</id><published>2006-07-30T18:12:00.000-07:00</published><updated>2006-07-30T19:06:50.386-07:00</updated><title type='text'>Thank you Paul and John Paul!</title><content type='html'>You know it's been a while since I had one of those days where I truly had a great time writing code. Could be all the Java I've been working on these days, or maybe a few other reasons, but I've been feeling a little bogged down lately and it sure was nice to have a fun time coding again. So why was yesterday so nice you may ask? Well I'm back to some contracting work that I was working on last year on a well designed system written in ColdFusion, for one thing. And it's been quite easy to jump right back in to the system, which in itself is a testament to good design. But what made yesterday even that much better than the breath of fresh air which is working with ColdFusion was a little gift that Paul Kenney sent me the other day. I know, Sean has already told you about the wonderful new cfcUnit with Ant integration, brought to you via John Paul Ashenfelter, but I simply must sing it's praises again! Now I am a huge believer in TDD or Test Driven Development. JUnit is a big part of my development cycle these days, and I do try to use cfcUnit as much as I can. But to be honest, unit testing in cf has been pretty far behind Java, and the main reason is the fact that I want to test &lt;span style="font-style: italic;"&gt;while&lt;/span&gt; I'm coding, immediately. Having to deploy (unless you work locally out of a web root), and then go to the cfUnit test runner app, and then load my test case there, well, it's not exactly the greatest. But it is worth it, so I do it. Until now...&lt;br /&gt;&lt;br /&gt;So I finally deployed the new version of cfcUnit and stuck the ant-cfcunit.jar somewhere easy, in an ant-cfcunit directory in my home folder, btw, put together a quick build script and, well a few minor glitches, but 15 minutes of tinkering later... cfcUnit tests! Right there in eclipse! And some nice simple output in the console! This is freaking great! (Can you tell I'm excited, btw?) But really, I'm working on very broad changes to the model in this app, top level logic changes that will effectively make changes all over the codebase. So I want to pretty much work in isolation right in test cases before I put these components into the model and check them inside the app logic. What I want to do is work in complete isolation of the rest of the app, and test at a very fine grained level. The great think about being able to do this right in eclipse is, all I have to do is start the cf server, but I never have to leave the editor. Even though running tests from the test runner app is still outside of the application, this just &lt;span style="font-style: italic;"&gt;feels &lt;/span&gt;so much more natural, and, well, I guess more like JUnit. So thank you so much Paul and John Paul, much kudos to you!&lt;br /&gt;&lt;br /&gt;Since it would be helpful of course to show how this is done, here we go. As I said, I deployed the new, soon to be released cfcUnit to my app server, and put the ant-cfcunit.jar in /Users/Chris/ant-cfcunit/. My build.xml file looks like so:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;project name="tests" basedir="." default="VerboseTest"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="home" location="/Users/chris/"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="hostname" value="localhost"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;taskdef name="cfcUnit"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;classname="org.cfcunit.ant.CFCUnitTask"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;classpath="${home}/ant-cfcunit/ant-cfcunit.jar"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;target name="VerboseTest"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfcunit hostname="${hostname}"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testcase="org.foo.unitTests.AllTests" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verbose="true" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;haltonfailure="true" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;haltonerror="true"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;showstacktrace="true"/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/target&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;target name="SimpleTest"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfcunit hostname="${hostname}" testcase="org.foo.unitTests.AllTests" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verbose="false"/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/target&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/project&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Next, open up the and view, load the build button and hit the little play button, and watch her go! You can see I have the verbose version set as the default, and can change to a simple version if I need. Also, I have set up a test suite, and each time I change a cfc, I write a test case and add it to the suite. So there you have it, now go and test!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-115431099540014923?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/115431099540014923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=115431099540014923&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115431099540014923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115431099540014923'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/07/thank-you-paul-and-john-paul.html' title='Thank you Paul and John Paul!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-115298229079965981</id><published>2006-07-15T09:41:00.000-07:00</published><updated>2006-07-15T09:51:30.813-07:00</updated><title type='text'>mysql quick-tip</title><content type='html'>I just ran into an issue with rebuilding a mysql database for development, moving the database from a windows server to a linux one. By default windows mysql converts tables names to lowercase, when I imported the database onto my linux server all the filenames for the tables are also of course going to be lowercase. Unfortunately all of the app's queries refer to the tables with camel-case, probably the intention in the first place. Problem is, now my linux mysql instance cannot find any of these tables, because the filenames are lowercase. So how do we fix this? Well, luckily we can start mysql with the flag 'lower_case_table_names', set it to true and mysql will now force tables name to lowercase just like in windows:&lt;br /&gt;&lt;br /&gt;[chris@myFC4box ~]$ sudo mysqld_safe --lower_case_table_names=1 --user=mysql&lt;br /&gt;&lt;br /&gt;Hope that helps if anyone else gets in this bind!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-115298229079965981?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/115298229079965981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=115298229079965981&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115298229079965981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115298229079965981'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/07/mysql-quick-tip.html' title='mysql quick-tip'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-115258580176572556</id><published>2006-07-10T19:41:00.000-07:00</published><updated>2006-07-10T19:43:21.780-07:00</updated><title type='text'>Pointcuts, even more fun with regex!</title><content type='html'>Ok, so maybe 'fun' isn't the right word, but I have to say that I though it was pretty damn cool the first time I swapped out a pointcut for a regex one (yesterday)! Incase you're already wondering what the heck I'm blabbering on about, currently ColdSpring has a pretty simplistic pointcut model, you can only really define them as globs, strings which can contain the '*' wild-card. Simple, yes, but in that simplicity lies tremendous power, which is what I find so fascinating about AOP in the first places. So currently we can match all the set or get methods in an object by defining a pointcut with the mappedName 'set*' or 'get*', and just for a refresher, we would do that by creating an advisor like so (here we are providing a cachingAdvice):&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="cachingAdvisor" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class="coldspring.aop.support.NamedMethodPointcutAdvisor"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="advice"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="cachingAdvice" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="mappedNames"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;get*,set*&lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Here we are defining a NamedMethodPointcutAdvisor and providing it a list for mapped names, get* and set*. Side note, the &amp;lt;list&gt; element in ColdSpring refers to a CF Array, following the Java DTD, to use a CF List provide a string list as a &amp;lt;value&gt;. Behind the scenes, ColdSpring will create a NamedMethodPointcut, and provide it with the mappedNames value. This pointcut is what the framework will use to preform the method matching in order to identify the methods that you would like to add, in this case, the cachingAdvice to. So this is all very good, but what if what we want to do is add caching to all the methods EXCEPT the getters and setters. Ahhh, enter the RegexMethodPointcutAdvisor, which as you would probably guess, will create a RegexMethodPointcut. So lets see how that will look, with a pretty complex regex pattern to match all methods except the setters:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="cachingAdvisor" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class="coldspring.aop.support.RegexMethodPointcutAdvisor"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="advice"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogCachingAdvice" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="pattern"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;^((?!get).)*$&lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So as you can see, we are defining a very similar advisor, but this time we provide a property called 'pattern' which will be our regex pattern. This one's a bit complex as we need to use negative back referencing, which honestly is a bit confusing to me, but google is your friend! But the great part is now we can define methods to exclude from matching, which is tremendously powerful. Want to look for getters and setters? Use this pattern ^((?![g|s]et).)*$ and you should be fine.&lt;br /&gt;&lt;br /&gt;The two new components, RegexMethodPointcutAdvisor and RegexMethodPointcut are available via cvs. Happy AOP'n!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-115258580176572556?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/115258580176572556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=115258580176572556&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115258580176572556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115258580176572556'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/07/pointcuts-even-more-fun-with-regex.html' title='Pointcuts, even more fun with regex!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-115187743696677782</id><published>2006-07-02T14:56:00.000-07:00</published><updated>2006-07-02T14:57:16.980-07:00</updated><title type='text'>CFUnited wrap up, Unit Testing and RHH…</title><content type='html'>I just got back from a nice long ride to clear my head and shake out few neural passageways that seemed to have somehow become clogged with alcohol and lack of sleep, so I figured I would share my thoughts on the festivities of the past week. CFUnited was fantastic and I had a really, really good time, maybe even too good, I’m TIRED! As far as sessions go, I think my 2 favorites were Adam Wayne Lehman (aka. Adam Way)’s talk on security and Dave’s talk on ColdSpring. OK, I know it sounds very partial, right? But Dave was truly amazing; he’s a top-notch speaker and came prepared with an enormous amount of information, which was very well put together. He took his time with the material, and was even able to answer questions while going through the session and still make it through all his slides without rushing. Somehow or another he was able to squash a talk about AOP into 15 minutes and 1 slide and still have it make perfect sense. Dave’s a valuable member of our community and great leader for the ColdSpring project in general. While we’re on the subject of value, I don’t think a single person of any skill level didn’t learn something at Adam’s session on securing CF applications. Adam has a unique experience dealing with security issues in a very tight environment (Department of State), and went through an amazing amount of information, from designing baseline installation documents, to securing your OS (even Windows), to working with CF’s sandbox security. He went on to discuss how to attempt to prevent DoS attacks, and the importance on keeping on top of not only ColdFusion, but also JRun security patches, as well as using the &lt;cfDosAttack = false /&gt; setting in Application.cfm/cfc. Just kidding, it doesn’t exist. Put your documentation away. Unfortunately right as he was discussing a bunch of different cross site scripting attacks, my wife called twice, and I had to leave, so I hope to be able to catch that session again at some future conference. Other sessions worth noting were Paul Kenney and John Paul Ashenfelter’s pre-conference session on Unit testing, and John Paul’s session on Agile development process, which generated quite a stir at the conference. I heard many people talking about the session, even though I missed it. Of course, Sean’s sessions were great, but I have already seen them both, so for me they didn’t garner up as much excitement as the aforementioned. Don’t take that as any recommendation against seeing Sean speak, because you would be doing yourself a great disservice.&lt;br /&gt;&lt;br /&gt;OK, so aside from the sessions, I think one of the most important things I saw at the conference was the prevalence of discussions about unit testing. I talked with many people about how and why we should be unit testing our code. One thing that I repeatedly kept talking to people about however, was trying to write unit tests as early as possible, and not only because it is harder to write tests after your complete large pieces of application code (as you may inadvertently skip functionality that should be tested). In order to be able to write unit tests against individual objects in your model, those objects need to be as self-sufficient as possible, or they are not testable. This is a central concept in what is know as Test Driven Development, where testability is actually designed right into your components. It only takes a second to realize that when components are designed for testability, they become more cohesive and more loosely coupled. For example, lets say we are working on a DAO, and we access form variables in our queries. Well, this DAO is now completely un-testable because it is dependent on the form scope, which means it can only be tested in a running application. How about a service component that retrieves data from a Mach II or ModelGlue event object? Again, we can’t effectively write unit tests for that service because it is dependent on those frameworks. In Dave’s ColdSpring session, he discussed the problems associated with what he called a ‘brittle domain model’ where components are too dependent on other components to get their job done. These types of components are also much harder to unit tests, because you need to create a complex web of objects just to run a test. One of the other big problems with testing complex, dependent model components is, what you end up creating as a test case, is really a q/a type test on use cases. You are testing how a large dependency chain works in what you feel is the real world of your application. But when a small thing needs to change and begins to alter functionality deep down in your domain model, you have very little in place to reflect and catch those problems. As a case in point, within the past month on two separate occasions I made some changes to model objects that made my unit tests fail. I now tend to build unit tests for every single object, and then more unit tests for groups of objects returned as services from Spring. I then build all of those unit tests into one big test suite that I can run when I make some changes, and I can tie them into my build process. Anyway, back to my point, when I made the initial changes, I had introduced some issues that caused problems in other parts of my model. Now the thing is, I would have never caught these problems until q/a, which would have really sucked. One of these issues in fact would have only caused problems some of the time, making it really hard to test and find. However, these changes failed in the unit tests. You’re probably wondering how that could be, and here’s the thing. The components held themselves up when tested together, as services, because they supported each other (and ended up being a little brittle, I suppose), but the tests written against the components themselves actually tested the objects in ways that my application doesn’t necessarily function, making them really effective. The end result was I was able to fix both problems within minutes of running my test suite, but who knows how long debugging would have taken during q/a. Even though it definitely takes extra effort up front, I would strongly suggest looking into unit testing as early as possible, and also do some general research on test driven development, or TDD, there’s some great stuff out there. &lt;br /&gt;&lt;br /&gt;Oh, one last thing about that, as I have discussed, TDD lends itself very nicely to developing more cohesive and looser coupled model components, which just so happens to play very nicely with ColdSpring, which encourages the same thing by decoupling your model components from their dependencies. Wait, you may be thinking, if I decouple my model components from their dependencies, how do I put them together to test them? Well, it only takes 2 lines of code in setup in a test case to load a beanFactory, and just one more to retrieve a bean. As I had also mentioned before, try to test components by themselves as well as with all their dependencies resolved by ColdSpring, it really helps show their weaknesses!&lt;br /&gt;&lt;br /&gt;Happy testing! And oh yeah, RHH!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-115187743696677782?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/115187743696677782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=115187743696677782&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115187743696677782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115187743696677782'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/07/cfunited-wrap-up-unit-testing-and-rhh.html' title='CFUnited wrap up, Unit Testing and RHH…'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-115126307024259195</id><published>2006-06-25T12:02:00.000-07:00</published><updated>2006-06-25T12:17:50.260-07:00</updated><title type='text'>24hrs till CFunited! (Sort of)</title><content type='html'>Well, cfunited is actually 2 days away, but I'm driving down tomorrow to meet Paul K and Adam L (sounds like spy names or something) in Bethesda. I'm speaking at DoS on tuesday, and it's Adam's birthday, so I think the cfunited festivities should start a little early! I'm definitely looking forward to a really fun week, there's a lot of great sessions, and lots of really smart people to hang out with and try to leach some brain power off of!&lt;br /&gt;&lt;br /&gt;I also would like to extend the open invitation to anyone interested to have some adhoc bofs on Aspect Oriented Programming, I'd be happy to do my presentation from cfObjective, and although I haven't asked him, I'm hoping Simeon would take part, because he's been doing some really fantastic and cutting edge stuff with AOP and flex these days.&lt;br /&gt;&lt;br /&gt;OK, can't wait to see everyone there, and oh yeah, if anyone is going to be around BWI tuesday at 3ish and wants to pick up Dave Ross so he doesn't have to take a bus down to the conference, that would be really great. I'm not sure I can make it up there and back for the speaker dinner after the DoS thang...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-115126307024259195?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/115126307024259195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=115126307024259195&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115126307024259195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/115126307024259195'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/06/24hrs-till-cfunited-sort-of.html' title='24hrs till CFunited! (Sort of)'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114989032928668947</id><published>2006-06-09T14:53:00.000-07:00</published><updated>2006-06-09T14:58:49.306-07:00</updated><title type='text'>Go watch this and see your head spin wildly!</title><content type='html'>Check out this &lt;a href="http://www.youtube.com/watch?v=JHmp6E-icQo&amp;eurl=http%3A%2F%2Fclearsoftware%2Enet%2Findex%2Ecfm%3F"&gt;completely nutty video&lt;/a&gt; from Joe Rinehart demoing the new ModelGlue Unity. It's completely insane!&lt;br /&gt;&lt;br /&gt;For those of you who don't yet know, Unity is a wonderful marriage of the ModelGlue, ColdSpring and Reactor frameworks, which WILL change a huge amount of the landscape for many ColdFusion developers. Enjoy, and thanks Joe!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114989032928668947?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114989032928668947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114989032928668947&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114989032928668947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114989032928668947'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/06/go-watch-this-and-see-your-head-spin.html' title='Go watch this and see your head spin wildly!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114928563087267973</id><published>2006-06-02T14:21:00.000-07:00</published><updated>2006-06-02T15:00:30.916-07:00</updated><title type='text'>ColdSpring 1.0 RC1!</title><content type='html'>Well, I think it looks like I'm a little late to the party, because blogger SUCKS and I couldn't log into my own freakin' blog all day, but...&lt;br /&gt;&lt;br /&gt;I'm extremely happy to  announce the availability of &lt;a href="http://www.coldspringframework.org/index.cfm?objectid=95AAEC53-BC65-5B97-1706F209899047DA"&gt;ColdSpring 1.0 RC1&lt;/a&gt;! It's a bit overdue, and of course there will probably be a small wait for the final release, but things seem to be very stable at this point. So please, download the latest and provide some feedback to the list!&lt;br /&gt;&lt;br /&gt;PS, anyone wanting to donate some sweet server goodness to host a nice little mg4j blog app so I can move this damn thing, I'd be soooooo happy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114928563087267973?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114928563087267973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114928563087267973&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114928563087267973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114928563087267973'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/06/coldspring-10-rc1.html' title='ColdSpring 1.0 RC1!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114860999841112110</id><published>2006-05-25T19:17:00.000-07:00</published><updated>2006-05-25T19:19:58.446-07:00</updated><title type='text'>Flex 2, MG4J, and Spring. Bliss...</title><content type='html'>Perfect timing! I just read &lt;a href="http://www.corfield.org/blog/index.cfm/do/blog.entry/entry/Mach_II_Some_Advice" target="_blank"&gt;this post on Sean's&lt;/a&gt; blog, about some of the pitfalls of building Flex front ends for existing Mach II apps and started to write a comment, but it got too long. So I figured I'd just post it. I'm currently working on a big conversion of an application from a very evil and horrible framework to ModelGlue/Spring and Flex 2. This one's Java, but really that's circumstantial at this point, everything is pertinent to CF. I thought it may be an interesting read to write out my development process for this project, so here goes...&lt;br /&gt;&lt;br /&gt;I started by flowcharting everything the current app does, and putting names on each bit of data access that is descriptive (this app is bizarrely procedural in its current form!). From there I could identify what my Services would look like, and what methods they would need. That's pretty simplified, but it was almost that easy... Next I defined my DAOs and in certain places I created custom query objects. Too hard to explain, but there's some pretty hard core business logic about HOW to query for data in a lot of cases. Pretty much at the same time I designed the Domain Objects that I would be using at a higher level, raw data in more fine grained views.&lt;br /&gt;&lt;br /&gt;OK, next step, test like crazy! That's not really true, because I tend to write test cases for every Domain object as I create them, then every DAO/Gateway as I create them, then all the Services, when I hook them up in Spring, and that goes on and on... The main point here is that I'm concentrating on building and testing my model alone, and constructing services, because I know I'm going to be targeting both Flex and a normal web based app.&lt;br /&gt;&lt;br /&gt;So now on to the MG app. Views, controllers, a security system that is pretty standard to what I've been doing for years... This part is pretty easy, in my MG Controllers, I'll put a bunch of stuff in the event, and then I use it in views. Like every one...&lt;br /&gt;&lt;br /&gt;Now I have a nice little MG app, and hey it's in Java and really wasn't too hard to write! Amazing, Spring JDBC was a life savor here, btw... But how does this get into Flex! Luckily since I was thinking ahead, even though I would have done everything this way anyway, accessing Spring managed services from Flex is no big deal. I created remote proxies for each of the services, which look up the Spring bean factory through the application context and then retrieve their respective service bean, then defined them in flex-remote-services.xml. That was well, pretty much it! Then I just wrote the Flex front end, and for the most part, the Java to AS object mapping is perfect. As I got deeper into it my proxies started to look a lot more like my MG controllers, as a single method to the service proxies may call multiple methods on a few different services even, returning data keyed in a hashMap. Kind of like adding data the current event in MG. And that's it, my current development process, and what I've been up to for the past few months. Hope it's helpful!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114860999841112110?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114860999841112110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114860999841112110&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114860999841112110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114860999841112110'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/05/flex-2-mg4j-and-spring-bliss.html' title='Flex 2, MG4J, and Spring. Bliss...'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114739705785267836</id><published>2006-05-11T18:11:00.000-07:00</published><updated>2006-05-12T04:15:32.243-07:00</updated><title type='text'>Today's fluff...</title><content type='html'>OK, I liked the idea of &lt;a href="http://corfield.org/blog/index.cfm/do/blog.entry/entry/My_Most_Played_Album" target="_new"&gt;Sean posting his all time top played album,&lt;/a&gt; so here's a few lists of my own. I was looking at the top play counts for all my music in iTunes, and they're kind of skewed, I think because of the way I listen to music. I'm a big fan of shuffle. But here's some interesting (maybe) things:&lt;br /&gt;&lt;br /&gt;Last 5 albums played (because today I didn't shuffle!)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=65923490&amp;s=143441"&gt;Mastodon - Leviathan&lt;/a&gt;, the saviors of the new Metal? Perhaps, but I doubt it...&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?artistId=49249573"&gt;Minor Threat&lt;/a&gt; - Complete Discography, I'm not going to transfer all my $5 records...&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=19111616&amp;amp;s=143441"&gt;High On Fire - The Art of Self Defense&lt;/a&gt;, Stoner Metal at it's best!&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=3206810&amp;s=143441"&gt;Born Against - Nine Patriotic Hymns For Children&lt;/a&gt;, a huge influence on me...&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=80874901&amp;amp;s=143441"&gt;Gang of Four - Return the Gift&lt;/a&gt;, Last year another great 80s band rerecorded their greatest. I simply cannot stop listening!&lt;br /&gt;&lt;br /&gt;All time most played Songs:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?artistId=150057"&gt;Orange 9mm&lt;/a&gt; - Glistening (Driver Not Included), Used to be the singer of NYC hardcore band Burn, another big favorite&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?artistId=154628"&gt;Clutch&lt;/a&gt; - Mercury (Blast Tyrant), OK, that's a complete surprise, no idea how that happened&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?artistId=16629682"&gt;Gang of Four&lt;/a&gt; - Damaged Goods (Return The Gift / A Brief History of the Twentieth Century), see what I was saying...&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?artistId=93615"&gt;Oingo Boingo&lt;/a&gt; - Private Life (Nothing to Fear), another confusing pick there..&lt;br /&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewArtist?artistId=2987400http://www.blogger.com/img/gl.link.gif"&gt;The Dillinger Escape Plan&lt;/a&gt; - Sugar Coated Sour (Calculating Infinity). Think Praxis, but add more metal. Very odd...&lt;br /&gt;&lt;br /&gt;Well there you go, I'm not sure if that's the best representation of my musical tastes, but it's a pretty interesting way to look at someone. What do you like?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114739705785267836?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114739705785267836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114739705785267836&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114739705785267836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114739705785267836'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/05/todays-fluff.html' title='Today&apos;s fluff...'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114691984435228754</id><published>2006-05-06T05:43:00.000-07:00</published><updated>2006-05-06T05:50:44.366-07:00</updated><title type='text'>Luray, VA, I'm on my way...</title><content type='html'>It's 8:45, Saturday morning and I'm about to leave on a 3 day motorbike trip with my pops. 30 W through southeast PA to Gettysburg, where we'll drive around the civil war battlefields and have lunch. Then 15 S to Frederick MD and on to 340 S/W. We maybe will take a break in Harper's Ferry National Park, then we drive to Front Royal, the top of Shenandoah National Park, where we'll pick up Skyline Drive and go about 1/3 the way to Luray. It should be a great long ride, I'll post picks when I return, and maybe on the way. I hope I keep the paint up!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114691984435228754?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114691984435228754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114691984435228754&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114691984435228754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114691984435228754'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/05/luray-va-im-on-my-way.html' title='Luray, VA, I&apos;m on my way...'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114497780435865206</id><published>2006-04-13T18:19:00.000-07:00</published><updated>2006-04-13T18:23:24.380-07:00</updated><title type='text'>Yeah, I'm a nerd</title><content type='html'>&lt;a href="http://www.nerdtests.com/ft_nq.php?im"&gt;&lt;img src="http://www.nerdtests.com/images/ft/nq.php?val=8792" alt="I am nerdier than 97% of all people. Are you nerdier? Click here to find out!"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Well, I did it at work, in response to reading Sean's post. I wasn't gonna bother putting it on my blog, but after seeing it so much on MXNA, well...&lt;br /&gt;&lt;br /&gt;So the ridiculous part is, I tried to answer the all the questions the same, and jumped from 95 to 97. See, it's like it knew I was going to post it after succumbing to peer pressure, and gave me 2 more points!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114497780435865206?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114497780435865206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114497780435865206&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114497780435865206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114497780435865206'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/04/yeah-im-nerd.html' title='Yeah, I&apos;m a nerd'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114471638289515818</id><published>2006-04-10T17:40:00.000-07:00</published><updated>2006-04-10T17:46:22.946-07:00</updated><title type='text'>ModelGlue 1.1 released, 2.0 coming soon!</title><content type='html'>Congratulations to &lt;a href="http://clearsoftware.net/index.cfm" target="_blank"&gt;Joe Rinehart&lt;/a&gt; on the release of &lt;a href="http://clearsoftware.net/index.cfm?mode=entry&amp;entry=8418221B-E081-2BAC-6993D521C32F4D19" target="_blank"&gt;Model-Glue 1.1&lt;/a&gt;! Joe's been dropping bits of information about the upcoming release for a while now, and I know he's been working really hard, so I'm really happy for him getting this release out. Of course, I have a bit of a vested interest in MG 1.1, because it brings official support for &lt;a href="http://www.coldspringframework.org/" target="_blank"&gt;ColdSpring&lt;/a&gt;, along with a few other bug fixes.&lt;br /&gt;&lt;br /&gt;Along with the news on the 1.1 release, Joe also has &lt;a href="http://clearsoftware.net/index.cfm?mode=entry&amp;amp;entry=8426DAE8-E081-2BAC-69D4727AC6BA1D24" target="_blank"&gt;declared the end of life for MG 1.x&lt;/a&gt; development, because Model-Glue 2.0 is coming, and from what I've heard in dark alleys and late night IMs, 2.0 will be a very exciting release! Funny, at cfObjective, during the frameworks round table (or open source comedy hour) the question came up wether the development of Model-Glue was still active, as Model-Glue seemed to be under represented. Since Joe had been forced to miss the conference due to the fact that he had bought a new house and was a little busy moving, I became the official spokesperson for Model-Glue. I assured everyone that development has been very active, and now you can see why!&lt;br /&gt;&lt;br /&gt;It's a really exciting time right now, and not just for Model-Glue. Mach-II 1.1.0 was released recently, Fusebox 5 is in development, ColdSpring is moving closer to 1.0 daily (really!), Reactor 1.0 is almost out, Transfer, Tartan, cfcUnit, you get the point. These are great times for cf developers! Congratulations again to Joe!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114471638289515818?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114471638289515818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114471638289515818&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114471638289515818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114471638289515818'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/04/modelglue-11-released-20-coming-soon.html' title='ModelGlue 1.1 released, 2.0 coming soon!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114434825688953802</id><published>2006-04-06T11:25:00.000-07:00</published><updated>2006-04-06T11:58:31.923-07:00</updated><title type='text'>40 things about myself…</title><content type='html'>Last night my wife got this meme from a friend in Brooklyn. I thought it was a pretty cool way to know some things about your friends that you may not know. So today I hit up Sean’s blog and what do you know? He’s posted it there! So here goes my entry:&lt;br /&gt;&lt;br /&gt;Four jobs I have had in my life:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;&lt;a href="http://www.retailexpert.com" target="blank"&gt;Retail Expert&lt;/a&gt; - One of a thousand monkeys&lt;/li&gt;   &lt;li&gt;Sealworks - Senior Software Developer&lt;/li&gt;   &lt;li&gt;Urban Folk Art - After college I was a struggling artist in NYC for a while, UFA was an art collective and t-shirt company my fiends and I started&lt;/li&gt;   &lt;li&gt;Krabloonik - Shoveling dog poop, really. Worked for a summer taking care of sled dogs, and yeah they pulled sleds.&lt;/li&gt; &lt;/ol&gt; Four movies I watch over and over:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Blade Runner - Probably my all time favorite movie. I've seen it thousands of times&lt;/li&gt;   &lt;li&gt;Das Boot&lt;/li&gt;   &lt;li&gt;2001: A Space Odyssey&lt;/li&gt;   &lt;li&gt;2,000 Maniacs - Although I haven't seen it in a long time, my friends and I used to watch it religiously&lt;/li&gt; &lt;/ol&gt; Four places I have lived:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Philadelphia, PA&lt;/li&gt;   &lt;li&gt;Brooklyn, NY&lt;/li&gt;   &lt;li&gt;Providence, RI&lt;/li&gt;   &lt;li&gt;Snowmass Village, CO&lt;/li&gt; &lt;/ol&gt; Four TV shows I love to watch:&lt;br /&gt;&lt;br /&gt;OK, so this is tough. I really love tv, but I absolutely hate almost everything on tv right now. I for years believed that tv was a super important artistic device, one that MUST be monitored, at all times. Unfortunately, reality tv has completely destroyed it. So, my 2 cents aside, here's a few:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Simpsons - What's wrong with me! I forgot to put the Simpsons!!!!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Cheers - Man, I watched that show every day for years, and I still catch it time to time. I've had dreams I was hanging out in that bar!&lt;/li&gt;    &lt;li&gt;Coupling - Not on anymore, but still, funny as hell.&lt;/li&gt;   &lt;li&gt;How it's made - I don't know, it's fun to watch with a 5 year old&lt;/li&gt;   &lt;li&gt;C.S.I (I also watched Law &amp;amp; Order for years)&lt;/li&gt; &lt;/ol&gt; * Side note, I watched every variant of Star Trek...&lt;br /&gt;&lt;br /&gt;Four places I have been on vacation:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt; Czech Republic (Prague and all over Moravia)&lt;/li&gt;   &lt;li&gt;Salzburg, Austria (Vienna as well)&lt;/li&gt;   &lt;li&gt;Playa Del Carmen, Mexico&lt;/li&gt;   &lt;li&gt;San Fransico, CA&lt;/li&gt; &lt;/ol&gt; Four websites I visit daily:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;&lt;a href="http://www.corfield.org/blog/index.cfm" target="blank"&gt;An Architect's View&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;&lt;a href="http://clearsoftware.net/index.cfm" target="blank"&gt;clearsoftware.net&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;MXNA - Shortcut to everywhere else I suppose&lt;/li&gt;   &lt;li&gt;www.macromedia.com - I'm all over flex right now&lt;/li&gt; &lt;/ol&gt; Four of my favorite foods:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Pork Chops&lt;/li&gt;   &lt;li&gt;Cheese, all cheese&lt;/li&gt;   &lt;li&gt;Svickova Na Smetane - Czech goodness&lt;/li&gt;   &lt;li&gt;Almost everything my mother in law cooks&lt;/li&gt; &lt;/ol&gt; Four foods I dislike:&lt;br /&gt;&lt;br /&gt;Four? Man, I really like almost all food, but wait, there is..&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Beets - AHHHHHHH, run!&lt;/li&gt;   &lt;li&gt;Tuna fish salad&lt;/li&gt;   &lt;li&gt;Chicken salad&lt;/li&gt; &lt;/ol&gt; I like tuna, I like chicken, I guess I don't like mayonnaise!&lt;br /&gt;&lt;br /&gt;Four places I would rather be right now:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Czech Republic&lt;/li&gt;   &lt;li&gt;Barcelona (forgot to put that on the vacation list)&lt;/li&gt; &lt;/ol&gt; Ahh, I can't get four, I like where I live, and my job is doing well right now&lt;br /&gt;Four friends who I have tagged to do this! Like Sean, I will just post this, do what you will!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114434825688953802?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114434825688953802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114434825688953802&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114434825688953802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114434825688953802'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/04/40-things-about-myself.html' title='40 things about myself…'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114195320179103912</id><published>2006-03-09T17:13:00.000-08:00</published><updated>2006-03-09T17:19:12.740-08:00</updated><title type='text'>Off to cfObjective!</title><content type='html'>My bags are packed, my sessions are prepared, got my travel plans all squared, and I'm ready to go!! OK, actually, I haven't packed at all, I'm totally stressed about my presentations, and I have no idea how to get my eTickets printed out, cuz my printer's all f'd up. But other than that... I am very psyched, it's going to be a great conference! There's still some time for you slackers who haven't decided if you are going to get some tix, so lets go! The speaker list is awesome, the conf is right next to the Mall of Americas so in all your free time, there will be tons to do, right, and the networking opportunities alone are worth double the price of admission. See you there...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114195320179103912?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114195320179103912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114195320179103912&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114195320179103912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114195320179103912'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/03/off-to-cfobjective.html' title='Off to cfObjective!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-114035679608566560</id><published>2006-02-19T05:42:00.000-08:00</published><updated>2006-02-19T06:05:00.803-08:00</updated><title type='text'>Good AOP discussion on The Server Side</title><content type='html'>There's a really interesting &lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=39026" target="_new"&gt;thread on The Server Side&lt;/a&gt;, for anyone interested in AOP and wondering where they might want to use the technology. The original article discusses some the many myths and realities around AOP, also interesting reading. I particularly liked the comment by Bela Ban about how AOP is used in JBossCache, it's a good example of how tool developers are using AOP to create maintainable code in a very abstracted system. On the flip side, about a quarter of the way down there's a good stab at the highly confusing terminology involved with AOP. Very timely for me, because I had a heck of time talking through this with Judith Dinowitz this week, and one of the points I tried to make was that the biggest stumbling block for anyone getting into AOP is probably going to be the terminology. In practice, I think using AOP can be far simpler than in sounds, especially when used with an IoC container like ColdSpring, or Spring for Java. Sometimes I wonder if technologies in Java are purposefully discussed in a very confusing manner, just to keep the faint of hart at bay so the 'gurus' can closely guard their precious secrets. Yet another reason why I like ColdFusion so much, where even very advanced concepts can be discussed in human terms!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-114035679608566560?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/114035679608566560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=114035679608566560&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114035679608566560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/114035679608566560'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/02/good-aop-discussion-on-server-side.html' title='Good AOP discussion on The Server Side'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113977156234121305</id><published>2006-02-12T11:11:00.000-08:00</published><updated>2006-02-12T11:52:21.140-08:00</updated><title type='text'>Introducing auto-magic Remoting with ColdSpring</title><content type='html'>This is kind of a mix between some features that have been available in the ColdSpring BER and some new additions to the AOP framework. Not only is this a kick ass new feature, but it’s also a collaborative effort of Kurt, Dave, and myself, with lots of input from Paul Kenney and Sean Corfield. So kudos goes out to everyone involved! Here’s a general overview of what auto-magic remoting means. Let’s say you have a service component registered with ColdSpring, which does some database access for some piece of a web app. What if we want to take a few of the methods of that service and make them available as remote methods for a flex app, or a web service. Wouldn’t it be nice to simply add a component to the ColdSpring config file that has a list of methods you would like to expose, that will automatically configure itself to your service component, expose those methods as remote, taking care of the CFC to AS object translation for you? How about if you could also simply plug in a security through AOP as well, and pretty much write no additional code at all. Well, that’s exactly what ColdSpring Remoting is all about! So let’s see how we can do this in practice. We’ll start simply, with the configuration of a remote facade, or proxy (it’s sort of a little of both) for a service component, then we’ll add the CFC to AS object translation and finish up with some security. Here’s our service, it’s from the klondike records application available in the BER, in the examples folder.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfcomment"&gt;&amp;lt;!-- catalog service --&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="catalogService" class="net.klondike.component.CatalogService"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="catalogDAO"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogDAO" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="catalogGateway"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogGateway" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt; &lt;br /&gt;&lt;br /&gt;I won’t go into the code for the components, but this service has methods for listing, searching, adding and updating records (as in vinyl, not tables). I would like to create a remote façade to expose the ‘list’ methods, which would be any methods starting with ‘get’. So I’ll configure a RemoteFactoryBean which creates a proxy, writes it to disk at a specified location (so that the ColdFusion flashGateway can find it) and I’ll tell it which methods to include, which will have ‘remote’ access. Here’s the config:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfcomment"&gt;&amp;lt;!-- a remote service bean --&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="remoteCatalogService" class="coldspring.aop.framework.RemoteFactoryBean"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="target"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogService" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="serviceName"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;RemoteCatalogService&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="absolutePath"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;/usr/local/cf7/htdocs/klondike/machii/remoting/&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="remoteMethodNames"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;get*&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt; &lt;br /&gt;&lt;br /&gt;I set the target to the service cfc I already configured, I give this remote service a name and an absolute path (I could also have used the property ‘relativePath’, meaning webroot relative) where I want the RemoteFactoryBean to create the service, and I give it a pattern to match methods on, so in this case all methods that begin with ‘get’ are included as remote methods. That’s it! When ColdSpring starts up, I can ask it to create the service (I’ll get into that part later) and I’m done! No code written at all! This new remote service will now be available at www.yourdomain.com/klondike/machii/remoting/RemoteCatalogService, ready to go. Pretty slick, huh?&lt;br /&gt;&lt;br /&gt;OK, so a few things to point out before I move on. We are using AOP under the hood, so what you are creating is very similar to a proxy object, and it uses the same mechanism for method interception. So what does that mean? Well for one thing, adding translation to and from AS objects to CFCs is a matter of adding a type of around advice configured specifically for remoting. Of course this component is provided by ColdSpring, and the RemoteFactoryBean knows how to configure it for you, all you have to do is properly configure a flashUtilityService and give it to the RemoteFactoryBean. Here’s how we set that up:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfcomment"&gt;&amp;lt;!-- A ColdSpring provided component that inconjunction with flashUtilityService can map ActionScript objects to CFCs. --&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="flashMappings" class="coldspring.remoting.flash.flashMappings"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;constructor-arg name="mappings"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!-- Here we use a "list" element to pass in an array of structures to the constructor --&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;list&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;map&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;entry key="cfcType"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;net.klondike.component.Record&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/entry&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;entry key="asType"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;RecordVO&amp;lt;/value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/entry&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/map&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/list&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/constructor-arg&gt;  &lt;br /&gt;&amp;lt;/bean&gt; &lt;br /&gt;    &lt;br /&gt;&lt;span class="cfcomment"&gt;&amp;lt;!-- A service object which can be used by a remote facade to convert CFCs to ActionScript classes and visa versa --&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="flashUtilityService" class="coldspring.remoting.flash.flashUtilityService"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="flashMappings"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="flashMappings"/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt; &lt;br /&gt;&lt;br /&gt;I’ve defined a ColdSpring flashMappings object with the cfcType and asType to translate between. You provide a list of mappings, each one is defined as a map with a key for the CFC and AS types to translate between. Next I simply define the flashUtilityService and provide the mappings object. So now I just give this service to the RemoteProxyBean defined above. Now the config will look like this, all I have added is the property ‘flashUtilityService’:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="remoteCatalogService" class="coldspring.aop.framework.RemoteFactoryBean"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="target"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogService" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="serviceName"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;RemoteCatalogService&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="absolutePath"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;/usr/local/cf7/htdocs/klondike/machii/remoting/&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!-- add the new flashUtilityService --&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="flashUtilityService"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="flashUtilityService" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="remoteMethodNames"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;get*&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt; &lt;br /&gt;&lt;br /&gt;Now my remote service will do all the translation between AS objects and CFCs for me, viola! So what if I want to add a little security to this service, or some logging? As I said before, we are using AOP; RemoteProxyBean actually extends ProxyFactoryBean, and can be configured with any method interceptors or advisors as well. So adding logging and security is pretty much a breeze. I’m not going to go through setting up those advisors, you can read over my first and second AOP tutorials, but here’s how I add them to the remote service:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="remoteCatalogService" class="coldspring.aop.framework.RemoteFactoryBean"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="target"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogService" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="serviceName"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;RemoteCatalogService&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="absolutePath"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;/usr/local/cf7/htdocs/klondike/machii/remoting/&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="flashUtilityService"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="flashUtilityService" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!-- add the logging and security advisors --&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="interceptorNames"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;list&gt;&lt;br /&gt;    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;loggingAdvisor&amp;lt;/value&gt;&lt;br /&gt;    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;securityAdvisor&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/list&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="remoteMethodNames"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&gt;get*&amp;lt;/value&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/span&gt;&lt;/div&gt; &lt;br /&gt;&lt;br /&gt;There you go! I added the logging and security advisors in the same way as if I was setting up a normal AOP proxy bean, and that’s it. I now have a pretty sophisticated remote service, with type translation, logging and a security framework all built in, and I didn’t write a speck of code, all I did was rewire existing components from my application. Now that’s cool!&lt;br /&gt;&lt;br /&gt;Now all that we need to do is ask ColdSpring to actually create the remote service. There’s a couple of ways you can do this. If you call getBean(‘remoteCatalogService’) on the factory, that will follow the same principles as when using any factory with ColdSpring, and create the service. However, the RemoteFactoryBean has some useful methods for managing remote services, so you may want to retrieve the factory itself from ColdSpring. You can do this by calling getBean(‘&amp;remoteCatalogService’) on the bean factory. This will return an instance of the factory itself and you can then call factory.createRemoteProxy() to create the service, factory.destroyRemoteProxy() to remove it, and factory.isConstructed() to see if the service is ‘alive’. I have some creative uses of the RemoteProxyBean api that I’m looking forward to showing at cf.Objective, so I’ll see you there, and happy remoting!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113977156234121305?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113977156234121305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113977156234121305&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113977156234121305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113977156234121305'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/02/introducing-auto-magic-remoting-with.html' title='Introducing auto-magic Remoting with ColdSpring'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113948727172634749</id><published>2006-02-09T04:11:00.000-08:00</published><updated>2006-02-09T04:15:03.333-08:00</updated><title type='text'>cf.Objective sessions announced!</title><content type='html'>It’s 6:45 in the morning and I just got the &lt;a href="http://cfobjective.com/conference/index.cfm?event=sessions" target="_blank"&gt;cf.Objective session schedule&lt;/a&gt; and it looks so good I just have to tell the world immediately! I have to say that I am very impressed with the way this conference is turning out. Jared has put some extremely hard work into this thing, and it’s really paying off. From what I understand he’s been doing pretty much all of the coordinating by himself, he really deserves all the accolades he can get. But let’s get to the conference, shall we, my nose is getting too brown for comfort here! This is going to be a much more advanced leaning conference that other cf conferences that I have been to, that’s for sure, with a definite lean towards enterprise level application engineering. We have Software Engineering, Advanced Enterprise Engineering, and I’m really happy to see, Enterprise Server Tuning as session tracks, and pretty much every session in each track looks great. I particularly like the very timely mashup of Hal Helms speaking about Duck Typing, followed by yours truly speaking about AOP. We should cover a wide range of typing issues there, I have no idea if we will end up on opposite sides of the fence or not! Matt Woodward is doing OOP for nOObz, S Isaac Daeley on SQL Abstraction, Kevin Schmidt on SMS Gateways, it just goes on and on. I just can not imagine missing this conference if you have any interest in advanced coldfusion at all! So &lt;a href="http://cfobjective.com/conference/index.cfm" target="_blank"&gt;get out and register&lt;/a&gt;! NOW!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113948727172634749?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113948727172634749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113948727172634749&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113948727172634749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113948727172634749'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/02/cfobjective-sessions-announced.html' title='cf.Objective sessions announced!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113711895791879439</id><published>2006-01-12T18:02:00.000-08:00</published><updated>2006-01-12T18:22:37.946-08:00</updated><title type='text'>Mixins in ColdSpring? What would you like?</title><content type='html'>So a while back I was thinking about the ColdSpring AOP framework, and expanding it to support mixins. I really like the idea of doing something like this declaratively, I think it will be much cleaner and easer to debug when configuration is done from outside of your cfcs. What a surprise to read posts by both &lt;a href="http://clearsoftware.net/index.cfm?mode=entry&amp;entry=BC62A7BA-E081-2BAC-690DA2E20D609568" target="_blank"&gt;Joe&lt;/a&gt; and &lt;a href="http://www.corfield.org/blog/index.cfm/do/blog.entry/entry/Mixins" target="_blank"&gt;Sean&lt;/a&gt; today about ways to implement mixins! Well, I'm definitely going to get this started next week, (I really have to finish something first, there's a _remote_ possibility it will be done tomorrow, hint hint...) so if anyone has any wishes, drop a comment and we'll see what we can get in there. I mean, there's not too much to it, we'll be adding methods and perhaps instance data to cfc declaratively, but there were some comments on both blogs that make me think that I'd like to hear how people see using mixins so we can work that into the implementation. Thanks for the input!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113711895791879439?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113711895791879439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113711895791879439&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113711895791879439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113711895791879439'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/01/mixins-in-coldspring-what-would-you.html' title='Mixins in ColdSpring? What would you like?'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113683349866900130</id><published>2006-01-09T11:01:00.000-08:00</published><updated>2006-01-09T11:04:58.670-08:00</updated><title type='text'>Get On the Bus! Register for cf.Objective!</title><content type='html'>Looks like I’ll be speaking at &lt;a href="http://cfobjective.com/conference/" target="_blank"&gt;cf.Objective&lt;/a&gt; in March, along with some really great cf-gurus, Sean Corfield, Hal Helms, Joe Rinehart, Matt Woodward, Jared R, among others. Personally I’m really excited, it looks like Jared’s definitely trying to get this conference wrapped around some advanced enterprise level sessions. So get signed up!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113683349866900130?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113683349866900130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113683349866900130&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113683349866900130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113683349866900130'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/01/get-on-bus-register-for-cfobjective.html' title='Get On the Bus! Register for cf.Objective!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113683281429571276</id><published>2006-01-09T10:49:00.000-08:00</published><updated>2006-01-09T10:53:34.306-08:00</updated><title type='text'>Sean Corfield Spawns More Interface Debate…</title><content type='html'>The debate on whether or not ColdFusion needs interfaces returns, headed up by a really good post by &lt;a href="http://www.corfield.org/blog/index.cfm/do/blog.entry/entry/Interfaces_in_ColdFusion" target="_blank"&gt;Sean Corfield&lt;/a&gt;. There’s some excellent discussion going on in the replies, I’d say this is a definite must read thread. As good as many of the points are, however, I’m not swaying, I want interfaces, and as soon as I get my thoughts together, I’ll show some examples of how they can be used very effectively. One thing I would like to throw in is that interfaces aren’t only about typing and providing a contract for your objects. Interfaces can give your objects sudo-multiple inheritance. Lets say your object extends one base class, but also satisfies the methods for two interfaces, if you have methods in some objects that take arguments of any of those three types, four including the type of the composite object, that object can satisfy any of those type constraints, thus acting as 4 different objects from the point of view of the various methods. If we set the argument types to ‘any’ or ‘WEB-INF.cftags.component’, that method will accept any object, and we void all contractual obligations of our objects, no matter how conceptual they really are in ColdFusion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113683281429571276?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113683281429571276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113683281429571276&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113683281429571276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113683281429571276'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/01/sean-corfield-spawns-more-interface.html' title='Sean Corfield Spawns More Interface Debate…'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113651522012416723</id><published>2006-01-05T18:32:00.000-08:00</published><updated>2006-01-05T18:40:20.140-08:00</updated><title type='text'>Creating ColdFusion’s missing ‘instanceof’ method</title><content type='html'>Yesterday I was going back over some ColdSpring code, implementing some new features, and I came across the answer (sort of) to a question I remember being discussed a while back on CVCDev or topica. How do you find out if an object is an instance of a particular cfc or one of it’s subclasses? Unfortunately, ColdFusion doesn’t have the keyword ‘instanceof’ like Java and C#, which I suppose is far more commonly used in a strongly typed language. Why would it be more necessary? Well, for one thing the O’Reilly C# book I have advocates the use of instanceof before casting, alleviating ClassCastExceptions, but that’s another story. Anyway, I have run into a few situations in ColdFusion where I really need this functionality. So how do we do this in CF? Well, when I looked at what I had written a few months ago, although it works ok, the comment below it, ‘shouldn’t I be looking in the ‘extends’ key only?’, basically pointed out that it was a shotty implementation at best (btw, I looked back over the history of the file, and the original comment was ‘this sucks, I need to do this better later!’), so I asked &lt;a href="http://www.corfield.org/blog/index.cfm" target="blank"&gt;Sean&lt;/a&gt; what he thought about it. Here’s something along the line of the original code I sent him, the main problem here being that by using StructFind() I am searching every key in every nested struct:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"isInstanceOf"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"Boolean"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"obj"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"any"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt;/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"reqType"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"string"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfif ArrayLen(StructFindValue(getMetaData(obj), reqType, &lt;span class="cfvalue"&gt;"ALL"&lt;/span&gt;))&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn true /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfelse&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn false /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&gt;&lt;br /&gt;&amp;lt;/cffunction&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Sean immediately pointed out that that was ok, but slow. Maybe I should search recursively through the extends keys of the metadata. So here’s what I ended up with, which seems a heck of a lot tighter to me. I shied away from the recursive method call, because that seemed it would be putting a little extra overhead on the search, but this implementation seams nice to me, thank for the input Sean!&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"isInstanceOf"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"Boolean"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"obj"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"any"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt;/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"reqType"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"string"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var searchMd = getMetaData(obj) /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfif searchMd.name IS reqType &gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn true /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfelse&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfloop condition=&lt;span class="cfvalue"&gt;"#StructKeyExists(searchMd, "extends")#"&lt;/span&gt;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;lt;cfset searchMd = searchMd.extends /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;lt;cfif searchMd.name IS reqType&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn true /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;lt;/cfif&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfloop&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn false /&gt;&lt;br /&gt;&amp;lt;/cffunction&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113651522012416723?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113651522012416723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113651522012416723&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113651522012416723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113651522012416723'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/01/creating-coldfusions-missing.html' title='Creating ColdFusion’s missing ‘instanceof’ method'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113631406757949512</id><published>2006-01-03T10:47:00.000-08:00</published><updated>2006-01-03T10:47:47.590-08:00</updated><title type='text'>Fresh for 2006… ModelGlue for Java!</title><content type='html'>About a month ago I went down to the DC area to visit with Sean Corfield, Joe Rinehart, Doug Hughes, Scott Boyziod, and a few others, and for some reason Doug and I were talking about his port of ModelGlue for .Net. I don’t know why, maybe for pure masochism, I mentioned that maybe I would be interested in porting ModelGlue to Java. Well Joe though it was a good idea as well, so I decided to give it a go! Over the past month a few people have asked me why I would want to do such a crazy thing, and I do have some reasons! Most importantly, I know a lot of cfers are starting to think about getting into J2EE development, and I know from personal experience, that the initial learning curve, not so much of the language itself, but really of the architecture of J2EE, can stop people in their tracks. Maybe a familiar framework would be a bit of a helping hand? I think so. I’ve done a few J2EE apps and one of the things that I always seem to find myself saying is, ‘man I really like working with mach-ii and modelglue much better that any of these java frameworks’. Struts is too big and too messy for me, SpringMVC is actually pretty nice, but still kind of heavy. For me, I think ModelGlue sits about right for an MVC framework, since it is so lightweight. So I’d like to announce that an early alpha pre-release is not available from svn://clearsoftware.net/clearsoftware.net/ModelGlueJava.&lt;br /&gt;&lt;br /&gt;A few notes about this early release:&lt;br /&gt;&lt;br /&gt;Spring support is built into the framework, but by doing so, it is currently dependent on the spring distribution. Spring.jar is included in the lib folder of the distribution, along with other dependencies such as commons.beanUtils. An example of defining your controllers in a Spring config file can be seen in the Klondike Records sample app.&lt;br /&gt;&lt;br /&gt;I have not implemented asynchronous messaging or session state container support yet, but everything from the current BER of ModelGlue should (maybe) be implemented. &lt;br /&gt;&lt;br /&gt;I did make one possibly major, but really semantic change, that I just thought fit better into java. The viewState that you would normally access in views is called eventModel, and is of type EventModel, which extends HashMap. So add(Object key, Object value) and get(Object key) as well as other HashMap methods are available if getValue(String key [, Object defaultValue]) ) is not to your liking. I just really feel strongly that as a user we are dealing with a model object that is tied to the event when setting/accessing values in our controllers and our views. The names have changed to protect the innocent, but nothing more!&lt;br /&gt;&lt;br /&gt;Final notes, I’m not done at all! I’m hoping an early preview will gain some interest, and maybe some input and assistance from other java/cfers out there, so have fun, and of course, I’ll be changing things for a while!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113631406757949512?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113631406757949512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113631406757949512&amp;isPopup=true' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113631406757949512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113631406757949512'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2006/01/fresh-for-2006-modelglue-for-java.html' title='Fresh for 2006… ModelGlue for Java!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113520261321826698</id><published>2005-12-21T14:01:00.000-08:00</published><updated>2005-12-21T14:03:33.230-08:00</updated><title type='text'>Joe on Inversion of Control!</title><content type='html'>Last night I got into a nice long discussion on the DAL.net coldfusion channel with blanketgirl, no idea who she is, which ended up cornering me into trying to explain why ColdSpring is actually a good thing, not just a whole bunch of xml based hubbub. Unfortunately, since I was relaxing and having a few beers, my defenses didn't go too far past the basics of dependency injection and why I think it so usefull, shots easily deflected by the xml hating blanketgirl! What a surprise to read this &lt;a href="http://clearsoftware.net/index.cfm?mode=entry&amp;entry=4DB6F5E9-E081-2BAC-690C1ABD85AAD94C" target="blank"&gt;excellent post on Inversion of Control&lt;/a&gt; by Joe Reinhart today!. Joe puts out a very solid example on using mock implementations in development, but being able to make deployment changes in the ColdSpring config file, not in code. Hey man, where were you last night when I needed you! Kudos to a very well written post, and since Joe mentions that he will be writing about AOP soon, I'm very much looking forward to some great articles. Thanks again, and blanketgirl, go read up!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113520261321826698?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113520261321826698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113520261321826698&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113520261321826698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113520261321826698'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/12/joe-on-inversion-of-control.html' title='Joe on Inversion of Control!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113500898037760245</id><published>2005-12-19T08:15:00.000-08:00</published><updated>2005-12-19T08:16:20.390-08:00</updated><title type='text'>Defending the Bean</title><content type='html'>Over the last week there’s been some really interesting discussion about the idea of an ‘Anemic Domain Model’ for some reason including rethinking the usage of DAOs. I find it a pretty strange concern, if you want me to be honest. I’m not sure I follow the logic of reorganizing tiers of your domain model just to satisfy this notion that every object MUST have logic in them. Here’s some background, most of this discussion refers to &lt;a href="http://theserverside.com/news/thread.tss?thread_id=38047" target="new"&gt;this thread on TheServerSide&lt;/a&gt; which raises concern over having thin domain objects that are passed into DAOs for persistence instead of knowing how to persist themselves (ActiveRecord pattern, btw). The funny thing is the very first reply sums everything up pretty well by bringing up the analogy of a Cake (your anemic bean), an Oven (your persistence mechanism) and a Baker (which he says is the controller, I’ll get to that). In his scenario he asks the question, does a cake know how to bake itself? Of course not. I have a slightly different take on this example, though. &lt;br /&gt;&lt;br /&gt;You have a bakery, it’s a service, which provides cakes, as well as cookies and bread and what not. Components that make up the bakery, like the refrigerator, the oven, the display case, the baker, are each part of different tiers that, when composed together into the bakery, provide services to return cakes, cookies, bread, etc. Lets look at that oven/persistence tier. What exactly is wrong with putting persistence code into it’s own tier now? Doesn’t that assist in making clean, cohesive components? If I put that logic into the Cake object, isn’t that muddying up the logic of the cake a bit? Personally I find the DAO approach to fit nicely into an organized persistence tier off my applications. And, of course, ColdSpring will assist in building that bakery. Just as a side note, in the TSS thread the consensus was quickly reached that the DAO example was a pretty bad choice. So what was the issue again? Oh yeah the thin business objects.&lt;br /&gt;&lt;br /&gt;This is an argument that has been going on in the Java world for a while now. It’s against using transfer objects, because they don’t actually have any real business logic in them, so they’re not a real objects. I guess it could be said that this is contrary to the basic ideas of object oriented design, ok I guess Martin Fowler can say that. Rod Johnson, the creator of Spring, also warns against writing objects that only contain methods to expose their data, as they are not actual objects. But lets look at this. This is a Java issue. Java has no lightweight typed objects. C# solves this by providing an excellent Struct implementation which is really a lightweight typed class. So when you ask for the ‘name’ you get a String back. Quite different from Java’s alternative, various types of Maps, which all return Objects back, so casting is necessary. For many purposes, using a bean is a better alternative to a map, because getters return data in the correct type (this is addressed with generics in java 5). But wait a second. ColdFusion. Don’t we have a Struct? Of course we do. Any we are dynamically typed, so the casting issues are not a problem.  So if transfer objects are such a problem, why not use Structs, right?&lt;br /&gt;&lt;br /&gt;But wait. I don’t think we’ve really looked at the issues here. There’s more to consider. Typing IS an issue. We need to validate types when putting data INTO transfer objects, we want numbers to be numbers, not strings, just for a simple example of why, consider this. We pass a struct into a gateway object to retrieve all users of typeID=6, our where clause looks like this: WHERE user.typeID = #myStruct.type#. But some wily hacker comes along and figures out how to set that value to ‘truncate table user’. Whoa, hold on! That’s like uh, SUPER BAD! Certainly having a numeric type enforced on that data could have really helped here (any yeah I know, queryparam could help, but that’s not my point). I could have also built a validate method in either the TO or validator object which could have been used by some service object before even attempting to send the TO to the DAO. The point is that even though beans / TOs have little logic in them, their use is a part of a bigger picture, which makes up business logic. I have a novel idea that beans and transfer objects are actually part of architectures which represent logic by design. Isn’t that a huge part of OOP anyway? Complex logic is often represented by the interactions of the objects that make up our domain model. Some of those objects are going to make up our Persistence tier. Some of them are going to make up our Service tier. Some of them are going to be Domain Objects and represent our primary business (we sell books, so we have book objects). And some of those objects may very well be lightweight objects, but they assist in clear separation of our logic, they assist in typing and data validation, they may model forms from our view tier, etc, etc. Are they second class citizens on our domain, no way! Embrace the Bean!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113500898037760245?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113500898037760245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113500898037760245&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113500898037760245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113500898037760245'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/12/defending-bean.html' title='Defending the Bean'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113406989288552781</id><published>2005-12-08T11:23:00.000-08:00</published><updated>2005-12-08T11:24:52.900-08:00</updated><title type='text'>Reinventing the wheel is BAD!</title><content type='html'>I know you’ve probably been told that before, and it’s one thing I’ve told myself over and over again, but sometimes I just forget. I’m working on a soon to be explained, but I’ll keep quite for now, little side project in Java which requires creating beans and setting properties (hint). As I got down into the setProperty methods, I realized the rabbit hole is a lot deeper than I thought. The problem is, I will have a property name and a value that I want to find a method for in some given object. So I can look for methods with reflection, but a lot of issues arise. I have to look for a method that accepts not only the type of value I have, but also any classes it extends, the same goes for interfaces. Also, the bean may accept a primitive type, such as int, but for all sorts of reasons, you may have to wrap that value as an Integer object, which means I need to try to un-box those types (that’s what c# calls it, I can’t remember the java term) as well. After more than an hour, and after all sorts of methods, (setProperty is now becoming a chain of 4 or 5 methods and I’m not done!) I realized I better do some googling to see how this is done in say, Struts. I ended up looking into some apache commons code, initially reading it (dumb), when it struck me. What the hell am I doing? This code is written, and open source! Duh! So I scrapped my code and replaced it with one line of code using commons.beanUtils. &lt;br /&gt;&lt;br /&gt;Moral? Reinventing the wheel is a waste of time! There are lots of GREAT open source solutions to many common problems, the apache commons project is just one of them, specific to Java programming issues. The great thing is, other than the fact that the code is already written, you or I are just one person, dealing with the issues of entire systems. These tools are written by groups of very skilled programmers, they are singularly focused to provide highly tested, well written solutions, which are probably going to be better designed than what you or I are trying to come up with. I spent 2 hours doing something that really only had to take 5 minutes! This is one of the core mantras of the book Better, Faster, Lighter Java, which I guess I forgot for a second.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113406989288552781?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113406989288552781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113406989288552781&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113406989288552781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113406989288552781'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/12/reinventing-wheel-is-bad.html' title='Reinventing the wheel is BAD!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113318829665317857</id><published>2005-11-28T06:11:00.000-08:00</published><updated>2005-11-28T06:31:36.663-08:00</updated><title type='text'>Excellent ColdSpring posts</title><content type='html'>Sometimes the people who write the frameworks may not be the best at explaining them. Too intimate with inner workings, or perhaps too proud and wanting to divulge every - not actually fascinating - bit of alchemy involved. Lucky for me, there's some excellent blogs out there writing about ColdSpring. Scott Barnes posted &lt;a href="http://www.mossyblog.com/archives/550.cfm" target="blank"&gt;Coldfusion on Cruise Control&lt;/a&gt; today, and yesterday Matt Woodward posted &lt;a href="http://www.mattwoodward.com/blog/index.cfm?commentID=212" target="blank"&gt;ColdSpring: Better Model Management&lt;/a&gt;, both great articles and should be helpful to developers just getting their feet wet with ColdSpring. Thanks guys!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113318829665317857?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113318829665317857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113318829665317857&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113318829665317857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113318829665317857'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/11/excellent-coldspring-posts.html' title='Excellent ColdSpring posts'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113227598047239680</id><published>2005-11-17T16:50:00.000-08:00</published><updated>2005-11-17T17:06:20.486-08:00</updated><title type='text'>ColdSpring 0.5.0 Alpha Released!</title><content type='html'>We've just posted &lt;a href="http://www.coldspringframework.org/index.cfm?objectid=9FF5C5C6-0C53-CA93-517C29BB63456B8B" target="new"&gt;ColdSpring 0.5.0 Alpha&lt;/a&gt; over at &lt;a href="http://www.coldspringframework.org" target="new"&gt;www.coldspringframework.org&lt;/a&gt; containing numerous bug fixes and enhancements. The AOP framework should be significantly faster, and also contains a revised AfterThrowing Advice and MethodInterceptor. &lt;a href="http://www.corfield.org/blog/index.cfm" target="new"&gt;Sean Corfield's&lt;/a&gt; Autowire controller for &lt;a href="http://www.model-glue.com" target="new"&gt;ModelGlue&lt;/a&gt; is included along with a revised &lt;a href="http://www.mach-ii.com" target="new"&gt;Mach-ii&lt;/a&gt; plugin which had autowire capabilities, as well as new Remoting helper classes and Hierarchical BeanFactory and Application Context support contributed by Kurt Wiersma&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113227598047239680?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113227598047239680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113227598047239680&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113227598047239680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113227598047239680'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/11/coldspring-050-alpha-released.html' title='ColdSpring 0.5.0 Alpha Released!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113208096316769210</id><published>2005-11-15T10:34:00.000-08:00</published><updated>2005-11-15T11:14:30.223-08:00</updated><title type='text'>ColdSpring AOP Tutorial – Part Two, Around Advice</title><content type='html'>First off, sorry for the long delay in the AOP tutorials. I’ve been working pretty hard on the aop framework for a new release, and I don’t want to blog about features that are not yet available. Since we are going to do a 0.5 release this week, though, it’s time to get back on track. One thing I need to point out is that you will need to get the latest BER from CVS to try these examples, unless you already have the 0.5 release. Ok, so lets get back to where we left off. We previously talked about writing Before Advice to provide logging services to CatalogDAO. Although I didn’t discuss After Advice, we could have accomplished the same thing, with the added ability to log information about the return values from the method calls in our loggingAdvice by extending coldspring.aop. AfterReturningAdvice and putting the logging code in the method ‘afterReturning()’ instead of ‘before()’. Lets take a quick look at what that advice object would look like:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent name=&lt;span class="cfvalue"&gt;"loggingAfterAdvice"&lt;/span&gt; extends=&lt;span class="cfvalue"&gt;"coldspring.aop.AfterReturningAdvice"&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"setLoggingService"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; hint=&lt;span class="cfvalue"&gt;"Dependency: security service"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"loggingService"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"net.klondike.service.LoggingService"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.m_loggingService = arguments.loggingService /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"getLoggingService"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"net.klondike.service.LoggingService"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; hint=&lt;span class="cfvalue"&gt;"Dependency: security service"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn variables.m_loggingService /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"afterReturning"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"returnVal"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"any"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"method"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"coldspring.aop.Method"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"args"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"struct"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"target"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"any"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var rtnString = ‘’ &amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var arg = '' /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var argString = '' /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var objName = getMetadata(arguments.target).name /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif StructKeyExists(arguments,’returnVal’)&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif isStruct(arguments.returnVal)&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset rtnString = “ returned a struct with” &amp; StructCount(arguments.returnVal) &amp; “ values.” /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfelseif isArray(arguments.returnVal)&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset rtnString = “ returned an array with ” &amp; ArrayLen(arguments.returnVal) &amp; “ values.” /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfelseif isObject(arguments.returnVal)&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset rtnString = “ returned a record cfc ” /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfelse&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset rtnString = “ returned ” &amp; arguments.returnVal /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.m_loggingService.info("[" &amp; objName &amp; "] " &amp; method.getMethodName() &amp; "() " &amp; rtnString) /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/cfcomponent&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;A few things to note here, we have to check to see if ‘returnVal’ actually exists in arguments before using it, because if the method you are advising does not return a value, ‘returnVal’ will not exist. Also, and this differs from the early alpha release, it is not necessary to return ‘returnVal’ if it exists. This value is available for you to inspect only. If you need to alter the result of method invocation, you should be working with Around Advice.  In order to configure this Advice, we would take the same steps as we did with the Before Advice, configure the NamedMethodPointcutAdvisor with this Advice, and configure the ProxyFactoryBean with the CatalogDao as the target.&lt;br /&gt;&lt;br /&gt;So now that I have covered the more simple types of Advice, let’s look at the more powerful Around Advice, called MethodInterceptor. First off, let me explain some of the motivation behind the naming convention.  There is an organization called the Aopalliance that has provided standard interfaces to method interception for the development of aop frameworks. The idea being that as long as developers adhere to these interfaces, your code will be portable across different aop implementations. That sounds like a good idea to me, since who knows if someone is going to come along and write a much better aop framework that I have done. So that being said, MethodInterceptor is a type of Around Advice, meaning that it allows you to place code before and after the method call, and gives you complete control of actually calling the method. So let’s see how this works in practice, and while we’re at it I’ll cover some of the api available in the framework. This time I’m going to create an Advice to cache cfcs returned from the dao’s fetch() method, looking first to see if they exist there, and also update the cache in the save() method. This implementation is pretty simplistic and should not be viewed as a real world example, but hopefully it will get your mind going. First lets review the CatalogDAO cfc so know what methods we are going to be advising.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent name=&lt;span class="cfvalue"&gt;"CatalogDAO"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"init"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"Any"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn this /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"setDataSource"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; hint=&lt;span class="cfvalue"&gt;"Dependency: datasource name"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"dsn"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"string"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.m_dsn = arguments.dsn /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"fetch"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;" net.klondike.component.Record"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"recordID"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"numeric"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var record = CreateObject('component','net.klondike.component.Record').init() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var qrySelect = 0 /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfquery name=&lt;span class="cfvalue"&gt;"qrySelect"&lt;/span&gt; maxrows=&lt;span class="cfvalue"&gt;"1"&lt;/span&gt; datasource=&lt;span class="cfvalue"&gt;"#variables.m_dsn#"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SELECT QUERY …&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfquery&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif qrySelect.RecordCount&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record.setRecordID(qrySelect.recordID) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record.setArtistID(qrySelect.artistID) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record.setGenreID(qrySelect.genreID) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record.setTitle(qrySelect.title) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record.setReleaseDate(qrySelect.releaseDate) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record.setImage(qrySelect.image) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record.setPrice(qrySelect.price) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record.setFeatured(qrySelect.featured) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn record /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"create"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"record"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"net.klondike.component.Record"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var qryInsert = 0 /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfquery name=&lt;span class="cfvalue"&gt;"qryInsert"&lt;/span&gt; datasource=&lt;span class="cfvalue"&gt;"#variables.m_dsn#"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;INSERT QUERY …&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfquery&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"update"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"record"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"net.klondike.component.Record"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var qryUpdate = 0 /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfquery name=&lt;span class="cfvalue"&gt;"qryUpdate"&lt;/span&gt; datasource=&lt;span class="cfvalue"&gt;"#variables.m_dsn#"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UPDATE QUERY …&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfquery&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/cfcomponent&amp;gt; &lt;/span&gt;&lt;/div&gt;  &lt;br /&gt;&lt;br /&gt;Obviously a little SQL has been removed, and I’ve also included a change in the fetch() method. We are now going to create a Record cfc from the data in the query and return that instead of a query object, so we can cache it. OK, so lets look at the around advice.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent name=&lt;span class="cfvalue"&gt;"simpleCachingAdvice"&lt;/span&gt; extends=&lt;span class="cfvalue"&gt;"coldspring.aop.MethodInterceptor"&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.objectCache = StructNew() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.cacheTime = 45 /&amp;gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"invokeMethod"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"any"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"mi"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"coldspring.aop.MethodInvocation"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var args = arguments.mi.getArguments() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var methodName = arguments.mi.getMethod().getMethodName() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var record = 0 /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var rtn = 0 /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif methodName IS &lt;span class="cfvalue"&gt;'fetch'&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif StructKeyExists(variables.objectCache, args[&lt;span class="cfvalue"&gt;'recordID'&lt;/span&gt;]) and (DateDiff(&lt;span class="cfvalue"&gt;"m"&lt;/span&gt;, variables.objectCache[args[&lt;span class="cfvalue"&gt;'recordID'&lt;/span&gt;]].cached, Now()) LT 45) &amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cflock name=&lt;span class="cfvalue"&gt;"simpleCachingAdvice"&lt;/span&gt; timeout=&lt;span class="cfvalue"&gt;"5"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record = variables.objectCache[args[&lt;span class="cfvalue"&gt;'recordID'&lt;/span&gt;]].obj /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cflock&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfelse&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset record =  arguments.mi.proceed() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cflock name=&lt;span class="cfvalue"&gt;"simpleCachingAdvice"&lt;/span&gt; timeout=&lt;span class="cfvalue"&gt;"5"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif StructKeyExists(variables.objectCache, args[&lt;span class="cfvalue"&gt;'recordID'&lt;/span&gt;]&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.objectCache[args[&lt;span class="cfvalue"&gt;'recordID'&lt;/span&gt;]] = StructNew() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.objectCache[args[&lt;span class="cfvalue"&gt;'recordID'&lt;/span&gt;]].cached = Now() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.objectCache[args[&lt;span class="cfvalue"&gt;'recordID'&lt;/span&gt;]].obj = record /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cflock&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn record /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfelseif methodName IS &lt;span class="cfvalue"&gt;'save'&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cflock name=&lt;span class="cfvalue"&gt;"simpleCachingAdvice"&lt;/span&gt; timeout=&lt;span class="cfvalue"&gt;"5"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif StructKeyExists(variables.objectCache, args[&lt;span class="cfvalue"&gt;'record'&lt;/span&gt;].getRecordID() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.objectCache[args[&lt;span class="cfvalue"&gt;'record'&lt;/span&gt;].getRecordID()] = StructNew() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.objectCache[args[&lt;span class="cfvalue"&gt;'record'&lt;/span&gt;].getRecordID()].cached = Now() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.objectCache[args[&lt;span class="cfvalue"&gt;'record'&lt;/span&gt;].getRecordID()].obj = args[&lt;span class="cfvalue"&gt;'record'&lt;/span&gt;] /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cflock&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn arguments.mi.proceed() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfelse&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn arguments.mi.proceed() /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"flushCache"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cflock name=&lt;span class="cfvalue"&gt;"simpleCachingAdvice"&lt;/span&gt; timeout=&lt;span class="cfvalue"&gt;"5"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset StructClear(variables.objectCache) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cflock&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/cfcomponent&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So let’s examine what’s going on here. First we extend coldspring.aop.MethodInterceptor and overwrite invokeMethod() which receives an argument of type coldspring.aop.MethodInvocation. MethodInvocation will take care of moving through the chain of any Advice defined and then call the proxied method, by calling its proceed() method. The other public methods for MethodInvocation are getArguments() which returns the arguments you sent to the proxied method, getMethod() which returns a Method object which represents the actual method call, and getTarget() which returns the proxied object itself. From the Method cfc returned from getMethod(), getMethodName() is available as well, so you can see you pretty much have full access to the method call. In invokeMethod() above, the first thing I do is set some local variables to getArguments() and getMethod().getMethodName(), retrieving the argument collection and the name of the method. If the method name is ‘save’, I look in the local cache to see if a Record cfc exists that hasn’t expired, and if it does, I return that object instead of proceeding with the method call. If the Record instance doesn’t exist in the cache I store the result of calling proceed() in the cache. The ‘fetch’ method similarly will store the result of proceed(), and all other methods simply call proceed() without performing any additional work. There’s a very important point to take care to understand here. When using around advice, you are responsible for calling proceed() to get the method to execute and you are also responsible for returning the result of that call if necessary. This completely differs from using Before or After advice, where neither the method call or the return are your responsibility. This obviously makes Around Advice far more powerful, but you may want to think twice before using it if you don’t need to alter the method call itself. One other thing to take note of, if this particular Advice is not the last Around Advice configured, than any other Around Advice will NOT execute when I retrieve the Record cfc from the cache, because of the fact that I am not calling proceed(). This is another pitfall to be very weary of when designing apps using this technology!&lt;br /&gt;&lt;br /&gt;So lets move on to the configuration. This time I am going simplify things a bit by skipping the setup of the Advisor all together. If you don’t care about matching the methods in a target, because your intension is to match all methods as you would with the ‘*’ pattern, you can just reference the Advice directly in the interceptorNames list for the ProxyFactoryBean. This will internally create a DefaultPointcutAdvisor for you, which will match all methods in the target. The resulting configuration file will look like the following.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfcomment"&gt;&amp;lt;!-- set up the security advisor --&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="simpleCachingAdvice"&lt;br /&gt;&amp;nbsp;&amp;nbsp;class="net.klondike.aspects.simpleCachingAdvice" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cfcomment"&gt;&amp;lt;!-- set up a proxy for the dao --&amp;gt; &lt;/span&gt;&lt;br /&gt;&amp;lt;bean id="catalogDAOTarget"&lt;br /&gt;&amp;nbsp;&amp;nbsp;class="net.klondike.component.catalogDAO"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="dsn"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;klondike&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;lt;bean id="catalogDAO"&lt;br /&gt;&amp;nbsp;&amp;nbsp;class="coldspring.aop.framework.ProxyFactoryBean"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="target"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogDAOTarget" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="interceptorNames"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;list&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;simpleCachingAdvice&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;lt;/list&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;/div&gt;   &lt;br /&gt;&lt;br /&gt;You can see that this is a little more convenient, but there will be a bit of overhead in the fact that the all method calls will be processed through the interceptor instead of just the methods that actually use the cache. You may also have noticed that I also added a method to my advice that is not directly used by the aop framework, flushCache(). Just because an advice object is used by the aop framework doesn’t mean it’s not a full fledged business object! You can still retrieve the simpleCachingAdvice from the coldspring bean factory with a call to bf.getBean(“simpleCachingAdvice”) and call flushCache() in some other object in your application. This gives you an enormous amount of flexibility and power. Think about counting method calls. Have you ever put a tracking system in your apps to keep track how many users are in the system and the last thing they did? How many places in your app would that code exist, more importantly how easy would it be to turn off that system? Definitely a candidate for aop! Well I hope that I’ve sparked some more interest and brought some more of the details to light. Look for the next installment where I will cover building a suite of throws advice with the new After Throwing object, and I’ll try not to let so much time go by this time!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113208096316769210?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113208096316769210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113208096316769210&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113208096316769210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113208096316769210'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/11/coldspring-aop-tutorial-part-two.html' title='ColdSpring AOP Tutorial – Part Two, Around Advice'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113081638256225674</id><published>2005-10-31T19:37:00.000-08:00</published><updated>2005-10-31T19:39:42.573-08:00</updated><title type='text'>Joe Rinehart introduces Arf!</title><content type='html'>With all of the hubbub about Ruby on Rails running around, it was only a matter of time until some smart person came along and wrote an implementation of Active Record for codfusion. Well it looks like that smart person is &lt;a href="http://clearsoftware.net/client/index.cfm?mode=entry&amp;entry=49CAFDF4-E081-2BAC-69AD5772ABCF584B" target="blank"&gt;Joe Rinehart&lt;/a&gt;! Congratulations Joe, I’ve though a bit about active record myself and I’m sure that it was a lot of work. I’m really excited about messing around with it, and I think it’s another great step for the language in general. These are exciting times for coldfusion!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113081638256225674?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113081638256225674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113081638256225674&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113081638256225674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113081638256225674'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/10/joe-rinehart-introduces-arf.html' title='Joe Rinehart introduces Arf!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113054612275288129</id><published>2005-10-28T17:32:00.000-07:00</published><updated>2005-10-28T17:35:22.760-07:00</updated><title type='text'>ColdSpring has a new home!</title><content type='html'>Dave has just announced the opening of &lt;a href="http://www.coldspringframework.org" target="_new"&gt;www.coldspringframework.org&lt;/a&gt;, where you can get the latest stable release as well as cvs access to bleeding edge versions. You'll also find documentation as well as api docs, forums and a listserve. Dave really put a lot of hard work into the site, and I did a little design work as well. It looks great and I think it will be a great resource, so check it out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113054612275288129?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113054612275288129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113054612275288129&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113054612275288129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113054612275288129'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/10/coldspring-has-new-home.html' title='ColdSpring has a new home!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-113011801525563626</id><published>2005-10-23T18:37:00.000-07:00</published><updated>2005-10-24T12:50:35.156-07:00</updated><title type='text'>Announcing Team Fusion!</title><content type='html'>I’m not sure how people get into these super-hero programming alliances, so I started my own, Team Fusion! We’re very serious and action oriented, so we get an exclamation point as well as a star. Ok, I just wanted a cool logo for my coldfusion friends’ links and it sounded funny to me, so I killed an hour making it. But if anybody thinks I should add someone to the all powerful Team Fusion!, let me know!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-113011801525563626?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/113011801525563626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=113011801525563626&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113011801525563626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/113011801525563626'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/10/announcing-team-fusion.html' title='Announcing Team Fusion!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112947551055578587</id><published>2005-10-16T08:09:00.000-07:00</published><updated>2005-10-16T08:14:12.696-07:00</updated><title type='text'>A few picks...</title><content type='html'>I just added a &lt;a href="http://www.flickr.com/photos/39163311@N00/52972772/in/set-1148843/" target="new"&gt;few picks&lt;/a&gt; from the frameworks conference and the following friday night to my flickr site. Dave and I  split kind of early and went to my friend Erik's house in baltimore. Erik has somehow become the caretaker of a small circus train once owned by the famous side show attraction and baltimore native &lt;a href="http://www.johnnyeckmuseum.com/about.html" target="new"&gt;Johnny Eck&lt;/a&gt;. We had an amazing time drinking lots of beer, driving the train around his backyard, and getting a significant and well earned lecturing by Erik's wife. Sorry Charlotte!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112947551055578587?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112947551055578587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112947551055578587&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112947551055578587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112947551055578587'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/10/few-picks.html' title='A few picks...'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112925740754218681</id><published>2005-10-13T19:31:00.000-07:00</published><updated>2005-10-13T19:36:47.553-07:00</updated><title type='text'>Model Glue is Good!</title><content type='html'>Ok, you already know that, but I've never worked with model glue before. I've been a mach-ii guy for a while and I like it. But now that coldspring is said to be super easy to integrate with mg, I figured, I better take a look. So here's a quick rundown of the day. 10:00, I slept late, OK? My kids stayed at their grandparents last night, it's the first day I've slept passed 7:00 in years! Anyway, at 10:00 I got model glue from svn, went straight for the ber! I figured I better clean up my dev machine at this point because I had 3 versions of coldspring and 2 versions of the record store example app on there, so that took a little while. I changed the layout of the model components a little and shifted around my root folder so both controller apps could share a config folder, as well as the coldspring config file.&lt;br /&gt;&lt;br /&gt;After initial set up, I decided to read the quickstart guide, OK skimmed it, and figured I'd jump in and see if things would just work. I copied the 2 listeners in to the controllers.mg folder, replaced all the event.getArgs() with event.setValue() and put return values back in the event instead of returning them. I really like this part. I have had numerous discussions with mach-ii developers about putting data in the event in listeners, instead of all the request scope stuff. I have apps that do this exclusively, so this fits perfectly to me. I hit the views next, this was basically nothing. I just switched my event.getArg() to viewState.getValue(), which I do first thing anyway to get local references, so that was simple. I did all this before creating the xml, since I figured that's where the differences would lie. &lt;br /&gt;&lt;br /&gt;Working with the xml file was really pretty easy, my only big problem was I read the quickstart guide too fast and didn't put my message tags in a broadcast block, so when I fired up the app, I got my layout view with nothing. Then I figured out the proper way to use the ViewCollection.getView() method and got my nice layout page with my error template. However, looking at some debugging I did see that my model components were completely wired up through coldspring no problem! After a little more kludging and some teasing in the coldspring irc channel I think I got into the swing of things pretty well. Since mg has no filters, that means more control logic in the controller, so it's a little heftier that the corresponding listener. Is that a bad thing? I don't think so. Why do I need xml to tie all that logic together anyway? A few things here and there kind of tripped me up, but after I felt a little more comfortable, I stopped trying to make mg fit the app that I already had written, and worked on it as a mg app instead. So after all that, I had a completely functioning app at 5, inheriting all the model goodness from the mach-ii app, logging, security and caching.&lt;br /&gt;&lt;br /&gt;Overall impressions? I like it, as a matter of fact I really like it. One of the things that's great about coldspring is it's very lightweight, especially if you're using Sean's autowire controller for mg or our autowiring plugin for mach-ii (which will be in the next release). Coldspring just does its work and gets out of your way. Model glue seems to follow right along with that mantra, it's nice and light. Filters and plugins are very powerful, but maybe we don't need them so much. Maybe we don't need to rely on them so much, to be more precise. You need to concentrate on business logic, and model glue gets right out of your way, and lets you get to it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112925740754218681?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112925740754218681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112925740754218681&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112925740754218681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112925740754218681'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/10/model-glue-is-good.html' title='Model Glue is Good!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112891556577919836</id><published>2005-10-09T20:38:00.000-07:00</published><updated>2005-10-09T20:39:25.783-07:00</updated><title type='text'>ColdSpring 0.2.1 with AOP Released!</title><content type='html'>Emerging from the depths of vaporware the coldspring.aop packages have been released along with a point release of ColdSpring! Dave has also included a Model Glue adapter, which you can read about on his blog &lt;a href="http://www.d-ross.org/index.cfm?objectid=D871E434-A9DF-3A91-EFAB8EF3EADCD815" target="new"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Download &lt;a href="http://cfopen.org/frs/download.php/134/coldspring.zip" target="new"&gt;ColdSpring 0.2.1&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112891556577919836?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112891556577919836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112891556577919836&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112891556577919836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112891556577919836'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/10/coldspring-021-with-aop-released.html' title='ColdSpring 0.2.1 with AOP Released!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112882800843220686</id><published>2005-10-08T20:15:00.000-07:00</published><updated>2005-10-12T14:55:03.826-07:00</updated><title type='text'>ColdSpring AOP Tutorial – Part One</title><content type='html'>Since I have already given an overview of ColdSpring’s AOP concepts, I’m going to just dive right into things. For part one of the developing with ColdSpring AOP, I’ll show how you can use a simple form of Advice called Before Advice to provide logging services to a model component. These examples are from the Klondike Records application that I showed at the frameworks conference last week, which we will also be releasing as an example application. I’ll show you how to define an Advice cfc, which will extends coldspring.aop.BeforeAdvice, how to define Pointcuts via Advisors in a standard ColdSpring config file, and how to use coldspring.aop.ProxyFactoryBean to wrap the Advice around methods of a target object by creating a Proxy object, containing the target. Think about the proxy object like an egg. The object you want to apply logging to would be the yoke and the Advice that provides the logging functionality is the egg white surrounding it. When the proxy factory creates this egg, and this is the great part, everything in you application thinks that it’s the same object that’s in the yoke! OK, so so let’s get right into it. First we’ll define a model component, which will be called CatalogDAO.cfc which we’ll then add logging services to.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent name=&lt;span class="cfvalue"&gt;"CatalogDAO"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"init"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"Any"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn this /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- setters for dependencies ---&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"setDataSource"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; hint=&lt;span class="cfvalue"&gt;"Dependency: datasource name"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"dsn"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"string"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"rue"&lt;/span&gt;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.m_dsn = arguments.dsn /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- fetch a record ---&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"fetch"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"query"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"recordID"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"numeric"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfquery name=&lt;span class="cfvalue"&gt;"qrySelect"&lt;/span&gt; maxrows=&lt;span class="cfvalue"&gt;"1"&lt;/span&gt; datasource=&lt;span class="cfvalue"&gt;"#variables.m_dsn#"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SELECT QUERY …&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfquery&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn qrySelect /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- insert record ---&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"create"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"record"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"net.klondike.component.Record"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var qryInsert = 0 /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfquery name=&lt;span class="cfvalue"&gt;"qryInsert"&lt;/span&gt; datasource=&lt;span class="cfvalue"&gt;"#variables.m_dsn#"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;INSERT QUERY …&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfquery&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- update record ---&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"update"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"record"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"net.klondike.component.Record"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var qryUpdate = 0 /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfquery name=&lt;span class="cfvalue"&gt;"qryUpdate"&lt;/span&gt; datasource=&lt;span class="cfvalue"&gt;"#variables.m_dsn#"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UPDATE QUERY …&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfquery&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&amp;lt;/cfcomponent&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Obviously we’re skipping some details, but the point is that this is just a standard model component; we don’t extend anything or put any special code here. The component should be completely usable with or without AOP. In my example app you will see that this dao is used as part of a service component, which is used by the catalogListener in the mach-ii app. The nice thing about using AOP to provide logging is that neither the dao nor the service component that uses it will have any code in them pertaining to logging. They are only concentrated on fetching and storing records, cohesion. I like to use log4j, so I’ll create a LoggingService cfc to handle the configuration details and provide a common api to my Aspects. Also, if I want to switch this out to use cflog or another implementation, I can do that in one place. So here’s the LoggingService cfc, but I’ll skip showing how to actually configure log4j, since I have already shown that in an earlier post. This service basically just retrieves the logger and wraps its info() method.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent name=&lt;span class="cfvalue"&gt;"LoggingService"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"init"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"net.klondike.service.LoggingService"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var category = CreateObject(&lt;span class="cfvalue"&gt;"java", "org.apache.log4j.Category"&lt;/span&gt;) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.logger = category.getInstance('net.klondike') /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn this /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"info"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;message"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"string"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif variables.logger.isInfoEnabled()&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.logger.info(arguments.message) /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;/cfcomponent&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Ok, now onto the AOP part. I will first create a Before Advice to retrieve information about the current method being invoked and send it off as the message argument to the logging service’s info() method. Here’s the loggingBeforeAdvice cfc.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cftag"&gt;&amp;lt;cfcomponent name=&lt;span class="cfvalue"&gt;"loggingBeforeAdvice"&lt;/span&gt; extends=&lt;span class="cfvalue"&gt;"coldspring.aop.BeforeAdvice"&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- setters for dependencies ---&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"setLoggingService"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"void"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; hint=&lt;span class="cfvalue"&gt;"Dependency: security service"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"loggingService"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"net.klondike.service.LoggingService"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.m_loggingService = arguments.loggingService /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"getLoggingService"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"net.klondike.service.LoggingService"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; output=&lt;span class="cfvalue"&gt;"false"&lt;/span&gt; hint=&lt;span class="cfvalue"&gt;"Dependency: security service"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfreturn variables.m_loggingService /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--- before() is called by the aop framework before method invocation ---&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cffunction name=&lt;span class="cfvalue"&gt;"before"&lt;/span&gt; access=&lt;span class="cfvalue"&gt;"public"&lt;/span&gt; returntype=&lt;span class="cfvalue"&gt;"any"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"method"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"coldspring.aop.Method"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"args"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"struct"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfargument name=&lt;span class="cfvalue"&gt;"target"&lt;/span&gt; type=&lt;span class="cfvalue"&gt;"any"&lt;/span&gt; required=&lt;span class="cfvalue"&gt;"true"&lt;/span&gt; /&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var arg = '' /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var argString = '' /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset var objName = getMetadata(arguments.target).name /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfloop collection=&lt;span class="cfvalue"&gt;"#args#"&lt;/span&gt; item=&lt;span class="cfvalue"&gt;"arg"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif isSimpleValue(args[arg])&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfif len(argString)&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset argString = argString &amp; ', ' /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset argString = argString &amp; arg &amp; '=' &amp; args[arg] &amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/cfloop&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;cfset variables.m_loggingService.info("[" &amp; objName &amp; "] " &amp; method.getMethodName() &amp; "(" &amp; argString &amp; ") called!") /&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;/cfcomponent&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This probably looks more complicated that it really is, so I’ll walk through it. First off we extend coldspring.aop.BeforeAdvice, which provides typing for the aop framework, and the ‘before’ method which you will overwrite. Next we have a setter and a getter which ColdSpring will use to inject the LoggingService, and the AOP framework will use to clone the Advice. The heart of this cfc, however, is the before() method, which gets passed a Method object, responsible for handling the actual method call, the argument collection passed to the method, and the target object which receives the method call. You can see that you have an amazing amount of power at this point. But all I’m going to do here is get the name of the target object through metadata, the name of the method from the Method object, and I’ll loop through the arguments to find simple values that I can print as strings. From this I make a string to pass to my loggingService that will look something like this: ‘[net.klondike.component.catalogGateway] getGenres() called!’. One important thing to note here is that Before Advice can alter the arguments going into the method at this point, but is not responsible for actually executing the method, even though it does have access to it. There is another type of Advice that should be used if you want control over method execution, called Around Advice, but I will delay that discussion until part two. Here’s where the advice of ‘be really careful’ comes in. No other object in you application has any idea of what is going on at this point, so you can really cause havoc, so be careful!&lt;br /&gt; &lt;br /&gt;Ok, so now we have a DAO that we want to apply logging to, a simple loggingService, and a Before Advice to apply the logging service with. Now this may seem like a lot of work to add logging to a method, and that’s true. But this Advice can be applied to ALL you model components without writing any more code, logging method calls across your entire application. All that’s left is configuring these components. As I wrote in my earlier post, this is a matter of identifying Join Points, methods that you want to log in objects, which is done through Pointcuts, with an Advisor. An Advisor is basically a collection of methods and advice to apply to them. OK, so here’s the ColdSpring config file that will tie all this together.&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;beans&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!—define the logging service --&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;bean id="loggingService"&lt;br /&gt;        class="net.klondike.component.LoggingService" /&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--define the loggingBeforeAdvice and set its logging service property to reference the bean above --&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;bean id="loggingBeforeAdvice" &lt;br /&gt;        class="net.klondike.aspects.loggingBeforeAdvice"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="loggingService"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="loggingService" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/bean&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!—now define a NamedMethodPointcutAdvisor, set the advice property to the bean above, and set its mappedNames property to ‘*’ which will create a pointcut to match all methods excluding any init method --&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;bean id="loggingAdvisor" &lt;br /&gt;        class="coldspring.aop.support.NamedMethodPointcutAdvisor"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="advice"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="loggingBeforeAdvice" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="mappedNames"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;*&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/bean&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!-- to create the proxy object, first create our dao as the target object --&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;bean id="catalogDaoTarget"&lt;br /&gt;        class="net.klondike.component.catalogDAO"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="dsn"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;klondike&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/bean&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!-- now create a ProxyFactoryBean with the id catalogDAO, set the target to the catalogDaoTarget  bean above, and give it ,the id of the NamedMethodPointcutAdvisor above in the list of interceptorNames --&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;bean id="catalogDAO" &lt;br /&gt;        class="coldspring.aop.framework.ProxyFactoryBean"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="target"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogDaoTarget" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="interceptorNames"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;list&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;loggingAdvisor&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/list&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/bean&amp;gt; &lt;br /&gt;  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cfcomment"&gt;&amp;lt;!--now to use the proxy DAO, we give the id of the ProxyFactoryBean to the catalog service as the reference for the property catalogDAO --&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;bean id="catalogService"&lt;br /&gt;        class="net.klondike.component.CatalogService"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="catalogDAO"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogDAO" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/bean&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;That’s it for the configuration. When you ask the ColdSpring bean factory for your catalogService, ColdSpring will create the ProxyFactoryBean and ask it to return a proxy object. The ProxyFactoryBean will in turn get a reference to the target object, the real DAO object, get the Advisor which contains the Aspect we created, causing the loggingService to be created, and will finally generate an entirely new cfc, which contains the target object, the proxy for the catalogDAO. This proxy object will be the same type as the target object and will contain all the same methods as the target, except that it will now flow every method through an instance of the loggingBeforeAdvice. If I want to add the same advice say to a gatewayObject, all I have to do is create another target object, and another ProxyFactoryBean and give it the same Advisor. If this doesn’t seem powerful enough for you, you can also create a new Advice, say a securityAdvice, and create a new Advisor, matching only the ‘save’ method, and give this to the ProxyBeanFactory we defined above. That would make that bean definition look something like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="cfcode"&gt;&lt;span class="cfvalue"&gt;&amp;lt;bean id="catalogDAO" &lt;br /&gt;        class="coldspring.aop.framework.ProxyFactoryBean"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="target"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ref bean="catalogDaoTarget" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="interceptorNames"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;list&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;loggingAdvisor&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;securityAdvisor&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/list&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Adding the securityAdvisor after the loggingAdvisor causes it to be chained after the loggingAdvice, so if that Advice does something like throw an ‘InvalidCredentials’ error, the loggingAdvice will get a chance to write to the log before the method execution stops. So that’s just a small piece of the framework, the least powerful type of Advice we have available. After Advice is very similar to Before Advice, except that it occurs after method execution, giving you access to the return variable from the method as well as argument collection that was passed into the method. Wow, so that’s a pretty big blog post! I hope I’ve wet your appetite, and stay tuned because a super-prealpha-ubermethodology-oops-sorry-release is just around the corner!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112882800843220686?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112882800843220686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112882800843220686&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112882800843220686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112882800843220686'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/10/coldspring-aop-tutorial-part-one.html' title='ColdSpring AOP Tutorial – Part One'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112873711353506038</id><published>2005-10-07T18:48:00.000-07:00</published><updated>2005-10-07T19:05:50.676-07:00</updated><title type='text'>Whoa, there’s a lot of code in there!</title><content type='html'>I just popped over to the fisheye site that Dave and I use to track development and there’s a lot of code going into that there cvs! From mid September there have been over 10K lines added! We’re closing in on 20K in the ColdSpring repository! Now granted, there’s a whole bunch of example apps, tests apps, and I think maybe Dave added the Macromedia pet store app, but the point is ColdSpring is very active right now. Expect big releases very, very soon. I’m doing my best to release the AOP framework this weekend, so stay tuned! I swear we’re not sleeping…  &lt;br /&gt;&lt;br /&gt;Bye the way, incase you haven’t been told this before, Fisheye’s the bomb! If you use cvs or subversion, you have to take a look at Fisheye. Of course if you don’t use some type of source control, um, I have no idea how you are managing your software development, you shouldn’t be doing that. Go get cvs. Right now!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112873711353506038?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112873711353506038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112873711353506038&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112873711353506038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112873711353506038'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/10/whoa-theres-lot-of-code-in-there.html' title='Whoa, there’s a lot of code in there!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112786779805412289</id><published>2005-09-27T17:33:00.000-07:00</published><updated>2005-09-27T18:00:11.546-07:00</updated><title type='text'>Introduction to ColdSpring AOP</title><content type='html'>Aspect Oriented Programming is a fairly new programming model that assists in handling far reaching services, like logging, security, transactions and object caching, in your model. Services like these are beginning to be referred to as ‘crosscutting concerns’, because they are applied broadly across your application. In order to add a service such as logging to an application, you typically find yourself applying very similar code all throughout your model, which when scrutinized, probably has nothing to do with the actual functionality of your components. AOP allows you to insulate these types of crosscutting concerns from the rest of you application, and apply them broadly based on certain policies that you as the developer define. &lt;br /&gt;&lt;br /&gt;Using AOP is basically a process of looking at the types of concerns in your application and then breaking them apart into primary concerns, like your managing your shopping cart or navigating through and administering your product catalog, your application’s primary business logic, and crosscutting, generalized concerns, such as logging and security. These crosscutting concerns become what are known as ‘aspects’, and with AOP can be written singularly focused on the issues they solve, becoming more portable and reusable. These aspects are then applied to your model according to policies that you define, through a process known as ‘weaving’, which is performed by the AOP framework.&lt;br /&gt;&lt;br /&gt;Defining policies is a matter of identifying ‘join points’ in your model, specific areas where you would like to apply the ‘advice’ of your aspects, meaning the specific action that you would like to take place at a certain time in your application. Join points are created using ‘pointcuts’ which are defined with wildcards or regular expressions to identify methods in your objects. Don’t get too worried about the terminology here; the primary concept is that you already have objects with methods in them that you want to add functionality to. You do this through advice. There are three types of advice available in ColdSpring AOP, before, after, and around advice. Before advice is run before the join point will be performed; after advice will be run after the join point. Around advice is like a combination of both. Around advice is actually quite powerful because it is given full control of the execution of the join point and it has the ability to advise errors through try/catch blocks.&lt;br /&gt;The final concepts to understand in AOP are ‘target’ and ‘proxy’ objects. The target object is object in your model that you want to apply your aspects to. Through the process of weaving, the AOP framework will use the policies you defined via pointcuts to build a new proxy object containing the configured advice, which, and here’s the most important part, appears to be one in the same as the target object to the rest of your application. Now I know a lot of this is sounding confusing and a bit difficult, but it’s important to understand that most of the work is actually done for you. You will primary concern yourself with creating the advice objects themselves. Pointcuts are defined through configuration and ColdSpring AOP handles the rest. In the context of ColdSpring, the configuration is done through an xml file, and the proxy object can be swapped out for the target object with minimal effort. &lt;br /&gt;&lt;br /&gt;I’ll post some actual examples after I get a chance to run through them at the conference and get some feedback. Hopefully I’ll get a chance to meet a few people who just may have read some of this there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112786779805412289?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112786779805412289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112786779805412289&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112786779805412289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112786779805412289'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/09/introduction-to-coldspring-aop.html' title='Introduction to ColdSpring AOP'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112774884561668314</id><published>2005-09-26T08:21:00.000-07:00</published><updated>2005-10-03T08:54:17.030-07:00</updated><title type='text'>ColdSpring, AOP and the Fusebox/Frameworks Conference</title><content type='html'>This weekend was one of those crazy weekends that your eyes and wrists hurt and the end of. On top of the kids waking up at all hours so I'm not even getting any sleep, I wrote just a ridiculous amount of code, and now I'm just staring at the work I'm supposed to be doing for my day job like it's in Russian or something. But it was super worth it, because I've got some big news for everyone. First off, for a while now I've been using Dave Ross's ColdSpring CFC container in a big project I'm working on, which kind of lead me to work on ColdSpring. A lot of work was done this weekend merging code with the current version, and that was honestly an exiting experience. I've never before worked with another developer who I see completely eye to eye with, it made me think a bit about pair programming / xp, if it actually is useful. Anybody who has any experience it, please share your experiences, I'd love to hear about it. Anyway, working on ColdSpring kind of lead me into doing a whole lot of work another big side project.&lt;br /&gt;&lt;br /&gt;While talking with Dave about the types of things that can be brought into ColdSpring, I started thinking heavily about how the aop framework is used in Spring for Java, and the type of stuff we could build into ColdSpring if we had an aop (Aspect Oriented Programming) layer. So after a hell of a lot of thinking and completely unintelligible chicken scratch notes left around the house, driving my wife nuts when I want to know what happened to the menu with all the little boxes drawn on the back of it, I am very pleased to tell you that I have a functional aop framework to be released in the very near future, hopefully at the Frameworks Conference. I'm not going to go into great detail about what aop is and how it's used right now, I have some real tutorials coming. But I will be going to the Fusebox/Frameworks conference with Dave, where I guess we'll make the official announcement. I have some great examples that I've been bustin my butt to put together, maybe I should have started an example app before this past saturday? I'm looking forward to showing these at a BOF session at the conference, so look for Dave and me there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112774884561668314?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112774884561668314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112774884561668314&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112774884561668314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112774884561668314'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/09/coldspring-aop-and-fuseboxframeworks.html' title='ColdSpring, AOP and the Fusebox/Frameworks Conference'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112731020408720226</id><published>2005-09-21T06:28:00.000-07:00</published><updated>2005-09-25T08:50:00.600-07:00</updated><title type='text'>Using log4j in ColdFusion</title><content type='html'>I went to an interview last Thursday and in the course of it the lead developer and I (my job had apparently been filled!) got into a two hour discussion about caching cfcs with oscache, working with coldspring, aop, and using log4j in coldfusion. Although the interview part didn’t lead to much, I did leave thinking about a lot of cool things, especially pressing being incorporating log4j into a side project that I’m getting pretty heavily involved in. I’ve worked with log4j in java, and it’s super simple, very fast, easy to configure, and I’ve been thinking of using it in cf, but basically haven’t tried. Although I think cflog is just a wrapper around log4j anyway, by using it directly you gain the benefit of setting the max size of the log file created, along with configuration of backup files, the level of logging to output (debug, info, warn, error, fatal), and formatting of the messages. Also, most importantly, it’s really easy to turn on and off, and since log4j is built to be extremely fast the cost of log statements in your code is marginal. So if I’ve peeked you interest, here’s a little rundown of how to get log4j running, with some extra links at the end of the post, including a link to an excellent tutorial on ColdFusion Developer’s Journal, which to be honest, much of this is a paraphrasing anyhow. So on to the code…&lt;br /&gt;&lt;br /&gt;The first thing to know is ColdFusion comes with an older version of log4j which uses the now depreciated concept of categories, now known as loggers, but for simplicity’s sake, these are the same thing. An instance of one of these represents a logging space which you are free to name and configure at will. It’s advisable to use package naming conventions with loggers, sorry categories, as this is the norm in java. Also worth noting is that loggers are hierarchical, meaning that a logger named ‘myco.foo’ inherits configuration properties from the logger ‘myco’, if it exists. You perform logging through one of the printing methods debug, info, warn, error, fatal. These are directly related to the standard logging levels DEBUG &lt; INFO &lt; WARN &lt; ERROR &lt; FATAL, meaning the level is ascending. A logging method is considered enabled if it is equal to or grater that the current logging level. So if the logging level is set to WARN, myLogger.error(‘Uh oh, big problem occurred’), will output to your log file, but myLogger.info(‘ran method x()’) will not. The last 2 components to logging are patterns, which I’m going to completely skip, and just give you the logging pattern that you’re pretty much gonna use anyway, and appenders, which you output your logging to. Appenders can be a console, file, a socket server, JMS, NT Event Log, and the Unix System Log, you can start to see the incredible flexibility here. All that’s left is to create a config file and start logging!&lt;br /&gt;&lt;br /&gt;I like to use a properties file, the format I mentioned when discussing classloaders, but you can also use an xml file. Here’s a sample properties file called logger.properties:&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffff33"&gt;# create a category called myco.foo, set it’s level to INFO, and set the appender to myAppen (you can name this anything, but keep it simple)&lt;br /&gt;log4j.category.myco.foo=INFO, myAppen&lt;br /&gt;# myAppen is set to be a FileAppender. &lt;br /&gt;log4j.appender.myAppen =org.apache.log4j.RollingFileAppender&lt;br /&gt;log4j.appender.myAppen.File=/usr/local/cf7/htdocs/sampleApp/logs/sample.log&lt;br /&gt;# we’ll use a standard layout&lt;br /&gt;log4j.appender.myAppen.layout=org.apache.log4j.PatternLayout&lt;br /&gt;log4j.appender.myAppen.layout.ConversionPattern=%-4r [%t] %-5p %c - %m%n&lt;br /&gt;# and set the filesize limit and backup file&lt;br /&gt;log4j.appender.myAppen.MaxFileSize=100KB&lt;br /&gt;log4j.appender.myAppen.MaxBackupIndex=1&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Now to get log4j running you just need to load this config file. The best place for this is probably in Application.cfm, as apposed to somewhere buried in your code. One thing to note, though. Once log4j is configured, it’s going to be running until you’re cf server/instance is restarted, so if you want to stop logging, you’ll need to remove the configuration code and restart cf. So here’s my Application.cfc:&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffff33"&gt;&amp;lt;cfscript&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;if (NOT IsDefined("application.loggerInit")) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;configurator = CreateObject("java", "org.apache.log4j.PropertyConfigurator");&lt;br /&gt;configurator.configure('/usr/local/cf7/htdocs/sampleApp/logs/logger.properties');&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;application.loggerInit = true;&lt;br /&gt;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;lt;/cfscript&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Just a few things to note. I’m checking to see if if I’ve already initialized log4j, I created a ‘logs’ inside my sampleApps app folder, which contains my logger.properties config file and the samle.log file which will be created, and I’m using absolute path names in Application.cfm and in my config file. You could work around this, but… So now, you’re ready to begin logging! Let’s log a cfc being created. First I’ll retrieve the logger I created from an org.apache.log4j.Category instance and store it so other methods can use it, then use the ‘info’ method to do the logging:&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffff33"&gt;&amp;lt;cfcomponent name="myCFC"&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cffunction name="init" returntype="myCFC"&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;cfset var category = CreateObject("java", "org.apache.log4j.Category") /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;cfset variables.logger = category.getInstance('myco.foo') /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;cfset variables.logger.info('myCfc created") /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;cfreturn this /&gt;  &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;/cffunction&gt;&lt;br /&gt;&amp;lt;/cfcomponent&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;And that’s all there is to it! Sorry about the length of the post, hopefully it’s not too much to consume, but has given you some ideas to get rolling. Happy logging!&lt;br /&gt;&lt;br /&gt;introduction to log4j: &lt;a href="http://logging.apache.org/log4j/docs/manual.html" target="new"&gt;http://logging.apache.org/log4j/docs/manual.html&lt;/a&gt;&lt;br /&gt;log4j PatternLayout Class: &lt;a href="http://logging.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html" target="new"&gt;http://logging.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html&lt;/a&gt;&lt;br /&gt;ColdFusion Developer's Journal article on log4j: &lt;a href="http://cfdj.sys-con.com/read/42122.htm" target="new"&gt;http://cfdj.sys-con.com/read/42122.htm&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112731020408720226?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112731020408720226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112731020408720226&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112731020408720226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112731020408720226'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/09/using-log4j-in-coldfusion.html' title='Using log4j in ColdFusion'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112689135201635706</id><published>2005-09-16T10:13:00.000-07:00</published><updated>2005-09-21T18:40:36.560-07:00</updated><title type='text'>Replicating Java’s Object.toString() method in CF</title><content type='html'>Here’s a little trick that may come in handy sooner or later. It’s something I desperately needed today, and was getting frustrated without it. In java if you call toString() on an object it returns the class name and the hex of its memory address. It’s quite handy for debugging things like making sure you're working with a singleton or a new object. But you can’t call toString() on a cfc. So here’s how you can get the same output in cf: &lt;br /&gt;&lt;br /&gt;&lt;font color="#ffff33"&gt;&amp;lt;cfset myObject = CreateObject('component','com.myco.MyObject') /&amp;gt;&lt;br /&gt;&amp;lt;cfset system = CreateObject('java','java.lang.System') /&amp;gt;&lt;br /&gt;&amp;lt;cfset objString = getMetaData(myObject).name &amp; "@"&amp; FormatBaseN(system.identityHashCode(myObject), 16) /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;cfdump var="#objString#" /&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;This will output something along the lines of 'com.myco.MyObject@fe029d42'. Just for a little teaser of what’s to come, I really wanted this for logging the creation of new cfcs with log4j. A little tutorial on using log4j with coldfusion is coming next…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112689135201635706?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112689135201635706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112689135201635706&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112689135201635706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112689135201635706'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/09/replicating-javas-objecttostring.html' title='Replicating Java’s Object.toString() method in CF'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112622852721027340</id><published>2005-09-08T18:06:00.000-07:00</published><updated>2005-09-21T18:40:17.043-07:00</updated><title type='text'>I’ll make the first one a good one!</title><content type='html'>I said I would write some cool stuff about ColdFusion, right? Well how about I make my first post a good one. I'm currently working with Dave Ross on a really cool project that does some interesting things concerning Mach-ii properties and external configuration files (more on that later). I’m a big mac guy, Dave’s not, so we got into an issue with filepaths, and I suggested maybe loading the config file from the classpath, since the file was really external to the application anyway.&lt;br /&gt;&lt;br /&gt;So after I remembered that I was working in coldfusion instead of java, I came up with a cool solution, with ended up using a bit of java. A little backround info is needed to understand how this is done. Whenever you write a cfc or cfm file (or udf), cf compiles the code into a type of java class file, which is basically a normal java object. Since it is a java object you can actually use methods from the base java objects, Object and Class When you run your app, that class is loaded into the jvm that coldfusion is using through a ClassLoader, which you can obtain from the cfc, through base java objects. Before I get too far, here’s a simple example of calling a method from a cfc’s base java objects to show the type of object it is:&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffff33"&gt;&amp;lt;cfcomponent name="test2.cfc"&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cffunction name="dumpStuff" access="public" returntype="any"&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;cfdump var="#getClass().getName()#" /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&amp;lt;/cfcomponent&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Kind of cool, because getClass() is a method of java’s Object class and getName() is from the Class (that’s its name) that it returns. So going back loading files, Class has a method getClassLoader() which will return the ClassLoader I mentioned that was used to load that object into the JVM. Why do you want this? Well a ClassLoader can be used to load more that just classes, and the cool thing is it searches through a classpath to find what it’s looking for, which is configured from outside of your application, through CFAdministrator, or Jrun Admin, or through Tomcat, or a .profile file or whatever. And that makes it a very portable way to load things!&lt;br /&gt;&lt;br /&gt;Ok, I have a feeling your still wondering why you would want to do this.  Remember how I said that Dave was loading things into Mach-ii properties from a config file? Well here’s how and then maybe a little why later. This relies on another Java class, java.util.Properties, that reads a plain text file as key/value pairs and loads them into a similar construct as a cf struct, and even though this sounds like a lot of work, it’s surprisingly easy. We’ll do this in a plugin and have it happen as soon as the app starts up, so first a properties file, I’ll call it ‘myprops.properties’, it looks like this:&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffff33"&gt;datasource=mydsn&lt;br /&gt;mailserver=127.0.0.1&lt;br /&gt;serveradmin=admin@mydomain.com&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Now the plugin, with some comments:&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffff33"&gt;&amp;lt;cfcomponent extends="MachII.framework.plugin"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;cffunction name="configure"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;!--- Java Properties object ---&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfset var props = createObject("java","java.util.Properties")/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfset var propNames = 0/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfset var prop = 0 /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfset var p = 0 /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;!--- You would probably want this set elsewhere! ---&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfset var propFileName = “myprops.properties “ /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfset var classPathResource = 0 /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;!--- here we’ll use use a method of ClassLoader to open an InputStream on the property file and tell the Properties object to load it ---&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfset classPathResource = getClass().getClassLoader().getResourceAsStream(propFileName)/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfset props.load(classPathResource)/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;!--- now we just use methods from the Properties object to read the values and put them in the Mach-ii property manager using the  key names ---&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfset propNames = props.keySet().toArray()/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;cfloop from="1" to="#arraylen(propNames)#" index="p"&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;cfset prop = propNames[p] /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;cfset setProperty(prop,props.get(prop))/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;lt;/cfloop&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/cffunction&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/cfcomponent&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Since this happens as soon as the plugin is loaded, you have those properties available at application startup, and you now have application properties that are configurable from outside of the Mach-ii conf file! Cool, huh? More stuff to come soon…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112622852721027340?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112622852721027340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112622852721027340&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112622852721027340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112622852721027340'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/09/ill-make-first-one-good-one.html' title='I’ll make the first one a good one!'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16515669.post-112620349789629898</id><published>2005-09-08T02:13:00.000-07:00</published><updated>2005-09-08T17:03:47.603-07:00</updated><title type='text'>Testing 1,2,3...</title><content type='html'>Is this thing on? I just flew in from Philly and boy are my arms tired! No really, but... &lt;br /&gt;&lt;br /&gt;I've got a lot of things to tell you but I'm running short on time. I promise to write a whole lot about Cold Fusion, Java, and Flash, and probably some senseless information about raisin my kids, driving my bike, and I don't know, brewing beer or something. Check back, you'll see...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16515669-112620349789629898?l=cdscott.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cdscott.blogspot.com/feeds/112620349789629898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16515669&amp;postID=112620349789629898&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112620349789629898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16515669/posts/default/112620349789629898'/><link rel='alternate' type='text/html' href='http://cdscott.blogspot.com/2005/09/testing-123.html' title='Testing 1,2,3...'/><author><name>Chris Scott</name><uri>http://www.blogger.com/profile/17578621333416282600</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://static.flickr.com/23/41592425_fdd497ffc5.jpg'/></author><thr:total>2</thr:total></entry></feed>
