Environment Hook Up’s

If you would like to dynamically configure the RemoteObject’s endpoint to point to Development server, Production server, Training server or your Local Server, and also if you would like to append a Secure AMF or a non secure AMF messagebroker servlet, please see below

package org.util
{ 
import mx.core.FlexGlobals;

public class EnvironmentUtil
{
public static const DEV_SERVER_URL:String             = 'https://abcd-dev.xyz.ab.org/contextroot/';
public static const LOCAL_SERVER_URL:String           = 'https://localhost:9443/contextroot/';
public static const SYSTEMS_TEST_SERVER_URL:String    = 'https://abcd-sys.xyz.ab.org/contextroot/';
public static const TRAINING_SERVER_URL:String        = 'https://abcd-trn.xyz.ab.org/contextroot/';
public static const TRANSIENT_SERVER_URL:String       = 'https://{server.name}:{server.port}/workerportal/';

public static function get defaultServer():String
{
   return EnvironmentUtil.DEV_SERVER_URL;
}

public static function get isNotProduction():Boolean
{
  return (isDevEnvironment() || isLocalEnvironment());
}

public static function get remoteEndPoint():String
{
   var remoteURL:String = EnvironmentUtil.isLocalEnvironment() ? defaultServer : EnvironmentUtil.TRANSIENT_SERVER_URL;
   if(EnvironmentUtil.isLocalEnvironment()){
     remoteURL += "messagebroker/amf";
   } else {
      remoteURL += "messagebroker/amfsecure";
 }
  return remoteURL;
}

public static function isDevEnvironment():Boolean
{
   return FlexGlobals.topLevelApplication.root.loaderInfo.url.indexOf('213.345.250') != -1;
}

public static function isLocalEnvironment():Boolean
{
   return FlexGlobals.topLevelApplication.root.loaderInfo.url.indexOf('file:///') != -1;
}

public static function isLocalhost():Boolean
{
     return FlexGlobals.topLevelApplication.root.loaderInfo.url.indexOf('localhost') != -1;
}}}
USAGE:
<s:RemoteObject
 id="pingServiceRO"
 destination="pingServiceRO"
 endpoint="{ EnvironmentUtil.remoteEndPoint }"
 />

 <parsley:Object
 id="pingService"
 type="org.chouhans.flexy.PingService">

 <parsley:Property
 name="pingRO"
 idRef="pingServiceRO"
 />

 </parsley:Object>

Reading Hebrew and Arabic in Flex

Some History on Bi-Directional texts, Semitic languages and the languages which are read from right to left:

Arabic, Hebrew, and the non-Semitic languages using the Arabic or the Hebrew alphabet, such as Persian and Yiddish, are written from right to left (except for their numbers!). Urdu which is also derived from Arabic and Persian language and ancient indo – aryan language binti is written from right to left. Ancient Egyptian, Etruscan, Greek and the oldest Latin could be written in both directions. Also Chinese and Japanese can be written right to left (also written from top to bottom, vertically). Korean is NOT written from right to left.

More on these @

http://en.wikipedia.org/wiki/Semitic_languages

http://en.wikipedia.org/wiki/Horizontal_and_vertical_writing_in_East_Asian_scripts

http://en.wikipedia.org/wiki/Bi-directional_text

Here is a sample test to read a text from right to left and vice versa.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark"
         xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
   <s:layout>
       <s:VerticalLayout />
   </s:layout>
    <fx:Style>
      @namespace s "library://ns.adobe.com/flex/spark";
      @namespace mx "library://ns.adobe.com/flex/mx";      
     @font-face {
       src: url("font/DroidSans.ttf");
       fontFamily: DroidSans;
      }
     s|Label {
        fontFamily: DroidSans;
        fontSize: 24;
      }
    </fx:Style>

    <fx:Script>
      <![CDATA[
          import flashx.textLayout.formats.Direction;
         [Bindable]
         private var textDirection:String = "rtl";         
         protected function onClick( event:MouseEvent ):void {
            if (myLabel.getStyle("direction")=="ltr") {
               myLabel.setStyle("direction", Direction.RTL);
             } else {
               myLabel.setStyle("direction", Direction.LTR);
                }
          }
         ]]>
       </fx:Script>
       <s:VGroup  
         width="100%"
         height="100%"
         paddingTop="20"
        >
       <s:Label
         id="myLabel"
         width="100%"
         text="שלום ‎בעולם‎"
         backgroundColor="#ffff00"
         layoutDirection="{ textDirection }"
       />
       <s:Button
         label="toggle RTL-LTR"
         click="onClick(event)"
        />
       <s:Label
          text="{ myLabel.getStyle('direction') }"
          />
       </s:VGroup>
