Pages

Monday, 5 March 2012

Sample Application using Swiz framework and BlazeDS Flex


About the Swiz Framework
Swiz is a framework for Adobe Flex and ActionScript that aims to bring complete simplicity to RIA development. Swiz provides:
  • Inversion of Control / Dependency Injection
  • Event handing and mediation
  • A simple life cycle for asynchronous remote methods
  • A framework that is decoupled from your application code 
In contrast to other major frameworks for Flex, Swiz:
  • Imposes no JEE patterns on your code
  • No repetitive folder layouts
  • No boilerplate code on your development
  • Does not require you to extend framework-specific classes
Swiz represents best practices learned from the top RIA developers at some of the best consulting firms in the industry, enabling Swiz to be simple, lightweight, and extremely productive.

You can download the swiz framework for adobe Flex through the following link.

Swiz makes use of BeanLoader class which is an utility for loading all the components configured into their central factory.

Beans.Mxml

<?xml version="1.0" encoding="utf-8"?>
<BeanLoader
 xmlns:mx="http://www.adobe.com/2006/mxml"
 xmlns="org.swizframework.util.*"
 xmlns:controller="swiz.*" xmlns:delegate="swiz.*" xmlns:model="swiz.*">

 <!-- custom channel set -->
 <DynamicChannelSet id="myAmfChannel">
 <serverPort>8080</serverPort>
 <contextRoot>/sample</contextRoot>
 </DynamicChannelSet>

 <!-- Remote Services -->
 <mx:RemoteObject id="loginService" destination="LoginService" showBusyCursor="true" channelSet="{myAmfChannel}"/>

  <!-- Controllers -->
 <controller:LoginController id="loginController"/>

  <!-- Delegates -->
 <delegate:LoginDelegate id="loginDelegate"/>

  <!-- Models -->
 <model:LoginModel id="applicationViewModel"/>

  </BeanLoader>  

As shown above, we have configured the services, controller, delegates and model objects for Login and Employees.
loginService is a remote object, which interact with the service classes configured with BlazeDS.
loginDelegate and employeeDelegate: These classes are used to invoke the remote methods with the services configured. These classes extend AbstractDelegate from Swiz. Functions used in them return AsyncToken.
loginController This class hold the Event handling methods and configure the event types as static constant type. Methods which need to be invoked when an event is occurred is configured with the "Mediate" metadata. We need to define the event type, and if any properties are sent with this event. For further details, refer to Event Handling and Dynamic Mediators in swiz framework.
LoginModel This class act as the Model classes, which holds data that need to be shown in UI or pass the data between the components. We bind the controls with the variables defined in the model class, so when ever there's change in the data, those will be reflected immediatly.

remoting-config.xml

This is xml file avilable for the flex project nature which uses BlazeDS to communicate with java. We have to include the following <destination> element in remoting-config.xml. My default Location of this file is  "C:\Program Files\apache-tomcat-6.0.20\webapps\sample\WebContent\WEB-INF\flex\remoting-config.xml"

<destination id="LoginService" >
<properties>
<source>test.LoginService</source>
</properties>
<adapter ref="java-object"/>
</destination> 

emp.mxml


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"  backgroundColor="#EEEEEE"
 preinitialize="preInitialize()" horizontalAlign="center" verticalAlign="middle"
 xmlns:Login="employee.*" xmlns:success="employee.*">


 <mx:Script>
     <![CDATA[
          import swiz.LoginModel;
          import org.swizframework.Swiz;
        
         [Autowire(bean="applicationViewModel")]
         [Bindable]
         public var applicationViewModel:LoginModel;
               
         private function preInitialize():void {
             Swiz.loadBeans( [Beans] );
        }
        
     ]]>
 </mx:Script>
 
 <mx:ViewStack selectedIndex="{applicationViewModel.mainViewIndex}" width="100%" height="100%">
 <Login:loginpage id="loginpage"/>
 <success:successpage id="successpage"/>
  </mx:ViewStack>

</mx:Application>
 
In order to make use of the components that are configured in SwizBean.mxml, we need to load them to Swiz class. So we call out the Swiz.loadBeans() passing the SwizBean as an array element, when the application is in preinitialize state.


Annotations used :


[Autowire(bean="applicatiobViewModel")]<pre>public var applicationViewModel:ApplicationViewModel;
 Autowire metadata is used to define the bean name and is injected with the object that is configured in SwizBeans.xml with the ID field.
 
When swiz process the BeanLoaders i.e SwizBeans.mxml, it caches all the objects they contain in a central factory and interrogates them to find their Autowire metadata elements.



[Mediate(event="login",properties="userName, password")]
public function validateLogin(userName:String, password:String):void {
 executeServiceCall(loginDelegate.validateLogin(userName,password),validateLogin_success,validateLogin_failure);
}

Swiz uses the Mediate metadata, which is used for event handling. There is no necessary for us to write bunch of codes to handle the events.

