The most comprehensive explaination of Flex 4 Skin
3 February 2010 2:46 AM
by Charles
The most comprehensive explaination of Flex 4 Skin

One of the biggest change you will encounter when develop or migrate to Flex 4 is the spark skin creation. It’s a big leap to separate UI design from programming. There are many resources available to start tutoring the skin development. I found the best one so far among them is this slides created by Saurabh Narula.
It’ll make a lot easier to go over this stack first before diving into the thick document. It’s worth the time.

Acrobat.com now on iPhone
Objective-C: Simulating slow network speeds
Database normalization and de-normalization | Programming and Development
Developer Justin James provides an overview of the basics of normalization and de-normalization, with an emphasis on the Third Normal Form. via blogs.techrepublic.com.com
————————————————————————————–
One of the central ideas in relational databases is the concept of normalization. Normalization and de-normalization play a significant role in your ability to write applications that perform well and tolerate data changes without creating inconsistencies. In this article, I will talk about the basics of normalization and de-normalization, so that you can get a handle on this topic.
The field of database theory contains a number of normalization levels; however, when the typical developer or DBA says that a database is “normalized,” they are referring to what is called the Third Normal Form or 3NF (there are quite a few “Normal Forms”). This is what I will focus on in this column.
In 3NF, each table has a key column, and the only actual data in the table are things that directly belong to that key’s concept; this is very similar to object-oriented theory. Table A is an example dataset that is not properly 3NF.
Table A
Not normalized. (Click the image to enlarge.)
Because Table A is not normalized, we create the following problems for ourselves:
- If a customer record ever changes, we need to make the change in every invoice record in the table, which leaves a lot of room for error.
- If another table needs to refer to customers, it will either need to refer to invoices (which is confusing and does not create a canonical record for each customer) or replicate the customer data elsewhere, creating two sources of customer data.
- Making a change to a customer record involves locking every row with that customer, which can be problematic.
- There’s no way of uniquely identifying any given customer.
To normalize this table, we identify each unique record type; in this example, we have two record types (invoice and customers) within each actual record. Next, we split those records into separate tables and give each table a unique ID. This ID should be a value that is wholly independent from the record because, even if the business logic says that the data cannot change, the business logic could change in the future. Additionally, the ID value (a “primary key”) should be one that the database can easily look for and allow for easy partitioning of data between servers if needed; as such, using an integer value with an autoincrementer is ideal for primary keys. After normalization, we will have two pairs of tables (Table B and Table C).
Table B
Normalized invoice table. (Click the image to enlarge.)
Table C
Normalized customer table. (Click the image to enlarge.)
As you can see, we now have two tables that only contain the data relevant to the table. As a result, if we have another table that needs to deal with customers, it can refer to the independent customer table, which will eliminate data duplication; also, each customer only needs to be updated in one place. In addition, we can now uniquely identify customers. As a bonus, we save a ton of space in the database.
This all sounds great, right? It sure does. But as we know, there are rarely any free lunches in the world of software development. In this case, the cost of this tasty meal is performance, particularly for reading and aggregate operations. Searching goes quite quickly, thanks to all of those convenient primary keys. But let’s pretend that we want to make a sales report at the end of the month that looks like our pre-normalization table; we’ll need to execute a long-running query (after all, we’re grabbing a month’s worth of data) that will need to perform JOIN operations on all of these tables. In the process, we will need to lock all of those rows and generally jam up the database in the process. There are good reasons why reports get run at night, and this is one of them.
We resolve this problem with a data warehouse. (I am not going to go far into data warehouse theory, which is a deep topic.) A data warehouse is designed for pure read speed and typically looks like a de-normalized table. In fact, the way a data warehouse usually works is to periodically take a “snapshot” of the online, relational database used for the day-to-day work and create a variety of de-normalized tables, each designed to meet a particular reporting need. From there, reports are run against the data in the warehouse. This way, the long running, resource-hungry reports can be run against tables that are optimized for those reports’ needs without tying up the online database. The drawback is significant expense in having extra database servers and storage, and the fact that you are reporting against data that are not real-time accurate.
Flex 3: Delaying Instantiation to Improve Startup Time with Components
This tutorial is inspired by the book Flex 3 Cookbook
- none - no components created.
- all - all components will be created, and queued, based on their creationIndex.
...
<mx:Script>
[
Flex: Basic overview of Cairngorm 3 Libraries
- Guidelines explaining the motivation
- Tools to adhere to this guideline framework.
- Libraries to extend existing architectural framework and solve existing problems.
<mx:TextInput text="{ model.firstName }"/>
<cg:Observe source="{ model.firstName }" handler="runEffectFunction"/>
..
<cg:ObserveValue source="{ model.firstName }" value="{ Name.SARA }" handler="runEffectFunction"/>
<observer:EventListener source="{ model }" type="{ Person.UPDATE_EVENT }" handler="runEffectFunction"/>
<popup:PopUpWrapper open="{model.openPopUp}"> <mx:Label text="Hello World"/> </popup:PopUpWrapper>
...
<popup:PopUpWrapper
open="{model.openPopUp}"
center="true"
modal="false"
childList="{PopUpManagerChildList.POPUP}"
opening="openingHandler()"
opened="openedHandler()"
closing="closingHandler()"
closed="closedHandler()">
<mx:Label text="Hello World!"/>
<popup:PopUpWrapper>
<validators:ValidatorGroup id="validatorGroup">
<validators:validators>
<mx:StringValidator id="firstnameValidator"
source="{ firstnameInput }"
required="true"
minLength="3"
property="text"
triggerEvent="change"/>
<mx:StringValidator id="lastnameValidator"
source="{ lastnameInput }"
enabled="{ lastnameValidatorEnableFlag }"
required="true"
minLength="2"
property="text"
triggerEvent="change"/>
</validators:validators>
Facebook woos developers with a roadmap | Web Crawler - CNET News
![]()
Facebook's Ethan Beard outlines what the company is up to in the next six months.
(Credit: CNET / Josh Lowensohn)PALO ALTO, Calif.--Facebook on Wednesday took the wraps off its brand new development roadmap, unveiling changes and features the company is planning to implement within the next three to six months.
Many of the changes are smaller, simply rearrangements of certain parts of the user interface. However, the company is also making some radical moves like enforcing badly written applications and enabling developers to acquire user e-mail addresses as well as create Facebook-like sites outside of the social network's walls.
Ethan Beard, Facebook's director of platform marketing, who gave the presentation in Facebook's headquarters here, said that the one thing the company kept hearing from developers was that they needed to know what the company was working on ahead of time--and not just for short-term development, but a year down the line. "You want to know what's going on inside of Facebook," he said. "And today is to provide you with a lot more predictability."
That predictability revolves around the company's roadmap, which now sits on a new developer site. Beard says that it will remain updated with new items, planned changes, and APIs as they are announced. The company is also making publicly available a bug list, which will show developers problems with the site that Facebook is working on, as well as how they are being prioritized to be fixed.
More information about the new developer APIs can be found on Facebook's developer site.
For those of you who are developers or who are interested in becoming a developer on the Facebook framework, there are new changes and initiatives that may be of interest .
Open BlueDragon + Railo + ColdFusion on Tomcat | Matt's excellent article
As a corollary to Sean's post about running Railo, OpenBD, and ColdFusion on JRun, I thought I'd outline my preferred development environment these days, which is to run all the necessary CFML engines on Apache Tomcat. Note that this approach will work equally well on Jetty, JBoss, GlassFish, or more or less any servlet container or JEE server you choose.
Great minds think alike because coincidentally enough, Dave Shuck also has just published two blog posts (part 1, part 2) about setting up a similar environment. I figure I'll throw mine out there as well because the more information available the better.
So why not use JRun? Well, aside from the fact that JRun is getting very long in the tooth at this point, personally (and you'll probably hear me say this in a couple of conference presentations this year), I think the ColdFusion model stands Java on its head a bit, particularly when you do a standalone install of ColdFusion. Yes, it makes it easy to install and configure ColdFusion, but in my opinion it also shields people from how Java web applications actually work, so I've become a big fan of treating ColdFusion like what it is: a Java web application.
This to me makes far more sense than letting ColdFusion and JRun dictate your Java environment. And I think you'll see in this blog post that "installing" CFML engines on Tomcat is actually easier than installing ColdFusion. The only even remotely tricky part is installing Tomcat (and in most cases it isn't tricky at all), so let's tackle that first.
As an aside, if you just want to try Open BlueDragon and don't want to bother with the Tomcat installation, just download the Ready2Run Jetty + OpenBD distribution, start Jetty, and you're done!
Installing Tomcat
I'm assuming you already have Java installed, and I recommend Java 1.6 updater 10 or later (updater 11 is the latest) since previous versions had a bug that makes CFC instantiation horrendously slow. So, if the following looks complicated, it's really only because I'm outlining how to get the Java settings correct if you need to worry about it. Chances you won't need to do most of these steps, and once Tomcat's running the CFML piece of this puzzle is dead simple.
First, download Tomcat. As of this blog post the latest version is 6.0.18, and you'll want the "Core" binary distribution. After the download completes, unzip the file you downloaded. Now comes the tricky install process. Oh wait, I forgot--there is no install process! All you have to do is start Tomcat after you unzip it. If you have your Java environment set up correctly Tomcat should find Java fine and fire right up.
To start Tomcat, open a terminal (or DOS window if you must ...) and navigate to your Tomcat directory, then the bin directory. For example if you unzipped Tomcat to /home/yourname/apache-tomcat-6.0.18, you would navigate to /home/yourname/apache-tomcat-6.0.18/bin. (Note that all of this runs perfectly well on Windows, and though I would never recommend using Windows for anything, you do not have to use Linux to get any of this to work.)
Once you're in the bin directory, run the startup.sh script (./startup.sh) and you'll see some output similar to this:
Using CATALINA_BASE: /home/mwoodward/apache-tomcat-6.0.18
Using CATALINA_HOME: /home/mwoodward/apache-tomcat-6.0.18
Using CATALINA_TMPDIR: /home/mwoodward/apache-tomcat-6.0.18/temp
Using JRE_HOME: /usr/share/java/jdk1.6.0_11
As long as you see something similar everything's likely fine. If you see errors, the most likely culprit is that Tomcat can't find Java. You can either set a JAVA_HOME environment variable, or you can explicitly tell Tomcat where to find Java by adding the JAVA_HOME location to the catalina.sh script in the bin directory. Open catalina.sh in your favorite text editor, and after the big block of comments at the top of the file (denoted with # signs), add the following line:
JAVA_HOME=/path/to/your/jdk
Note that this should be the path to your JDK's home directory, not to a directory such as lib, etc. inside the directory. In my case I have Java in /usr/share/java/jdk1.6.0_11 so that's the value I use for JAVA_HOME. Save catalina.sh and run startup.sh again and everything should work now.
Check to make sure Tomcat is running by browing to http://localhost:8080 You should a page confirming that Tomcat is configured correctly.
![]()
Installing Open BlueDragon
Once Tomcat is running, since Open BlueDragon is a standard Java WAR (web application archive) file, "installing" OpenBD on Tomcat really just means copying a file to Tomcat's webapps directory so the WAR file is deployed. A WAR file is actually the same format as a JAR file (which is essentially a ZIP file ...), but it has an XML file that tells servlet containers how to deploy the application.
Here are the installation steps for OpenBD:
Download the Open BlueDragon WAR ("J2EE Standard WAR") file from http://openbluedragon.org/download.cfm
Copy the WAR file (which unless you change it is called openbd.war) to /path/to/tomcat/webapps
Wait a few seconds for Tomcat to auto-deploy the WAR file, and browse to http://localhost:8080/openbd to see a test page:
![]()
That's it! You now have Open BlueDragon running on Tomcat. Tomcat will deploy the WAR into a context path with the same name as the WAR file, which in this case is openbd, hence the URL http://localhost:8080/openbd If you want to deploy another instance with a different context path name, just change the name of the WAR file as you copy it (e.g. cp opendb.war /path/to/tomcat/webapps/mynewcontextpath.war) and you'll have another instance with a different context path.
As for where to put your CFML files, just put them in /path/to/tomcat/webapps/openbd (or whatever you called your context path), and of course all URLs for this instance will include the context path in them. I won't be covering how to run Tomcat on port 80 or hook things into Apache in this blog post, but I'll cover that in a future post.
Installing Railo
To install Railo you follow the exact same steps as above with Open BlueDragon:
Download the Railo WAR from http://railo.ch/en/index.cfm?treeID=224 -- you want the WAR file under "Railo Custom" at the bottom of the page
Copy the WAR file to /path/to/tomcat/webapps. In this case since the file name includes the version number, I did a cp railo-3.0.2.001.war /path/to/tomcat/webapps/railo.war, which will make the context path "railo"
Wait a few seconds for Tomcat to auto-deploy the WAR file, and browse to http://localhost:8080/railo to see a test page:
![]()
As with OpenBD above, just put your CFML files in /path/to/tomcat/webapps/railo to run them on Railo in the railo context path.
Installing ColdFusion
ColdFusion is a bit of a different beast since Adobe doesn't distribute a standard WAR file, but luckily you easily can generate one by running the installer. The steps below are when you run the installer on Linux but the same principles apply on other operating systems. Let's generate a WAR file for ColdFusion.
If you don't have it handy, download the developer edition of ColdFusion from http://www.adobe.com/support/coldfusion/downloads.html
Run the installer (note on Linux you need to run the installer as root)
Accept the license agreement (which is really fun to page through on the console installer--I think if you hit enter 28 times that will get you to the "Do you accept?" prompt ;-)
Select Developer Edition (or use a serial number if you prefer)
KEY STEP: Choose an installation type of "J2EE Configuration (WAR file)"
Select the stuff you don't want to include in the installation. I typically uncheck all four choices (docs, LiveCycle, search services, and start on init) when I generate a WAR
Choose the installation directory or accept the default
Enter the admin password
Choose to enabled or disable RDS. I find it's handy to have RDS on development instances so you can use the Eclipse tools to interact with the datasources.
Enter the RDS password
Confirm the installation selections and continue
Wait a minute or so for the WAR to be generated At the end of this process you have a CF 8 WAR file sitting in your install directory (which by default on Linux is /opt/coldfusion8). Now the installation is more or less as above with OpenBD and Railo since we have a standard WAR file we can deploy on Tomcat:
Copy the cfusion.war file into /path/to/tomcat/webapps As indicated above, this will mean your context path will be "cfusion" unless you rename the WAR file while copying it.
Wait a few seconds for Tomcat to auto-deploy the WAR file
Browse to http://localhost:8080/cfusion to complete the installation process for the WAR.
Note that you only have to go through the 12-step program above to generate the WAR once, unless you want to change the installation options. So when you need another instance of ColdFusion on Tomcat, just copy the WAR file over again and give it a different name (and hence a different context path) from any other instances.
If this matters to you, please be aware that for some reason ColdFusion isn't officially supported on Tomcat. Why is a bit of a mystery since Tomcat is the servlet container used in JBoss, and in my experience ColdFusion runs just fine on Tomcat. I only bring it up if you're in an environment where official support matters.
Why Do This?
You now have Tomcat running and can easily develop and test on Open BlueDragon, Railo, or Adobe ColdFusion. To me that's reason enough to use a development setup such as this. Also based on my experience helping people get this type of environment set up, it really does start to open up people's eyes to what's really going on under the hood with ColdFusion. Yes, if you do the multi-instance installation of ColdFusion you do get some server management features you don't get otherwise, but based on how I'm using ColdFusion these days, I simply don't need those features, particularly on development.
What I do need, on the other hand, is the ability to develop on both ColdFusion 8 and (increasingly) Open BlueDragon, so rather than trying to shoehorn OpenBD into the ColdFusion/JRun environment, I prefer to use a standard Java servlet container such as Tomcat and put all the CFML engines and instances I need on Tomcat.
Next Steps
You're probably already wondering how to get things to run "for real," meaning eliminating the port number and context path for your users. This can be done several different ways, so I'll cover some options in future blog posts. In the mean time, check out Dave's blog posts (links above) for some info on setting things up with Apache and mod_jk, which is one way to go. You can also change the port Tomcat runs on, or proxy from Apache out to Tomcat for CFML sites, so there's no shortage of ways to set up more or less any configuration you want.
Matt has provided excellent instructions on how to install on Tomcat openbd and Railo as well as Adobe's CF, all within the same developer build
FirebugTarget - A Flex Logging Tool I found
Hey folks, I came across this simple Flex logging when I was investigating the latest developments in the logging framework world, for my project at work. While I will do a good review of one of the best logging tools out there, Thunderbolt, for now I just wanted to bring up a simple blogging utility. It's called FireBugTarget and was made to be able to use Firefox's Firebug console, to log warnings, information, errors and so forth. I found it on Danny Patterson's blog, and he explained how he created a simple mx.logging framework implementation, and I have tested it on both Firefox and Internet Explorer (with Internet Development Tools). All you have to do to get this working is, put the .as file somewhere in amongst your packages and refer to it, as shown below:
import com.dannypatterson.logging.FirebugTarget; import mx.logging.ILogger; import mx.logging.Log; var logger:ILogger = Log.getLogger("myLogger"); var logTarget:FirebugTarget = new FirebugTarget(); logTarget.addLogger(logger); logger.info("info from flex"); logger.error("error from flex"); logger.warn("warn from flex"); logger.debug("debug from flex");









