Saturday, November 21, 2009

Owning my On Domain

Today I realized how much I love owning my own domain!!  Since 2002 (ish) I bought lonestarbandit.com and have been using ZoneEdit.com to forward my email addresses to yahoo.com account, but 2 weeks ago I bought a moto-droid and it beautifully syncronizes with gmail, so today I am making the switch to gmail.  And if I didn't own my domain, I would have to let everyone know about my mail switch (which would of been a nightmare).  But with zoneedit.com, I made a configuration change and whoola my mail is now at gmail.com

How SWEET is that!!!

Thanks ZoneEdit!!!

Tuesday, November 17, 2009

Worth Noting Android 2.0 Apps

While I usually try to keep my posts too dynamic web content, today i'll be posting about android apps... You might be wondering why, well I got the Motorola Droid on the Verizon network. 

1.) Verizon Network - I know this isn't an app, but keeping with the largest 3g network while getting an iPhone like appliance is GREAT!!

2.) Music, Camera, Gallery, Maps, Browser, Messaging, Facebook  - I might have missed one, but the apps that are installed by default are awesome.  The maps is probably the best since now I have a GPS navigator in my phone.  Don't have to worry about carrying a GPS with me at all times.  And that goes with all the base installed apps, it reduces the number of electronics I carry.  Before the Droid, I felt like batman with a belt full of gadgets.

The real list, I had trouble creating a priority, so this is in no particular order... There are so many GREAT apps.

3.) The Weather Channel, Accuweather or WeatherBug - They are all great and all have their advantages.  I use the weather channel because of the widget and its location tracking.  I don't have to remember the zip code for the current city I am in. :-D

4.) Maps etc...  Places Directory, My Tracks, and My Maps editor by Google, Movies, Google Sky Map -  All of these build upon the Map concept, but adds places to it.  Places Directory you can manually look up a place to eat, local theatres, etc.. My Tracks  records where you are going and places it on Google my maps, and Map Editor lets you retrieve those Google my maps, Movies - Brings up local theatres and what is playing there, watch trailiers, new to dvd, etc..  Google Sky Map - Point your phone to the sky and your droid will become a star map.

5.) QIK - Live Feeds from you Droid using your camera!!

6.) Ringdroid - create ringtones from mp3

7.) Shazam - It listens to the song and then tells you who sings it and the song name... And if you so desire takes you to Amazon MP3 to buy it.

8.) ShopSavvy - Scan a barcode with the camera, and it will show other (mostly online) places and their pricing

9.) Taskiller - keeps your Droid running lean

10.) SportTap - keeps you up to date on Sports

11.) File System (AndroZip or Astro or BOTH) - They both have great features

12.) Misc stuff (Bubble, AK Notepad, colorNote, colorPict, flashlight, draw and share, ultimate stop watch , gps status, wifi analyzer) - All these add little pieces of heaven to your android.

13.) Photoshop.com - editing images

14.) Pandora -  great app, although i haven't used it much on the phone.

Friday, November 13, 2009

Enhancing coldbox - adding core Environment Safe logic without touching the core

Background
I know this is a no no, but our office uses subset of production data in our test system to have final sign off on new or changing applications. So when we decided to move to coldBox for a framework, I wasn't sure how environment safe coding was accomplished.

I quickly learned about the interceptor EnvironmentControl, which was a great first start. But there wasn't any settings for plugin MailService to stop emails from being sent. So my first inclination (and coding attempt) was to change mailService.cfc directly. Well I learned that is a mistake. We are now moving from 3b1 to 3b3 and realizing it is a pain when you change the core.

Enhancing Coldbox
Now that I understand a lot more on how Coldbox is running, i realized that my solution can be handle by an interceptor.  Using the announcement of afterPluginCreation, I created a EnvironmentSafeMailService.cfc interceptor that inject methods and properties into MailService plugin.  THIS IS AWESOME!

