Maven & Flex-mojos
Monday 29 September 2008 @ 4:42 pm

To build and deploy Flex application I usually use Apache Ant with Flex Ant Tasks which come with the Flex SDK.

A few month ago the Flex-mojos blog got my attention and I added it to my RSS Reader and now I finally got the time to play around with it.

“Flex-mojos is a collection of maven plugins to allow maven to compile, optimize, test and … Flex SWF, Flex SWC, Air SWF and Air SWC. The main goal is to provide a full support to all mxmlc/compc options.”

“Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.”

This all sounds pretty promising so I gave it a try. I am under OS X so the commands are slightly different under Windows.

Install Maven

export M2_HOME=/path/to/maven
export M2=$M2_HOME/bin
export PATH=$M2:$PATH
mvn --version

If you see the Maven and Java version info you know your installation was successful.

Flex Mojos with Flex SDK 3.1.0

The first thing I tried was to follow the Flex-mojos HelloWorld tutorial. I got the same 4 missing artifacts error like you see below in the comments. After some research on Velos blog and the goal to compile with 3.1.0 the research began ;).

The first thing is to copy the Maven settings.xml from /path/to/maven/conf/settings.xml to ~/.m2 which is your Maven user directory.

HINT: You can open this hidden directory in Finder from the Terminal with open ~/.m2.

Integrate the settings by Velo like described here and provided here.

Update to 2.0M5 (and change the path to your sdk):

mvn info.flex-mojos:install-mojo:2.0M5:install-sdk -Dflex.sdk.folder=/Users/soenkerohde/sdks/3.1.0/ -Dversion=3.1.0.2710

Due to a typo bug in the 2.0M5 super-pom we will work without super pom so you have to comment the parent node add add the contents from the super-pom which should look like this pom.xml.

Now things should be ready to go:

mvn install
...
...
INFO] Installing /Users/soenkerohde/maven/myproject/target/simple-flex-application-1.0-SNAPSHOT.swf to /Users/soenkerohde/.m2/repository/com/example/flex/simple-flex-application/1.0-SNAPSHOT/simple-flex-application-1.0-SNAPSHOT.swf
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12 seconds
[INFO] Finished at: Mon Sep 29 16:01:16 CEST 2008
[INFO] Final Memory: 9M/55M
[INFO] ------------------------------------------------------------------------
soenkerohde:myproject soenkerohde$

Yeah! So this was “HelloWorld” and my first impression of Maven after walking into every trap is pretty good. I will try to blog more when I get more experience.

I also read a few things about Maven archetypes which is the Maven project templating toolkit. If I find time I would give this also a try. Just check the links to get some inspiration.

Links

Comments (1) - Posted in Flex by Sönke  




Swiz Framework - Brutally Simple
Wednesday 24 September 2008 @ 11:59 am

After the 360Flex took place in San Jose I watched a few of the video recordings which are available through Adobe Media Player. Ted Patrick was also so nice to put them on his blog.

I am always interested in new Flex frameworks and Swiz got my attention. I watched the video and started to play around with it. What I like most about the framework is the use of metadata aka annotations which really reduces the amount of code.

When I first checked out the source I recognized that the DynamicMediator which was shown in the presentation was not committed yet. However, I started to build an example project where the views got the controller injected via Autowire. After a few days I was a bit frustrated because I also wanted to use the Mediate metadata and surprise, the code was committed. I updated the library and could remove all the controller references from the views which decoupled things like I wanted it to have. And recently Chris Scott, the developer behind Swiz, also blogged about the update for DynamicMediator.

When you have no clue what I am talking about be sure to check the presentation of Chris at 360Flex. There was no more need to study the docs after watching the video since the framework is really a “Brutally simple micro-architecture for Rich Internet Application development with Adobe Flex“.

So what’s it all about? Swiz is an IoC or Dependency Injection framework. I have used IoC frameworks in the past and got the point why it is cool but I always disliked the XML configuration files. Swiz uses similar concepts like Spring in the Java world were annotations were introduced in 2.5.

