Garbage Collection in the UcompOS RPF

OscarTheGrouch In large and sophisticated Flash-based applications, such as the Rich Portal Applications you develop with the UcompOS Rich Productivity Framework, Garbage Collection becomes an increasingly important consideration.

Garbage Collection is a computer science concept that deals with memory management and re-allocating memory occupied by objects that are no longer needed or in use by the computer program.

Garbage Collection in a large-scale event-driven Flash architecture is a crucial consideration and unfortunately, can also be a tedious proposition to properly implement.

One of the more important considerations in aiding with Garbage Collection in Flash-based application is proper management of event listeners.

In a best-practice implementation, any call to addEventListener() would be followed up with a call to removeEventListener() once the event listener was no longer needed. Event listeners perpetuate the objects they are associated with so even once a particular object is destroyed, that doesn’t necessarily mean any event listeners associated with it will be destroyed too.

Failure to remove event listeners once they are no longer needed in a large-scale implementation can cause memory leaks and performance can break down over time.

In all your Flash applications, you should employ this strategy when and where possible.

In a typical large-scale UcompOS RPF implementation, Flash-based applications and sub-applications are continuously being loaded and unloaded into the UcompOS Portal.

The concept of Proxy Components in the UcompOS RPF involves event listeners being attached to a Proxy Component in one entity that represents an object in another UcompOS entity and then listening for dispatched events.

Therefore, the concept of garbage collection takes on especially critical importance in the UcompOS RPF because if UcompOS applications are being loaded and unloaded constantly and the event listeners that are attached to them are not being properly removed, performance would become an issue in a large-scale implementation.

The UcompOS Portal has been designed such that when SWF content that has been loaded into the UcompOS Portal is unloaded, a garbage collection routine is implemented to try to optimize system performance. (The three ways SWF content is loaded into the UcompOS Portal is in UcompOS Window instances, UcompOS Artifact instances, or into the UcompOS run-time.)

As of the UcompOS RPF Public Alpha release 0.4.6, some additional enhancements to the garbage collection process have been implemented that I will discuss here.

Understanding the UcompOS RPF garbage collection architecture can help you build more scalable Rich Portal Applications.

The recent enhancements come in the realm of Proxy Components.

By strict convention, all Proxy Components must extend the SDK class AbstractProxyComponent. As of UcompOS RPF 0.4.6, AbstractProxyComponent now extends a new SDK class called SDKEventDispatcher which extends EventDispatcher.

(Also, as a side-note, the AbstractProxyComponent class now implements IEventDispatcher in addition to IProxyComponent so you can refer to your Proxy Components as IEventDispatcher or IProxyComponent instances interchangably.)

SDKEventDispatcher simply overrides addEventListener() and offers a protected property _listeners of type Array.

I chose to create this separate class versus simply overriding addEventListener() in AbstractProxyComponent so that in the event the new clean-up process employed can be useful outside the scope of a Proxy Component, one could simply extend SDKEventDispatcher versus EventDispatcher.

Here is the over-ridden addEventListener():

override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
{
	_listeners.push({type:type,listener:listener});
	super.addEventListener(type,listener,useCapture,priority,true);
}

Notice that I am always assigning a true value to the useWeakReference parameter in the super call to addEventListener(). This is because in the context of attaching event listeners to Proxy Components, you always would want them to be weak references to aid in garbage collection.

In AbstractProxyComponent, there is a new protected method, cleanup() which is as follows:

protected function cleanup(event:SDKEvent=null):void
{
	while(_listeners.length)
	{
		var object:Object = _listeners.pop();
		removeEventListener(object.type,object.listener);
	}
	_sdkModel.removeProxyComponent(this.uuid);
	var commandObject:CommandObject = new CommandObject("SDK.cleanup",{uuid:this.uuid});
	var dataPackage:DataPackage = new DataPackage(Utilities.createUID(),_sdkModel.connectionId,this.destination,commandObject);
	_sdkClient.send(dataPackage);
}

What the cleanup() method does is it automatically removes any event listeners that have been attached to the Proxy Component.

It also sends a message to the end-point of the Proxy Component targeting its SDK.cleanup public API method that is built into the UcompOS SDK and therefore exposed by any UcompOS entity. This aids in UcompOS RPF garbage collection-related activities.

Calls to cleanup() do not occur automatically.

When you would call cleanup() in a Proxy Component would be an implementation specific consideration.

For instance, with these new capabilities, I have updated some of the UcompOS Portal Proxy Components that are built into the UcompOS SDK.

Consider the updated constructor of the UcompOSWindowProxy class:

public function UcompOSWindowProxy()
{
	super();
 
	// set the destination property to the UcompOS Portal
	super._destination = _sdkModel.root;
	<strong>addEventListener(CLOSE,cleanup);</strong>
}

The call to addEventListener(CLOSE,cleanup) is the new addition to the constructor.

What it does is it causes the inherited cleanup() method to always be called when the UcompOS Window instance on the UcompOS Portal that is represented by the UcompOSWindowProxy instance is closed.

Therefore, any event listeners you have attached to the UcompOSWindowProxy instance are automatically removed whenever the window is closed.

In 100% of the possible use cases for the UcompOSWindowProxy, this is the desired behavior.

The net result of this is you don’t have to worry about making your own calls to removeEventListener() for your particular UcompOSWindowProxy instances.

The same sort of behavior has been engineered into some of the other Proxy Components built into the UcompOS SDK including UcompOSAlertProxy, UcompOSDialogueProxy, UcompOSArtifactProxy, and UcompOSBrowserWindowProxy.

Consider this strategy when you are building your own Proxy Components and remember to always use removeEventListener() in all your other Flash applications whether you are deploying them in the UcompOS Portal or not.

Uploading Files to a UcompOSArtifactProxy Instance

In a major UcompOS Portal Application I am building, I place UcompOS Artifact instances that represent file volumes on the UcompOS Portal. Over this past weekend, I found myself with the need to enable the user to right-click on the file volume artifacts (revealing their context menus) and choose an “Upload Files” option with the goal of providing the user a way to upload files directly to the root directory of the particular file volume.

My initial approach to this was to attach a Context Menu to the artifact instances with an “Upload Files” option.  I then created an event listener to listen for the UcompOSArtifactProxy.MENU_ITEM_SELECT event dispatched by the UcompOSArtifactProxy instance.

Once this event is dispatched, I reasoned I could then create a FileReferenceList instance and then call its browse() method and go from there.

However, when I attempted this, I was reminded of an important detail when an error was thrown once I called the FileReference.browse() method.

Just like the launching of AIR applications as well as the entry into Full Screen Mode, the opening of the file browse dialogue by the Flash Player must succeed a user-triggered mouse event.

In the context of the UcompOS Continuum, the entity where the mouse event occurs is the UcompOS Portal.  This is a completely separate entity from the code that is calling the FileReference.browse() method.

In my implementation, I have a Flash application that is running as a background application that sets up the aforementioned UcompOS Artifact instances that represent file volumes.

So when the user right clicks on the artifact and selects the Context Menu item, they are actually operating on the UcompOS Portal itself.

An SDKEvent is then dispatched to the background application and then what follows is the call to FileReferenceList.browse().

However, as far as the Flash Player is concerned, in that scenario, the call to FileReferenceList.browse() does NOT proceed a user-triggered mouse event because the mouse event occurs in a totally different scope.

So I have engineered a new process into the UcompOS Portal to enable the goals I described above.