So how did I do it?  First I realized I have to add and replace functions and properties within MailService, therefore, the plugin MethodInjector came in handy.  But I needed to rename the send function in mailService.  So I can create my own logic and when appropriate call the original send function.

Ignoring the functionality I created for the environment safe feature, here is my code to override functionality with mailService.  All the methods and properties i'm inserting exist in the interceptor class I created.

<cffunction name="afterPluginCreation" access="public" returntype="void" hint="Executes after the framework and application configuration loads, but before the aspects get configured. " output="false" >
 <!--- ************************************************************* --->
 <cfargument name="event" required="true" default="" type="any" hint="path to plugin.">
 <cfargument name="interceptData" required="true" type="any" hint="path to plugin.">

 <cfscript>
  var local = StructNew();

  // ONLY AFFECT mailService plugin
  if ( compareNoCase(arguments.interceptData.pluginPath,"mailService") EQ 0 ) {

   //get plugin methodInjector to make our lives easier
   local.methodInject = getPlugin("MethodInjector");
   local.methodInject.start(arguments.interceptData.oPlugin);

   //make copy of original send
   this['MailServiceSend'] = arguments.interceptData.oPlugin['send'];
   local.md = getMetaData(this['mailServiceSend']);
   local.md.NAME = "mailServiceSend";
   arguments.interceptData.oPlugin.injectMixin( this['MailServiceSend'] );

   //inject new metdata (properties and methods) into MailService
   arguments.interceptData.oPlugin.injectPropertyMixin( "emailDebug", this.getEmailDebug(), "variables.instance" );
   arguments.interceptData.oPlugin.injectPropertyMixin( "emailDebugTOAddress", this.getEmailDebugTOAddress(), "variables.instance" );
   arguments.interceptData.oPlugin.injectMixin( this['getEmailDebug'] );
   arguments.interceptData.oPlugin.injectMixin( this['setEmailDebug'] );
   arguments.interceptData.oPlugin.injectMixin( this['getEmailDebugTOAddress'] );
   arguments.interceptData.oPlugin.injectMixin( this['setEmailDebugTOAddress'] );
   arguments.interceptData.oPlugin.injectMixin( variables['debugConfigured'] );
   arguments.interceptData.oPlugin.injectMixin( variables['traceIt'] );
   arguments.interceptData.oPlugin.injectMixin( this['send'] );

   local.methodInject.stop(arguments.interceptData.oPlugin);
   getPlugin("logger").tracer("EnvSafe MailService Functions Loaded");

  }
 </cfscript>
</cffunction>

Here is the interceptor and a quick guide on how to use it.

Wednesday, November 11, 2009

Being Thread Safe in Coldbox/Coldfusion

Thread safe never crossed my mind.  I never put CFC in the application scope to allow quicker execution (bypassing the createobject function).  But now that my office has implemented ColdBox, it cache's a lot for you, including its handlers - which are CFCs.  Well, we got bit by that evil words "THREAD SAFE".  Our code WASN'T... yes including my code.

So what does that mean.  Well I'll try to do a quick explanation, thread safe is any variable that is dedicated to a SINGLE user will NOT be shared to other users.  For example, in a object a "private" variable is NOT thread safe.  So if many users use the same object (implementation of a class), then we must make sure the variables being passed around are LOCAL to that function.  Therefore, in a CFC (depending on language) you must force your function variables to be LOCAL to the function only.

In CF8 use of the VAR keyword provides this
<cfset var myLocalVar = "" />

In CF9 the use of the scope LOCAL provides this
<cfset local.mylocalvar="" />

So for those of us still on CF8, i recommend using the following.
<cfset local=StructNew() />
<cfset var local=StructNew() />  *reader Jason found mistake in my post*
and then the rest of the code you can use
<cfset local.myLocalVar = "" />
without using the VAR keyword.

Also, as Sean Corfield commented below, using this methodology will NOT cause conflict with CF9 local scope.


Also, here is another blog post on the subject