• Home
  • About Me
  • AIR Central
  • AS3 Libs
  • Books
  • Flex Central
  • Resources
  • The Guru's
  •  

    Amazon S3 ActionScript Classes

    May 30th, 2007

    If you have seen this video showing the Apollo, you saw an Apollo app that communicated with Amazon’s S3 data storage service. Well, Christian Cantrell has now posted the ActionScript classes that he wrote for this communication. I have also added this to the AS3 Libs section of this blog.


    Artemis/Hibernate Apollo Application

    May 30th, 2007

    Well it has been a while that I have been promising to document this sample app. Here is the basis. ArtemisEmployee is an application that uses a Hibernate back end with an embedded hsqldb database to store the employee data. The UI is built with Apollo and the data streams between the Java back end and the Apollo UI via the Artemis Bridge.

    Here is the code involved in the Java back end. It is a very simple application consisting of a single bean class and a delegate for point of connection. The delegate has 2 methods for getting and Employee object and updating an Employee object.

    Here is the Employee.hbm.xml file:

    1. <?xml version="1.0"?>
    2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    4. <!-- Generated May 9, 2007 7:38:47 AM by Hibernate Tools 3.2.0.beta8 -->
    5. <hibernate-mapping package="com.everythingflex.artemisEmployee.vo" default-lazy="false">
    6.     <class name="Employee" table="Employee">
    7.         <id name="employeeId" type="int">
    8.             <column name="EMPLOYEE_ID" />
    9.             <generator class="assigned" />
    10.         </id>
    11.         <property name="firstName" type="string">
    12.             <column name="FIRST_NAME" length="50" not-null="true" />
    13.         </property>
    14.         <property name="lastName" type="string">
    15.             <column name="LAST_NAME" length="50" not-null="true" />
    16.         </property>
    17.         <property name="email" type="string">
    18.             <column name="EMAIL" length="50" not-null="true" />
    19.         </property>
    20.         <property name="jobTitle" type="string">
    21.             <column name="JOB_TITLE" length="50" not-null="true" />
    22.         </property>       
    23.     </class>
    24. </hibernate-mapping>

    Here is the corresponding Employee.java bean:

    1. package com.everythingflex.artemisEmployee.vo;
    2.  
    3. public class Employee {
    4.  
    5.     private int employeeId;
    6.     private String firstName;
    7.     private String lastName;
    8.     private String email;
    9.     private String jobTitle;
    10.     /**
    11.      *
    12.      */
    13.     public Employee() {
    14.         super();
    15.         // TODO Auto-generated constructor stub
    16.     }
    17.     /**
    18.      * @param employeeId
    19.      * @param firstName
    20.      * @param lastName
    21.      * @param email
    22.      * @param jobTitle
    23.      */
    24.     public Employee(int employeeId, String firstName, String lastName, String email, String jobTitle) {
    25.         super();
    26.         this.employeeId = employeeId;
    27.         this.firstName = firstName;
    28.         this.lastName = lastName;
    29.         this.email = email;
    30.         this.jobTitle = jobTitle;
    31.     }
    32.     /**
    33.      * @return the email
    34.      */
    35.     public String getEmail() {
    36.         return email;
    37.     }
    38.     /**
    39.      * @param email the email to set
    40.      */
    41.     public void setEmail(String email) {
    42.         this.email = email;
    43.     }
    44.     /**
    45.      * @return the employeeId
    46.      */
    47.     public int getEmployeeId() {
    48.         return employeeId;
    49.     }
    50.     /**
    51.      * @param employeeId the employeeId to set
    52.      */
    53.     public void setEmployeeId(int employeeId) {
    54.         this.employeeId = employeeId;
    55.     }
    56.     /**
    57.      * @return the firstName
    58.      */
    59.     public String getFirstName() {
    60.         return firstName;
    61.     }
    62.     /**
    63.      * @param firstName the firstName to set
    64.      */
    65.     public void setFirstName(String firstName) {
    66.         this.firstName = firstName;
    67.     }
    68.     /**
    69.      * @return the lastName
    70.      */
    71.     public String getLastName() {
    72.         return lastName;
    73.     }
    74.     /**
    75.      * @param lastName the lastName to set
    76.      */
    77.     public void setLastName(String lastName) {
    78.         this.lastName = lastName;
    79.     }
    80.     /**
    81.      * @return the jobTitle
    82.      */
    83.     public String getJobTitle() {
    84.         return jobTitle;
    85.     }
    86.     /**
    87.      * @param position the jobTitle to set
    88.      */
    89.     public void setJobTitle(String jobTitle) {
    90.         this.jobTitle = jobTitle;
    91.     }
    92.    
    93.    
    94. }

    The Delegate is the point of access between Apollo and Java. Here is the Delegate class:

    1. package com.everythingflex.artemisEmployee.business;
    2.  
    3. import org.hibernate.Session;
    4. import org.hibernate.SessionFactory;
    5. import org.hibernate.Transaction;
    6. import org.hibernate.cfg.Configuration;
    7.  
    8. import com.effectiveui.artemis.ArtemisBridge;
    9. import com.effectiveui.artemis.event.ArtemisResultEvent;
    10. import com.everythingflex.artemisEmployee.vo.Employee;
    11.  
    12.  
    13. public class Delegate {
    14.    
    15.     private SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    16.  
    17.     public ArtemisResultEvent getEmployee(Integer id){
    18.         ArtemisResultEvent result = new ArtemisResultEvent();
    19.         Session session = null;
    20.         try{;
    21.             session = sessionFactory.openSession();
    22.             Employee e = (Employee) session.load(Employee.class,id);
    23.             result.setResult(e);
    24.         } catch (Exception E) {
    25.             System.out.print(E);
    26.         } finally {
    27.             session.flush();
    28.             session.close();
    29.         }
    30.         return result;
    31.     }
    32.    
    33.     public ArtemisResultEvent updateEmployee(Employee employee){
    34.         ArtemisResultEvent result = new ArtemisResultEvent();
    35.         Session session = null;
    36.         Transaction tx = null;
    37.         Boolean results = true;
    38.         try{
    39.             session = sessionFactory.openSession();
    40.             tx = session.beginTransaction();
    41.             session.update(employee);
    42.             tx.commit();
    43.         } catch (Exception E) {
    44.             results = false;
    45.             System.out.print(E);
    46.         } finally {
    47.             tx = null;
    48.             session.flush();
    49.             session.close();
    50.         }
    51.         result.setResult(results);
    52.         return result;
    53.     }
    54.    
    55.     /**
    56.      * @param args
    57.      */
    58.     public static void main(String[] args) {
    59.         // TODO Auto-generated method stub
    60.         ArtemisBridge.getInstance().bootstrap();
    61.         //Delegate d = new Delegate();
    62.         //d.getEmployee(1);
    63.     }
    64.  
    65. }

    OK, now for the Apollo side of the application:

    Here is the Employee ActionScript class that maps to the Java Employee class:

    1. package com.everythingflex.artemisEmployee.vo
    2. {
    3.     [RemoteClass(alias="com.everythingflex.artemisEmployee.vo.Employee")]
    4.     [Bindable]
    5.     public class Employee
    6.     {
    7.        
    8.         public var employeeId:int;
    9.         public var firstName:String;
    10.         public var lastName:String;
    11.         public var email:String;
    12.         public var jobTitle:String
    13.     }
    14. }

    This is the bridge class that is making the connection between Apollo and Java and handling the results.

    1. package com.everythingflex.artemisEmployee.bridge
    2. {
    3.     import com.effectiveui.artemis.mirror.ArtemisObject;
    4.     import com.effectiveui.artemis.mirror.call.ArtemisObjectCall;
    5.     import flash.utils.getQualifiedClassName;
    6.     import mx.rpc.events.ResultEvent;
    7.     import flash.events.EventDispatcher;
    8.     import com.everythingflex.artemisEmployee.vo.Employee;
    9.    
    10.     public class EmployeeArtemisObject extends ArtemisObject
    11.     {
    12.        
    13.         public static const LIB_ID:String = "com.everythingflex.artemisEmployee.business.Delegate";
    14.        
    15.         public function EmployeeArtemisObject(){
    16.             super();
    17.         }
    18.                
    19.         public function getEmployee(employeeId:int):void{
    20.             var artemisCall:ArtemisObjectCall = new ArtemisObjectCall(LIB_ID, "getEmployee", employeeId);
    21.             artemisCall.addEventListener(ResultEvent.RESULT, getEmployeeResult);
    22.             send(artemisCall);
    23.         }
    24.        
    25.         public function getEmployeeResult(e:ResultEvent):void{
    26.             EventDispatcher(e.target).removeEventListener(e.type, getEmployeeResult);
    27.             var rEvent:ResultEvent = new ResultEvent("employeeResult", false, true, e.result);
    28.             dispatchEvent(rEvent);
    29.         }
    30.        
    31.         public function updateEmployee(employee:Employee):void{
    32.             var artemisCall:ArtemisObjectCall = new ArtemisObjectCall(LIB_ID, "updateEmployee", employee);
    33.             artemisCall.addEventListener(ResultEvent.RESULT, updateEmployeeResult);
    34.             send(artemisCall);
    35.         }
    36.        
    37.         public function updateEmployeeResult(e:ResultEvent):void{
    38.             EventDispatcher(e.target).removeEventListener(e.type, updateEmployeeResult);
    39.             var rEvent:ResultEvent = new ResultEvent("updateEmployeeResult", false, true, e.result);
    40.             dispatchEvent(rEvent);
    41.         }
    42.        
    43.     }
    44. }

    Finally the main Apollo application file which makes the connection to the bridge and the calls to get the Employee objects from the hsqldb and also update the Employee as well.

    1. <?xml version="1.0" encoding="utf-8"?>
    2.  
    3. <mx:ApolloApplication xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:custom="custom.*"
    4.     creationComplete="initArtemisBridge()"
    5.     backgroundImage="@Embed('bg.png')"
    6.     backgroundColor="#FFFFFF" height="420" width="340" layout="absolute">
    7.  
    8.     <mx:Script>
    9.         <![CDATA[
    10.             import mx.collections.ArrayCollection;
    11.             import com.effectiveui.artemis.mirror.call.ArtemisObjectCall;
    12.             import mx.rpc.events.ResultEvent;
    13.             import com.effectiveui.artemis.event.ArtemisServiceEvent;
    14.             import com.effectiveui.artemis.ArtemisBridge;
    15.             import com.everythingflex.artemisEmployee.vo.Employee;
    16.             import com.everythingflex.artemisEmployee.bridge.EmployeeArtemisObject;
    17.            
    18.             private var bridge:ArtemisBridge = ArtemisBridge.getInstance();
    19.             private var employeeArtemisObject:EmployeeArtemisObject;
    20.             [Bindable]
    21.             private var isBridgeStarted:Boolean = false;
    22.             [Bindable]
    23.             private var updateEnabled:Boolean = false;
    24.            
    25.             [Bindable]
    26.             private var employee:Employee;
    27.            
    28.             private function initArtemisBridge():void{
    29.                 ti.text = "Bridge Not Running \n";
    30.                 bridge.startServer();
    31.                 bridge.addEventListener(ArtemisServiceEvent.ARTEMIS_STARTED, bridgeStarted);
    32.                 employeeArtemisObject = new EmployeeArtemisObject();
    33.                 employeeArtemisObject.addEventListener("employeeResult", employeeResult);
    34.                 employeeArtemisObject.addEventListener("updateEmployeeResult", updateEmployeeResult);
    35.             }
    36.             private function bridgeStarted(e:ArtemisServiceEvent):void{
    37.                 ti.text += "Bridge Started \n";
    38.                 isBridgeStarted = true;
    39.             }
    40.            
    41.             private function getEmployee():void{
    42.                 ti.text += "getEmployee(" + employeeId.value + ") \n";
    43.                 ti.verticalScrollPosition += 50;
    44.                 employeeArtemisObject.getEmployee(employeeId.value);
    45.             }
    46.            
    47.             private function employeeResult(_employee:ResultEvent):void{
    48.                 employee = Employee(_employee.result);
    49.                 if(employee.employeeId > 0){
    50.                     updateEnabled = true;
    51.                 }
    52.             }
    53.            
    54.             private function updateEmployee(employee:Employee):void{
    55.                 ti.text += "updateEmployee(" + employee + ") \n";
    56.                 ti.verticalScrollPosition += 75;
    57.                 employee.firstName = firstName.text;
    58.                 employee.lastName = lastName.text;
    59.                 employee.email = email.text;
    60.                 employee.jobTitle = jobTitle.text;
    61.                 employeeArtemisObject.updateEmployee(employee);
    62.             }
    63.            
    64.             private function updateEmployeeResult(status:ResultEvent):void{
    65.                 if(status.result){
    66.                     ti.text += "update successful \n";
    67.                 } else {
    68.                     ti.text += "update failed \n";
    69.                 }
    70.             }
    71.            
    72.            
    73.         ]]>
    74.     </mx:Script>
    75.     <mx:Style>
    76.         TextArea {
    77.             backgroundAlpha: .2;
    78.             color: #FFFFFF;
    79.         }
    80.         TextInput {
    81.             backgroundAlpha: .2;
    82.             color: #FFFFFF;
    83.         }
    84.         Label {
    85.             color: #FFFFFF;
    86.         }
    87.     </mx:Style>
    88.     <mx:TextArea id="ti" width="300" height="189" x="19" y="33"/>
    89.     <mx:NumericStepper minimum="1" maximum="9" id="employeeId" stepSize="1" x="151.5" y="230" enabled="{isBridgeStarted}" width="45"/>
    90.     <mx:Button click="getEmployee()" label="Load Employee" x="207" y="230" enabled="{isBridgeStarted}"/>
    91.     <mx:Label x="19" y="232" text="Search by EmpoyeeId:"/>
    92.     <mx:Label x="19" y="260" text="First Name:"/>
    93.     <mx:Label x="19" y="286" text="Last Name:"/>
    94.     <mx:Label x="19" y="312" text="Email:"/>
    95.     <mx:Label x="19" y="340" text="Job Title:"/>
    96.     <mx:TextInput x="89" y="284" id="lastName" text="{employee.lastName}" width="230"/>
    97.     <mx:TextInput x="89" y="258" id="firstName" text="{employee.firstName}" width="230"/>
    98.     <mx:TextInput x="89" y="310" id="email" text="{employee.email}" width="230"/>
    99.     <mx:TextInput x="89" y="338" id="jobTitle" text="{employee.jobTitle}" width="230"/>
    100.     <mx:Label x="19" y="15" text="Status Log"/>
    101.     <mx:Button x="257" y="378" label="Update" width="62" click="updateEmployee(employee)" enabled="{updateEnabled}"/>
    102. </mx:ApolloApplication>

    So, here is what actually is taking place in this example.

    First, (after manually starting the Java ArtemisBridge) the Apollo application makes its connection to the listening port on the Java class.

    Making the connection

    Then the user loads an Employee object by id using the Hibernate load method. The Java Employee object is retrieved from the hsqldb and passed into the Apollo application.

    Employee is loaded

    The user then may edit the Employee data and send it back to Java where it is updated using the Hibernate update method.

    Employee Updated

    The ArtemisBridge will obviously need to started automatically by the Apollo application and this will be possible in future versions of the Apollo runtime.