I think the use case I am speaking to here is one that has good merit to be repeated by many developers – i.e. a widget that you can upload files to.  I can envision many scenarios where this could be useful such as file conversion utilities for one.

The model I have developed involves creating an uploadFiles property on the UcompOSArtifactProxy‘s data Object property.

The value of this uploadFiles property must be the same String value as the label placed on a Context Menu item that is attached to the artifact.

What will happen in this case, when the user selects the context menu option on the artifact on the UcompOS Portal, the file browse dialogue will open, and the user will be able to select multiple files.

After the user selects the files, what happens next is very important.

The UcompOS Portal will dispatch to the UcompOSArtifactProxy instance an SDKEvent for each attached file.

The SDKEvent‘s data property will have two properties: fileName:String and fileData:ByteArray, i.e. the name of the file and the contents of the file as a ByteArray.

From here you can do whatever you need to do with this information including upload the file to a remote server, do some sort of conversion, or anything else your specific use case requires.

Below, is a very simple code-based example of how you can create an Artifact and the user can change the artifact’s icon representation by uploading a new image to it.

The application is a UcompOS Flash application loaded into the UcompOS Portal as a background application.

package
{
	import flash.display.Sprite;
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSArtifactProxy;
	import com.ucompass.ucompos.sdk.SDKClient;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
	import flash.events.Event;
 
	public class Main extends Sprite
	{
 
		private static const UPLOAD_LABEL:String = "Upload a new artifact image";
 
		public function Main()
		{
			// Instantiate the UcompOS SDK
			SDKClient.getInstance(this);
 
			// Create a UcompOS Artifact Proxy instance
			var artifact:UcompOSArtifactProxy = new UcompOSArtifactProxy();
 
			// Listen for uploaded files
			artifact.addEventListener(UcompOSArtifactProxy.UPLOAD_FILE,uploadHandler);
 
			// Initialize the artifact using a pre-defined image
			artifact.add("RIGHT CLICK ON ME!",null,"http://desktop.ucompass.com/UploadToArtifact/cloud-48x48.png",100,100,true,true,{uploadFiles:UPLOAD_LABEL});
 
			// Establish the context menu on the artifact with an Upload option
			artifact.setContextMenu(new XML(""));
		}
 
		private function uploadHandler(event:SDKEvent):void
		{
			var artifact:UcompOSArtifactProxy = event.target as UcompOSArtifactProxy;
 
			// Replace the artifact image with the content of the uploaded file
			artifact.setImage(event.data.fileData);
 
			// Show the name of the uploaded file as the label on the artifact
			artifact.setLabel(event.data.fileName);
		}
 
	}
 
}

Also, here is a link to a movie that shows the simple application in action.

Building Full Screen Mode UcompOS Implementations

Since the release of Adobe Flash Player 9 in 2006, the Flash Player is capable of entering into what is known as “Full Screen Mode“.

In Full Screen Mode, the content playing in the Flash Player takes over the entire viewport of the display device such that the only content in view and capable of being interacted with is the content currently being executed in the Flash Player.

Depending on the nature of your application, this can in some circumstances create a much more focused and positive experience for your users.

The UcompOS Portal is configured to operate in Full Screen Mode and the UcompOS SDK provides a means for sending the UcompOS Portal into Full Screen Mode from one of your UcompOS applications or sub-applications.

Of course there are some rules and principles to observe when leveraging the power of Full Screen Mode in your UcompOS Applications.

In my blog posting on the Mechanics of UcompOS Desktop (AIR 2.0) Applications, we learned that the launching of an AIR application by the Flash Player must be preceded by a user-triggered mouse event.

The same rule applies to entering into Full Screen Mode.

The UcompOSGlobalManagerProxy class has two pertinent methods:  enterFullScreenMode(); and exitFullScreenMode();.

Both of these methods accept an optional single input parameter, message, of type String.

When you call either of these methods from one of your UcompOS applications or sub-applications, in order to generate the compulsory user mouse click, the UcompOS Portal throws up an Alert dialogue asking the user if they want to allow the request to go into or out of full screen mode.

Of course having the dialogue appear for exitFullScreenMode(); calls is somewhat dubious as all the user needs to do is hit the Escape key on their computer to break out of Full Screen Mode but for continuity, I have decided to keep the mechanics of throwing the Alert in calls to both enterFullScreenMode(); and exitFullScreenMode();.

The optional message parameter lets you customize the text that is presented on the Alert dialogue.

When the UcompOS Portal breaks into or out of Full Screen Mode, a Continuum Event (an instance of the SDKEvent class) of type UcompOSGlobalManagerProxy.SCREEN_MODE_CHANGE is broadcast.

The data Object of the event will have a state property with a literal string value of “normal” or “fullScreen” so that your applications and sub-applications can behave accordingly when the user enters/exits Full Screen Mode.

In the scenario we discussed in my AIR 2.0 UcompOS Applications posting mentioned above, we saw we can leverage the UcompOSArtifactProxy class to create a clickable UcompOS Artifact that immediately launches a particular AIR application (with the aid of the UcompOSAIRProxy class).

This same concept is also available with Full Screen Mode implementations.  You can create a UcompOS Artifact and assign its data Object special properties that tell the UcompOS Portal to launch or exit Full Screen Mode when the artifact is clicked on.

The property names will be enterFullScreenMode and exitFullScreenMode and both should be of type Boolean with a value of  true.

They should be mutually exclusive and you should not have the enterFullScreenMode and exitFullScreenMode properties set on the artifact’s data Object simultaneously.  If you do, the exitFullScreenMode property takes precedent.

Let’s look at a simple code-driven example:

private var artifact:UcompOSArtifactProxy;
 
private function start():void
{
 
 SDKClient.getInstance(this);
 UcompOSGlobalManagerProxy.getInstance().addEventListener
(UcompOSGlobalManagerProxy.SCREEN_MODE_CHANGE,screenModeChangeHandler);
 artifact = new UcompOSArtifactProxy();
 artifact.add(null,null,"http://www.server.com/enterFullScreenModeImage.png");
 artifact.data = {enterFullScreenMode:true};
 
}
 
private function screenModeChangeHandler(event:SDKEvent):void
{
 
 switch(event.data.state)
 {
 
 case "fullScreen":
 artifact.data = {exitFullScreenMode:true};
 artifact.setImage(null,"http://www.server.com/exitFullScreenModeImage.png");
 break;
 case "normal":
 artifact.data = {enterFullScreenMode:true};
 artifact.setImage(null,"http://www.server.com/enterFullScreenModeImage.png");
 
 }
 
}

An important point to make about Full Screen Mode implementations, at this time, UcompOS HTML content cannot be displayed while in full-screen mode.  UcompOS HTML applications and sub-applications rely on an iframe implementation which is outside the visual scope of the Flash Player.

UcompOS HTML entities can still be interacted with via Proxy Components while in Full Screen Mode however.

The same applies to UcompOS AIR 2.0 content.  It cannot be in view while the in Full Screen Mode but it can be interacted with by Proxy Component-driven interactions.

Building Drag and Drop Experiences in the UcompOS RPF

The UcompOS RPF couldn’t rightfully be called a “Rich Productivity Framework” if it didn’t have a model to support drag and drop interactivity.  Drag and Drop behavior could perhaps be considered one of the key characteristics of an application that helped to define the term “Rich Internet Application” in the early 2000s.

