Cross Column

Showing posts with label Adobe Flex. Show all posts
Showing posts with label Adobe Flex. Show all posts

Friday, January 23, 2009

Setting Web Services to A Different URL in ActionScript

Some Web Services don't provide a correct port address in its WSDL. To get around this issue, it requires developers to set new endpointURI in MXML/ActionScript files.

There are two ways of calling web service operations in Adobe Flex:
  1. Use Flex built-in WebService class

  2. Use web service proxy classes (automatically generated by WSDL Instrospection Wizard)

Using Flex Built-In WebService Class


Using the first approach, you can set endpointURI on the WebService instance. The creationComplete event is thrown when the application is initialized. In this case, you can attach a listener (i.e., initApp()) to intercept the event and set the correct endpointURI on the WebService instance. Note that the new endpointURI set on the WebService instance applies to all operations defined in it.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx=http://www.adobe.com/2006/mxml
layout="vertical"creationComplete="initApp()"
xmlns:search="search.*">

<mx:WebService
id="myWebService"
wsdl="http://www.example.com:7753/search/query/Search?WSDL"
showBusyCursor="true">

<mx:operation name="doSimpleSearch" resultFormat="XML"
fault="onFault(event)"
result="showResult(event)"/>

<mx:operation name="login" resultFormat="XML"
fault="onFault(event)"
result="showResult(event)"/>

</mx:WebService>

<mx:Script>


private function initApp():void
{
myWebService.endpointURI =
"http://www.example.com:7753/search/query/Search";
myWebService.login("yyy", "yyy");
}
]]>

</mx:WindowedApplication>

Using Web Service Proxy Classes

You can also use the Flex Builder Import Web Service feature to automatically generate connection code for invoking SOAP-based web service operations. The generated code includes client-side (ActionScript) web service proxy classes that return strongly typed objects. You can use the generated code to call web service operations directly and to pass strongly typed objects as operation parameters.

Generated web service proxy files
The Import Web Service feature introspects a provided WSDL file and generates the following ActionScript class files:
  • BaseServiceName.as

  • IServicename.as

  • etc.

To see the full list of generated files and their descriptions, see Adobe Help.

For example, our service is named SearchService which is retrieved from the WSDL file. Using Import Web Service feature in FlexBuilder, it generates the following files:
  • BaseSearchService.as

  • ISearchService.as

  • etc.

To fix the URL issue, you locate endpointURI in the BaseServiceName.as file. Then set it to be the correct URL as shown below:
BaseSearchServicePort.endpointURI = "http://myserver:7777/search/query/Search"

This should work when you use the generated code to call web service operations directly. Without this fix, you will get the notorious stream error #2032.

I also noticed that there is a generated WSDL file in the project under .wsdl folder. It may be a good idea to change the URL in that WSDL file to be correct.

Thursday, January 22, 2009

Two Ways of Calling Web Service in Flex

There are two ways of calling web service operations in Flex:
  1. Use Flex built-in WebService class
  2. Use web service proxy classes (automatically generated by WSDL Instrospection Wizard)

Flex Built-in WebService Class


The <mx:WebService> tag gives you access to the operations of SOAP-compliant web services deployed on a web server.

See a working example here.

Web Service Proxy Classes


You can use the Flex Builder "Import Web Service" feature to automatically generate connection code for invoking SOAP-based web service operations. The generated code includes client-side (ActionScript) web service proxy classes that return strongly typed objects. You can use the generated code to call web service operations directly and to pass strongly typed objects as operation parameters. See the details on Adobe Flex 3 Help.

The following two tables compare these two approaches:


































Flex WebService Class
Example

<mx:WebService


 id="myWebService"


 wsdl="http://.../OracleSearch?WSDL"


 showBusyCursor="true">



<mx:operation name="login" resultFormat="XML"


 fault="onFault(event)"


 result="onLoginComplete(event)"/>


</mx:WebService>


Request
  1. myWebService.login(userName, password);
  2. myWebService.login(preEncodedXml);