</s:Application>

In order to run the above source code, you will need the fonts shown below:

You may get this here http://www.fontsquirrel.com/

Hope you enjoyed reading the post !!!

Parsley’s Constructor Based Injection [InjectConstructor]

Implementing Constructor based Injection:

Constructor based injection in Parsley can be achieved using [InjectConstructor] metadata tag. It provides us with cleanest injection style as per encapsulation because it allows you to create immutable classes.

When we say its a constructor based injection, doesn’t that mean the metadata tag has to be placed on the constructor ?

Here is what I am trying to say:

package com.xyz{
     public class abc{
         [InjectConstructor] 
         public function abc(){
             }
    }
}

But, unfortunately the Flash Player currently ignores metadata tags placed on constructors you have to place a [InjectConstructor] tag on the class declaration to tell Parsley to perform Constructor Injection.

package com.bookstore.actions { 
 [InjectConstructor] 
 class LoginAction { 
 private var service:LoginService; 
 private var manager:UserManager;   
 function LoginAction (service:LoginService, manager:UserManager = null) { 
 this.service = service; 
 this.manager = manager; 


}

Constructor injection selects the dependencies based on the parameter types. This means that it only works for dependencies where you know that the Context will always contain at most one object with a matching type. It is also good practice to use interfaces as parameter types so that you can switch implementations in the configuration without modifying the class.

Using interfaces:

package com.bookstore.actions { 
 [InjectConstructor] 
 class LoginAction { 
 private var service:ILoginService; 
 private var manager:IUserManager;   
 function LoginAction (service:ILoginService, manager:IUserManager = null) { 
 this.service = service; 
 this.manager = manager; 


}

In the above code, parsley framework container throws an error if it does not contain an object of type LoginService, but it will simply silently ignore the second parameter if the Context does not contain an object of type UserManager.

Configuring Constructor based injection:

As MXML compiler generates the object creation code and parsley only gets hold of the object after it was instantiated to perform additional configuration, one cannot directly use simple MXML tags for configuration.

<Objects xmlns:fx="http://ns.adobe.com/mxml/2009" 
 xmlns="http://www.spicefactory.org/parsley" 
 <fx:Script> 
 <![CDATA[ import com.bookstore.actions.*; ]]> 
 </fx:Script>
 <fx:Declarations> 
 <Object type="{LoginAction}"/>
 </fx:Declarations> 
</Objects>  

Here is how we pass in the constructor args:

<parsley:Objects xmlns:parsley="http://www.spicefactory.org/parsley">
    <fx:Declarations>
          <!-- Configuring Login Action -->
          <parsley:Object  id="loginAction" type="{LoginAction}">    
             <parsley:ConstructorArgs>           
                <parsley:ObjectRef  idRef="userManager"/>             
                <fx:String>login</fx:String>
             </parsley:ConstructorArgs>
           </parsley:Object>

           <!-- Configuring User Manager -->
           <parsley:Object  id="userManager" type="{UserManager}">    
             <parsley:ConstructorArgs>           
                <fx:String>administrator</fx:String>
             </parsley:ConstructorArgs>
           </parsley:Object>
     </fx:Declarations>
</parsley:Objects>

When using Parsley’s Object tag it’s the framework that is responsible for instantiating the object so that Constructor Injection can be performed.

There are no restrictions when you are using XML configuration.

Source: http://www.spicefactory.org/parsley/docs/2.4/manual/injection.php

Differences between [Inject] and [FastInject] tags

In order to illustrate the difference between [Inject] and [FastInject] we first need to know the difference between describeType and describeTypeJSON functions.

describeType:  The describeType() method returns an xml dump that contains all the details you’d ever need to know about any object that is passed in as a parameter. This method implements the programming concept of reflection API for the ActionScript language.

Ex: trace(flash.utils.describeType(flash.display.MovieClip));

Note: describeType() only shows public properties and methods, and will not show properties and methods that are private, package internal or in custom namespaces. If you need only to traverse an object’s inheritance hierarchy and do not need the other information provided by describeType(), use the getQualifiedClassName() and getQualifiedSuperclassName() functions instead.

More on this topic at http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/package.html#describeType()

describeTypeJSON:  With this  method it’s possible to retrieve reflection data as an object and to filter certain types of information using the constants.

HIDE_NSURI_METHODS = 1
INCLUDE_BASES = 2
INCLUDE_INTERFACES = 4
INCLUDE_VARIABLES = 8
INCLUDE_ACCESSORS = 16
INCLUDE_METHODS = 32
INCLUDE_METADATA = 64
INCLUDE_CONSTRUCTOR = 128
INCLUDE_TRAITS = 256
USE_ITRAITS = 512
HIDE_OBJECT = 1024
FLASH10_FLAGS = 1535

Ex:
package avmplus
{
    public function getInterfaces(object:*):Array
    {
        return describeTypeJSON(object, INCLUDE_TRAITS | INCLUDE_INTERFACES).traits.interfaces;
    }
}

Note:  The describeTypeJSON is defined in the avmplus.* package and supported for Flash Player 10.1

More on this topic at http://www.tillschneidereit.de/2009/11/22/improved-reflection-support-in-flash-player-10-1/

[Inject] v/s [FastInject]:

Parsley has the ability of reflection API which reflects on all managed objects and reflection of components which is very expensive operation due to numerous number of properties,methods and events. Which means that Parsley   2.1 and below uses describeType() method on all of its manages objects. [Inject] tag uses the describeType() method to introspect its managed objects.

Introduced in Parsley 2.2, the [FastInject] tag is the key to the performance optimization. [FastInject] uses the describeTypeJSON() method which is faster than describeType(). Note that the impact of reflecting huge UIComponents is still high. Parsley maintains an internal reflection cache, so that each class is only processed once, but if you are using a high number of different component classes this may not help much.In a smaller application this effect is negligible but its a concern for larger applications.

<parsley:FastInject property="model" type="{MyPanelPM}" /> 
 
<parsley:FastInject injectionComplete="init();"> 
 <parsley:Inject property="model" type="{MyPanelPM}"/> 
 <parsley:Inject property="status" type="{MyApplicationStatus}"/> 
</parsley:FastInject>
 
Action Script:
function MyView () { 
 FastInject .view(this) 
 .property("pm") 
 .type(MyViewPM) 
 .complete(injectionComplete) 
 .execute(); 

 
private function injectionComplete () : void { /* ... */ }

Corrections:  describeType() and describeTypeJSON() are not included in Parsley framework, they are part of avmplus package of the Flash Player. describeTypeJSON is provided in Flash Player 10.1 and above.

reflection in fp 10.1

If the user runs the Flex Application built with Parsley framework against Flash Player’s versions 10.1 and above, Parsley intelligently uses the faster describeTypeJSON() and if the application is run against Flash Player versions below 10.1, Parsley uses  the slower describeType()

In reality, FastInject neither uses describeType() nor describeTypeJSON(). FastInject is used for injecting a managed object from the nearest Context in the view hierarchy into a view without reflecting on the view. This way the FastInject  retrieves a particular object from the IoC Container without actually getting wired to it to avoid the cost of reflection and hence its fast.

Sources:

http://www.spicefactory.org/parsley/docs/2.4/manual/?page=view&section=intro
http://www.tillschneidereit.de/2009/11/22/improved-reflection-support-in-flash-player-10-1/
http://www.scottgmorgan.com/blog/index.php/2007/10/22/say-hello-to-my-little-friend-describetype/

An answer to the most commonly asked question by most confused Flex Developers

About the item renderer and item editor life cycle

Flex creates instances of item renderers and item editors as needed by your application for display and measurement purposes. Therefore, the number of instances of an item renderer or item editor in your application is not necessarily directly related to the number of visible item renderers. Also, if the list control is scrolled or resized, a single item renderer instance may be reused to represent more than one data item. Thus, you should not make assumptions about how many instances of your item renderer and item editor are active at any time.

Because Flex can reuse an item renderer, ensure that you fully define its state. For example, you use a CheckBox control in an item renderer to display a true (checked) or false (unchecked) value based on the current value of the data property. A common mistake is to assume that the CheckBox control in the item renderer is always in its default state of unchecked. Developers then write an item renderer to inspect the data property for a value of true and set the CheckBox control to checked if found.

However, you must take into account that the CheckBox may already be checked. So, you must inspect the data property for a value of false, and explicitly uncheck the control if it is checked.

Source: http://livedocs.adobe.com/flex/3/html/help.html?content=cellrenderer_4.html