This discussion doesn’t focus on building drag and drop interactivity within a single UcompOS application.  Obviously, you can implement whatever sort of drag and drop interactivity within a singular UcompOS HTML, Flash, Flex, or AIR application without restriction or consideration of UcompOS mechanics.

The real power in a UcompOS Rich Portal Application is in implementing inter-application drag and drop interactivity.

Dragging names from an address book application to an e-mail application, dragging images from a file manager to a text editor, highlighting multiple resources and dragging them to a widget to perform some operation on the items simultaneously – these are some of the experiences that can be created.

The mechanics of drag and drop UcompOS implementations are worthy of discussion.  There are some important considerations that need to be made in order for the UcompOS Portal to enable your applications to be configured appropriately for inter-application dragging and dropping.

Sandboxing in the UcompOS RPF

The philosophy of the UcompOS RPF is to achieve the highest degree of sandboxing possible while still achieving our interaction objectives.

Our sandboxing is less for security purposes and more to create an isolated, self-contained environment for a UcompOS entity that is free from unintentional disruption by other UcompOS entities.

Communication between applications in the UcompOS RPF should exclusively occur using the classes built into the SDK.

In no way should you plan to, or should you need to, attempt to directly access classes, properties, or methods of other UcompOS entities within an individual UcompOS entity. You should exclusively rely on the powerful implementation of a UcompOS entity’s public API methods, Services Dictionary, and Proxy Components.

The one exception to this is the implementation of dragging and dropping across two different UcompOS entities.  But the UcompOS Portal handles all the logic for you so that you don’t need to worry about anything other than what should be dragged and what should be allowed to be a drop target and how it should behave when receiving a drop.

The topic of sandboxing in the Flash Player and loading SWF content into other SWF content is a necessarily thorough and rigorous conversation.

In the UcompOS RPF, any SWF content – be it a UcompOS application or sub-application – is loaded into the UcompOS Portal with an implementation of the SWFLoader class.

The SWFLoader has some very important properties that essentially articulate the permissions the child SWF content has in terms of accessing information (classes, properties, methods) of the parent SWF content it was loaded into.

One of the chief goals of the UcompOS RPF is complete disaggregation.  The framework wants you to be able to place resources at any network address without consequence.

Therefore, all SWF content is loaded into the UcompOS Portal with the trustContent property set with a true value.

There are three different ways SWF content is loaded into the UcompOS Portal as listed below:

  • SWF-based UcompOS application loaded invisibly into the UcompOS run-time
  • SWF-based sub-application loaded into a UcompOS Window
  • SWF-based sub-application loaded into a UcompOS Artifact

When you load SWF content into the UcompOS Portal, you can articulate how tightly it is to be sandboxed.

As far as SWF-based UcompOS applications loading invisibly into the UcompOS run-time, you can set a sandbox=”true” or sandbox=”false” attribute to the root tag in that application’s manifest file.  The default condition is sandbox=”true”.

Also, if you look at the signatures of the add(); methods of both UcompOSWindowProxy and UcompOSArtifactProxy, you’ll see they both have sandbox parameters that default to a true value.

By default, a SWF loaded into a UcompOS Window or UcompOS Artifact will take on the sandbox configuration of its root UcompOS Application.

From an implementation point of view, the only difference between the two configurations is SWF content loaded with the sandbox=”true” configuration has the following property set to the SWFLoader used to load the content:

swfLoader.loadForCompatibility = true;

According to the Adobe’s ActionScript 3 documentation:

“Set this property to
true

to indicate that the loaded application might be compiled with a different version of the Flex framework and you want your application to be able to interact with it. Setting the value of the
loadForCompatibility

property to
true

also causes the LoaderContext of the Loader to load the sub-application into a sibling application domain of the main application, rather than a child application domain.”

A full discussion of the LoaderContext and ApplicationDomain classes is outside the scope of this blog posting, but essentially, setting the loadForCompatibility property to true is a form of sandboxing in that you are able to load Flex content created with a different version of the SDK than the parent SWF content.

Unless you have very specific reasons, in most all cases you’ll leave the sandbox property in its default configuration (sandbox=true).

Our plan is that we will always keep the UcompOS Portal running on the latest public release of Flex 4 so leaving sandbox=true will insure you won’t have to continue to update your Flex-based UcompOS content.

Scenarios for when you would want to set sandbox=false are complex and sophisticated and will be covered in an upcoming posting.

The Marshall Plan

The implications laid out above are somewhat important to elaborate upon.

We want to be able to load SWF content created with any version of the Flex SDK into the UcompOS Portal, and then we still want to be able to enable it to participate in drag and drop interactivity with other SWF content, that may have been produced with still other versions of the Flex SDK.

How is this possible?  After all, classes such as the DragManager are involved and certainly it seems we’ll run into compatibility issues.

The answer is taking advantage of a concept the people at Adobe have created that they call the Marshall Plan.  I recommend you explore this important topic.  It deals with how data is marshalled across the boundaries between two different SWFs.

As of the Beta 2 release of Flex 4, the classes that enable this marshalling to automatically occur are no longer automatically compiled into the SWF.  You have to explicitly add them at compilation time.

This must be added as an argument to the Flex compiler for your application:

-includes=mx.managers.systemClasses.MarshallingSupport

Failure to add this to a Flex 4 Beta 2 UcompOS application that is set up for dragging and dropping will yield unpredictable results, and even run-time errors.

Building a Simple Drag and Drop Example

If you have two different UcompOS entities – one the drag source, the other the drag destination – you would set each of them up as if they were both in the same overall application.

You’d set up the drag source to specify the behavior of the drag initiation, and your drag destination to implement your desired behavior of when items are dragged and dropped onto the target.

There is another scenario however and it involves dragging and dropping to a UcompOS Artifact.

In our example, we want to build a very simple example that shows a UcompOS Flex application that employs a DataGrid.  We then want to implement an artifact and enable the user to drag and drop an item from the DataGrid to the artifact.

When the item is dropped, we want to throw a simple HTML alert that outputs some information about the item that was just dropped.

Here are the three resources used to accomplish this task:

The Dock Manifest

<applications>
 <application background="true" default="true">
   http://applications.ucompass.com/SampleApps/UcompOSExamples/assets/manifests/DragAndDropExample.xml
 </application>
</applications>

The Application Manifest

<application selfLoading=”true” width=”206″ height=”250″ preloaderTitle=”Drag and Drop Example”>
 
 <source>
  <base>http://applications.ucompass.com/SampleApps/UcompOSExamples/bin-debug/DragAndDropExample.swf</base>
 </source>
 
 <titles>
  <title default=”true” locale=”en_US”>UcompOS Drag and Drop Example</title>
 </titles>
 
 <icons>
  <icon default=”true” locale=”en_US”>
   http://applications.ucompass.com/SampleApps/UcompOSExamples/assets/png/nature/Cloud-48×48.png
  </icon>
 </icons>
 
</application>

The Application Code