Swiz currently support two kinds of annotations: Autowire and Mediate
Autowire automatically injects references to objects which very defined in the BeanLoader and mediated methods get invoked when the belonging event was fire with event member variables as parameters.

The other hot discussed IoC framework is currently Mate. The presentation of Laura Arguello at 360Flex is really great and really nails down what the common problems are and how to solve them. I pretty much share the dislike of coding in XML blogged by Olesen and discussed on InfoQ. Another review of Mate is done by Flash Magazine and the structure is visualized in a diagram by Fatara Systems. But don’t get me wrong. Mate looks really awesome but to my personal preference I prefer something more lightweight like Swiz.

The weakness of Swiz is currently that the Autowire and Mediate uses strings instead of constants which means there is no compile time check if things work or not. On the one hand you should use conventions how you name the “beans” to autowire and the event types to mediate and on the other hand it would not be to hard to build a kind of pre-compiler which validates that the annotations match. My convention for beans is to use the class name starting lowercase like

<Beanloader ... xmlns:ctrl="com.soenkerohde.myproject.ctrl.*">
    <ctrl:MyController id="myController" />
</Beanloader>

.
So it can be used/injected with:

[Autowire(bean="myController")]
public var myController:MyController;

For the dynamic mediators my current approach is to type the event with the full qualified classname like

[Mediate(event="com.soenkerohde.myproject.events.LoginEvent", properties="username,password")]
public function login(username:String, password:String):void

The event would look like this:

package com.soenkerohde.myproject.event
import flash.events.Event;
public class LoginEvent extends Event
{
  public static const LOGIN_EVENT:String = "com.soenkerohde.myproject.events.LoginEvent";
  public var username:String;
  public var password:String;
  public function LoginEvent(username:String, password:String)
  {
    super(LOGIN_EVENT);
    this.username = username;
    this.password = password;
  }
}

However, it would be nice to have something during compile time. Let’s see how Swiz evolves and what other frameworks enter the arena.

Comments (5) - Posted in Flex, Swiz by Sönke  




AIR HTML with “_blank” Links Part II - Using HTMLHost
Thursday 4 September 2008 @ 11:37 am

I few days ago I blogged about how to open target=”_blank” anchor links in the system browser and leaving normal links in the HTML control of AIR. Since that I learned a bit more and people pointed me to the AIR docs. There you can find a great chapter about “Defining browser-like user interfaces for HTML content”.

So there is an easier method like mine which waited for the complete event of the HTML control and added custom event listeners for each anchor tag.

Like it is described in the docs you can extend the default HTMLHost class with for instance CustomHost. To handle links which should open a new window you simply override the createWindow method and implement it fitting to your needs

The simpliest approach might be using HTMLLoader.createRootWindow:

public override function createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader
{
	return HTMLLoader.createRootWindow();
}

To set the new CustomHost the HTML control can be defined like this:

<mx:HTML htmlHost="{new CustomHost()}" />

Besides that you can override a bunch of other methods which would trigger because of called JavaScript functions like window.open, window.close, window.blur, etc.. If you use the HTML control of AIR be sure to read about “Scripting the HTML Container” with all its sub-chapters - great read!

Comments (1) - Posted in AIR by Sönke  




Google Chrome Browser
Tuesday 2 September 2008 @ 7:48 pm

Yesterday I posted about Firefox 3 and the new concepts Mozilla Labs is working on and today I came across Google Chrome. Check out the Google Chrome comic book which illustrates the ideas behind in a really nice way. The german news site heise said the beta will be available today 9pm.

News on Google Blog

Update: The browser is now available for download

Comments (2) - Posted in General by Sönke  




AIR HTML with “_blank” Links
Tuesday 2 September 2008 @ 5:51 pm

I have played with the WebKit engine of AIR which is exposed to Flex with the HTML control.

You can set the content by specifying a http location or by setting the htmlText which should be HTML code as a String. Let’s play with the HTML so create a new Flex/AIR project in Flex Builder and use this code:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
	<mx:Script>
		<![CDATA[
			[Bindable]
			private var htmlCode:String = "<a href='http://adobe.com'>Adobe</a>";
		]]>
	</mx:Script>
 
	<mx:HTML htmlText="{htmlCode}" width="100%" height="100%" />
 