When an event is occurred, swiz looks for the event name. If the name matches with that configured with the function that is configured with the Mediate metadata, than that function is invoked. If we pass any parameters with the event, we can fetch those with the properties value and define the properties as comma seperated. These should be defined in the order, as passed while calling the event.

Lets look into the files that are used for Login :

loginpage.mxml


<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"  backgroundColor="#FFFFFF"
 horizontalAlign="center" verticalAlign="middle">
   
    <mx:Script>
     <![CDATA[
   
     import swiz.LoginController;
     import mx.events.DynamicEvent;
     import swiz.LoginModel;
   
     import org.swizframework.Swiz;
   
     [Autowire(bean="applicationViewModel")]
     [Bindable]
     public var applicationViewModel:LoginModel;
   
     private function validateLogin():void {
     var e:DynamicEvent = new DynamicEvent(LoginController.LOG_IN);
     e.userName = userName.text;
     e.password = password.text;
     Swiz.dispatchEvent(e);
     }
   
     private function clear():void {
     userName.text = "";
     password.text = "";
     applicationViewModel.message = "";
     }
       
   
   
     ]]>
    </mx:Script>
   
    <mx:Label text="the result is :{applicationViewModel.message}"

 includeInLayout="{applicationViewModel.message.length != 0}"
 paddingBottom="10"
 color="red" fontWeight="bold"/>

 <mx:VBox width="400" height="150"
 borderColor="#333333"
 dropShadowEnabled="true"
 borderStyle="solid"
 borderThickness="5"
 cornerRadius="5"
 backgroundColor="#EEEEEE"
 horizontalAlign="center" verticalAlign="middle">

 <mx:Label text="Employee Managment - Login" fontWeight="bold" fontSize="16" paddingTop="10" paddingBottom="10" color="#333333"/>

 <mx:Grid >
 <mx:GridRow>
 <mx:GridItem>
 <mx:Label text="User Name" fontWeight="bold" textAlign="right"/>
 </mx:GridItem>
 <mx:GridItem>
 <mx:TextInput id="userName" enter="password.setFocus()"/>
 </mx:GridItem>
 </mx:GridRow>
 <mx:GridRow>
 <mx:GridItem>
 <mx:Label text="Password" fontWeight="bold" textAlign="right"/>
 </mx:GridItem>
 <mx:GridItem>
 <mx:TextInput id="password" displayAsPassword="true" enter="validateLogin()"/>
 </mx:GridItem>
 </mx:GridRow>
 <mx:GridRow>
 <mx:GridItem colSpan="2">
 <mx:Spacer width="100%"/>
 <mx:Button label="Login" click="validateLogin()"/>
 <mx:Button label="Clear" click="clear()"/>
 </mx:GridItem>
 </mx:GridRow>
 </mx:Grid>
 </mx:VBox>
 </mx:Application>
 

successpage.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application horizontalAlign="center" backgroundColor="#ffffff" verticalAlign="middle"  xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Label text="successfully logged In...Welcom to Your HOME page"/>
</mx:Application>

LoginController.as

// ActionScript file
package swiz
{
 import swiz.LoginDelegate;
 import swiz.LoginModel;

 import mx.rpc.events.FaultEvent;
 import mx.rpc.events.ResultEvent;

 import org.swizframework.controller.AbstractController;

 public class LoginController extends AbstractController
 {
 public static const LOG_IN:String = "login";
 public static const LOG_OUT:String = "logout";

 [Autowire(bean="loginDelegate")]
 public var loginDelegate:LoginDelegate;


 [Autowire(bean="applicationViewModel")]
 [Bindable]
 public var applicationViewModel:LoginModel;

 [Mediate(event="login",properties="userName, password")]
 public function validateLogin(userName:String, password:String):void {
 executeServiceCall(loginDelegate.validateLogin(userName,password),validateLogin_success,validateLogin_failure);
 }

 [Mediate(event="logout")]
 public function logout():void {

 }

 private function validateLogin_success(event:ResultEvent):void {
 var message:String = event.result as String;
 if(message == "success"){
applicationViewModel.message="Login Successfull.";
applicationViewModel.mainViewIndex=1;
 }
 else {
 applicationViewModel.message = "Login failed. Please provide valid credentials.";
 }
 }

 private function validateLogin_failure(event:FaultEvent):void {
 applicationViewModel.message = "Error occurred while processing your request. Please try again.";
 }
 }
}
 
LoginDelegate.as

 // ActionScript file
package swiz
{
 import mx.rpc.AsyncToken;
 import mx.rpc.remoting.mxml.RemoteObject;

 public class LoginDelegate
 {

 [Autowire(bean="loginService")]
 public var loginService:RemoteObject;

 public function validateLogin(userName:String, password:String):AsyncToken {
 return loginService.validateLogin(userName,password);
 }

 }
}


LoginModel.as 

// ActionScript file
package swiz
{
 public class LoginModel
 {
 [Bindable] public var mainViewIndex:int = 0;
 [Bindable] public var message:String = "";

 }
}
 

Same is the case for displaying the employees and adding the employees.

No comments:

Post a Comment