<?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/halo"
 applicationComplete="start();" height="200" width="200">
 <fx:Script>
 <![CDATA[
 import com.ucompass.ucompos.sdk.SDKClient;
 import com.ucompass.ucompos.sdk.events.SDKEvent;
 import com.ucompass.ucompos.sdk.proxycomponents.UcompOSArtifactProxy;
 import com.ucompass.ucompos.sdk.proxycomponents.UcompOSHTMLProxy;
 
 import mx.collections.ArrayCollection;
 [Bindable]
 private var _people:ArrayCollection = new ArrayCollection([
 {Name:"Ed",Age:36},
 {Name:"Max",Age:2},
 {Name:"Mason",Age:1},
 {Name:"Abigail",Age:1}]);
 
 private function start():void
 {
 SDKClient.getInstance(this);
 var artifact:UcompOSArtifactProxy = new UcompOSArtifactProxy();
 artifact.add("Drag Here!",null,
 "http://applications.ucompass.com/SampleApps/UcompOSExamples/assets/png/nature/Cloud-48x48.png",
 300,300);
 artifact.dragDropManager(true,"items",["Name","Age"]);
 artifact.addEventListener(UcompOSArtifactProxy.DRAG_DROP,dragDropHandler);
 }
 
 private function dragDropHandler(event:SDKEvent):void
 {
 var droppedItems:Array = event.data.dragDropData;
 var droppedItem:Object = event.data.dragDropData[0];
 var h:UcompOSHTMLProxy = new UcompOSHTMLProxy();
 h.alert("Your name is "+droppedItem.Name+" and you are "+droppedItem.Age+".");
 }
 
 ]]>
 </fx:Script>
 <mx:DataGrid width="200" height="200" dataProvider="{_people}" dragEnabled="true">
 <mx:columns>
 <mx:DataGridColumn dataField="Name"/>
 <mx:DataGridColumn dataField="Age"/>
 </mx:columns>
 </mx:DataGrid>
</s:Application>

Video Demo

Drag and Drop Example

The Mechanics of UcompOS Desktop (AIR 2.0) Applications

One of the more important and high-impact features of the UcompOS Rich Productivity Framework is the ability for UcompOS Rich Portal Applications to extend to the desktop.

The technology leveraged to accomplish this is Adobe AIR 2.0.

When you consider the presence of AIR 2.0′s new NativeProcess class, which enables an AIR application to target the native Operating System’s base functionality, the prospect of building industrial-strength applications that place very few limits on the developer and allow their imaginations to extend to new heights becomes very attainable.

In this post I want to talk a bit about the mechanics of AIR applications in the UcompOS RPF.  Understanding these mechanics can help you conceptualize and then deploy the most compelling rich experiences for your UcompOS Rich Portal Application.

The first thing to understand is that in the context of the UcompOS RPF, any AIR application will simply be another UcompOS entity.

A UcompOS entity represents any application or sub-application running in a UcompOS implementation.  The UcompOS Portal itself is a UcompOS entity.  All the UcompOS entities running at one time in the UcompOS RPF comprise what I refer to as the UcompOS Continuum as you know if you’ve been reading my blog postings.

There are a few different ways to launch a UcompOS AIR entity – as an application from the UcompOS Application Dock, using the UcompOSAIRProxy class, or by creating a UcompOS Artifact the user can click on to launch the AIR application.

First, let’s understand the mechanics at work here.  The UcompOS Portal is obviously a Flash-based browser entity.  In order for a browser-based Flash application to launch an AIR application, a couple things need to happen.

First, the author of the AIR application has to articulate that the application is allowed to be launched by the browser.

This is very easy to accomplish.

You simply need to have the following element as a direct child of the root element in the application’s manifest descriptor file.

<allowBrowserInvocation>true</allowBrowserInvocation>

The manifest descriptor file is NOT the UcompOS application manifest for the application.  It is the XML file that articulates the base-level behaviors and properties of an AIR application.

If you try to compile an AIR application that instantiates the UcompOS AIR SDK that does not have the above provision made, you’ll get a compilation error.

Does this mean that the only way your UcompOS AIR applications should be launched is by the browser via the UcompOS Portal?

Not necessarily.  There are ways you can set it up so that when your UcompOS AIR application is launched directly by the end-user, it opens the UcompOS Portal to a precise configuration.

It can even be configured so that your AIR application can save custom file types on the user’s desktop that when double-clicked upon can launch the AIR application which in turn launches the UcompOS Portal and then feeds one or more applications with the data contained in the desktop file.

These are a bit more advanced topics that I’ll definitely devote coverage to these capabilities sometime in the next month or so.

The next thing we need to understand is that the browser can only launch an AIR application following a user-triggered mouse click event.

When you configure an AIR application as the base source for a UcompOS Application in that application’s UcompOS Application Manifest and have the application show up on the UcompOS Application Dock, the UcompOS Portal is configured such that the clicking of the application icon on the dock is the click that is used to immediately launch the AIR application.

When you configure the Application manifest that will use an AIR application as its base source code, there are some parameters you need to incorporate into the manifest.

Below is a sample application manifest from a UcompOS AIR application that provides an example of this:

 
<application>
 <source>
 <base>http://desktop.ucompass.com/Camera_Example/Camera_Example.air</base>
 <params>
 <param>
 <name>appId</name>
 <value>Camera-Example</value>
 </param>
 <param>
 <name>publisherId</name>
 <value>0E5CA255707A7E3F70F12D38B16B8D2A4C17413C.1</value>
 </param>
 </params>
 </source>
 <titles>
 <title locale="en_US" default="true">My Camera</title>
 </titles>
 <icons>
 <icon locale="en_US" default="true">http://desktop.ucompass.com/Camera_Example/icons/camera.png</icon>
 </icons>
</application>

Note that you must at least include the appId and publisherId parameters.

There are a couple other ways to launch a UcompOS AIR application as a sub-application.

The first is with the UcompOSAIRProxy class which is built into the UcompOS SDK.

The UcompOSAIRProxy Class

The UcompOSAIRProxy class deserves some attention in this posting.  It is a Proxy Component that is used to create a virtual representation of a UcompOS AIR application in a UcompOS entity.  Inspecting the class is a good way to learn more about the mechanics of UcompOS AIR Applications.

Let’s look at the signature of the UcompOSAIRProxy‘s constructor:

public function UcompOSAIRProxy(appSource:String, appId:String,
      publisherId:String, airVersion:String, host:String="127.0.0.1", 
      operationPort:uint=0, validationPort:uint=0)

Let me touch on each of the parameters of the UcompOSAIRProxy‘s constructor:

  • appSource: This is the URL of the .air package file associated with the AIR application
  • appId: This is the application id of the AIR file as it exists in the AIR application’s descriptor file
  • publisherId: This is the value of the publisherid that is found in the file at $APP_INSTALL_DIR/Contents/Resources/META-INF/AIR/publisherid - WARNING: the publisherid will be deprecated in AIR 2.0 soon and I will then remove it as a required parameter in the UcompOSAIRProxy’s constructor at that time
  • airVersion: This is the minimum version of AIR to run the application.  AIR 2.0 is the UcompOS minimum requirement.
  • host: UcompOS AIR Applications rely on the ServerSocket class to communicate with other UcompOS entities.  By default, the UcompOS AIR application binds to 127.0.0.1 on the local machine and other UcompOS entities target that destination in socket transmissions.  However, you can override this and bind to some public facing IP address.  (NOTE: The implications here are remotely deployed UcompOS AIR Applications)
  • operationPort and validationPort: UcompOS AIR Applications bind to two ports – one for validation purposes and the other for actual UcompOS data transmissions.  By default, the UcompOS SDK will start with port number 1024, and climb upward using the first two openly available ports for operation and validation.  These port numbers can be explicitly articulated.