</mx:WindowedApplication>

If you test the application you see the link to Adobe and when you click it the Adobe site is shown. Now let’s change the htmlCode to:

private var htmlCode:String = "<a href='http://adobe.com' target='_blank'>Adobe</a>";

Everything looks the same when you test but when you click the link nothing happens but since target=”_blank” is set you would expect that the link opens in a new window. But AIR does not know where to open the link because the property navigateInSystemBrowser from the HTMLLoader class which is used by the HTML control is set to false.

If we now simply switch navigateInSystemBrowser to true the effect would be that all links open in the system browser but we (at least me) only want the target=”_blank” links to open in the system browser and a normal link (like implicit target=”_self”) would substitute the current site.

For that purpose we have to manipulate the DOM of the loaded HTML content so we can handle _blank links differently. This application then would look like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	width="1000" height="600">
 
 
	<mx:Script>
		<![CDATA[
			import mx.logging.Log;
			import mx.logging.ILogger;
 
			private static const logger:ILogger = Log.getLogger("Main");
 
			[Bindable]
			private var htmlCode:String = "<a href='http://adobe.com' target='_blank'>Adobe (in new window)</a><br/><a href='http://adobe.com'>Adobe</a>";
 
			private function onComplete(e:Event):void
			{
				var document:Object = HTML(e.currentTarget).htmlLoader.window.document;
				var anchors:Object = document.getElementsByTagName("a");
 
				for(var i:Number=0; i < anchors.length; i++) {
					var a:Object = anchors[i];
 
					// Check if anchor has target and if it is _blank so it should be handled seperatly
					var targetAttr:Object = a.attributes.getNamedItem("target");
					if(targetAttr != null && targetAttr.nodeValue == "_blank")
					{
						var urlAttr:Object = a.attributes.getNamedItem("href");
						logger.debug("set link to " + urlAttr.nodeValue);
 
						a.onmouseup = function(o:Object):void{
							o.preventDefault();
							logger.info("handle link " + o.srcElement);
							navigateToURL(new URLRequest(o.srcElement), "_blank");
						};
					}
				}
			}
 
		]]>
	</mx:Script>
 
	<mx:TraceTarget fieldSeparator="->" includeCategory="true" />
 
	<mx:HTML htmlText="{htmlCode}" width="100%" height="100%" complete="onComplete(event)" />
 
</mx:WindowedApplication>

We have added a listener for the HTML complete event and then we get all anchors from the DOM to add own listeners when they are clicked. In this inline defined event handler we call navigateToUrl with target set to “_blank” which perfectly opens the URL in the system browser.

Comments (1) - Posted in AIR, ActionScript by Sönke  




Firefox 3 and New Concepts
Monday 1 September 2008 @ 11:45 am

Last week I updated from Firefox 2 to 3 and I wanted to share some of my experiences. Most of the time I am a Mac user so I was really happy that the new Firefox now looks like a real Mac citizen with the new chrome design, great! Almost all plug-ins had updates for Firefox 3 available so also no big problem there.

One thing I recognized and I find pretty scary is the thing how passwords are stored. I don’t know if the situation changed with the new version but if you did not set a master password all your log-ins (username/password) can be shown in plain text. So if someone has access to your computer it takes him/her seconds to steal user accounts. So go to the Preferences->Security and click “Saved Password …”. Then click “Show Passwords” and you know what I mean so be sure to set a master password.

Another news around Firefox and Mozilla from last week was that the contract with Google to be the preselected search engine will continue for another three years. This makes Google responsible for around 85% of the total Mozilla revenue.

Firefox 3 ist a great update I think but there is still room for innovation like Mozilla Labs shows. Check out the video with ideas for a new tab concept and if you are interested read the post by Aza Raskin:


Firefox Proposal: A Better New Tab Screen from Aza Raskin on Vimeo.

Comments (1) - Posted in General by Sönke