Response myWebService.login.lastResult
Parameters

  1. Marshaled and validated by SchemaManager (i.e., provide multiple parameters mapped to message parts in the WSDL definition) [see Note #1]

  2. Bypassing the marshaling and validation of SchemaManager (i.e., use a pre-encoded node such as a single XML object, XMLList object, etc.)


Advantage(s)

  1. Even "Import from WSDL" Introspection Wizard fails, you can still call web service operations.


Disadvantage(s)

  1. Need to know the mappings between the WSDL definition and the MXML Web services declaration [see Note #2].

  2. If the marshaling and validation is done at runtime, it incurs overhead.

  3. If the marshaling and validation is bypassed, the SOAP payload may be invalid.






































Generated Web Service Proxy Class
Example

<search:OracleSearchService id="myWebService">


 <search:login_request_var>


  <search:Login_request>


   <search:username>{tiNameInput.text}</search:username>


   <search:password>{tiPassInput.text}</search:password>


  </search:Login_request>


 </search:login_request_var>


</search:OracleSearchService>


Request myWebService.login_send()
Response myWebService.login_lastResult
Parameters Strongly typed objects (i.e., Login_request class instance).
Advantage(s)

  1. Parameters are strongly typed.

  2. No need to know the mappings between the WSDL definition and the MXML Web services declaration [see Note #1] because the Web Service Introspection Wizard generates proxy classes that take care of web service data mapping and event plumbing.


Disadvantage(s)

  1. Sometimes "Import from WSDL" Introspection Wizard fails to convert.

  2. Sometimes generated SOAP message based on wizard's interpretation of schema is invalid (i.e., invalid to a specific implementation of web server).

  3. Whenever WSDL is updated, you need to regenerate proxy classes.







Notes

  1. Based on WSDL's schema definition, WSDL introspection wizard generates a set of web service proxy classes in advance. At runtime, operation's parameters are provided as strongly-typed objects (i.e., content objects) and marshaled/validated to SOAP message body.
  2. The mappings between the WSDL definition and the MXML Web services declaration depend on the operation style (Document or RPC), encoding mechanism used (literal or encoded), type (simple or complex) of parameter, and number of parameters. (You can read "Develop Web services clients with Macromedia Flex" article to understand the mapping issues although it is a little bit out-of-date).

How to Make External Components Available to Your Flex Code

MXML tags correspond to ActionScript classes or properties of classes. Flex parses MXML tags and compiles a SWF file that contains the corresponding ActionScript objects. For example, Flex provides the ActionScript HBox class that defines the Flex HBox control. In MXML, you create a HBox control by using the following MXML statement:
<mx:HBox id="mainWindow"  width="100%" height="30" 
borderSkin="{components.TopBorder}" backgroundColor="#A5A7Ad"
backgroundAlpha="0.75" cornerRadius="15" paddingLeft="0"
paddingTop="0" paddingRight="0" paddingBottom="0"
verticalGap="0" verticalAlign="middle">

When you declare a control using an MXML tag, you create an instance object of that class. This MXML statement creates a HBox object, and initializes the borderSkin property of the HBox object to the components.TopBorder Class. To avoid compilation error, you need to make externally defined classes and packages available to your code by using import statement. For components.TopBorder, you need to import it like this:
<mx:script>
<![CDATA[import components.TopBorder;]]>
</mx:Script>
It is possible for you to omit this import statement if you have other components from the same package being referenced in the same MXML file. Say, in the same MXML file that references components.TopBorder, we also have the following MXML tag which references VStack from the same package (i.e., components):

<components:VStack id="worklistComp"  width="100%" height="100%" 
headerStyleName="StackLabel" backgroundColor="#e8eaed" boderThickness="0">

To avoid compilation error, you need to add an namespace declaration as this:

<mx:windowedapplication xmlns:components="components.*" 
width="452" height="364" layout="vertical" ...>

Because the reference of components.VStack has made components package available to your code by MXML compiler, you don't need to import it again.

In summary, you always need to make externally defined classes and packages available to your Flex code by:
  • If you reference it in MXML tag, you use xmlns attribute to declare a prefix and its path (i.e., xmlns:components="components.*") and use that prefix in the tag name (i.e., <components:VStack>).

  • If you reference it in MXML attribute or node value, you use ActionScript import statement to make it available.

Friday, January 16, 2009

Installing Eclipse and Its Plug-ins (FB, Jupiter, Subclipse)

This article documents the procedure of setting up Eclipse to use the following plug-ins:
  • Flex Builder plug-in 3.0.2 (i.e., FB3_WWEJ_Plugin.exe)
  • Jupiter plug-in 3.4.1.1 (i.e., edu.hawaii.ics.csdl.jupiter_3.4.1.1.jar)
  • Subclipse plug-in
To read more about these plug-ins, refer to the following documents:

The Eclipse platform we use is "Eclipse IDE for Java EE Developers" and you can download it from here. Our version is 3.4.1.

Follow these steps to install Eclipse and its plug-ins:
  1. Install Eclipse by unzipping the archive to a folder, say E:\MyApplications.
  2. Click on E:\MyApplications\eclipse\eclipse.exe to start Eclipse.
  3. Install Flex Builder plug-in by clicking on FB3_WWEJ_Plugin.exe
    • Adobe Flex Builder 3 Installer will be launched.
    • Choose an install folder for Flex Builder (e.g., E:\Program Files\Adobe\Flex Builder 3 Plug-in)
    • Choose an Existing Eclipse Folder (e.g., E:\MyApplications\eclipse)
    • If you already have Flash Player installed, you can skip additional installations
    • Close all instances of Eclipse or Flex Builder before proceed with the installation
    • If you install the plug-in on a machine that already has a registered Flex Builder installation, it will be automatically registered. Otherwise, you need to register.
  4. Install Jupiter plug-in by copying its jar file into the plugins directory of Eclipse (e.g., E:\MyApplications\eclipse\plugins).
  5. Install the Subclipse plug-in
    • In Eclipse, open Help -> Software Updates
    • Software Updates and Add-ons wizard will be launched
      • If you try to install the Subclipse plug-in (or any Eclipse plug-in) from the intranet, you'll need to set the Proxy in Eclipse first. You do that in Window->Preferences->General->Network Connectivity.
    • Click on Available Software tab
    • Click on Add Site button
    • Add the following location: http://subclipse.tigris.org/update_1.4.x
    • Expand http://subclipse.tigris.org/update_1.4.x site
    • Select "Subclipse" and "JavaHL Adapter"and then click on "Install" button
As you might have noticed, there are 3 different ways of installing Eclipse plug-ins:
  1. Use InstallAnywhere installer
  2. Copy jar file into plugins directory
  3. Use Eclipse's Software Update

Final Words

When features and plug-ins are manually installed on top of an Eclipse-based product install located on a FAT file system that has already been run at least once, the product must be explicitly restarted with -clean. That is,

eclipse.exe -clean


Learn More
  1. Eclipse IDE Tutorial

Thursday, January 15, 2009

Importing Foreign Projects from SVN in Flex Builder

How does one go about opening someone else's project in Flex Builder using Subversion? You can directly import a project without creating a dummy one first and there are two ways of achieving this:

(1) From File menu...

  1. File > Import > Other
  2. Select Checkout Projects from SVN
  3. Check Use existing repository location: and select svn://rws...
  4. Select a project folder
  5. Use the default setting in Checkout from SVN dialog.

(2) From SVN Respository Exploring perspective...

  1. Browse in the SVN navigator to the project folder that you want to include into your existing workspace.
  2. Right click and bring up context menu.
  3. Choose Checkout...
  4. Checkout from SVN dialog will pop up and offer to check out the project in the current workspace.



To install Subversion in Flex Builder, you can get the the Subclipse plugin and follow the instructions as shown here.

Thursday, December 4, 2008

Loading SWFs at Runtime in Flex

Loading SWFs to an application at runtime all use Loader class in Flex. This includes SWFLoader and ModuleLoader which delegate to Loader class internally. Note that Modules are SWF files that can be loaded and unloaded by an application. Their loading is managed by ModuleManager which ensure that there is only one copy of a module loaded, no matter how many times you call the load() method for that module.

The Loader class can be used to load other external display assets such as image files (i.e., JPG, PNG, or GIF file) . Also you can use the URLLoader class to load text or binary data. However, we only focus on loading SWFs with Loader class in this article.

SWF files can be loaded over HTTP or from the local file system at runtime. There are four basic steps to using the Loader class:
  1. Create the Loader instance
  2. Create a URLRequest instance that specifies the SWF's location.
  3. Create a LoaderContext instance which has properties that define the following:

  • The ApplicationDomain for the loaded SWF
  • The SecurityDomain for the loaded SWF
  1. Pass the URLRequest instance and LoaderContext instance to the Loader instance's load() or loadBytes() methods.

When loading SWF files with the Loader.load() method, you have two decisions to make: into which security domain the loaded SWF file should be placed, and into which application domain within that security domain? When loading a SWF file with the Loader.loadBytes() method, you have the same application domain choice to make as for Loader.load(), but it's not necessary to specify a security domain, because Loader.loadBytes() always places its loaded SWF file into the security domain of the loading SWF file.

Security Domain Decision


The first decision to make is into which security domain the loaded SWF file should be placed. The choice of security domain is meaningful only if you are loading a SWF file that might come from a different domain (a different server) than the loading SWF file. When you load a SWF file from your own domain, it is always placed into your security domain. But when you load a SWF file from a different domain, you have two options. You can allow the loaded SWF file to be placed in its "natural" security domain, which is different from that of the loading SWF file; this is the default. The other option is to specify that you want to place the loaded SWF file placed into the same security domain as the loading SWF file, by setting myLoaderContext.securityDomain to be equal to SecurityDomain.currentDomain. This is called import loading, and it is equivalent, for security purposes, to copying the loaded SWF file to your own server and loading it from there. In order for import loading to succeed, the loaded SWF file's server must have a policy file trusting the domain of the loading SWF file.

Note that content in the Air application security sandbox cannot load content from other sandboxes into its SecurityDomain.

For more information, see the following:


Application Domain Decision



The second decision to make is into which application domain within the security domain that loaded SWF file is placed. However, you specify it only when loading a SWF file written in ActionScript 3.0 (not a SWF file written in ActionScript 1.0 or ActionScript 2.0).

Application domains are used to partition classes that are in the same security domain. They allow multiple definitions of the same class to exist and allow children to reuse parent definitions.

Every security domain is divided into one or more application domains, represented by ApplicationDomain objects. Application domains are not for security purposes; they are used to partition classes that are in the same security domain. If you are loading a SWF file from another domain, and allowing it to be placed in a separate security domain, then you cannot control the choice of application domain into which the loaded SWF file is placed; and if you have specified a choice of application domain, it will be ignored. However, if you are loading a SWF file into your own security domain (either because the SWF file comes from your own domain, or because you are importing it into your security domain) then you can control the choice of application domain for the loaded SWF file.

You have four choices for what kind of ApplicationDomain property to use:
  • Child of loader's ApplicationDomain. The default. You can explicitly represent this choice with the syntax new ApplicationDomain(ApplicationDomain.currentDomain). This allows the loaded SWF file to use the parent's classes directly, for example by writing new MyClassDefinedInParent(). The parent, however, cannot use this syntax; if the parent wishes to use the child's classes, it must call ApplicationDomain.getDefinition() to retrieve them. The advantage of this choice is that, if the child defines a class with the same name as a class already defined by the parent, no error results; the child simply inherits the parent's definition of that class, and the child's conflicting definition goes unused unless either child or parent calls the ApplicationDomain.getDefinition() method to retrieve it.
  • Loader's own ApplicationDomain. You use this application domain when using ApplicationDomain.currentDomain. When the load is complete, parent and child can use each other's classes directly. If the child attempts to define a class with the same name as a class already defined by the parent, the parent class is used and the child class is ignored.
  • Child of the system ApplicationDomain. You use this application domain when using new ApplicationDomain(null). This separates loader and loadee entirely, allowing them to define separate versions of classes with the same name without conflict or overshadowing. The only way either side sees the other's classes is by calling the ApplicationDomain.getDefinition() method.
  • Child of some other ApplicationDomain. Occasionally you may have a more complex ApplicationDomain hierarchy. You can load a SWF file into any ApplicationDomain from your own SecurityDomain. For example, new ApplicationDomain(ApplicationDomain.currentDomain.parentDomain.parentDomain) loads a SWF file into a new child of the current domain's parent's parent.

When a load is complete, either side (loading or loaded) may need to find its own ApplicationDomain, or the other side's ApplicationDomain, for the purpose of calling ApplicationDomain.getDefinition(). Either side can retrieve a reference to its own application domain by using ApplicationDomain.currentDomain. The loading SWF file can retrieve a reference to the loaded SWF file's ApplicationDomain via Loader.contentLoaderInfo.applicationDomain. If the loaded SWF file knows how it was loaded, it can find its way to the loading SWF file's ApplicationDomain object. For example, if the child was loaded in the default way, it can find the loading SWF file's application domain by using ApplicationDomain.currentDomain.parentDomain.

SWFLoader


If you are loading a SWF file using SWFLoader that comes from a different domain (a different server) than the loading SWF file, the secuirty domain decision will be made based on trustContent property on the SWFLoader object. If the trustContent property is set to be true, Flex will place the loaded SWF file into the same security domain as the loading SWF file. Otherwise, the loaded SWF file will be placed in its "natural" security domain, which is different from that of the loading SWF file. If trustContent property is set to be false and the loaded SWF file is placed into the same security domain as the loading SWF file, it also set the application domain to be child of the loader's application domain which allows the loaded SWF file to use the parent's classes directly. If any of the settings violate security restrictions, an securityError can be thrown.

ModuleLoader


Module files can be loaded over HTTP or from the local file system at runtime. However, a Flex module must be in the same security domain as the application (SWF) that loads it. For example, if the loading SWF is in a remote security domain, the loaded module will be placed in the same security domain as the loading SWF file; otherwise, ModuleLoader didn't set the securityDomain property in the LoaderContext. By default, modules are loaded into the child of the current application domain. You can specify a different application domain by using the applicationDomain property of the ModuleLoader class.

When you're using modules in an AIR application any module SWF must be located in the same directory as the main application SWF or one of its subdirectories, which ensures that like the main application SWF, the module SWF is in the AIR application security sandbox.

Enabing Keyword Substitution with SVN in Flex Builder

Similar to CVS, Subversion supports keyword substitution (i.e., substitute keywords--pieces of useful, dynamic information about a versioned file-- into the contents of the file itself).

Subversion defines the list of keywords available for substitution. That list contains the following five keywords, some of which have aliases that you can also use:






























KeywordAliases
DateLastChangedDate
RevisionLastChangedRevision or Rev
AuthorLastChangedBy
HeadURLURL
Idn/a


Simply adding keyword anchor text to your file does nothing special. Subversion will never attempt to perform textual substitutions on your file contents unless explicitly asked to do so. To tell Subversion whether or not to substitute keywords on a particular file, we again turn to the property-related subcommands. The svn:keywords property, when set on a versioned file, controls which keywords will be substituted on that file. The value is a space-delimited list of the keyword names or aliases found in the previous table.

In FlexBuilder, say, you want to add svn:keywords property to multiple files located in the same folder. Right click that folder, select Team > Set Property and fill in information like this:

Then click OK button to set it. To view the property settings on a specific file, you right click that file and select Team > Show Properties. A SVN Properties view will be displayed with name/value pairs. However, before you can view the SVN properties, you need to enable the view by selecting Window (Menu) > Other Views. A Show View dialog will pop up and you can select SVN Properties to enable it.

For example, say you have a versioned file named AbstractHeader.as with a file header like this:
/* Copyright (c) 2007, 2008, Oracle. All rights reserved.  */
/* $HeadURL$ */
/* $Id$ */

With no svn:keywords property set on that file, Subversion will do nothing special. Now, let's enable substitution of the Id and HeadURL keyword by following above-described steps. Immediately after you commit this property change, Subversion will update your working file with the new substitute text as follows:
/* Copyright (c) 2007, 2008, Oracle. All rights reserved.  */
/* $HeadURL: svn://rws65122fwks.us.oracle.com/AirGadgets/src/com/oracle/apps/search/AbstractHeader.as $ */
/* $Id: AbstractHeader.as 26 2008-12-04 00:58:26Z sguan $ */

Sunday, October 12, 2008

Item Renderer in Flex

Adobe Flex supports several controls that you can use to represent lists of items. These controls let the application user scroll through the item list and select one or more items from the list. All Flex list components are derived from the ListBase class, and include the following controls: DataGrid, HorizontalList, List, Menu, TileList, and Tree.

Each list control has a default mechanism for controlling the display of data, or view, and lets you override that default. To override the default view, you create a custom item renderer.

The following example shows how you can create a simple TileList item renderer which displays custom items with an icon and a label in the TileList control’s tiles.

<mx:TileList
dataProvider="{xmlListColl}"
itemRenderer="TileListItemRenderer"
columnCount="3"
columnWidth="150"
rowCount="2"
rowHeight="100" />


TileListItemRenderer is an item renderer class which is defined in an MXML file named TileListItemRenderer.mxml as shown below:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Image source="{data.@src}" horizontalCenter="0" verticalCenter="0" />
<mx:Label text="{data.@lbl}" fontWeight="bold" horizontalCenter="0" bottom="0" />
</mx:Canvas>




If you want to make a TileList control use this renderer, and have each renderer instance display an image and a label, you would write the following code:
var itemRenderer:ClassFactory = new ClassFactory(TitleListItemRenderer);
myTileList.itemRenderer = itemRenderer;




However, in MXML, you can use the following syntax:
<mx:TileList
dataProvider="{xmlListColl}"
itemRenderer="TileListItemRenderer"



and the MXML compiler automatically creates the ClassFactory instance for you.
At runtime, Flex uses it to generate instances of item renderer class (i.e.,
TitleListItemRenderer).

© Travel for Life Guide. All Rights Reserved.

Analytical Insights on Health, Culture, and Security.