A UcompOSAIRProxy class has three specific types of SDKEvent instances associated with it:

  • UcompOSAIRProxy.AIR_APPLICATION_LAUNCHED: Dispatched when the AIR application has launched
  • UcompOSAIRProxy.AIR_APPLICATION_QUIT: Dispatched when the AIR application has quit
  • UcompOSAIRProxy.AIR_APPLICATION_STATUS: Dispatched following a call to the UcompOSAIRProxy instance’s getStatus(); method

An instance of UcompOSAIRProxy also has a getter/setter on the Boolean property status which returns true when the AIR application is running.

The UcompOSAIRProxy class has two methods key to our discussion: launchApplication(); and quitApplication();

You could use launchApplication(); to launch a UcompOS AIR Application as a sub-application.

When you do, however, the UcompOS Portal must find a way to meet the compulsory user-triggered mouse-click requirement mentioned above.

It does this by throwing an Alert onto the interface of the UcompOS Portal asking the user if they agree to allow the AIR application to launch and then by clicking “OK”, the user is providing the necessary mouse-click.

The full signature of the launchApplication(); method is as follows:

public function launchApplication(message:String=null):void

The message parameter allows you to display a custom message on the Alert used in this scenario.

There is an alternative way to launch a UcompOS AIR sub-application that I’ll cover next.

Using a UcompOS Artifact to launch an AIR Application

By now, you know that the UcompOSArtifactProxy class in the UcompOS SDK provides a way to implement the equivalent of “desktop widgets” on the UcompOS Portal interface.  I prefer the term “Artifact” over “Widget” however as I feel widget has functionality implied, whereas a UcompOS Artifact can be functional and can be a full-fledged UcompOS sub-application or it can be strictly presentational.

As is the case with all Proxy Components (i.e. any class that extends AbstractProxyComponent), UcompOSArtifactProxy instances have a data property.

When you set the data property of a UcompOSArtifactProxy instance, this data property is housed on the actual artifact itself on the UcompOS Portal.

There are two special properties that can be added to this data Object: launchAIRApplication and quitAIRApplication

The values of these properties would be the uuid property of the UcompOSAIRProxy instance that was to be launched upon a mouse click of the artifact involved.

So the following code may be something you’d see in practical operation:

var myAIRAppProxy:UcompOSAIRProxy = new UcompOSAIRProxy("http://apps.mysite.com/myApp.air","My-App","My-Publisher-Id","2.0");
var myArtifactProxy:UcompOSArtifactProxy = new UcompOSArtifactProxy();
myArtifactProxy.add("Label for my Artifact",imageContent);
myArtifactProxy.data = {launchAIRApplication:myAIRAppProxy.uuid};

In the above example, as soon as the artifact is clicked on, the AIR application will launch.

You could also do something like the following too:

private function launchHandler(event:SDKEvent):void
{
 switch(event.type)
 {
 case UcompOSAIRProxy.AIR_APPLICATION_LAUNCHED:
  myArtifactProxy.setImage(imageContentAppOn);
  myArtifactProxy.data = {quitAIRApplication:myAIRAppProxy.uuid};
 break;
 case UcompOSAIRProxy.AIR_APPLICATION_QUIT:
  myArtifactProxy.setImage(imageContentAppOff);
  myArtifactProxy.data = {quitAIRApplication:myAIRAppProxy.uuid};
 break;
 }
}

In the above example, we are listening to see when the AIR application is launched as well as when it quits.  We then replace the artifact image with a status indicator using the UcompOSArtifactProxy‘s setImage(); method so it easily shows the user if the associated AIR application is running or not.

As an example of how I am using this concept myself, in the Educator 2 Rich Portal Application I am building entirely on top of the UcompOS RPF, on the taskbar (an artifact container with a number of artifacts housed in it), there is an icon to launch the “Educator 2 Desktop”, which is obviously an AIR application.

When they click this icon, the Educator 2 Desktop immediately launches and the icon turns green indicating the feature is connected.  When they click it again, the Educator 2 Desktop quits and the icon turns red indicating the feature is disconnected.

Meet the UcompOS Portal Proxy Components

If you’ve read my previous postings, you should now have a basic understanding of some of the core mechanics of the UcompOS Rich Productivity Framework including Proxy Components and Services Dictionaries.

The concept of the UcompOS Continuum should also be somewhat clearer now as well as the roles of the UcompOS Portal and the UcompOS SDK in the context of the UcompOS Continuum.

Despite the obvious significance of the UcompOS Portal, in the context of the UcompOS Continuum, it is just another entity with the UcompOS SDK implemented that publishes a Services Dictionary of public API methods exposed for other entities.

To take advantage of this fact, the UcompOS SDK has a host of Proxy Components built into it that can be thought of as client interfaces to the public API methods exposed by the UcompOS Portal.

Understanding the mechanics of building your own UcompOS public API methods and Proxy Components to those public API methods is the key to unleashing the true power of the UcompOS RPF and creating the most compelling rich experiences for users of your Rich Portal Application.

But even a basic exploration of the SDK’s built-in UcompOS Portal Proxy Components is a fun way to explore and learn.

In this post, I’ll introduce you briefly to the UcompOS Portal Proxy Components.  I won’t spend a lot of time detailing them as you’ll likely see some dedicated blog postings from me covering the individual Proxy Components and their nuances in the coming weeks.

Each Proxy Component covered is built into all 3 UcompOS SDKs – AIR, Flex/Flash, and JavaScript.

The implementation details of using the AIR and Flash/Flex (ActionScript 3.0) Proxy Components versus the JavaScript Proxy Components are very subtle and of course full SDK documentation is online for the ActionScript 3.0 SDK as well as the JavaScript SDK.

Since the SDK documentation is online, I won’t spend a lot of time covering the methods, properties, and events of the Proxy Components (as you can get all this information in the docs), rather I’ll just give a first-person synopsis of what you can do with each of the Proxy Components.

UcompOSAIRProxy

The UcompOSAIRProxy class allows you to create a virtual representation of a UcompOS AIR application in an entity.  Once you create this virtual representation, you then use this class’s launchApplication(); and quitApplication(); method to control the start and stop of the AIR application.  Then any communication with the AIR application is handled via the traditional means of Proxy Components and public API methods.  The UcompOSAIRProxy class would be used when you wanted to launch a UcompOS AIR application as a sub-application.  If the UcompOS AIR application was to be a base application, you would just have the network URL to the air package in the application manifest and the AIR application would be launchable from the UcompOS application dock.  See my tutorial entitled A Simple HTML Digital Camera Browser for an example of this.

UcompOSArtifactContainerProxy

The UcompOSArtifactContainerProxy class lets you create a container for UcompOS Artifacts on the UcompOS Portal.  A UcompOS Artifact is essentially a “widget” that can be an image or SWF application that can have functionality attached to it (drag and drop, double click, click, rollover, context menu, etc.).

A UcompOS Artifact Container then is a visual layout container for these artifacts.  I gave an example of this in my tutorial entitled Building a UcompOS Weather Channel Widget.

An example may be a taskbar.  Suppose I want to layout a number of widgets each with its own specific functionality attached to it along the bottom right corner of my UcompOS Portal interface.

To do this I could create a UcompOS Artifact Container via the UcompOSArtifactContainerProxy class.  Then when I create my UcompOS Artifact, I would pass a reference to my UcompOSArtifactContainerProxy instance and the artifact would be placed into the relevant container.

There are 3 layout options at present with the UcompOS Artifact Container: HBox, VBox, and Tile

These are parallel to the classes of the same name in the mx.containers package from the Flex 3 framework (FYI the UcompOS Portal is built on Flex 4).

UcompOSArtifactProxy

