Monday, September 28, 2009

Start An Application When Linux, RedHat, Starts

Here you go:
  • Create a control script in /etc/init.d folder that responds to at least start and stop commands.
  • In this script, include a comment line: chkconfig 35 80 20 (there is a meaning to it: for which runlevels the process is to be off or on).
  • Run the chkconfig --add your_control_script command. Run it with --list option to verify that the control script has been added to the list of processes to start at boot time.
  • If there are any problems during boot time, they are recorded in the /var/log/boot.log and/or /var/log/messages files.
Note:
Global environ variables are usually defined in the /etc/profile script. This script is automatically run by every interactive shell process (or a shell process with --login argument). The /etc/profile doesn't seem to be executed automatically during the boot process, though. You may need to do:
. /etc/profile
in your control script if you need to use any of the global environ variables.

How to Share Files between Mac and Other Computers

I mean, other than via a USB disk.

Share Mac's Files via FTP
  • Go to Settings -> Sharing and enable File Sharing
  • Click the Options button and check the FTP.
  • From a windows machine, point to the mac using ftp://11.123.123.321 (use mac's ip)
  • Provide your mac's user and password.

Sunday, September 27, 2009

Android: News Summary

  • In July 2009, a new SDK version was released, called 1.5 release 3. Was it a release corresponding to the Android update that happened 1-2 months after the Cupcake update?
  • There is also Android 1.6 SDK available, that will work only with Android 1.6 to be made available on Oct 2009.

Friday, September 25, 2009

Connect To A Remote Windows Workstation To Provide Support

So, someone from you family, living far away from you, asked you to help him/her with her windows computer and you would like to help, but are not willing to spend $450 for air tickets. Well, sometimes it may be a good idea to spend this money and spend some time with your family. But if there are reasons you can't do it right at this moment, but you would still like to help with the computer problem, what do you do? Especially, if it's your older relative or friend? Not really technical savvy or even scarred of this new and strange technology.

One simple approach I have found (after trying two other approaches with only partial success), is a product called TeamViewer. The personal/non-profit use is free. The thing works like this:
  • The person that receives the support, downloads and runs the TeamViewerQS, which generates a random ID and password.
  • The supporter downloads the TeamViewer and starts it. It asks for a user and password.
  • The supported needs to obtain these to pieces of information from the other person (phone, email, text message, etc.) and enter.
  • The rest is simple. Just like the MS Remote Desktop or VNC.
A really cool part of this is, you can actually test the TeamViewer first without getting your relative at all. The company provides a "test" machines you can connect to for testing. Easy, they're probably running just a bunch of windows virtual boxes. But still, it's a good idea.

Enjoy! And do make at another time a trip to visit your family in person. In my case, the relative I needed to help, lives in Poland. I live in Oregon. TeamVeaver was helpful.

Friday, September 18, 2009

Glassfish Enterprise Server: Changing Port

