Index: lams_common/src/flash/org/lamsfoundation/lams/common/comms/Communication.as =================================================================== diff -u --- lams_common/src/flash/org/lamsfoundation/lams/common/comms/Communication.as (revision 0) +++ lams_common/src/flash/org/lamsfoundation/lams/common/comms/Communication.as (revision 0c2296844646cad43d3baf2c2bbfe745367ef1cc) @@ -0,0 +1,129 @@ +import org.lamsfoundation.lams.common.util.* +import org.lamsfoundation.lams.common.comms.* +/** +* @ +* @author DI 05/04/05 +* @version 0.1 +* +*/ +class org.lamsfoundation.lams.common.comms.Communication { + private var _serverUrl:String; + private var errorCodes:Array; + private var url:String; //URL for server + private var ignoreWhite:Boolean; // + private var responseXML:XML; //XML object for server response + private var wddx:Wddx; //WDDX serializer/de-serializer + //TODO DI 11/04/05 Manage key/handler relationship - temp solution + private var requestCallBack:Function; + private var onXMLData:Function; + + /** + * Comms constructor + */ + function Communication(){ + trace('Communication.constructor'); + //Set up error codes used in communication with server + errorCodes=[1,2,3]; + ignoreWhite = true; + _serverUrl = ''; + wddx = new Wddx(); + } + + /** + * request a design from the server + * @param requestUrl URL on the server for request script + * @param handlerFn a callback function to call with the response object + */ + public function getRequest(requestUrl:String,handlerFn:Function){ + trace('Communication.getRequest()'); + //Create XML response object (deleting old XML if neccesary), assign data+load events and load XML + if(responseXML!=null){ + delete responseXML; + } + responseXML = new XML(); + + //Set ondata handler to validate data returned in XML object + responseXML.onData = function(src){ + if (src != undefined) { + //Check for login page + if(src.indexOf("j_security_login_page") != -1){ + //TODO DI 12/04/05 deal with error from session timeout/server error + trace('j_security_login_page received'); + this.onLoad(false); + }else { + //Data alright, must be a packet, allow onLoad event + this.parseXML(src); + this.loaded=true; + this.onLoad(true,this); + } + } else { + this.onLoad(false); + } + } + //Assign onLoad handler + responseXML.onLoad = Proxy.create(this,xmlOnLoad,responseXML); + + //TODO DI 11/04/05 Stub here for now until we have server implmenting new WDDX structure + //responseXML.load(_serverUrl+requestUrl); + responseXML.load('xml/sampleLearningDesign.xml'); + requestCallBack = handlerFn; + } + + /** + * XML onLoad handler called after data validation + * @param success XML load status + * @param wrappedPacketXML The wrapped XML response object + */ + private function xmlOnLoad(success:Boolean,wrappedPacketXML:XML){ + /* + * Validate the XML + * If No Errors THEN + * Use key to lookup the handler for the object + * fire callback handler passing in server response object + * ELSE + * deal with errors + * END IF + */ + trace('Communication.xmlOnLoad') + + //Load ok? + if(success){ + var responseObj:Object = wddx.deserialize(wrappedPacketXML); + //Call request handler function now that we have a response + //Match key with handler and call handler + requestCallBack(responseObj.messageValue); + }else { + //TODO DI 12/04/05 Handle onLoad error + trace('XML load failed!'); + } + } + + /** + * Send an object to the server + */ + public function sendObject(){ + + } + + /** + * @param obj WDDX Packet + */ + public function sendAndReceiveXML (obj:XML){ + + } + + /** + * returns current server URL + */ + function get serverUrl():String{ + return _serverUrl; + } + + + /** + * sets current server URL + */ + function set serverUrl(val:String){ + _serverUrl = val; + } +} \ No newline at end of file Index: lams_common/src/flash/org/lamsfoundation/lams/common/comms/Wddx.as =================================================================== diff -u --- lams_common/src/flash/org/lamsfoundation/lams/common/comms/Wddx.as (revision 0) +++ lams_common/src/flash/org/lamsfoundation/lams/common/comms/Wddx.as (revision 0c2296844646cad43d3baf2c2bbfe745367ef1cc) @@ -0,0 +1,424 @@ +/* +Wddx Serializer/Deserializer for Flash MX 2004 v1.0 +Coded to work with ActionScript 2.0 +-------------------------------------------------- + Created by + Branden Hall (bhall@waxpraxis.org) + Dave Gallerizzo (dgallerizzo@figleaf.com) + + Based on code by + Simeon Simeonov (simeons@allaire.com) + Nate Weiss (nweiss@icesinc.com) + + Version History: + 8/10/2000 - First created + 9/5/2000 - Minor bug fix to the deserializer + 9/15/2000 - Commented out Wddxserializetype creation in the + deserializer as they are not needed in most cases. + 9/21/2000 - Simplified the use of the deserializer. No longer need + to create the XML object yourself and the load and + onLoad methods are part of the Wddx class. + 9/30/2000 - Cleaned up code and removed load and onLoad methods. + Updated sample code. + 12/28/2000 - Added new duplicate method to WddxRecordset object + 1/10/2001 - Fixed problem where serialization caused text to always drop to lower + case. Thanks to Bill Tremblay for spotting this one! + 1/17/2001 - Minor update to the serializer code so that it properly adds text nodes. + Thanks for the catch from Carlos Mathews! + Also, the deserialization of primitive types now results in primitives + rather than instances of the object wrapper + 1/20/2001 - Quick fix to the deserializer for recordsets so that for..in loops can get + the elements of the recordset in the proper order. + 2/5/2001 - Fix to the string deserialization so that it handles special characters + properly, thanks to Spike Washburn for this one! + 11/9/2001 - Finished small optimizations, fixed encoding issues and fixed case preservation + issue. + 11/16/01 - (bkruse@macromedia.com)- put all Wddx classes in Object.Wddx namespace to fix + scoping issues. + 4/19/2002 - Fixed various small bugs with date and number serialization/deserialization + 4/19/2002 - Removed Wddx classes from Wddx namespace and put into _global namespace + 9/11/2003 - Converted to AS 2.0 by Jobe Makar. Divided into two classes: Wddx and WddxRecordset + Authors notes: + Serialization: + - Create an instance of the Wddx class + - Call the serialize method, passing it the object your wish + to serialize, it will return an XML object filled with the + serialized object. + + + Example: + var myXML:XML; + var foo:Wddx = new Wddx(); + myXML = foo.serialize(bar); + + + Deserializtion: + - Get the XML you want to deserialize + - Create an instance of the Wddx class + - Call the serialize method of your Wddx + object and pass it your XML. It will return + the deserialized object. + + Example: + var myXML:XML = new XML(); + // + // XML is loaded here + // + var foo:Wddx = new Wddx(); + var myObj:Object = foo.deserialize(myXML); + + + - Branden 9/30/00 + +*/ + +import org.lamsfoundation.lams.common.comms.* + +class org.lamsfoundation.lams.common.comms.Wddx { + // Build some tables needed for CDATA encoding + var et:Object = new Object(); + var etRev:Object = new Object(); + var at:Object = new Object(); + var atRev:Object = new Object(); + var timezoneString:String; + var preserveVarCase:Boolean = true; + var useTimezoneInfo:Boolean = true; + var packet:XML; + var wddxPacket:XMLNode; + var useTimeZoneInfo:String; + var tzOffset:Number; + function Wddx() { + for (var i = 0; i<256; ++i) { + if (i<32 && i != 9 && i != 10 && i != 13) { + var hex = i.toString(16); + if (hex.length == 1) { + hex = "0"+hex; + } + et[i] = ""; + at[i] = ""; + } else if (i<128) { + et[i] = chr(i); + at[i] = chr(i); + } else { + et[i] = "&#x"+i.toString(16)+";"; + etRev["&#x"+i.toString(16)+";"] = chr(i); + at[i] = "&#x"+i.toString(16)+";"; + atRev["&#x"+i.toString(16)+";"] = chr(i); + } + } + et[ord("<")] = "<"; + et[ord(">")] = ">"; + et[ord("&")] = "&"; + etRev["<"] = "<"; + etRev[">"] = ">"; + etRev["&"] = "&"; + at[ord("<")] = "<"; + at[ord(">")] = ">"; + at[ord("&")] = "&"; + at[ord("'")] = "'"; + at[ord("\"")] = """; + atRev["<"] = "<"; + atRev[">"] = ">"; + atRev["&"] = "&"; + atRev["'"] = "'"; + atRev["""] = "\""; + // Deal with timezone offsets + tzOffset = (new Date()).getTimezoneOffset(); + if (tzOffset>=0) { + timezoneString = "-"; + } else { + timezoneString = "+"; + } + timezoneString += Math.floor(Math.abs(tzOffset)/60)+":"+(Math.abs(tzOffset)%60); + } + // Serialize a Flash object + function serialize(rootObj) { + delete wddxPacket; + var temp:XML = new XML(); + packet = new XML(); + packet.appendChild(temp.createElement("wddxPacket")); + wddxPacket = packet.firstChild; + wddxPacket.attributes["version"] = "1.0"; + wddxPacket.appendChild(temp.createElement("header")); + wddxPacket.appendChild(temp.createElement("data")); + if (serializeValue(rootObj, wddxPacket.childNodes[1])) { + return packet; + } else { + return null; + } + } + // Determine the type of a Flash object and serialize it + function serializeValue(obj, node) { + var bSuccess:Boolean = true; + var val:String = obj.valueOf(); + var tzString = null; + var temp:XML = new XML(); + // null object + if (obj == null) { + node.appendChild(temp.createElement("null")); + // string object + } else if (typeof (val) == "string") { + serializeString(val, node); + // numeric objects (number or date) + } else if (typeof (val) == "number") { + // date object + if (typeof (obj.getTimezoneOffset) == "function") { + // deal with timezone offset if asked to + if (useTimeZoneInfo) { + tzString = timezoneString; + } + node.appendChild(temp.createElement("dateTime")); + node.lastChild.appendChild(temp.createTextNode(obj.getFullYear()+"-"+(obj.getMonth()+1)+"-"+obj.getDate()+"T"+obj.getHours()+":"+obj.getMinutes()+":"+obj.getSeconds()+tzString)); + // number object + } else { + node.appendChild((new XML()).createElement("number")); + node.lastChild.appendChild((new XML()).createTextNode(val)); + } + // boolean object + } else if (typeof (val) == "boolean") { + node.appendChild(temp.createElement("boolean")); + node.lastChild.attributes["value"] = val; + // actual objects + } else if (typeof (obj) == "object") { + // if it has a built in serializer, use it + if (typeof (obj.wddxSerialize) == "function") { + bSuccess = obj.wddxSerialize(this, node); + // array object + } else if (typeof (obj.join) == "function" && typeof (obj.reverse) == "function") { + node.appendChild(temp.createElement("array")); + node.lastChild.attributes["length"] = obj.length; + for (var i:Number = 0; bSuccess && i1) { + dataObj = ""; + var i:Number = 0; + for (i=0; i=0; i--) { + if (node.childNodes[i].nodeName.toLowerCase() == "field") { + var attr:Object = this.deserializeAttr(node.childNodes[i].attributes["name"]); + dataObj[attr].wddxSerializationType = "field"; + for (var j = (node.childNodes[i].childNodes.length-1); j>=0; j--) { + dataObj[attr][j] = new Object(); + var tempObj:Object = this.deserializeNode(node.childNodes[i].childNodes[j]); + dataObj.setField(j, attr, tempObj); + } + } + } + // dataObj.wddxSerializationType = "recordset"; + return dataObj; + } + } + function deserializeAttr(attr) { + var max:Number = attr.length; + var i:Number = 0; + var char:String; + var output:String = ""; + while (i0) { + var val; + if (typeof (val=arguments[0].valueOf()) == "boolean") { + // Case preservation flag is provided as 1st argument + preserveFieldCase = arguments[0]; + } else { + // First argument is the array of column names + var cols = arguments[0]; + // Second argument could be the length or the preserve case flag + var nLen = 0; + if (arguments.length>1) { + if (typeof (val=arguments[1].valueOf()) == "boolean") { + // Case preservation flag is provided as 2nd argument + preserveFieldCase = arguments[1]; + } else { + // Explicitly specified recordset length + nLen = arguments[1]; + if (arguments.length>2) { + // Case preservation flag is provided as 3rd argument + preserveFieldCase = arguments[2]; + } + } + } + for (var i:Number = 0; i0) { + colNamesList += ","; + } + colNamesList += col; + } + } + var nRows:Number = this.getRowCount(); + node.appendChild((new XML()).createElement("recordset")); + node.lastChild.attributes["rowCount"] = nRows; + node.lastChild.attributes["fieldNames"] = colNamesList; + var bSuccess:Boolean = true; + for (i=0; bSuccess && i= 0; i--) { + observersSnapshot[i].update(this, infoObj); + } + } + + /** + * Removes all observers from the observer list. + */ + public function clearObservers():Void { + observers = new Array(); + } + + /** + * Indicates that the subject has changed. + */ + private function setChanged():Void { + changed = true; + } + + /** + * Indicates that the subject has either not changed or + * has notified its observers of the most recent change. + */ + private function clearChanged():Void { + changed = false; + } + + /** + * Checks if the subject has changed. + * + * @return true if the subject has changed, as determined by setChanged(). + */ + public function hasChanged():Boolean { + return changed; + } + + /** + * Returns the number of observers in the observer list. + * + * @return An integer: the number of observers for this subject. + */ + public function countObservers():Number { + return observers.length; + } +} \ No newline at end of file Index: lams_common/src/flash/org/lamsfoundation/lams/common/util/Observer.as =================================================================== diff -u --- lams_common/src/flash/org/lamsfoundation/lams/common/util/Observer.as (revision 0) +++ lams_common/src/flash/org/lamsfoundation/lams/common/util/Observer.as (revision 0c2296844646cad43d3baf2c2bbfe745367ef1cc) @@ -0,0 +1,16 @@ +import org.lamsfoundation.lams.common.util.Observable; + +/** + * The interface that must be implemented by all observers of an + * Observable object. + */ +interface org.lamsfoundation.lams.common.util.Observer { + /** + * Invoked automatically by an observed object when it changes. + * + * @param o The observed object (an instance of Observable). + * @param infoObj An arbitrary data object sent by + * the observed object. + */ + public function update(o:Observable, infoObj:Object):Void; +} \ No newline at end of file Index: lams_common/src/flash/org/lamsfoundation/lams/common/util/Proxy.as =================================================================== diff -u --- lams_common/src/flash/org/lamsfoundation/lams/common/util/Proxy.as (revision 0) +++ lams_common/src/flash/org/lamsfoundation/lams/common/util/Proxy.as (revision 0c2296844646cad43d3baf2c2bbfe745367ef1cc) @@ -0,0 +1,17 @@ +import org.lamsfoundation.lams.common.util.* +class org.lamsfoundation.lams.common.util.Proxy { + public static function create (oTarget:Object, fFunction:Function):Function { + var parameters:Array = new Array (); + var l = arguments.length; + + for (var i = 2; i < l; i++) { + parameters[i - 2] = arguments[i]; + } + + var fProxy:Function = function (){ + var totalParameters:Array = arguments.concat (parameters); + fFunction.apply (oTarget, totalParameters); + }; + return fProxy; + } +} Index: lams_common/src/flash/org/lamsfoundation/lams/common/ws/Workspace.as =================================================================== diff -u --- lams_common/src/flash/org/lamsfoundation/lams/common/ws/Workspace.as (revision 0) +++ lams_common/src/flash/org/lamsfoundation/lams/common/ws/Workspace.as (revision 0c2296844646cad43d3baf2c2bbfe745367ef1cc) @@ -0,0 +1,39 @@ +import org.lamsfoundation.lams.common.ws.* +import org.lamsfoundation.lams.authoring.* + +/** +* Canvas is +*/ +class org.lamsfoundation.lams.common.ws.Workspace { + //Model + private var workspaceModel:WorkspaceModel; + //View + private var workspaceView:WorkspaceView; + + /** + * workspace Constructor + * + * @param target_mc Target clip for attaching view + */ + public function Workspace (target_mc:MovieClip,depth:Number,x:Number,y:Number,w:Number,h:Number){ + //trace('workspace.constructor') + //Create the model. + workspaceModel = new WorkspaceModel(); + + //Create the authoring view and register with model + workspaceView = new WorkspaceView(workspaceModel, undefined,target_mc,depth,x,y,w,h); + workspaceModel.addObserver(workspaceView); + } + + + public function userSelectItem(id:Number){ + trace('Workspace.userSelectItem'); + //todo DI 07/04/05 write code user design selection, just a stub at the moment, calls itemSelected + itemSelected(1); + } + + private function itemSelected(designId:Number){ + //Design has been chosen, get Canvas to open design + Application.getInstance().getCanvas().openDesignById(designId); + } +} Index: lams_common/src/flash/org/lamsfoundation/lams/common/ws/WorkspaceController.as =================================================================== diff -u --- lams_common/src/flash/org/lamsfoundation/lams/common/ws/WorkspaceController.as (revision 0) +++ lams_common/src/flash/org/lamsfoundation/lams/common/ws/WorkspaceController.as (revision 0c2296844646cad43d3baf2c2bbfe745367ef1cc) @@ -0,0 +1,18 @@ +import org.lamsfoundation.lams.common.ws.CanvasModel +import org.lamsfoundation.lams.common.mvc.* +import org.lamsfoundation.lams.common.util.* + +/* +* Makes changes to the Canvas Authoring model's data based on user input. +*/ +class org.lamsfoundation.lams.common.ws.WorkspaceController extends AbstractController { + /** + * Constructor + * + * @param cm The model to modify. + */ + public function WorkspaceController (cm:Observable) { + super (cm); + } + +} Index: lams_common/src/flash/org/lamsfoundation/lams/common/ws/WorkspaceModel.as =================================================================== diff -u --- lams_common/src/flash/org/lamsfoundation/lams/common/ws/WorkspaceModel.as (revision 0) +++ lams_common/src/flash/org/lamsfoundation/lams/common/ws/WorkspaceModel.as (revision 0c2296844646cad43d3baf2c2bbfe745367ef1cc) @@ -0,0 +1,12 @@ +import org.lamsfoundation.lams.common.util.Observable; +import org.lamsfoundation.lams.common.ws.*; +/* +* Model for the Canvas +*/ +class org.lamsfoundation.lams.common.ws.WorkspaceModel extends Observable { + /* + * Constructor. + */ + public function WorkspaceModel (){ + } +} Index: lams_common/src/flash/org/lamsfoundation/lams/common/ws/WorkspaceView.as =================================================================== diff -u --- lams_common/src/flash/org/lamsfoundation/lams/common/ws/WorkspaceView.as (revision 0) +++ lams_common/src/flash/org/lamsfoundation/lams/common/ws/WorkspaceView.as (revision 0c2296844646cad43d3baf2c2bbfe745367ef1cc) @@ -0,0 +1,50 @@ +import org.lamsfoundation.lams.common.util.* +import org.lamsfoundation.lams.common.ws.* +import org.lamsfoundation.lams.common.mvc.* +/** +Authoring view for the canvas +*/ +class org.lamsfoundation.lams.common.ws.WorkspaceView extends AbstractView +{ + //Canvas clip + private var _workspace_mc:MovieClip; + + /* + * Constructor + */ + public function WorkspaceView (m:Observable, c:Controller,target_mc:MovieClip,depth:Number,x:Number,y:Number,w:Number,h:Number){ + // Invoke superconstructor, which sets up MVC relationships. + // This view has no user inputs, so no controller is required. + super (m, c); + // + createWorkspace (target_mc,depth,x,y,w,h); + } + /* + * Creates workspace movie clip + * + * @param target_mc The clip in which to create the movie clip. + * @param depth The depth at which to create the movie clip. + * @param x The movie clip's horizontal position in target. + * @param y The movie clip's vertical position in target. + */ + public function createWorkspace (target_mc:MovieClip,depth:Number,x:Number,y:Number,w:Number,h:Number):Void + { + _workspace_mc = target_mc.attachMovie ("Workspace", "workspace_mc", depth); + _workspace_mc._x = x; + _workspace_mc._y = y; + _workspace_mc.bg_mc._width = w; + _workspace_mc.bg_mc._height = h; + //Workspace initially invisible + _workspace_mc._visible = false; + } + + /* + * Updates state of the canvas, called by Canvas Model + * + * @param o The model object that is broadcasting an update. + * @param infoObj object with details of changes to model + */ + public function update (o:Observable,infoObj:Object):Void { + //Go through update object and update mc with visual changes required + } +}