The UcompOSArtifactProxy is a class used to create UcompOS Artifacts on the UcompOS Portal.

A UcompOS Artifact can be thought of as a widget.  The widget can be purely presentational, or it can have functionality attached to it as my Weather Channel Widget example demonstrated.

The visual content of a UcompOS Artifact can articulated as one of three forms:

  1. The network URL to an image (PNG, GIF, JPG)
  2. The network URL to a SWF appication
  3. A ByteArray representation of an image

You then attach functionality to a UcompOS Artifact by calling the UcompOSArtifactProxy‘s many public methods and attaching various event listeners to it to handle click, double click, rollover, rollout, drag and drop, and other various events.

If the visual content of your artifact is a SWF, this SWF can be a UcompOS sub-application for even more exciting interactive possibilities.

At this point, HTML-type applications cannot be used as artifacts

As described above in my discussion of the UcompOSArtifactContainerProxy class, you can add a UcompOS Artifact to a container so that groups of similar artifacts can be arranged together in a logical presentation.

One cool thing you can do, if you don’t add an artifact to a container and just position it at specified coordinates on the UcompOS Portal, you can make it draggable.  And because you can configure artifacts to accept drops, the ability to drag and drop one artifact to another to create some desired behavior or functionality exists.

I’ll likely devote a tutorial to this interesting capability in the near future.

UcompOSBrowserWindowProxy

The UcompOSBrowserWindowProxy class lets you launch a satellite browser window from the UcompOS Portal.  You can add generic content to the browser window, or you can load a UcompOS sub-application.

The ability to communicate with a UcompOS sub-application loaded in a satellite browser window is the exact same as if the sub-application was loaded in the UcompOS Portal run-time, in a UcompOS Window, or in a UcompOS Artifact.

UcompOSDockProxy

The UcompOSDockProxy class lets you exert control over the UcompOS Portal’s Application Dock.

You can do things such as set context menus to the application icon an entity is associated with.  You can also change the size of the icons on the dock as well as control the “genie” effect (the effect where the dock icons expand and then contract as the mouse passes over them).

You can also hide the dock completely using the showDock(visible:Boolean):void; method.

And one of the more important capabilities is you can set an alert for the icon on the dock an entity is associated with using the setAlert(); method.  This would be useful perhaps in e-mail or instant messaging applications to alert the user of receipt of a new e-mail or instant message.

UcompOSGlobalManagerProxy

The UcompOSGlobalManagerProxy class provides an interface to a number of important visual and data features  of the UcompOS Portal.

For instance, if you wanted the UcompOS Portal to throw a generic Flex-style Alert, you could use the createAlert(); method.

If you wanted to dispatch an event to all entities in the UcompOS Continuum, you could use the dispatchContinuumEvent(); method.

Suppose you wanted to launch another UcompOS application from within an entity.  You could call the launchApplication(); method and pass the manifest URL of the target application’s application manifest.

These are only a few of the important duties the UcompOSGlobalManagerProxy facilitates.

UcompOSHTMLProxy

The UcompOS Portal is a Flex 4 application embedded in an HTML wrapper.

The UcompOSHTMLProxy class lets you call JavaScript functions in the HTML wrapper.

The class provides the alert();, confirm(); and prompt(); methods which invoke the JavaScript functionality of the same name.

You can then add event listeners such as UcompOSHTMLProxy.CONFIRM_SUBMIT and UcompOSHTMLProxy.PROMPT_SUBMIT to capture user-input.

You can also use the javascript(); method to pass pure JavaScript code.

So one possibility here, in the ucompos/local/LocalLib.js JavaScript file in the UcompOS Developers Package that you customize to create your own authentication, you can implement your own JavaScript methods that perform specific tasks and then access these methods from the UcompOSHTMLProxy.

UcompOSMenuBarProxy

The UcompOSMenuBarProxy lets you set the dataProvider for the UcompOS Menu Bar and your particular menu bar implementation comes into view when the UcompOS application associated with the entity that set the menu bar model comes into focus.

You can even associated a menu bar model with an individual UcompOS Window instance.

You then attach event listeners to capture user menu selections.

Two cool random quick points is that you can pass a baseMenu=true value to the second parameter of the setMenuBar(); method and it will remove the default UcompOS menu bar item so you can 100% customize the menu.  Also, in your dataProvider to the menu you can attach an icon property with the network URL of images you want to use for the individual menu bar nodes.

UcompOSStyleProxy

The UcompOSStyleProxy class lets you take control over the portal’s visual presentation including the background image (wallpaper) that appears on the UcompOS portal.

With the setTheme(); method, you can set the MDI window theme to one of 3 different pre-existing window themes.  Right now, I just have the 3 that come packaged with the flexlib.mdi package implemented (Windows XP, Mac OS 9, and the default style) but it is my intention to expand this.

There is also a setEffects(); method that let you control the visual effects that occur when UcompOS Windows are closed or minimized/maximized.  The options are Default, Linear, and Vista which are the effects built into the flexlib.mdi package.

There is also a generic setStyle(); method that lets you set a generic CSS style property to the UcompOS Portal.

One important point about this method.  When you call setStyle();, the UcompOS Portal dispatches a UcompOS Continuum Event – meaning that all entities get notified about the style change.

So if you did something like this:

UcompOSStyleProxy.getInstance().setStyle("Button","color",0xFF0000);

Every entity would be notified that the Button selector’s color property was just given a red value on the UcompOS Portal.

You could then listen for this UcompOSStyleProxy.STYLE_CHANGE event and change the visual presentation of an entity’s internal controls accordingly.

UcompOSWindowProxy

The UcompOSWindowProxy class is used to create MDI window instances on the UcompOS Portal and then load generic web content or a UcompOS sub-application into them.

The class documentation is definitely worth a look as there are a lot of really cool features you can employ with UcompOS Window instances.

So that’s it.  A brief look at all the UcompOS Portal Proxy Components built into the UcompOS SDK.

I invite you to view the source code of the the JavaScript SDK and you can check the UcompOS Flash/Flex SDK written in ActionScript 3 out of the UcompOS SVN Repository.  Viewing this code will give you some better ideas of how to construct Proxy Components.

I have not yet made the source code of the UcompOS Portal publicly viewable and do not have a timeline for doing so but if you have questions about how I have built the public API methods on the UcompOS Portal, please bring questions to me in the UcompOS Forum and I’ll share relevant strategies and code examples.

Building a UcompOS Weather Channel Widget

In this tutorial posting we are going to look at several advanced features of the UcompOS Rich Productivity Framework.

You’ll want to download the source of the example application at the link below so you can follow along and there is also a video tutorial that goes along with this tutorial posting.

Download the Weather Widget Example Source Code

We will be building a small UcompOS application that attaches a Current Weather Conditions Widget to a UcompOS Portal implementation.  The source of the weather data will be The Weather Channel’s API Service.

We are going to look at a number of different UcompOS Rich Productivity Framework concepts in this tutorial including:

  • Working with both the UcompOS JavaScript and Flash SDK
  • Creating UcompOS background applications
  • Working with both UcompOS Artifacts and UcompOS Artifact Containers
  • Working with the UcompOS HTML Proxy

Let’s first start by looking at the application and exploring its functionality.  Then we’ll dissect the implementation carefully and explain exactly how everything was set up.

Below is a screen capture showing our simple implementation.

Demo

We can see a transparent bar on the bottom of the UcompOS Portal.  To the far right, we see a little weather icon with a temperature reading on top of it.