I couldn't find a straight and good answer easily. So, here's what you to change the port your server is listening on:
  • start the server
  • go to admin console (default: http://localhost:4848)
  • Open: Configuration -> HTTP Service -> Network Config -> Network Listeners
  • The main port is listed as the listener1, I believe.
That's it. Simple. You don't even need to restart the server for the change to take effect.

Changing it by editing the domain.xml file is possible, but the server always chokes for a while to accept it. You can also use asadmin get server and asadmin set ... but this is still more messy than just doing it in the console.

Monday, September 7, 2009

Parsing a Text on Android Phone

Introduction
I have a wiki markup text that I need to parse. My first version, which I use in DroidWiki application for Android, is a wiki custom parsing. I wrote my own parsing, because I haven't found a parsing code on the internet that was light enough to be used on Android phone. That code does a regular expression matching for each wiki tag. So, every line is matched at least Recently, I decided to try my hand at more fancy parsing: just parse into a sequence of tokens. Below, are the results of my research on this topic.

Using One-Character-At-A-Time Parsing
One way to solve the problem is to use a one-pass parsing, having the Java code to look at each character (just once) and isolate the tokens this way. Using the character iterator goes like this:
StringCharacterIterator iter = new StringCharacterIterator(markup);

for( char c = iter.first(); c != CharacterIterator.DONE; c = iter.next() ) {
// process the char: is it one of the characters that starts any of the syntax tokens?
}

This could be fast, but the code would be complicated. I decided for a different approach.

Using Interpreter Design Pattern

The idea:
  1. Parse the text and convert it to a sequence of basic tokens:
    • every continuous piece of a regular text is a token
    • every sequence of syntax is a token (for example, the char less-than if parsing HTML text would be a simgle token by itself)
  2. Process the list of these basic tokens and aggregate them into complete syntactical elements (for example, every complete HTML tag would be a single token).
If you want, create
  • a SimpleToken class for item 1 above,
  • a base Token class and specialize it for more significant/complex syntactical elements for item 2 above

Thursday, September 3, 2009

Compiling a Flex Application with Ant

Introduction
This blog summarizes how to compile a Flex application using ant.

Creating the build.xml File
The build.xml file:
<project name="fishbaitTestModule" basedir="." default="compile_flex_project">

<!-- Properties -->
<property environment="env" />
<property name="flexhome_dir" location="${env.FLEX_HOME}" />
<property name="src_dir" location="${basedir}/../test-src" />
<property name="libs_dir" location="${basedir}/libs" />
<property name="deploy_dir" location="${basedir}/deploy" />

<!-- Define the flex ant task -->
<taskdef resource="flexTasks.tasks" classpath="${libs_dir}/flexTasks.jar"/>

<target name="clean">
<delete dir="${deploy_dir}" />
</target>

<target name="init" depends="clean">
<mkdir dir="${deploy_dir}" />
</target>

<!-- Don't touch. Required by flex ant task -->
<property name="FLEX_HOME" location="${flexhome_dir}" />
<target name="compile_flex_project" depends="init">
<mxmlc file="${src_dir}/testSuites/FishBaitTestModule.mxml" output="${deploy_dir}/FishBaitTestModule.swf">
<load-config filename="${flexhome_dir}/frameworks/flex-config.xml"/>
<source-path path-element="${flexhome_dir}/frameworks"/>

<compiler.source-path path-element="${src_dir}"/>

<compiler.debug>false</compiler.debug>

<!-- List of SWC files or directories that contain SWC files. -->
<compiler.library-path dir="${basedir}/libs" append="true">
<include name="AirMonkeyLibrary.swc" />
<include name="MonkeyFlexUnitLibrary.swc" />
<include name="fluint.swc" />
</compiler.library-path>
</mxmlc>
</target>

</project>


How To Use The Script
  • create FLEX_HOME environment variable on your system (we tested this on WinXP) and point it to Flex root folder.
  • copy files flexTasks.jar and flexTasks.tasks into libs_dir folder. You can obtain these files from Adobe.
  • Note: the ant FLEX_HOME property just above the compile_flex_project target needs to be there; it seems that the mxmlc task uses and requires it, even if you already have envvar with the same name setup on your system.
  • the src_dir, libs_dir properties point to folders where the Flex source, required SWC files are located, respectively. The deploy_dir is where the SWF files will be created, your compiled application.
  • FYI: If you are running your Ant script from Eclipse, the Ant you're running is installed in ...\eclipse\plugins\org.apache.ant_1.7.0.v200803061910 or similar folder.

Using FlexUnit to Unit Test Cairngorm Visual Objects

Introduction
In a RIA application a typical split of the source code (counted by code size, in bytes) is as follows:
  • 45-60% - client: visual objects like views and their sub-components with their logic
  • 15-20% - client: non-visual objects (primarily Cairngorm worker-to-service piping)
  • 30-35% - server: middle-tier code
In the couple medium-size business application, I have analyzed, the middle-tier was implemented in Java and the client was implemented in Flex using the Cairngorm architecture. So, I don't have verified numbers for other RIA configurations.

If we are determined to use TDD or simple just provide automated tests for our application and get the most coverage for the effort required to develop these tests, it seems we could use the following testing methodologies:
  • FlexUnit testing for the client, especially the client's visual objects
  • FlexMonkey tests for whole client's features
  • jUnit tests for the middle-tier code.
I another blog, I will touch on the FlexMonkey. In this one, I'd like to present how we can unit test the visual layer of the client using the FlexUnit framework. jUnit testing is well described in many other sources.

Testing Scenario
In the spirit of Cairngorm, a UI user gesture is directed to a handler which creates a Cairngorm message, attaches a payload to it (any relevant information) and dispatches it (event.dispatch()). Our test will mimic a user gesture (click a button) and will try to catch the dispatched Cairngorm event and verify its payload. We're using Flex 3 (ver. 3.2) and FlexUnit 4 beta 2.

Sample Application
To explain the topic, I'll be using the following sample application. The view (Main.mxml adds it to the ViewStack) is (to see the code in a new window, move your mouse pointer over the code and click the left of the icons that appear in upper-right corner):
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="400" height="300">

<mx:Script source="MyViewScript.as" />

<mx:HBox verticalAlign="middle" >
<mx:Text id="txtValue" text="Entry:" />
<mx:TextInput id="entryTextInput" />
<mx:Button id="btnSave" label="Save" click="onBtnSaveClick(event)" />
</mx:HBox>

</mx:VBox>

The script used bu the view is:
import gov.olcc.fishbait.events.SaveEntryEvent;
import gov.olcc.fishbait.model.ViewModelLocator;
import gov.olcc.fishbait.vo.EntryVO;

public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();

public function onBtnSaveClick(event):void
{
trace("clickHandler detected an event of type: " + event.type);

var entryVO: EntryVO = new EntryVO();
entryVO.text = entryTextInput.text;

var saveEvent: SaveEntryEvent = new SaveEntryEvent(entryVO);

saveEvent.dispatch();
}


and the TestRunner class to run the test is
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*"
xmlns:flexunit="http://www.adobe.com/2009/flexUnitUIRunner"
xmlns:business="gov.olcc.fishbait.business.*"
xmlns:control="gov.olcc.fishbait.control.*"
xmlns:view="gov.olcc.fishbait.view.*"
layout="vertical"
width="100%" height="100%"
creationComplete="runTests()">

<mx:Script>
<![CDATA[
import com.adobe.cairngorm.control.FrontController;
// import gov.olcc.fishbait.view.TestFishBaitView;
import gov.olcc.fishbait.view.MyView;
import org.flexunit.runner.FlexUnitCore;
import org.flexunit.flexui.TestRunnerBase;
import gov.olcc.fishbait.view.MainTest;
// import gov.olcc.fishbait.view.TestFishBait;

//Add an import statement(s) for the class(es) under test
private var core: FlexUnitCore;

private function runTests():void
{
core = new FlexUnitCore();
core.addListener(testRunner);
core.run(MainTest);
}

]]>
</mx:Script>

<!-- Cairngorm Controller and Service Locator -->
<control:FishBaitController id="controller" />
<business:Services id="services" />

<flexunit:TestRunnerBase id="testRunner" width="100%" height="100%" />
</mx:Application>

The trick is to be able to catch the Cairngorm event. What is not obvious, the event.dispatch() method uses a CairngormEventDispatcher, so we need to add our listener to it. The resulting test code is
package gov.olcc.fishbait.view {
import com.adobe.cairngorm.control.CairngormEventDispatcher;
import flash.events.MouseEvent;
import gov.olcc.fishbait.events.SaveEntryEvent;
import gov.olcc.fishbait.model.ViewModelLocator;
import gov.olcc.fishbait.vo.EntryVO;
import mx.automation.codec.AssetPropertyCodec;
import org.flexunit.Assert;
import org.fluint.uiImpersonation.UIImpersonator;
import org.flexunit.async.Async;

public class MainTest {
var myView: MyView;
public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();

[Before(async,ui)]
public function setUp():void {
myView = new MyView();
UIImpersonator.addChild(myView);
}

[After(async,ui)]
public function tearDown():void {
UIImpersonator.removeChild( myView );
}   

[Test(async,timeout="3000")]
public function testOnBtnSaveClick():void {
CairngormEventDispatcher.getInstance().
addEventListener(SaveEntryEvent.SAVE_TEXT,
Async.asyncHandler( this, handleTestOnBtnSaveClick, 3000 ),
false,0,true);

myView.entryTextInput.text = "Test Text";
var clickEvent: MouseEvent = new MouseEvent(MouseEvent.CLICK);
myView.btnSave.dispatchEvent(clickEvent);
}

private function handleTestOnBtnSaveClick(event:SaveEntryEvent,
passThroughData:Object):void {
var entry:EntryVO = event.text;
Assert.assertEquals("Test Text", entry.text);
}
}
}

Other points about this test:
  • We use FlexUnit UIImpersonator as a parent to our view. Without adding a view to a parent, the UI controlls are not initialized and can't be used.
  • To get the instance of the CairngormEventDispatcher, we use its static mathod getInstance().
  • Since the actual test happens in the event handler, we need to user an annotation [Test(async,timeout="xxx ms"] to request the Async support for the test.
  • Then, instead of providing just the handler method as an argument to the assEventListener(), we wrap this method in Async.asyncHandler(), which will wait for the handler to be called unless the handler will not be called within specified time, in which case the test will fail.
And this is it. Enjoy testing Cairngorm visual objects.