tag:blogger.com,1999:blog-165156692024-02-20T16:35:24.917-08:00Truths and LiesChris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.comBlogger69125tag:blogger.com,1999:blog-16515669.post-28226440516925310972011-06-27T19:52:00.000-07:002011-06-27T19:53:20.277-07:00Introducing Swiz AOP!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.<br /><br />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.<br /><br />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.<br /><br />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?<br /><br />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!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com2tag:blogger.com,1999:blog-16515669.post-76787791094353769222011-05-03T10:22:00.000-07:002011-05-03T10:29:13.640-07:00Swiz 1.1 Released with Flex 4.5 Mobile Support!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...)<br /><br />We're proud to also include support for some new features included in <a href="http://www.adobe.com/products/flash-builder.html">Flash Builder 4.5</a>, which now automatically completes Swiz metadata!<br /><br />Swing on over to <a href="http://swizframework.org/">www.swizframework.org</a> for details, or grab the download <a href="http://bit.ly/Swiz1dot1">here</a>. Congrats to Team Swiz for the new release!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com0tag:blogger.com,1999:blog-16515669.post-85204273346545705532010-12-15T09:20:00.000-08:002010-12-15T09:36:28.091-08:00Swiz 1.0 Released!!! And in honor, may I present FoShizzle!!!In honor of the long awaited Swiz Framework 1.0 release, available from <a href="http://swizframework.org">swizframework.org</a>, may I present for your pleasure my snoop approved, 100% chronic extension <a href="http://dl.dropbox.com/u/2642661/foshizzle.swc">FoShizzle</a>!!<br /><br />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.<br /><br /><swiz:customProcessors><br /> <processor:DispachizzleProcessor/><br /> <processor:EventHandizzleProcessor/><br /> <processor:InjectizzleProcessor/><br /> <processor:PostizzleConstrizzleProcessor/><br /> <processor:PreDestrizzleProcessor/><br /></swiz:customProcessors><br /><br />Snoopified metadata names can be used as following:<br /><br />Dispachizzle == Dispatcher<br />HandizzleThaEventizzle == EventHandler<br />Injectizzle == Inject<br />PostizzleConstrizzle == PostConstruct<br />PreDestrizzle == PreDestroy<br /><br />Enjoy!!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com0tag:blogger.com,1999:blog-16515669.post-85193525955879207052009-01-29T17:52:00.000-08:002009-01-29T18:02:58.428-08:00More Swiz features, or Swiz 0.0.5 Part 2!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 <a href="http://code.google.com/p/swizframework/">Swiz</a>, 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 <bean> 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. <br /><br />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:<br /><br /><div class="cfcode"><span class="cfvalue"><?xml version="1.0" encoding="utf-8"?><br /><BeanLoader xmlns="org.swizframework.util.*" <br />   xmlns:mx="http://www.adobe.com/2006/mxml"<br />   xmlns:swizframework="org.swizframework.*"<br />   xmlns:delegates="foo.delegates.*"<br />   xmlns:factory="org.swizframework.factory.*"><br /><br /> <!-- hello service --> <br /> <mx:RemoteObject id="widgetService" destination="widgetService"/><br /><br /> <!-- delegate for the hello controller --><br /> <delegates:WidgetDelegate id="widgetDelegate"/><br /> <br /> <factory:Prototype id="widgetController"<br /> className="foo.controllers.WidgetController"/><br /> <br /></BeanLoader></span></div><br />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! <br /><br />Good to end on another cliffhanger, right?Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com5tag:blogger.com,1999:blog-16515669.post-17565207525329955792009-01-26T18:51:00.000-08:002009-01-26T19:54:05.152-08:00A bunch of sci-fi movies I can't wait to watch with my kidsSpurred on by a tweet by <a href="http://www.coldfusionjedi.com/">Ray Camden</a>, 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:<br /><br />1. Blade Runner (probably my all time favorite movie)<br />2. 5th Element<br />3. 12 Monkeys<br />4. Legend<br />5. Dark City<br />6. 2001<br />7,8,9. All three LOTR's.<br />10. Planet of the Apes<br />11. Alien(s)<br />12. Pan's Labyrinth (maybe, it's pretty scary but it's on the appletv)<br /><br />And the ones my wife has deemed 'acceptable'. Ok, some are a stretch in the genre...<br /><br />1. Narnia<br />2. The Dark Crystal<br />3. The Goonies<br />4. Wall-e<br />4. Harry Potter 1,2 & 3. We decided 4 and 5 are too heavy<br />5. All 4 Indiana Jones<br />6. Of course all Star Wars, we watch the damn Clone Wars cartoon every freaking Saturday. God it SUCKS!<br />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"!<br /><br />Honorable non-sci-fi mention. We just watched The Wiz, that was very funny to watch with them!<br /><br />So, what are you watching with yours?Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com6tag:blogger.com,1999:blog-16515669.post-18896091922175194972009-01-06T18:49:00.000-08:002009-01-07T18:37:31.853-08:00New Swiz 0.0.5 for the New Year!<span style="font-style:italic;">Update</span>: Just wanted to clear up a few typos. You need to call setStrict(true) <span style="font-style:italic;">before</span> 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.<br /><br />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 <a href="http://code.google.com/p/swizframework/downloads/list">Swiz</a> over at our <a href="http://code.google.com/p/swizframework/">googlecode site</a>! 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 <a href="http://soenkerohde.com/">Sönke Rohde</a>. 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...<br /><br />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:<br /><br /><div class="cfcode"><span class="cfvalue">[Mediate(event="user:SaveUserEvent", properties="user")]<br />public function saveUser(user : User) : void { ... }</span></div><br />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:<br /><br /><div class="cfcode"><span class="cfvalue">[Mediate(event=com.foo.SaveUserEvent.SAVE_EVENT, properties="user")]</span></div><br />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:<br /><br /><div class="cfcode"><span class="cfvalue">private function onInitialize() : void {<br /> Swiz.setStrict(true).loadBeans( [ Beans ] );<br />}<br /></span></div><br />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:<br /><br /><div class="cfcode"><span class="cfvalue">[Mediate(event="com.foo.SaveUserEvent.SAVE_EVENT", properties="user")]<br />public function saveUser(user : User) : void { ... }</span></div><br />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:<br /><br /><div class="cfcode"><span class="cfvalue">[Mediate(event="com.foo.SaveUserEvent", properties="user")]<br />public function saveUser(user : User) : void { ... }</span></div><br />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:<br /><br /><div class="cfcode"><span class="cfvalue">[Mediate(event="com.foo.EventConsants.SAVE_USER_EVENT", properties="user")]</span></div><br />for your mediator, and then dispatch a DynamicEvent like this:<br /><br /><div class="cfcode"><span class="cfvalue">var e : DynamicEvent = new DynamicEvent(EventConsants.SAVE_USER_EVENT);<br />e.user = currentUser;<br />Swiz.dispatchEvent( e );</span></div><br />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.<br /><br />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:<br /><br /><div class="cfcode"><span class="cfvalue">[Mediate(event="${userController.SAVE_USER_EVENT}", properties="user")]</span></div><br />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:<br /><br /><div class="cfcode"><span class="cfvalue">[Mediate(event="${userController.eventTypes.SAVE_USER_EVENT}", properties="user")]</span></div><br />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!<br /><br />Changes / Fixes for Swiz 0.0.5:<br /><br />- DynamicChannelSet now contains an 'endPointName' property that can be set to 'flex2gateway' for ColdFusion<br />- Multiple calls to autowire for an object or view will only create mediators once<br />- handleAutowireEvent ignores flash.* and mx.* classes<br />- DynamicMediators allow event properties to be null<br />- Primitive objects can be added to BeanLoaders<br />- Autowire now supports by type (with [Autowire] instead of [Autowire(bean="foo")])<br />- DynamicResponder supports passing an array of values to be passed back into the result handler<br /> * for example to have the original saved object passed in to a save result function<br />- Refactored all bean factory specific functionality out of Swiz and into BeanFactory<br />- Added Strict flag and MediatorUtils for event type checking<br />- Added ExpressionUtils, also or event type checking<br />- Added Prototype object, for non-singleton bean definitionsChris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com3tag:blogger.com,1999:blog-16515669.post-22109910668279380252008-09-21T11:29:00.000-07:002008-09-21T11:46:43.713-07:00Swiz updates and documentation!You may have heard (certainly not here!) about a little Flex framework I have been working on called <a href="http://code.google.com/p/swizframework/">Swiz</a>. 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 <span class="blsp-spelling-error" id="SPELLING_ERROR_0">podcasts</span>. 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 <a href="http://code.google.com/p/swizframework/wiki/GettingStarted">Swiz documentation</a> on <a href="http://code.google.com/p/swizframework/wiki/DynamicMediators"><span class="blsp-spelling-error" id="SPELLING_ERROR_1">DynamicMediators</span></a> as well as updated the <a href="http://code.google.com/p/swizframework/wiki/ProjectSetup">project setup</a> page. Here's a quick rundown of the changes for the week.<br /><br />At 360|Flex I learned that the Flex 3 <span class="blsp-spelling-error" id="SPELLING_ERROR_2">SDK</span> will automatically include custom <span class="blsp-spelling-error" id="SPELLING_ERROR_3">metadata</span> compiled into a library. So now there is no reason to add the additional compiler arguments unless you are using the Flex 2 <span class="blsp-spelling-error" id="SPELLING_ERROR_4">SDK</span>. Also, there has been a little confusion between the first <span class="blsp-spelling-error" id="SPELLING_ERROR_5">swc</span> I posted and the latest about how to get Swiz properly initialized. The correct method is to call Swiz.<span class="blsp-spelling-error" id="SPELLING_ERROR_6">loadBeans</span>( [ loaders ] ) in a function that is invoked in your main application on <span class="blsp-spelling-error" id="SPELLING_ERROR_7">preinitialize</span>. This will allow Swiz to load all of your beans before any views are added to stage and then <span class="blsp-spelling-error" id="SPELLING_ERROR_8">autowire</span> your views as they are added.<br /><br />The major new addition, however, is the new <a href="http://code.google.com/p/swizframework/wiki/DynamicMediators"><span class="blsp-spelling-error" id="SPELLING_ERROR_1">DynamicMediators</span></a>, 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 <span class="blsp-spelling-corrected" id="SPELLING_ERROR_10">explanation</span>. 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 <a href="http://code.google.com/p/swizframework/"><span class="blsp-spelling-error" id="SPELLING_ERROR_11">google</span> code site</a>, and if you are interested, join <a href="http://groups.google.com/group/swiz-framework">the user group</a> and provide feedback to help Swiz grow!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com4tag:blogger.com,1999:blog-16515669.post-2656728227321186862008-09-12T06:22:00.000-07:002008-09-22T15:47:56.707-07:00Big news from ColdSpring!!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 <a href="http://www.coldspringframework.org">www.coldspringframework.org</a> to download 1.2, you will be pleasantly greeted with a brand new site!!!<br /><br />Congratulation and a huge thank you to everyone involved! I'd like to especially thank <a href="http://rmaxim.blogspot.com/">Rachel Maxim (Lehman)</a> for the awesome work on the site design, <a href="http://www.wiersmablog.com/machblog/">Kurt Wiersma</a> for the <a href="http://www.mach-ii.com/">Mach-ii</a> powered implementation, <a href="http://www.adrocknaphobia.com/">Adam Lehman</a> for the hosting, and <a href="http://www.briankotek.com/blog/">Brian Kotek</a> for documentation, bug fixes and general leadership in this release process. Awesome work everyone! Enjoy!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com3tag:blogger.com,1999:blog-16515669.post-11908305043218125402008-07-08T05:27:00.000-07:002008-07-08T05:29:51.855-07:00Philadelphia CFUG meeting, this Thursday on Swiz!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 <a href="http://www.phillycfug.org/index.cfm/2008/7/8/CFUG-Meeting-THIS-Thursday">here</a>, but if you around, drop by to get an introduction into my new Swiz Framework!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com3tag:blogger.com,1999:blog-16515669.post-52382356492923532562008-06-27T19:24:00.000-07:002008-06-27T19:29:34.330-07:00Joe Rinehart's Nuts!!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 <a href="http://www.firemoss.com/blog/index.cfm/Hiberailooving">Hiberailooving</a> 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!<div><br /></div><div>Thanks Joe!</div>Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com0tag:blogger.com,1999:blog-16515669.post-30050363676145763622008-05-05T18:11:00.000-07:002008-05-05T18:15:55.284-07:00Post cfObjective decompressionAnother 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 <a href="http://www.corfield.org/blog/index.cfm/do/blog.cat/catid/edmund">Edmund</a> framework. I had already marked his cfUnited session as a must see, so now I am really excited. <a href="http://compoundtheory.com/">Mark Mandel</a> 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.<br /><br />Of course, what I was particularly excited about was the amazing buzz at the conference about my new <a href="http://code.google.com/p/swizframework/">Swiz Framework</a> 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 <a href="http://maximporges.blogspot.com/">Maxim</a>, <a href="http://www.asfusion.com/">Laura and Nahuel</a> looking over each other's source code and sharing ideas. This had to be the top highlight of the conference for me. <a href="http://mate.asfusion.com/">Mate</a> 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.<br /><br />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!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com3tag:blogger.com,1999:blog-16515669.post-30628469532650957502008-04-20T18:02:00.000-07:002008-04-20T18:04:55.188-07:00Congratulations Jared and Jenna!!!Elisabeth Pearl Rypka-Hauer ROCKS!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com0tag:blogger.com,1999:blog-16515669.post-33567912589249030932007-11-25T09:53:00.000-08:002007-11-25T10:03:46.936-08:00Possibly my last ColdSpring update this weekend...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 (<a href="http://code.coldspringframework.org/browse/CSP-89" target="_new">CSP-89</a>). 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!).<br /><br />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!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com1tag:blogger.com,1999:blog-16515669.post-35952904967055711132007-11-24T13:25:00.000-08:002007-11-24T13:51:00.992-08:00Even More ColdSpring Updates!!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:<div><br /></div><br /><div></div><br /><div class="cfcode"><span class="cftag"><cfcomponent extends=<span class="cfvalue">"coldspring.cfcunit.AbstractAutowireTests"</span>><br /><br /> <cffunction name=<span class="cfvalue">"getConfigLocations"</span> access=<span class="cfvalue">"public"</span> returntype=<span class="cfvalue">"string"</span> output=<span class="cfvalue">"false"</span>><br /> <cfset var path = GetDirectoryFromPath(getMetaData(this).path) /><br /> <cfreturn path & "/testBeans.xml" /><br /> </cffunction><br /> <br /> <cffunction name=<span class="cfvalue">"onSetUp"</span> access=<span class="cfvalue">"public"</span> returntype=<span class="cfvalue">"void"</span> output=<span class="cfvalue">"false"</span>><br /> <!--- this is where my setup would be... ---><br /> <cfset variables.sys = CreateObject('java','java.lang.System') /><br /> <cfset variables.sys.out.println("onSetUp executed!") /><br /> </cffunction><br /> <br /> <cffunction name=<span class="cfvalue">"onTearDown"</span> access=<span class="cfvalue">"public"</span> returntype=<span class="cfvalue">"void"</span> output=<span class="cfvalue">"false"</span>><br /> <!--- this is where my teardown would be... ---><br /> <cfset variables.sys.out.println("onTearDown executed!") /><br /> </cffunction><br /> <br /> <cffunction name=<span class="cfvalue">"setStructBean"</span> access=<span class="cfvalue">"public"</span> returntype=<span class="cfvalue">"void"</span> output=<span class="cfvalue">"false"</span>><br /> <cfargument name=<span class="cfvalue">"structBean"</span> type=<span class="cfvalue">"coldspring.tests.structBean"</span> required=<span class="cfvalue">"true"</span> /><br /> <cfset variables.structBean = arguments.structBean /><br /> </cffunction><br /> <br /> <cffunction name=<span class="cfvalue">"testNothing"</span> access=<span class="cfvalue">"public"</span> returntype=<span class="cfvalue">"void"</span> output=<span class="cfvalue">"false"</span>><br /> <cfset variables.sys.out.println("some structBean data: " & variables.structBean.getData().intOne) /><br /> <cfset AssertNotNull(variables.structBean) /><br /> </cffunction><br /><br /></cfcomponent></span></span></div><br /><br />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...Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com1tag:blogger.com,1999:blog-16515669.post-47516434626960137462007-11-24T05:48:00.000-08:002007-11-24T06:48:43.273-08:00More ColdSpring updates!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 <include> 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:<div><br /></div><div>First I have a ListFactoryBean instance, which you need to remember from spring semantics will return an Array.</div><div></div><br /><div class="cfcode"><span class="cfvalue"><bean id="list.factory" class="coldspring.beans.factory.config.ListFactoryBean"><br /> <property name="sourceList"><br /> <list><br /> <value>one</value><br /> <value>two</value><br /> <value>three</value><br /> </list><br /> </property><br /></bean></span></div><div><br /></div><div>And now here's a MapFactoryBean, which will return a Struct:</div><br /><div class="cfcode"><span class="cfvalue"><bean id="map.factory" class="coldspring.beans.factory.config.MapFactoryBean"><br /> <property name="sourceMap"><br /> <map><br /> <entry key="one">&tl;value>hello&tl;/value><br /> <entry key="one"><value>world</value><br /> </map><br /> </property><br /></bean></span></div><br /><div>Now I can use the ref tag for these maps and lists instead of directly defining them.</div><div><br /><div class="cfcode"><span class="cfvalue"><bean id="testBean" class="coldspring.tests.testBean" lazy-init="false"><br /> <property name="myList"><br /> <ref bean="list.factory"/><br /> </property><br /> <property name="myMap"><br /> <ref bean="map.factory"/><br /> </property><br /></bean></span></div><br /></div><div>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.</div>Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com1tag:blogger.com,1999:blog-16515669.post-90318132766496114442007-11-23T17:56:00.001-08:002007-11-23T18:14:02.148-08:00Long, long awaited ColdSpring updates!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. <div><br /></div><div>I have committed 2 fixes that should make Mark Mandel and Barney B really happy. <a href="http://code.coldspringframework.org/browse/CSP-84" target="_blank">CSP-84</a> 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. <a href="http://code.coldspringframework.org/browse/CSP-83" target="_blank">CSP-83</a> 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!</div><div><br /></div><div>OK, that's it for right now, there is A LOT more to come...</div>Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com0tag:blogger.com,1999:blog-16515669.post-92116724587659101682007-06-11T05:00:00.000-07:002007-06-11T05:05:31.101-07:00Flex 3 beta Now on Labs!Well, that pretty much sums it up, Flex 3 aka AIR (not too sure of that codename myself!) is now available on <a href="http://labs.adobe.com/">Adobe Labs</a>. It sure looks like the RIA space is really heating up now. I know a lot of Flex developers have had harsh criticism on <a href="http://silverlight.net/">MS Silverlight</a>, 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 <a href="http://d5.allthingsd.com/20070531/video-steve-jobs-and-bill-gates-together-part-3-of-7/">interview with Bill Gates and Steve Jobs</a> 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!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com0tag:blogger.com,1999:blog-16515669.post-67741471867212011922007-03-26T18:10:00.000-07:002007-03-26T18:23:58.177-07:00cf.Objective() session updatesI finally got my sessions to Jared, and he has <a href="http://www.cfobjective.com/conference/index.cfm?event=page.sessions">posted an updated list</a>. 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 <a href="http://www.cfobjective.com/conference/index.cfm?event=page.register">get on your tickets</a> 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!<br /><br />I am also bringing my Flex/ColdSpring session to <a href="http://cfunited.com/">CFUnited</a>, which is also shaping up to be another great conference, so go <a href="https://secure.teratech.com/cfunited07/register.cfm">register for CFUnited</a> too! Honestly, the value of conferences like these cannot be measured. I got my shinny newish job at <a href="http://www.cynergysystems.com/">Cynergy Systems</a> through contacts I made at CFUnited last year (along with <a href="http://www.cbetta.com/blog/index.cfm">Dave Carabetta</a>). If your looking for the best way to advance your career with marginal expense, these conferences are surely your best bet. See you there!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com2tag:blogger.com,1999:blog-16515669.post-56503701265064341532007-01-29T17:09:00.000-08:002007-01-29T17:56:55.576-08:00Unlocking the power of CF MetadataLately 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:<br /><br /><div class="cfcode"><span class="cftag"><cfset obj = CreateObject('component','com.foo.mycfc').init() /><br /><cfdump var="#getMetadata(obj)#" /></div></span><br /><br />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"' (<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.<br /><br />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!<br /><br />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:<br /><br /><div class="cfcode"><span class="cftag"><cfcomponent displayname="EntryService"><br /><br /> <span class="cfcomment">... init method and setters for dependencies ...</span><br /><br /> <cffunction name="getEntriesByCategoryID" access="public" returntype="array" cs_LogFields="categoryID" output="false" ><br /> <cfargument name="categoryID" type="numeric" required="true" /><br /> <cfargument name="numToReturn" type="numeric" required="false" default="-1" /><br /> <cfargument name="activeOnly" type="boolean" required="false" default="true" /><br /> <br /> <cfreturn variables.entryGateway.getEntries(arguments.numToReturn, arguments.activeOnly, arguments.categoryID) /><br /> </cffunction><br /><br /> <span class="cfcomment">... more service methods ...</span><br /><br /></cfcomponent></span></div><br /><br />Next we have our logging service, I've used cflog in this example and added a setter for the log file name.<br /><br /><div class="cfcode"><span class="cftag"><cfcomponent displayname="LoggingService"><br /><br /> <cffunction name="init" returntype="net.litepost.component.logging.LoggingService" access="public" output="false"><br /> <cfreturn this /><br /> </cffunction><br /> <br /> <cffunction name="setFilename" access="public" returntype="void" output="false"><br /> <cfargument name="filename" type="string" required="true" /><br /> <cfset variables.filename = arguments.filename /><br /> </cffunction><br /> <br /> <cffunction name="info" access="public" returntype="void" output="false"><br /> <cfargument name="message" type="string" required="true" /><br /> <cflog file="#variables.filename#" type="information" text="#arguments.message#"><br /> </cffunction><br /><br /> <span class="cfcomment">... rest of logging methods ...</span><br /> <br /></cfcomponent></span></div><br /><br />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.<br /><br /><div class="cfcode"><span class="cftag"><cfcomponent name="loggingAdvice" extends="coldspring.aop.AfterReturningAdvice"><br /><br /> <span class="cfcomment"><!--- setters for the logging service ---></span><br /> <cffunction name="setLoggingService" returntype="void" access="public" output="false"<br /> hint="Dependency: security service"><br /> <cfargument name="loggingService" type="net.litepost.service.LoggingService" required="true"/><br /> <cfset variables.m_loggingService = arguments.loggingService /><br /> </cffunction><br /> <br /> <cffunction name="afterReturning" access="public" returntype="void"><br /> <cfargument name="returnVal" type="any" required="false" /><br /> <cfargument name="method" type="coldspring.aop.Method" required="false" /><br /> <cfargument name="args" type="struct" required="false" /><br /> <cfargument name="target" type="any" required="false" /><br /> <br /> <cfset var arg = '' /><br /> <cfset var argString = '' /><br /> <cfset var logFields = "" /><br /> <br /> <span class="cfcomment"><!--- first I need the metadata for the target object of the method call ---></span><br /> <cfset var objMd = getMetadata(arguments.target) /><br /> <cfset var objName = objMd.name /><br /> <br /> <span class="cfcomment"><!--- I also need the name of the method that was called ---></span><br /> <cfset var methodName = method.getMethodName() /><br /><br /> <span class="cfcomment"><!--- I will use a private function to retrieve the metadata for that function ---></span><br /> <cfset var functionMd = getFunctionMetadata(objMd,methodName) /><br /> <br /> <span class="cfcomment"><!--- 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 ---></span><br /> <cfif StructKeyExists(functionMd, "cs_LogFields")><br /> <cfset logFields = functionMd.cs_LogFields><br /> <cfelse><br /> <cfset logFields = StructKeyList(args)/><br /> </cfif><br /> <br /> <span class="cfcomment"><!--- now all we need to do is loop over our logFields list, and build out a string from those values (restricting to simpleValues) ---></span><br /> <cfloop list="#logFields#" index="arg"><br /> <cfif StructKeyExists(args, arg) and isSimpleValue(args[arg])><br /> <cfif len(argString)><br /> <cfset argString = argString & ', ' /><br /> </cfif><br /> <cfset argString = argString & arg & '=' & args[arg] ><br /> </cfif><br /> </cfloop><br /> <br /> <span class="cfcomment"><!--- Now send it to the logging service! ---></span><br /> <cfset variables.m_loggingService.info("[" & objName & "] " & method.getMethodName() & "(" & argString & ") called!") /><br /> <br /> </cffunction><br /> <br /> <span class="cfcomment"><!--- here's our private method to retrieve just a particular function metadata from the full metadata from a cfc ---></span><br /> <cffunction name="getFunctionMetadata" access="private" returntype="struct" output="false"><br /> <cfargument name="metadata" type="struct" required="true"/><br /> <cfargument name="function" type="string" required="true"/><br /> <cfset var ix = 0/><br /> <cfset var mdFunctions = arguments.metadata.functions/><br /> <br /> <cfloop from="1" to="#ArrayLen(mdFunctions)#" index="ix"><br /> <cfif mdFunctions[ix].name EQ arguments.function><br /> <cfreturn mdFunctions[ix]/><br /> </cfif><br /> </cfloop><br /> <cfreturn StructNew()/><br /> <br /> </cffunction><br /><br /></cfcomponent></span></div><br /><br />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.<br /><br />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!<br /><br /><a href="http://cdscott.blogspot.com/2005/09/introduction-to-coldspring-aop.html">Introduction to ColdSpring AOP</a><br /><a href="http://cdscott.blogspot.com/2005/10/coldspring-aop-tutorial-part-one.html">ColdSpring AOP Tutorial – Part One</a><br /><a href="http://cdscott.blogspot.com/2005/11/coldspring-aop-tutorial-part-two.html">ColdSpring AOP Tutorial – Part Two, Around Advice </a><br /><a href="http://cdscott.blogspot.com/2006/02/introducing-auto-magic-remoting-with.html">Introducing auto-magic Remoting with ColdSpring</a>Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com6tag:blogger.com,1999:blog-16515669.post-86710735359358945522007-01-26T10:59:00.000-08:002007-01-26T11:06:14.630-08:00I'm the quintessential CF Developer!!WOW! I can't believe it! I'm actually the quintessential CF Developer, <a href="http://www.buntel.com/blog/index.cfm?mode=entry&entry=54DB3FFD-4E22-1671-5BDCF74737695F12">as far as Tim Buntel is concerned</a>! He was a little off on his meme though, so I thought I would update it, make it a little more accurate:<br /><br />Chris, the web developer persona<ul><li> 38 years old</li><li> 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</li><li> 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...)</li><li> Bought a house a 6 years year ago, a 1885 Stone Victorian, slowly renovating. Decorations are partially vintage, but not really.</li><li> 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!</li><li> Couldn't give a rat's ass about the Oscars</li><li> Into How It's Made, Mythbusters, secretly watches American Chopper even though I hate it, random nature and science stuff</li><li> 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)</li><li> Food? A little bit of everything, especially if it's on the grill</li><li> 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</li><li> I lost a lot of hours watching Devo videos on youtube. I do not know why...</li></ul>Help Tim, what's your persona??Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com2tag:blogger.com,1999:blog-16515669.post-18376966452858850742007-01-26T10:04:00.000-08:002007-01-26T10:17:26.928-08:00Some Excellent Flex articles...Kind of late on this, but in case you missed em, a couple of <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_0">Cynergy</span> <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-corrected" id="SPELLING_ERROR_1">coworkers</span> / Flex super gurus have <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-corrected" id="SPELLING_ERROR_2">written</span> some must read flex articles you probably want to check out.<br /><br />First up, Andy Trice did a <a href="http://www.cynergysystems.com/blogs/page/andrewtrice?entry=census_mashups_using_strikeiron_web">killer <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_3">mashup</span></a> with Yahoo Maps and <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_4">StrikeIron's</span> census web service. Really cool demo, and of course <a href="http://www.cynergysystems.com/blogs/page/andrewtrice">Andy's blog</a> is pretty much a must read.<br /><br />Andy and <a href="http://www.cynergysystems.com/blogs/page/keunlee"><span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_5">Keun</span> Lee</a> also wrote a great article, second in a series on <a href="http://www.adobe.com/devnet/flex/articles/frontback_pt2.html">Building <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_6">RIAs</span> from front to back</a> at Adobe's Dev center. Part one was also written by Carson <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_7">Hager</span> and Dave Wolf, <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_8">Cynergy</span> execs and killer developers too. Some really great stuff.Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com1tag:blogger.com,1999:blog-16515669.post-55783919121594527292007-01-01T09:45:00.000-08:002007-01-01T10:15:13.099-08:00Happy New Year! (From ColdSpring too!)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 <alias> tag! Here's how it's used:<br /><br />Lets say you have a bean defined, perhaps a reactor factory like the following, which you have referenced all throughout a complex configuration file:<br /><br /><bean id="myReactorFactory" class="reactor.reactorFactory"><br /> <constructor-arg name="configuration"><br /> <value>/config/reactor.xml<br /> </constructor-arg><br /></bean><br /><br />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:<br /><br /><alias name="myReactorFactory" alias="ormService"/><br /><br />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)!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com3tag:blogger.com,1999:blog-16515669.post-1162956004170381812006-11-07T19:14:00.000-08:002006-11-07T19:20:04.183-08:00Thank you Pennsylvania!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!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com4tag:blogger.com,1999:blog-16515669.post-1157768161622522342006-09-08T19:13:00.000-07:002006-09-08T19:16:01.646-07:00New Job's Resolution...Rock! I simply could not help myself, isn't she a beauty?<br /><br /><img src="http://static.flickr.com/96/238046029_57d711326d.jpg" width="375" height="500" alt="Bring on the metal..." />Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com1tag:blogger.com,1999:blog-16515669.post-1155664752760413192006-08-15T10:52:00.000-07:002006-08-15T10:59:32.203-07:00Congratulations Paul and Adam!In case you haven't heard, Adobe has aquired two great members of our community, Paul Kenney and Adam Way[ne Lehman]. Read about <a href="http://corfield.org/blog/index.cfm/do/blog.entry/entry/Paul_Kenney_to_join_Adobe">Paul's job</a> with Sean, and <a href="http://http://www.buntel.com/blog/index.cfm?mode=entry&entry=0E32EA10-4E22-1671-5A32FF89F738E4AB">Adam's new job</a> as North America's new ColdFusion Specialist (that's a hell of a title Adam!).<br /><br />Best of luck to both of you!Chris Scotthttp://www.blogger.com/profile/17578621333416282600noreply@blogger.com5