The transparent bar is actually a UcompOS Artifact Container and the weather widget is a UcompOS Artifact instance.

When I right click on the temperature reading, we see a context menu as shown below:

ContextMenu

We’ll look at how this weather widget was constructed as a UcompOS application.

First, let’s look at the Weather Widget itself which is a simple ActionScript 3 Flash CS5 application.

This tutorial assumes you have at least a basic command of the ActionScript 3 programming language so we will not study the construction of the weather widget itself in too much detail, but will rather focus on some of the key aspects of it as they pertain to creating a UcompOS Rich Productivity experience.

The main .fla file for our widget is named weather.fla.

As you can see below, its main document class is a class named Weather and the Flash movie itself is a small square of dimensions 25 pixels x 25 pixels.  Below is a look at the set up of our Flash movie:

FlashSetup

Next, let’s look in my Flash movie’s File > ActionScript Settings > Library Path location in my weather.fla file and we’ll see we have implemented our UcompOSSDK.swc file which is the UcompOS Flash SDK:

SWCSetup

Now let’s take a look at the main Weather class and see how it works.

Let’s first take a moment to reflect on what we want our Flash application to do.

We want our Flash movie to display an icon that displays the current weather conditions and then overlaid on top of that image we want the current temperature to display.

We also want our Flash movie to have a Context Menu associated with it that will let users access certain extended functionality like the ability to change to a new location to retrieve current weather conditions for.

First, in our constructor function for our Weather class, we are going to instantiate the UcompOS SDK by calling the static getInstance() method of the SDKClient class and passing it a self-reference:

SDKClient.getInstance(this);

Next, we’ll create the Loader that will house the image that will display the current weather conditions and add it to the stage:

_loader = new Loader();
 
addChild(_loader);

Now comes a key step.  We are going to create a UcompOSArtifactProxy instance and we will set its self property to true:

_artifact = new UcompOSArtifactProxy();
 
_artifact.self = true;

The Flash movie we are building here is going to be added to the UcompOS Portal as a UcompOS Artifact.  By setting the self property to true, we can manipulate the widget on the UcompOS Portal from within the widget itself.

Now, we are going to add an event listener to handle selections the user makes to items on the Context Menu that we’ll eventually add to the widget:

_artifact.addEventListener(UcompOSArtifactProxy.MENU_ITEM_SELECT,contextMenu_handler);

Next, I’ll create an instance of a TemperatureReport class.  Let’s see what the TemperatureReport class is.

Back in our weather.fla Flash movie, we have a movie clip in the Library named TemperatureReport that is associated with a class of the same name (TemperatureReport).  The movie clip has on its main timeline a simple TextField with the instance name of _textField.

In our TemperatureReport class, we have a public setter function, set temperature, that accepts a value of type String and sets the value as the text property on our _textField instance.

Now, back in our main Weather class, we’ll add the TemperatureReport instance to the stage and position it at (0,5):

_temperatureReport = new TemperatureReport();
addChild(_temperatureReport);
_temperatureReport.y = 5
_temperatureReport.x = 0;

Next we are going to create an instance of the UcompOSHTMLProxy class:

_html = new UcompOSHTMLProxy();

Finally, we will call our private getWeather(); method.

A full discussion of the Weather Channel API is well outside the scope of this tutorial.  In our application, we are using an API to a service called Enrich to access the Weather Channel API.  The API to Enrich is installed in the UcompOS SDK in a class called EnrichComm but again, the implementation details of how we are actually retrieving the weather data in use here is irrelevant.

The specifications for our application are we want to be able to pass a zip code to indicate our location.  The Weather Channel API has a public method that translates a zip code into a weather station identifier.

Once we have our weather station identifier, we can then call the Weather Channel API and request the current weather and pass our station identifier.

The Weather Channel API will return an XML representation of the current weather and our handler will pick out the key values we are interested in using E4X (EcmaScript for XML).

We are interested in the current temperature, the icon that represents the current weather, and the actual official city name that our zip code is associated with.

Now, we will call the load() method on our Loader instance and pass the URL of the current weather icon and we are going to set the temperature property on our TemperatureReport instance to display the current temperature.

Next, we are going to create an XML model for the Context Menu that we want to appear on our weather widget that will let the user change to a different location, open the detailed current weather conditions for the location, or see the 10-day forecast for the location.

We will then pass our XML model to the setContextMenu(); method of our UcompOS Artifact instance.  Since we set the self property of our UcompOSArtifactProxy instance to true, any methods we call on our artifact instance will be applied to the widget itself.

When the user selects an option on the context menu of the widget, the handler invoked is
the contextMenu_handler method.

Artifact context menu handlers are returned an SDKEvent by the UcompOSSDK.  The SDKEvent objects data property is an Object with a label property and this label property is the value of the label on the context menu item the user selected.

We are going to employ a simple switch / case block to handle 3 different scenarios.

Scenario 1 is a change of location where we will call the prompt method of our UcompOSHTMLProxy instance and attach an event listener for the PROMPT_SUBMIT event.

Scenario 2 is the 10-day forecast which we will open up in a UcompOS Window and load the web site on the Weather Channel of the current location in scope.

And Scenario 3, the default in our switch / case block is the detailed local weather conditions for our current location in scope which we will also display in a UcompOS Window.

Going back to Scenario 1 for a moment, the prompt method of the UcompOSHTMLProxy actually causes the UcompOS Portal’s HTML Wrapper to dispatch a call to the JavaScript prompt() command and displays the text passed to it.

The value the user enters into the Prompt dialogue is returned to our event handler which in our case is a private method named newLocation_handler and the value the user entered is contained in the response property of the SDKEvevt object’s data property.

So we now have finished building our widget.

We are now ready to set up the application that will attach the widget to the UcompOS Portal as
a UcompOS Artifact.

We are going to build a simple HTML UcompOS application to accomplish this.  Our HTML application is the file Weather_Widget.html in our example package’s html folder.

We will insert the the UcompOS JavaScript SDK into our application.

In any UcompOS HTML application, any method named start(); is used as the initialization code for the application.

In our start(); method, we are first going to create an instance of UcompOSArtifactContainerProxy and then call its add() method.

We will make it a container of type “HBox” meaning we want the artifacts placed in it to be laid out horizontally.  The second parameter of the add(); method is an Array of style objects where each object has a styleProp and a newValue property.

We want the container positioned along the entire bottom portion of my UcompOS Portal and to do this we’ll set the bottom, right, and left styles to the values you see here.
Container

We have an image that we want displayed as the background image for the container that is at the URL you see indicated above.

Then, we are going to create an instance of UcompOSArtifactProxy and call its add(); method.

var artifact = new UcompOSArtifactProxy();
artifact.add(null,"http://desktop.ucompass.com/Weather_Widget/flash/weather.swf",0,0,false,true,{},container,true);

The URL of our artifact will be the URL of the Weather Widget we created earlier which of course is a SWF file.

A couple key things to point out about our artifact.  First, the sandbox parameter is set to true.

We want the Flash content that constitutes our widget to be sandboxed as we don’t have any need for it to participate in drag and drop activity with other flash content loaded into our portal implementation.

Also, notice for the container parameter of the artifact we are passing a reference to our UcompOSArtifactContainer we created.  This tells the UcompOS Portal to load the artifact into the specified artifact container.

Now, we’re ready to create a simple application manifest for our application.

