<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>BarneyBlog</title>
	
	<link>http://www.barneyb.com/barneyblog</link>
	<description>Thoughts, rants, and even some code from the mind of Barney Boisvert.</description>
	<lastBuildDate>Wed, 25 Aug 2010 18:37:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/barneyblog" /><feedburner:info uri="barneyblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Scheduled Downtime This Evening</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/7yIM_e2bJmI/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/08/25/scheduled-downtime-this-evening/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 18:37:05 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[meta]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1576</guid>
		<description><![CDATA[Just a heads up that the server hosting barneyb.com and all it's various offspring (PotD, EventLog, etc.) will be going down about eight this evening to replace a faulty cooling fan.  Total outage should be less than 15 minutes, and it will be a complete outage (the IPs will be dead).
]]></description>
			<content:encoded><![CDATA[<p>Just a heads up that the server hosting barneyb.com and all it's various offspring (PotD, EventLog, etc.) will be going down about eight this evening to replace a faulty cooling fan.  Total outage should be less than 15 minutes, and it will be a complete outage (the IPs will be dead).</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/7yIM_e2bJmI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/08/25/scheduled-downtime-this-evening/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/08/25/scheduled-downtime-this-evening/</feedburner:origLink></item>
		<item>
		<title>Cron for CFML.  Again</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/4K9Wcdk4NXw/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/08/16/cron-for-cfml-again/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 06:27:49 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[cfml]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/2010/08/16/cron-for-cfml-again/</guid>
		<description><![CDATA[So tonight I built cron in CFML.  Again. Because it's missing from both the language framework and every runtime.  Am I the only one who constantly fights this battle?  In the past four years I've built four distinct cron implementations in CFML and it's completely retarded.
The JRE provides TimerTask, but it's a [...]]]></description>
			<content:encoded><![CDATA[<p>So tonight I built cron in CFML.  Again. Because it's missing from both the language framework and every runtime.  Am I the only one who constantly fights this battle?  In the past four years I've built four distinct cron implementations in CFML and it's completely retarded.</p>
<p>The JRE provides TimerTask, but it's a huge pain in the ass to use with CFML because the Java-to-CFML bridges are laughably weak.  OpenSymphony has Quartz (which is awesome), but being Java, it suffers the same problem.  Yes, even with the bennies CFGroovy offers in the Java space.</p>
<p>CFSCHEDULE is lame, especially on ColdFusion with it's 61 second frequency limit.  Even with an optimal implementation the entire mechanism is flawed because it's a) stuck with equal iteration periods, and b) can only invoke URLs.  Every distinct task requires punching a hole in your URL security, making a UI-layer facade for the task, etc. </p>
<p>The Java mechinisms are much better because they stay in-JVM (i.e., don't go through HTTP), but the statelessness of CFCProxy is a huge burden.  You can't access already-instantiated CFCs, which means you end up writing a massive pile of custom facade/proxy code to interface with your already-running business model.</p>
<p>The natural solution, of course, is implementing cron in CFML.  It allows you to pay either the HTTP or CFCProxy cost exactly once, as well as have cron's incredibly flexible scheduling format.  This fact, in it's various manifestations, drives me to drink rather ridiculous amounts.</p>
<p>The flip side, of course, is the dynamic reloading nature that CFML servers offer.  I simply cannot understand why other JVM frameworks have not copied this feature.  The complete avoidance of all the JVM restarts and classloading hell is a benefit worth enormous sacrifice.  Which, I suppose, is why I write CFML both for my salary and for personal projects.</p>
<p>Am I the only one who thinks this is a problem?  With both CFML and other JVM frameworks.</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/4K9Wcdk4NXw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/08/16/cron-for-cfml-again/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/08/16/cron-for-cfml-again/</feedburner:origLink></item>
		<item>
		<title>On-The-Fly YUI Compressor</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/AyLVp-oxFzU/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/08/03/on-the-fly-yui-compressor/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 01:35:14 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1570</guid>
		<description><![CDATA[A couple years ago I wrote about using YUI Compressor to do built-time aggregation and compression of static assets.  That works well and good if you have a build environment, but that's not always the case.  So, still using YUI Compressor, I set up a simple script that'll do runtime aggregation and compression of assets [...]]]></description>
			<content:encoded><![CDATA[<p>A couple years ago <a href="http://www.barneyb.com/barneyblog/2008/04/08/build-time-aggregation-of-jscss-assets/">I wrote about</a> using <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a> to do built-time aggregation and compression of static assets.  That works well and good if you have a build environment, but that's not always the case.  So, still using YUI Compressor, I set up a simple script that'll do runtime aggregation and compression of assets using my favorite mod_rewrite-based file caching mechanism.</p>
<p>The basic idea is that your HTML includes a reference to "agg_standard.js", which is an alias for whatever JS files you need for your standard user (as opposed to a mobile user, for example).  That request comes to your server and if the file exists, gets served back like any other JS file.  If it <em>doesn't</em> exist, however, mod_rewrite will forward it to a CFM page to generate it:</p>
<pre>RewriteCond     %{REQUEST_FILENAME}     !-s
RewriteRule     (/my_app)/static/(agg_.*)\.js$ $1/aggregator.cfm?name=$2.js
</pre>
<p>In our example, the request passed to aggregator.cfm would have "agg_standard.js" as the 'name' attribute, which is how we'll figure out what we need to aggregate together:</p>
<pre>switch (url.name) {
case "<span style="color: #0000ff;">agg_standard.js</span>":
  files = [
    "jquery/jquery" &amp; (request.isProduction ? ".min" : ""),
    "jquery/jquery.ui" &amp; (request.isProduction ? ".min" : ""),
    "yui/yahoo-min",
    "yui/event-min",
    "yui/history-min",
    "util",
    "jscalendar/calendar",
    "jscalendar/lang/calendar-en",
    "jscalendar/calendar-setup",
    "dracula/raphael-min",
    "dracula/graffle",
    "dracula/graph"
  ];
  break;
case "agg_iphone.js":
  files = [
    "jquery/jquery" &amp; (request.isProduction ? ".min" : ""),
    "yui/yahoo-min",
    "yui/event-min",
    "yui/history-min",
    "util"
  ];
  break;
}
</pre>
<p>The important bits, of course, is the Groovy script that actually does the aggregation and compression.  It uses YUI Compressor, so you'll need to have the yiucompressor-x.y.z.jar file on your classpath (probably in /WEB-INF/lib).  Here it is:</p>
<pre>import com.yahoo.platform.yui.compressor.*

sw = new StringWriter()
<span style="color: #0000ff;">variables.files</span>.each {
  def f = new File(variables.STATIC_DIR + it + '.js')
  sw.append('/* ').append(f.name).append(' */\n')
  if (! it.endsWith(".min") &amp;&amp; ! it.endsWith("-min")) {
    def compressor = new JavaScriptCompressor(f.newReader(), null)
    compressor.compress(sw, -1, false, false, false, false)
  } else {
    sw.append(f.text.trim())
  }
  sw.append('\n')
}
variables.buffer = sw.toString()</pre>
<p>Pretty straightforward: it just loops over the files, using a StringWriter to build up the aggregated buffer.  Each file is either compressed into the Writer or simply appended based on whether the file has already been minified (based on ".min" or "-min" in the filename).  Each file also gets a comment label in the Writer above it's contents so that the aggregated file is a little easier to parse (at the expense of a few extra bytes).  Once done, the Writer's contents are stored in the 'buffer' variable caching on the filesystem:</p>
<pre>&lt;cfset fileWrite(STATIC_DIR &amp; url.name, buffer) /&gt;
&lt;cflocation url="#url.name#" addtoken="false" /&gt;</pre>
<p>You'll notice that I'm not streaming the buffer back out to the user, but instead 302-ing back to the same URL.  This is important.  The reason is that Apache does a whole bunch of stuff to optimize static assets, and if I serve the content back with CFCONTENT, I'll miss out on all of that.  Yes, the 302 has a little bit of overhead on the initial page load, but it reduces the total transfer size by several hundred KB (because of the GZIPping), and avoids a rerequest on the next page load (because of the cache headers).  So it's completely worth it, the moreso because this is an application likely to generate extended usage rather than a content-centric site that is likely to see single-page "bounce" visits from search engines.</p>
<p>The last piece of the puzzle is handling versioning of your assets.  When you change your JS file, you necessarily have to invalidate your cache (by deleting the files) so the aggregated version can be rebuilt with the new JS.  The easiest way to do that is to use psuedo-versioning of your assets.  You'll see a lot of sites will add a timestamp or a version number to their files (e.g., "arc/yui/reset_2.6.5.css" from Yahoo.com) so that when the update the file it gets a new filename, and is therefore redownloaded by everyone (because it doesn't exist in their cache).  That's great, but it means you have to rename your files all the time which is kind of a pain.  But you can fake it:</p>
<pre>&lt;cfset STATIC_ASSET_VERSION = 15 /&gt;
&lt;script type="text/javascript" src="static/agg_standard_#STATIC_ASSET_VERSION#.js"&gt;&lt;/script&gt;
</pre>
<p>That'll generate a request to "agg_standard_15.js", as you might imagine, which isn't going to work so well.  But we can just change the 'switch' line from the first snippet to this:</p>
<pre>switch (REReplace(url.name, "^(agg_.*?)(_[0-9]+)?\.js$", "\1.js")) {</pre>
<p>Now it'll strip out that "fake" number string and switch on just "agg_standard.js", which is what we want.  But that 'fileWrite' call later will still use the full filename (with the number embedded).  That way subsequents will get the filesystem cacheing, the headers and GZIPping from Apache, and all the other love.  And when you rev your files, you need only increment the STATIC_ASSET_VERSION variable and you'll have a brand new set of virtual URLs for all your assets, no fuss, no muss.</p>
<p>Oh, and just in case you're wondering, the aggregation and compression is <em>fast</em>.  If you've ever used the command line or Ant task, you might fear that it's slow, but most of the time you see there is from the JVM spinning up, not the actual compression.  Since this is all in-JVM, you don't pay any of that cost.  It's certainly not fast enough to have it run in production on every request (hence the file caching), but it's totally reasonable to do on your production box as part of deploying a new version of the app.  It's also probably fast enough to have running every request on your internal test/staging boxes, though that'll depend on how much you're aggregating/compressing among other things.</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/AyLVp-oxFzU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/08/03/on-the-fly-yui-compressor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/08/03/on-the-fly-yui-compressor/</feedburner:origLink></item>
		<item>
		<title>Flash Scope CFC</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/-UwtqJJivAw/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/07/30/flash-scope-cfc/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 02:50:34 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1563</guid>
		<description><![CDATA[If you've ever used Grails, you probably know about the 'flash' scope that it provides for passing data from one request to the next.  Certainly not a must-have feature, but it's quite handy.  The typical use case is after a form submit, you set stuff into the flash scope and then redirect to some page [...]]]></description>
			<content:encoded><![CDATA[<p>If you've ever used Grails, you probably know about the 'flash' scope that it provides for passing data from one request to the next.  Certainly not a must-have feature, but it's quite handy.  The typical use case is after a form submit, you set stuff into the flash scope and then redirect to some page where you use the flash scope's contents to spit a message back to the user.  For example, after editing a user and submitting, you'd redirect the browser to the user listing page and display a "Successfully updated user" message at the top of the page.</p>
<p>The benefit of using the flash scope for doing this is that it only lasts one request, so if the user refreshes the listing page, they won't see the success message again (nor should they, since a user <em>wasn't</em> updated on the refresh).  It also keeps your URLs clean (because you don't have to pass stuff along on the query string), and lets you pass complex data (since there is no serialization).</p>
<p>I'm sure a lot of people have faked this functionality in some sort of use-specific way, and I know I'm guilty.  However, after preparing to do it yet again, I thought I'd build a more generic mechanism that I could reuse.  Before I give you the actual code, here's how you might use it:</p>
<pre>&lt;cfcase value="onRequestStart"&gt;
  &lt;cfset <span style="color: #0000ff;">flashScope = createObject("component", "FlashScope")</span> /&gt;
&lt;/cfcase&gt;

&lt;cfcase value="updateGoal"&gt;
  &lt;cfset xfa.success = "goalList" /&gt;
  &lt;cfset goalService = request.beanFactory.getBean("goalService") /&gt;
  &lt;cfset goalService.updateGoal(
    session.user.getId(),
    attributes.id,
    attributes.name,
    attributes.definition
  ) /&gt;
  &lt;cfset <span style="color: #0000ff;">flashScope.put("message", "Goal Updated Successfully!")</span> /&gt;
  &lt;cfset location("#self##xfa.success#") /&gt;
&lt;/cfcase&gt;

&lt;cfcase value="goalList"&gt;
  &lt;cfset goalService = request.beanFactory.getBean("goalService") /&gt;
  &lt;cfset goalList = goalService.getGoals(session.user.getId()) /&gt;
  &lt;cfif <span style="color: #0000ff;">flashScope.has("message")</span>&gt;
    &lt;cfset statusMessage = <span style="color: #0000ff;">flashScope.get("message")</span> /&gt;
  &lt;/cfif&gt;
  &lt;cfset include("dsp_goallist", "bodyContent") /&gt;
  &lt;cfset do("lay_auto") /&gt;
&lt;/cfcase&gt;</pre>
<p>As you can see, we're instantiating the flash scope at the start of every request.  Then in 'updateGoal', the 'message' key is set into the flash scope.  Finally in 'goalList', if there's a 'message' in the flash scope, it is set into a local variable (to be emitted within dsp_goallist.cfm).  Pretty straightforward.  The actual mechanism is a pair of structures: one in the request scope for incoming variables and one in the session scope for outgoing variables.  The FlashScope CFC is nothing more than a facade to those two structures.  This implies that you must have the session scope available to your application, of course.</p>
<p>I haven't created a full-on project for this but it garners sufficient interest and development activity, I'll certainly do that.  In the meantime you can <a href="https://ssl.barneyb.com/svn/barneyb/eventlog/trunk/lib/flash_scope/FlashScope.cfc">view/download the CFC</a> (or if you're using Subversion,<a href="https://ssl.barneyb.com/svn/barneyb/eventlog/trunk/lib/flash_scope/"> svn:externals it</a> into your project).</p>
<p>In the interest of full disclosure, I want to call out two shortcomings in the implementation, both of which are intentional (to minimize complexity):</p>
<ol>
<li>There is no respect paid to dealing with concurrent requests.  They'll happily intermix their variables in the flash scope, potentially causing errors and/or bizarre behaviour.</li>
<li>The scope isn't really tied to the 'next' request, it's tied to the 'next request that reads the flash scope'.  This can yield behaviour if your app assumes that the flash scope will be consumed, but it isn't for whatever reason.</li>
</ol>
<p>Both of these would require some sort of nonce on every request, which adds a whole layer of complexity and necessitates passing some sort of request parameter on the URL or whatever.  That's a) a mess, b) complicated, and c) application-specific.  As such, I've opted to intentionally <strong>not</strong> handle those cases since they're edge cases and I'd rather keep things simple.  That and I have this inexplicable obsession with 80-100 line, single-file microframeworks (see <a href="http://www.barneyb.com/barneyblog/projects/fb3-lite/">FB3lite</a>, <a href="http://www.barneyb.com/barneyblog/projects/cfgroovy2/">CFGroovy</a>, <a href="http://www.barneyb.com/barneyblog/projects/transaction-advice/">TransactionAdvice</a>, etc.).  :)</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/-UwtqJJivAw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/07/30/flash-scope-cfc/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/07/30/flash-scope-cfc/</feedburner:origLink></item>
		<item>
		<title>Closures, Closures, Closures</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/BsghEYS_yIs/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/07/23/closures-closures-closures/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 19:56:14 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1559</guid>
		<description><![CDATA[Guess what time it is, kids!!
It's "Barney still wants CFML closures" time!  Yay!
Today's impetus is Edmund, Sean Corfield's event driven programming framework.  In order to register event listeners, you have to a CFC instance with a specific method to be invoked on it, and which accepts an Edmund Event as it's sole argument.  Which means [...]]]></description>
			<content:encoded><![CDATA[<p>Guess what time it is, kids!!</p>
<p>It's "Barney still wants CFML closures" time!  Yay!</p>
<p>Today's impetus is <a href="http://edmund.riaforge.org/">Edmund</a>, <a href="http://corfield.org/">Sean Corfield</a>'s event driven programming framework.  In order to register event listeners, you have to a CFC instance with a specific method to be invoked on it, and which accepts an Edmund Event as it's sole argument.  Which means you have to have these silly little CFCs hanging about that simply get the event and then hand it off to the appropriate business components to actually do stuff.  Yes, I understand that's a very OO way to do it: lots of little, purpose-specific types passing messages between them.  But it's a bitch with CFML because every type has to be it's own file and you don't get context inheritance.</p>
<p>In Java most of the time your event listeners are anonymous inner classes &#8211; instances of classes that are defined inline.  That mechanism gets a lot of grief, and while I agree that it's a little more verbose than necessary in simple cases, it's a lot better than the crap that static typing and/or checked exceptions foists on you, and having a full class definition can be useful as things get more complex.</p>
<p>Groovy smoothes that a little by allowing you to define Closures and use them instead.  Under the hood, it's just converting them to your standard Java anonymous inner classes, but the syntax is rather nicer.  If you know Ruby, think lambdas.</p>
<p>This is what I'd do in Java:</p>
<pre>edmund.register("eventCreated", new GenericHandler() {
  public handleEvent(Event e) {
    <span style="color: #0000ff;">beanFactory.getBean("eventservice").postprocessEvent(e.value("eventId"));</span>
  }
});
</pre>
<p>or in Groovy:</p>
<pre>edmund.register("eventCreated", {
  <span style="color: #0000ff;">beanFactory.getBean("eventservice").postprocessEvent(e.value('eventId'))</span>
})
</pre>
<p>But in CFML, I need to create a separate type (in a separate file):</p>
<pre>&lt;cfcomponent&gt;

  &lt;cffunction name="init"&gt;
    &lt;cfargument name="beanFactory" /&gt;
    &lt;cfset variables.beanFactory = arguments.beanFactory /&gt;
  &lt;/cffunction&gt;

  &lt;cffunction name="handleEvent"&gt;
    &lt;cfargument name="e" /&gt;
    <span style="color: #0000ff;">&lt;cfset beanFactory.getBean("eventservice").postprocessEvent(e.value("eventId")) /&gt;</span>
  &lt;/cffunction&gt;

&lt;/cfcomponent&gt;
</pre>
<p>And then register it like this:</p>
<pre>&lt;cfset edmund.register("eventCreated",
  createObject("component", "MyEventHandler").init(beanFactory)
) /&gt;
</pre>
<p>What a mess.  Not only do I have to create a separate file to have that one single line of code in it (line 10), but I also have to worry about passing context around (in this case, the beanFactory), because the CFC instance doesn't inherit the context it's instantiated in (as closures and anonymous inner types do).  And this is a ridiculously trivial example.  Here's what I'd like to see in CFML:</p>
<pre>edmund.register("eventCreated", function(e) {
  <span style="color: #0000ff;">beanFactory.getBean("eventservice").postprocessEvent(e.value("eventId"));</span>
});
</pre>
<p>You can see that I'm following the ECMAScript-like nature of CFML expressions and stealing ECMAScript's function literal syntax (one of them, at least) to create an anonymous function.  In order for this to work, it'd have to be a closure (as ECMAScript functions are), not just a context-free function.  As an alternative (which is more complicated, but which has certain advantages in certain scenarios), would be to have a CFC literal (anonymous inner CFC) as well:</p>
<pre>edmund.register("eventCreated", new component() {
  function handleEvent(e) {
    <span style="color: #0000ff;">beanFactory.getBean("eventservice").postprocessEvent(e.value("eventId"));</span>
  }
});
</pre>
<p>Personally, I'd much prefer the closure if I only got one, but both would be nice.  The semantics of anonymous inner types can be a little wonky, and the advantages over simple closures is small, but they can still be really useful.  Now that we have a CFSCRIPT-based way of defining components, the language at least has syntactic constructs to express anonymous types, so it's theoretically possible.</p>
<p>So since I can't do all this neat stuff, you might ask what I did do.  I used ColdSpring with a purpose-sepecific adapter I wrote, along with a custom extension to Edmund to allow registering listeners from ColdSpring.  So my Edmund config looks like this:</p>
<pre>&lt;bean id="edmund"&gt;
  &lt;constructor-arg name="asyncByDefault"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/constructor-arg&gt;
  &lt;property name="eventListeners"&gt;
    &lt;map&gt;
      &lt;entry key="eventCreated"&gt;
        &lt;bean class="edmund.framework.ColdSpringListener"&gt;
          &lt;constructor-arg name="handler"&gt;&lt;ref bean="eventservice" /&gt;&lt;/constructor-arg&gt;
          &lt;constructor-arg name="method"&gt;&lt;value&gt;postprocessEvent&lt;/value&gt;&lt;/constructor-arg&gt;
        &lt;/bean&gt;
     &lt;/entry&gt;
  &lt;/property&gt;
&lt;/bean&gt;</pre>
<p>The ColdSpringListener bean simply takes care of delegating the configured method to the supplied bean when it is triggered, passing along the event arguments along.  This obviously is still pretty verbose, but the per-listener overhead is four lines of XML (in an existing file), not a 13 line CFC (in a new file).  That counts as a win by me.  The way I extended Edmund allowed passing a single listener or an array of listeners.  The method I added is here:</p>
<pre>&lt;cffunction name="setEventListeners" returntype="any" access="public" output="false"
  hint="I register multiple new listeners at once.  I DO NOT REPLACE listeners,
    despite being a setter.  I should be named addMultipleEventListeners, but must
    be named setEventListeners so I can be used from ColdSpring."&gt;
  &lt;cfargument name="listeners" type="struct" required="true"
    hint="I am a struct with event names as keys and either a single listener or
      array of listeners as values.  Note that there is no way to specify the
      handler method or whether listeners are asynchronous." /&gt;
  &lt;cfset var e = "" /&gt;
  &lt;cfset var i = "" /&gt;
  &lt;cfloop collection="#listeners#" item="e"&gt;
    &lt;cfif NOT isArray(listeners[e])&gt;
      &lt;cfset i = listeners[e] /&gt;
      &lt;cfset listeners[e] = arrayNew(1) /&gt;
      &lt;cfset arrayAppend(listeners[e], i) /&gt;
    &lt;/cfif&gt;
    &lt;cfloop from="1" to="#arrayLen(listeners[e])#" index="i"&gt;
      &lt;cfset register(e, listeners[e][i]) /&gt;
    &lt;/cfloop&gt;
  &lt;/cfloop&gt;
  &lt;cfreturn this /&gt;
&lt;/cffunction&gt;</pre>
<p>So is this good stuff?  It's OK.  It's solid for a CFML solution.  But there is no question that it pales in comparison to the elegance with which you could solve the problem in other languages.  Java (same age as CFML) has this, Ruby (a little older than CFML) has this, Python (much older than CFML) has this, and don't even get me started on Lisp (more than double the age of CFML).  It's not a concept new to computer science.</p>
<p>Alright.  Rant over.  Until next time I seriously consider rebuild huge swaths of CFML in Groovy just for closures and start yelling again.</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/BsghEYS_yIs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/07/23/closures-closures-closures/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/07/23/closures-closures-closures/</feedburner:origLink></item>
		<item>
		<title>Railo And AOP Transactions</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/WKkls7vLDj4/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/07/23/railo-and-aop-transactions/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 19:03:15 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[database]]></category>
		<category><![CDATA[railo]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1555</guid>
		<description><![CDATA[If you're reading this, chances are good you're a software developer.  And that means you never touch the DB outside a transaction, right?  Of course, right.
Most of the time, transactions are a bit of a bear because their use is orthagonal to your business tasks.  To put that another way, business operations flow vertically from [...]]]></description>
			<content:encoded><![CDATA[<p>If you're reading this, chances are good you're a software developer.  And that means you never touch the DB outside a transaction, right?  Of course, right.</p>
<p>Most of the time, transactions are a bit of a bear because their use is orthagonal to your business tasks.  To put that another way, business operations flow vertically from UI to backend to UI, and the various operations in your app typically flow mostly in separate parallel channels.  Transactions go <em>across</em> your application's structure, needing to be uniformly applied to all those operations, but being independent of all of them.  The "right" term for this is a "cross-cutting concern."</p>
<p>Fortunately, there are a pile of people in this world who are <em>way</em> smarter than I, and they've come up with <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">Aspect Oriented Programming</a> as a way to deal with these cross-cutting concerns.  The typical example shown is with logging, but transaction management is rather more useful, I think, isn't any more complicated, and is also more specific to AOP (whereas logging could be done with event-driven programming as well).  I'm not going to go into AOP, but if you're not using it, you should spend the time to learn a bit about it.  Really.</p>
<p>So the idea is to leverage AOP to automatically wrap your business methods with transactions.  In the CFML world, that means <a href="http://www.coldspringframework.org/">ColdSpring</a> and its AOP support (which is modelled after Java's Spring framework).  Unfortunately, that's the easy part.  Since CFML servers abstract away DB connections (behind DSNs), it's hard to get ahold of the proper context to do the transaction demarcation correctly from your application code.  Somehow you have to know what the engine is doing behind the scenes so you can start/stop transactions at the right places.</p>
<p>When I wrote <a href="http://www.barneyb.com/barneyblog/projects/transaction-advice/">transactionadvice.cfc</a> many years ago, I used a psuedo-ThreadLocal for tracking transactional method depth.  That way it can apply transactions at the top level, but skip them lower (nested) levels.  It works, but it doesn't handle multithreaded requests (i.e., using CFTHREAD) correctly, so it's far from ideal.  Using a real ThreadLocal would be better, but it requires Java or Groovy, and that's a dependency I don't want to require.  But for the majority of cases, it works fine.</p>
<p>Today, however, I discovered that Railo has this method:</p>
<pre>getPageContext().getDataSourceManager().isAutoCommit()</pre>
<p>It will tell you whether you're currently in autocommit (non-transaction) mode.  With this direct check of the transactional status, all the issues simply vanish, and the advice can be whittled down to this:</p>
<pre>&lt;cfcomponent extends="coldspring.aop.MethodInterceptor"&gt;

  &lt;cffunction name="invokeMethod" access="public" output="false" returntype="any"&gt;
    &lt;cfargument name="methodInvocation" type="coldspring.aop.MethodInvocation" required="true" /&gt;
    &lt;cfif getPageContext().getDataSourceManager().isAutoCommit()&gt;
      &lt;cftransaction&gt;
        &lt;cfreturn methodInvocation.proceed() /&gt;
      &lt;/cftransaction&gt;
    &lt;cfelse&gt;
      &lt;cfreturn methodInvocation.proceed() /&gt;
    &lt;/cfif&gt;
  &lt;/cffunction&gt;

&lt;/cfcomponent&gt;</pre>
<p>Copiously excellent, if you ask me.  About the only thing that would make it better is if CFML grew a isAutoCommit() or isInTransaction() method so you don't have to dig into the underlying Java bits in an engine-specific way.</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/WKkls7vLDj4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/07/23/railo-and-aop-transactions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/07/23/railo-and-aop-transactions/</feedburner:origLink></item>
		<item>
		<title>Tokenless location() Without Parameters</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/YeeSt3frs_Y/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/07/08/tokenless-location-without-parameters/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 17:46:36 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[railo]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1551</guid>
		<description><![CDATA[Both Railo and ColdFusion have added a builtin 'location' function in recent versions, and like their CFLOCATION counterpart, the default behaviour is to append the jsessionid/CFIDE/CFTOKEN tuple to the URL when redirecting.  I find this rather annoying, and it's even worse since FB3lite has a 'location' function which defaults it to false.  Unfortunately there isn't [...]]]></description>
			<content:encoded><![CDATA[<p>Both Railo and ColdFusion have added a builtin 'location' function in recent versions, and like their CFLOCATION counterpart, the default behaviour is to append the jsessionid/CFIDE/CFTOKEN tuple to the URL when redirecting.  I find this rather annoying, and it's even worse since FB3lite has a 'location' function which defaults it to false.  Unfortunately there isn't a way to use the FB3lite UDF in place of the engine built-in, so when you upgrade the server under a FB3lite app, suddenly the way your redirects work changes.</p>
<p>Fortunately, Railo implements the 'location' function as a CFML template, so you can easily go change the default.  If you install the WAR version the template is here:</p>
<pre>/WEB-INF/lib/railo-server/context/library/function/location.cfm</pre>
<p>If you install the bundled version, the 'railo-server' directory will be outside the webroot, typically here (thanks Todd):</p>
<pre>{installation-dir}/railo/railo-server/context/library/function/location.cfm</pre>
<p>Changing this file requires restarting your Railo webapp as the files are loaded once on startup.  As you'll quickly notice, there are a bunch of functions and tags that are implemented this way, so you can easily modify any or all of them to customize your environment.  Just be careful when you upgrade your Railo, as your changes will be overwritten.</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/YeeSt3frs_Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/07/08/tokenless-location-without-parameters/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/07/08/tokenless-location-without-parameters/</feedburner:origLink></item>
		<item>
		<title>Amazon S3 CFC Update – Now With Listings!</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/RHEEcFcBvRs/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/06/08/listings-for-amazon-s3-cfc/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 17:48:00 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[amazon]]></category>
		<category><![CDATA[cfml]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1543</guid>
		<description><![CDATA[I've added two new methods to my Amazon S3 CFC: listBuckets and listObjects.  Both of them do about what you'd expect, returning a CFDIRECTORY-esque recordset object containing the rows you are interested in.  I've attempted to make S3 appear like a "normal" filesystem where "/" is S3 itself, the top-level directories are your buckets, and [...]]]></description>
			<content:encoded><![CDATA[<p>I've added two new methods to my <a href="http://www.barneyb.com/barneyblog/projects/amazon-s3-cfc/">Amazon S3 CFC</a>: listBuckets and listObjects.  Both of them do about what you'd expect, returning a CFDIRECTORY-esque recordset object containing the rows you are interested in.  I've attempted to make S3 appear like a "normal" filesystem where "/" is S3 itself, the top-level directories are your buckets, and your objects are below that.  At the moment no consideration is made for paging or truncation.  Leveraging the new functionality, here's complete source for a simple S3 browser (minus your key/secret):</p>
<pre>&lt;cfparam name="url.path" default="" /&gt;

&lt;cfset s3 = createObject("component", "amazons3").init(
  "YOUR_AWS_KEY",
  "YOUR_AWS_SECRET"
) /&gt;

&lt;cfoutput&gt;
&lt;cfset bp = "" /&gt;
&lt;h1&gt;
&lt;a href="?path=#bp#"&gt;ROOT&lt;/a&gt;
&lt;cfloop list="#url.path#" index="segment" delimiters="/"&gt;
  &lt;cfset bp = listAppend(bp, segment, "/") /&gt;
  / &lt;a href="?path=#bp#"&gt;#segment#&lt;/a&gt;
&lt;/cfloop&gt;
&lt;/h1&gt;

&lt;cfif url.path EQ ""&gt;
  &lt;cfset b = s3.listBuckets() /&gt;
  &lt;ul&gt;
    &lt;cfloop query="b"&gt;
      &lt;li&gt;&lt;a href="?path=/#name#"&gt;#name#/&lt;/a&gt; #dateLastModified#&lt;/li&gt;
    &lt;/cfloop&gt;
  &lt;/ul&gt;
&lt;cfelse&gt;
  &lt;cfset q = s3.listObjects(listFirst(url.path, '/'), listRest(url.path, '/')) /&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href="?path=#reverse(listRest(reverse(url.path), '/'))#"&gt;..&lt;/a&gt;&lt;/li&gt;
    &lt;cfloop query="q"&gt;
      &lt;li&gt;
      &lt;cfif type EQ "dir"&gt;
        &lt;a href="?path=#listAppend(directory, name, '/')#"&gt;#name#/&lt;/a&gt;
      &lt;cfelse&gt;
        &lt;a href="#s3.s3Url(bucket, objectKey)#"&gt;#name#&lt;/a&gt;
      &lt;/cfif&gt;
      &lt;/li&gt;
    &lt;/cfloop&gt;
  &lt;/ul&gt;
&lt;/cfif&gt;
&lt;/cfoutput&gt;</pre>
<p>The default mode of operation assumes a delimiter of '/' (just like a filesystem).  If you want to do non-delimited operations (like generic prefix matching), you'll want to supply an empty delimiter, or you'll get weird results.  For example:</p>
<pre>&lt;cfset k_objects = s3.listObjects('my-bucket', 'k', '') /&gt;
</pre>
<p>If you omit the third parameter, the default 'k' will be used, and you'll get back objects within the 'k' psuedo-directory, rather than objects that begin with a 'k'.  This is the reverse of the default position of the raw S3 API, which assumes you want simple prefixing and makes you explicitly add the delimiter if you want psuedo-directory contents.</p>
<p>This dichotomy can also lead to weird results in the resulting recordset.  Every recordset comes with both 'bucket' and 'objectKey' columns that match the raw S3 nomenclature and 'directory' and 'name' columns that match the filesystem "view" of S3.  If you're doing raw prefixes you'll want to use bucket/objectKey (as the directory/name semantic doesn't work with prefixes).  If you're doing filesystem type stuff you'll probably want directory/name (though bucket/objectKey will still be correct).</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/RHEEcFcBvRs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/06/08/listings-for-amazon-s3-cfc/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/06/08/listings-for-amazon-s3-cfc/</feedburner:origLink></item>
		<item>
		<title>Groovy Gravity Processing</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/vwQVsZ21Cdw/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/05/28/groovy-gravity-processing/#comments</comments>
		<pubDate>Fri, 28 May 2010 21:42:29 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1534</guid>
		<description><![CDATA[Joshua (a coworker) and I have been talking about gravity simulation for a while, and this week I threw together a very simple model to do exactly that.  This grew out of a game called Flotilla that he came across somewhere and has been working with the developer to add a network multiplayer mode.  Flotilla, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.joshuafrankamp.com/">Joshua</a> (a coworker) and I have been talking about gravity simulation for a while, and this week I threw together a very simple model to do exactly that.  This grew out of a game called <a href="http://www.blendogames.com/flotilla/">Flotilla</a> that he came across somewhere and has been working with the developer to add a network multiplayer mode.  Flotilla, however, doesn't have a concept of gravity, and doesn't really have an explicit concept of mass either, except the implicit stuff in it's acceleration constraints.</p>
<p>Gravity, however, is kind of nasty to work with (from a computational perspective), particularly in a game situation (where you want realism, but not so real the game play sucks).  Fortunately, it's also exactly the kind of thing that I enjoy wasting my free time playing with.  So I threw together a simple model in Groovy, including a little type system and DSL to help keep my numbers straight.</p>
<p>So now when I divide a Force by a Mass, I'll get an Acceleration back.  Or if I multiply an Acceleration by a Time, I'll get a Velocity.  This was a huge win.  In the world of paper calculations, you don't do just arithmetic, you do unit algebra as well, which helps you ensure your answer makes sense (e.g., if you solve for velocity and get units of "meters per kilogram second", you screwed up somewhere).  But with a computer you don't have units, so I employed a simple type system to afford the same check I'd usually get from unit algebra.  And Groovy makes it remarkably easy to create both an expressive type system and a simple syntax (via operator overloading).</p>
<p>Then I hacked up Processing ever so slightly so I could implement a PApplet in Groovy and avoid the compilation step, and built a simple viewer for the model.  Emphasis on "simple".  Here's a capture with three bodies:</p>
<p><a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-1.png"><img class="aligncenter size-full wp-image-1535" title="gravity-1" src="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-1.png" alt="" width="648" height="509" /></a></p>
<p>The bodies' sizes represent their relative mass, the green lines represent gravitation between them, the red lines are the velocity vector (per body), and the pink lines are acceleration (also per body).  Here's a few seconds later in the same simulation:</p>
<p><a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-2.png"><img class="aligncenter size-full wp-image-1536" title="gravity-2" src="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-2.png" alt="" width="648" height="509" /></a></p>
<p>Now, because the bodies are far closer, the forces between them are much greater, which is going to result in a couple fairly impressive slingshots in a moment.  They've also picked up a fair amount of speed, though their active acceleration has surpassed their velocities (i.e., slingshots are imminent).  Here's after the slingshots have happened:</p>
<p><a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-3.png"><img class="aligncenter size-full wp-image-1537" title="gravity-3" src="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-3.png" alt="" width="650" height="510" /></a></p>
<p>After the two larger bodies slingshotted around each other, the two smaller bodies did the same thing, resulting in a <em>rapidly</em> expanding model.  As you can see the forces are falling away, though the smallest and largest bodies will soon meet up and cross paths.  The velocity of the little one is high enough that the big one can't slow it down enough to do more than deflect it upward a bit.</p>
<p><a href="http://processing.org/">Processing</a> again completely delivered on it's promise of providing a remarkably simple way to sketch out visual stuff.  Simple event handling, simple setup, a simple draw loop, and solid primitives.  I need to do a little mucking about, but adding 3D support (which the model handles, but the viewer doesn't) will be similarly trivial: flip the "use 3D" bit, and add 'z' coordinates from the model in the various calls.  Very nice, especially when coupled with the <a href="http://groovy.codehaus.org/">Groovy</a> syntax and capabilities.</p>
<p>An interesting project, though we'll see how generally useful.  Code, of course, is <a href="http://subversion.assembla.com/svn/gravity/trunk/">available from SVN</a>.  It's a single Eclipse project, including Groovy, Processing, the hacked PApplet (from Processing), the model and the viewer applet.  Check it out and run driver.groovy to see it in action.  While running SPACE will pause/unpause the action, though there is currently no way to rewind/reset the simulation.  If you don't want to check out the project, you can <a href="http://www.assembla.com/code/gravity/subversion/nodes">browse it directly</a>.  The interesting bits are in the /src/com/barneyb/gravity/ package.</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/vwQVsZ21Cdw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/05/28/groovy-gravity-processing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/05/28/groovy-gravity-processing/</feedburner:origLink></item>
		<item>
		<title>Tulsa CFUG Presentation (CFGroovy)</title>
		<link>http://feedproxy.google.com/~r/barneyblog/~3/H0VYckrYPqA/</link>
		<comments>http://www.barneyb.com/barneyblog/2010/05/26/tulsa-cfug-cfgroovy/#comments</comments>
		<pubDate>Wed, 26 May 2010 15:35:35 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1526</guid>
		<description><![CDATA[Yesterday I presented CFGroovy to the Tulsa CFUG via Connect.  The recording is now available on Connect, thanks to Steve.  You can also grab the slidedeck (as a PDF) I skimmed through, and of course, the CFGroovy framework itself (project page, core SVN, demo SVN), including the demo files that I showed.
]]></description>
			<content:encoded><![CDATA[<p>Yesterday I presented CFGroovy to the Tulsa CFUG via Connect.  The recording is now <a href="http://adobechats.adobe.acrobat.com/p20888993/">available on Connect</a>, thanks to Steve.  You can also grab the <a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/04/Polyglot_Programming.pdf">slidedeck (as a PDF)</a> I skimmed through, and of course, the CFGroovy framework itself (<a href="http://www.barneyb.com/barneyblog/projects/cfgroovy2/">project page</a>, <a href="https://ssl.barneyb.com/svn/barneyb/cfgroovy2/trunk/engine/">core SVN</a>, <a href="https://ssl.barneyb.com/svn/barneyb/cfgroovy2/trunk/demo/">demo SVN</a>), including the demo files that I showed.</p>
<img src="http://feeds.feedburner.com/~r/barneyblog/~4/H0VYckrYPqA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.barneyb.com/barneyblog/2010/05/26/tulsa-cfug-cfgroovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.barneyb.com/barneyblog/2010/05/26/tulsa-cfug-cfgroovy/</feedburner:origLink></item>
	</channel>
</rss>