Here is our manifest and the source code for the application will be the HTML application we just created.

ApplicationManifest

Finally, we’ll create our Dock Manifest for our UcompOS Portal implementation.

The <application/> tag here points to the manifest of our UcompOS application.
Manifest


A very important point to make here is that we have the background=”true” attribute set on our application tag.  What this is saying is immediately launch the application as a background process.  This causes the application to execute as soon as the user logs into the UcompOS Portal but the application is not placed on the application dock.

The UcompOS Portal can launch as many background processes as you need it to.

UcompOS Artifact Containers

In my last post a few minutes ago on UcompOS Artifacts, we learned that an artifact can be thought of as analogous to a desktop widget.

One of the parameters of the UcompOSArtifactProxy class’s add(); method is container which is of type UcompOSArtifactContainerProxy.

If the value of container is null, then the artifact instance is simply added to the UcompOS Portal interface positioned at the specified x, y coordinates where (0,0) is the upper-left origin of the main container.

However, an artifact container lets you arrange a group of related artifacts in a specific fashion.

There are currently three types of artifact containers: HBox, VBox, and Canvas – these names obviously are throwbacks to the Flex 3 container classes of the same name.

An artifact container is positioned and styled using CSS properties

Let’s see a simple example of the code behind the creation of a UcompOS artifact container.

The first step is to create an instance of UcompOSArtifactContainerProxy:

var container:UcompOSArtifactContainerProxy = new UcompOSArtifactContainerProxy();

Then we call the UcompOSArtifactContainerProxy‘s add() method.

Let’s look at the signature of add():

add(type:String, styles:Array = null):void;

type is a String that should either be of value HBox, VBox, or Canvas.  I plan to expand this to accept other properties such as HTileBox, VTileBox, etc.

styles is an Array of style objects where each style object has two properties: styleProp and newValue where styleProp is going to be a style that is available to the HBox, VBox, and Canvas containers in the Flex 3 framework.

An important note is that even though the UcompOS Portal is a Flex 4 application, the artifact containers are based on the Halo theme in the mx package.

Let’s see an actual code-based example:

var container:UcompOSArtifactContainerProxy = new UcompOSArtifactContainerProxy();
 
container.add("HBox",[{styleProp:"backgroundImage",
                       newValue:"http://desktop.ucompass.com/someImage.png"},
                       {styleProp:"bottom",newValue:0},{styleProp:"right",newValue:0}]);

The above would create an artifact container that was given a background image of the specific URL that was positioned permanently at the far lower right of the UcompOS Portal.

Then when we create our artifacts, we can pass the UcompOSArtifactContainerProxy instance as the container parameter and the artifact will automatically be placed into the container.  For instance:

var artifact:UcompOSArtifact = new UcompOSArtifact();
 
artifact.add("My Artifact",null,"http://desktop.ucompass.com/someImage.png",0,0,false,true,{},container);

Below is a simple example of an artifact container which has a transparent type background set with the backgroundImage style property that has 4 artifact instances attached to it.  This example comes from the Educator 2 application I am building on top of the UcompOS Rich Productivity Framework:

Artifact Container

Artifact Container

UcompOS Artifacts

In the UcompOS Rich Productivity Framework, there is a model that supports the creation of a type of utility called an Artifact which can be thought of as similar to a desktop widget where the desktop is the main interface of the UcompOS Portal main container.

An Artifact is created in a UcompOS application with the UcompOSArtifactProxy class that is built into the UcompOS SDK.

Artifacts can be flash-based (SWF) or image-based (PNG, GIF, or JPG).

Artifacts can then have functionality or behaviors attached to them.  Also, Flash-based artifacts can be UcompOS sub-applications so they can be Flash content that themselves have the UcompOS SDK implemented and can participate in transactions in the context of the UcompOS Continuum.

I am going to create a video tutorial today that shows how to build a UcompOS Artifact but for now, I’ll highlight in brief terms the code behind creating one.

The first step is creating a new instance of UcompOSArtifactProxy in a UcompOS application or sub application.  This of course occurs after the UcompOS SDK has been instantiated.

In ActionScript:

var artifact:UcompOSArtifactProxy = new UcompOSArtifactProxy();

In JavaScript:

var artifact = new UcompOSArtifactProxy();

Then you call the add(); method of the UcompOSArtifactProxy instance:

Let’s take a look at the signature of the add(); method:

add(label:String = null, imageBytes:ByteArray = null, imageSource:String = null, 
     x:uint = 0, y:uint = 0, draggable:Boolean = false, interactive:Boolean = true, 
    data:Object = null, container:UcompOSArtifactContainerProxy = null, 
    sandbox:Boolean = true):void

I’ll add that in the JavaScript SDK, there is no imageBytes paramater and the imageSource is how you articulate the SWF, JPG, GIF, or PNG content to be used for the artifact via its network URL.

The label property enables you to attach a label to the artifact.  As far as the source of the image that represents the artifact, it can be a ByteArray which at current will automatically be treated as an image-based artifact and the ByteArray would represent the ByteArray of a PNG, GIF, or JPG image.  If you don’t pass a ByteArray, you would pass the network URL of an image or SWF file.  If you pass both a ByteArray and a URL the ByteArray will take precedence.  If you pass neither a ByteArray or a URL, an IllegalOperationError will be thrown by the UcompOS SDK.

x and y let you position the artifact on the UcompOS Portal interface.  draggable indicates whether the user should be able to drag and drop the artifact on the UcompOS Portal interface.  interactive indicates if the artifact should accept mouseover, and click interactivity with the user.  When this property is true, the useHandCursor property on the item is implemented with a true value.

data lets you house a data Object on the artifact for convenience purposes so for instance if you have a double click handler attached to the artifact instance, when the double click event is dispatched, the data Object attached to the artifact is packaged into the event Object.

container is the Artifact Container that the artifact should be placed into.  I’ll be posting another blog this morning talking about UcompOS Artifact Containers and the UcompOSArtifactContainerProxy class.  If this value is null, then the artifact is placed on the UcompOS Portal interface with 0,0 being the upper-left origin points.

Finally, for SWF-based artifacts, sandbox represents whether the SWF content should be allowed to participate in drag and drop operations with other entities in the UcompOS Continuum where a value of false would allow this.

Note that all artifacts regardless of their sandbox property can be configured to accept drag and drop interactions.  But if you had something like a DataGrid in an artifact and you wanted to be able to drag and drop items from other SWF content into that DataGrid, you would need the sandbox property set to false.

UcompOS Artifacts

UcompOS Artifacts

In the example at left here, this represents an example of a number of artifacts that have been organized into an artifact container.

This is an example from my Educator 2 application I am building on top of the UcompOS Rich Productivity Framework.

The first artifact labeled “My Workspace” represents the user’s remote Educator 2 File System (where each user essentially has their own Content Management System interface).  The artifact labeled “Educator 1″ represents the user’s content area if their username also exists in our legacy Educator 1 product.

The remaining artifacts are all created with the aid of a class I’ll be discussing in a future posting called the UcompOSDesktopProxy which is able to talk to the end user’s desktop and each artifact represents a “mount point” on the end user’s computer.

In the case of these artifacts, they all have been implemented to support drag and drop behavior as well as double click behavior and I’ll showcase this functionality in an upcoming video tutorial I’ll create in the near future.

In this case here, when the user double clicks one of the artifacts, it launches a particular UcompOS application loaded into a UcompOS Window that showcases the file contents of each particular resource represented by the artifact.