Author: Christian Lopes
Date: 2011-01-04 16:11:24 -0800 (Tue, 04 Jan 2011)
New Revision: 23297

Added:
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/error/
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/error/CWError.as
Modified:
   cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test1.graphml
   cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test2.xgmml
   cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js
   
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/ExternalObjectConverterTest.as
   
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/XGMMLConverterTest.as
   
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/view/render/ImageCacheTest.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/AddDataFieldCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DrawGraphCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/ExportNetworkCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/RemoveItemsCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/UpdateDataCommand.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/GraphProxy.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/ExternalObjectConverter.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/methods/error.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/ErrorCodes.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/ImageCache.as
Log:
Improved error handling to add codes.
XGMML now accepts both "0"|"1" and "true"|"false" as boolean types.
CW now throws errors when trying to draw/update a network with invalid data 
values (node/edge ID has to be a string from now on).
Fixed bugs:
    - #2447: Date attributes exported as null to XGMML
    - #2445: Wrong data field types when using JavaScript objects as the 
network data
    - #2444: Null "number" values converted to 0 when updating data

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test1.graphml
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test1.graphml        
2011-01-04 20:59:57 UTC (rev 23296)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test1.graphml        
2011-01-05 00:11:24 UTC (rev 23297)
@@ -1,8 +1,10 @@
 <graphml>
   <key id="weight" for="node" attr.name="weight" attr.type="double"/>
+  <key id="ranking" for="node" attr.name="ranking" attr.type="int"/>
   <key id="type" for="node" attr.name="type" attr.type="string"/>
   <key id="shape" for="node" attr.name="shape" attr.type="string"/>
   <key id="label" for="node" attr.name="label" attr.type="string"/>
+  <key id="special" for="node" attr.name="special" attr.type="boolean"/>
   
   <key id="type" for="edge" attr.name="type" attr.type="string"/>
   <key id="interaction" for="edge" attr.name="interaction" attr.type="string">
@@ -15,33 +17,43 @@
   <graph edgedefault="undirected">  
     <node id="1">
       <data key="weight">0.45</data>
+      <data key="ranking">1</data>
       <data key="label">n1</data>
       <data key="type">1</data>
       <data key="shape">ELLIPSE</data>
+      <data key="special">false</data>
     </node>
     <node id="2">
       <data key="weight">0.22</data>
+      <data key="ranking">2</data>
       <data key="label">n2</data>
       <data key="type">2</data>
       <data key="shape">TRIANGLE</data>
+      <data key="special">true</data>
     </node>
     <node id="3">
       <data key="weight">0.09</data>
+      <data key="ranking">3</data>
       <data key="label">n3</data>
       <data key="type">1</data>
       <data key="shape">OCTAGON</data>
+      <data key="special">false</data>
     </node>
     <node id="4">
       <data key="weight">0.03</data>
+      <data key="ranking">4</data>
       <data key="label">n4</data>
       <data key="type">1</data>
       <data key="shape">DIAMOND</data>
+      <data key="special">false</data>
     </node>
     <node id="5">
       <data key="weight">0.10</data>
+      <data key="ranking">5</data>
       <data key="label">n5</data>
       <data key="type">3</data>
       <data key="shape">PARALLELOGRAM</data>
+      <data key="special">false</data>
     </node>
  
     <edge target="1" source="2" directed="true">

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test2.xgmml
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test2.xgmml  
2011-01-04 20:59:57 UTC (rev 23296)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test2.xgmml  
2011-01-05 00:11:24 UTC (rev 23297)
@@ -4,31 +4,43 @@
   <att type="real" name="GRAPH_VIEW_ZOOM" value="1"/>
   <att type="real" name="GRAPH_VIEW_CENTER_X" value="0"/>
   <att type="real" name="GRAPH_VIEW_CENTER_Y" value="0"/>
+  
   <node id="101" weight="0.45" label="A01">
     <att type="string" name="type" value="1"/>
+    <att type="integer" name="ranking" value="1"/>
     <att type="string" name="shape" value="ELLIPSE"/>
+    <att type="boolean" name="special" value="1"/>
     <graphics x="387.25" y="304" fill="#cccccc" outline="#333333" w="36" 
cy:nodeTransparency="0.8" cy:nodeLabelFont="SansSerif-0-11" type="ELLIPSE" 
h="36" width="1"/>
   </node>
   <node id="102" weight="0.22" label="A02">
     <att type="string" name="type" value="2"/>
+    <att type="integer" name="ranking" value="2"/>
     <att type="string" name="shape" value="TRIANGLE"/>
+    <att type="boolean" name="special" value="0"/>
     <graphics x="324.85" y="340" fill="#cccccc" outline="#333333" 
w="22.857142857142854" cy:nodeTransparency="0.8" 
cy:nodeLabelFont="SansSerif-0-11" type="ELLIPSE" h="22.857142857142854" 
width="1"/>
   </node>
   <node id="103" weight="0.09" label="A03">
     <att type="string" name="type" value="2"/>
+    <att type="integer" name="ranking" value="3"/>
     <att type="string" name="shape" value="OCTAGON"/>
+    <att type="boolean" name="special" value="0"/>
     <graphics x="324.85" y="412" fill="#cccccc" outline="#333333" 
w="15.428571428571429" cy:nodeTransparency="0.8" 
cy:nodeLabelFont="SansSerif-0-11" type="ELLIPSE" h="15.428571428571429" 
width="1"/>
   </node>
   <node id="104" weight="0.03" label="A04">
     <att type="string" name="type" value="1"/>
+    <att type="integer" name="ranking" value="4"/>
     <att type="string" name="shape" value="DIAMOND"/>
+    <att type="boolean" name="special" value="0"/>
     <graphics x="387.25" y="448" fill="#cccccc" outline="#333333" w="12" 
cy:nodeTransparency="0.8" cy:nodeLabelFont="SansSerif-0-11" type="ELLIPSE" 
h="12" width="1"/>
   </node>
   <node id="105" weight="0.1" label="A05">
     <att type="string" name="type" value="3"/>
+    <att type="integer" name="ranking" value="5"/>
     <att type="string" name="shape" value="PARALLELOGRAM"/>
+    <att type="boolean" name="special" value="0"/>
     <graphics x="449.6" y="339.95" fill="#cccccc" outline="#333333" w="16" 
cy:nodeTransparency="0.8" cy:nodeLabelFont="SansSerif-0-11" type="ELLIPSE" 
h="16" width="1"/>
   </node>
+  
   <edge id="1" target="101" source="102" weight="0.4" label="101 (25) 102">
     <att type="string" name="directed" value="true"/>
     <att type="string" name="sourceArrowShape" value="diamond"/>

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js   2011-01-04 
20:59:57 UTC (rev 23296)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js   2011-01-05 
00:11:24 UTC (rev 23297)
@@ -998,13 +998,13 @@
        var ids = [];
        
        // 1: Update all nodes and edges (same data):
-        var data = { weight: 1, new_attr: "ignore it!" };
+        var data = { weight: 1/*, new_attr: "ignore it!"*/ };
         vis.updateData(data);
        
         all = vis.nodes().concat(vis.edges());
         $.each(all, function(i, el) {
                same(el.data.weight, 1, "weight updated ("+el.data.id+")");
-               same(el.data.new_attr, undefined, "New attribute ignored 
("+el.data.id+")");
+//             same(el.data.new_attr, undefined, "New attribute ignored 
("+el.data.id+")");
        });
         
         // 2: Update more than one node and edge at once (by ID - ALL groups - 
same data):
@@ -1086,6 +1086,31 @@
                        ok(el.data.label != n.data.label, "Other nodes or edges 
label NOT updated ("+id+")");
                }
        });
+        
+        var id = nodes[0].data.id;
+        
+        // 6: Update a field with type 'number' to null (should work):
+        vis.updateData("nodes", [id], { weight: null });
+        ok(vis.node(id).data.weight === null, "Node weight should be null");
+        
+        // Test Errors:
+        var errId;
+        var onError = function(evt) {console.log(evt.value.id);
+               errId = evt.value.id;
+        }
+        vis.addListener("error", onError);
+        
+        // 7: Update a field with type 'int' to null (should set 0 as default):
+        vis.updateData("nodes", [id], { ranking: null });
+        same(errId, "dat001", "node.data.ranking (error: int type with null 
value)");
+        errId = null;
+        
+        // 8: Update a field with type 'boolean' to null (should set false as 
default):
+        vis.updateData("nodes", [id], { special: null });
+        same(errId, "dat001", "node.data.special (error: boolean type with 
null value)");
+        errId = null;
+        
+        vis.removeListener("error", onError);
     });
     
     test("Get Data Schema", function() {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/AddDataFieldCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/AddDataFieldCommand.as
      2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/AddDataFieldCommand.as
      2011-01-05 00:11:24 UTC (rev 23297)
@@ -31,6 +31,7 @@
     import flare.data.DataUtil;
     
     import org.cytoscapeweb.ApplicationFacade;
+    import org.cytoscapeweb.model.error.CWError;
     import org.cytoscapeweb.model.methods.error;
     import org.cytoscapeweb.util.Groups;
     import org.puremvc.as3.interfaces.INotification;
@@ -68,7 +69,7 @@
                 if (added) 
sendNotification(ApplicationFacade.GRAPH_DATA_CHANGED);
             } catch (err:Error) {
                 trace("[ERROR]: AddDataFieldCommand.execute: " + 
err.getStackTrace());
-                error(err.message, err.errorID, err.name, err.getStackTrace());
+                error(err);
             }
         }
     }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DrawGraphCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DrawGraphCommand.as
 2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DrawGraphCommand.as
 2011-01-05 00:11:24 UTC (rev 23297)
@@ -29,9 +29,8 @@
 */
 package org.cytoscapeweb.controller {
     
-    import flash.utils.setTimeout;
-    
     import org.cytoscapeweb.model.data.VisualStyleVO;
+    import org.cytoscapeweb.model.error.CWError;
     import org.cytoscapeweb.model.methods.error;
     import org.cytoscapeweb.view.GraphMediator;
     import org.cytoscapeweb.view.components.GraphView;
@@ -84,10 +83,9 @@
        
                        graphMediator.drawGraph();
                    }
-                
             } catch (err:Error) {
                 trace("[ERROR]: DrawGraphCommand.execute: " + 
err.getStackTrace());
-                error(err.message, err.errorID, err.name, err.getStackTrace());
+                error(err);
             }
         }
     }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/ExportNetworkCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/ExportNetworkCommand.as
     2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/ExportNetworkCommand.as
     2011-01-05 00:11:24 UTC (rev 23297)
@@ -62,7 +62,7 @@
                 graphProxy.export(data, url, window);
                 
             } catch (err:Error) {
-                error(err.message, err.errorID, err.name, err.getStackTrace());
+                error(err);
             }
         }
     }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/RemoveItemsCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/RemoveItemsCommand.as
       2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/RemoveItemsCommand.as
       2011-01-05 00:11:24 UTC (rev 23297)
@@ -64,7 +64,7 @@
                 
             } catch (err:Error) {
                 trace("[ERROR]: RemoveItemsCommand.execute: " + 
err.getStackTrace());
-                error(err.message, err.errorID, err.name, err.getStackTrace());
+                error(err);
             }
         }
     }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/UpdateDataCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/UpdateDataCommand.as
        2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/UpdateDataCommand.as
        2011-01-05 00:11:24 UTC (rev 23297)
@@ -69,7 +69,7 @@
                 sendNotification(ApplicationFacade.GRAPH_DATA_CHANGED);
             } catch (err:Error) {
                 trace("[ERROR]: UpdateDataCommand.execute: " + 
err.getStackTrace());
-                error(err.message, err.errorID, err.name, err.getStackTrace());
+                error(err);
             }
         }
     }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/GraphProxy.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/GraphProxy.as    
2011-01-04 20:59:57 UTC (rev 23296)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/GraphProxy.as    
2011-01-05 00:11:24 UTC (rev 23297)
@@ -48,8 +48,8 @@
        import mx.utils.StringUtil;
        
        import org.cytoscapeweb.ApplicationFacade;
-       import org.cytoscapeweb.model.converters.GraphMLConverter;
        import org.cytoscapeweb.model.converters.ExternalObjectConverter;
+       import org.cytoscapeweb.model.converters.GraphMLConverter;
        import org.cytoscapeweb.model.converters.SIFConverter;
        import org.cytoscapeweb.model.converters.XGMMLConverter;
        import org.cytoscapeweb.model.data.ConfigVO;
@@ -421,12 +421,10 @@
                         var f:DataField = schema.getFieldByName(k);
                         if (f != null) {
                             var v:* = data[k];
-                            v = DataUtil.parseValue(v, f.type);
-                            
-                            if (isNaN(v) && (f.type === DataUtil.INT || f.type 
=== DataUtil.NUMBER))
-                                throw new Error("Attempt to convert 
'"+data[k]+"' to NUMBER while updating the '"+k+"' data field");
-                            
+                            v = ExternalObjectConverter.normalizeDataValue(v, 
f.type, f.defaultValue);
                             ds.data[k] = v;
+                        } else {
+                            throw new Error("Cannot update data: there is no 
Data Field for '"+k+".");
                         }
                     }
                 }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/ExternalObjectConverter.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/ExternalObjectConverter.as
    2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/ExternalObjectConverter.as
    2011-01-05 00:11:24 UTC (rev 23297)
@@ -44,6 +44,8 @@
     import flash.utils.IDataInput;
     import flash.utils.IDataOutput;
     
+    import org.cytoscapeweb.model.error.CWError;
+    import org.cytoscapeweb.util.ErrorCodes;
     import org.cytoscapeweb.util.Groups;
     import org.cytoscapeweb.util.Utils;
     
@@ -111,7 +113,7 @@
             var nodes:Array = [], edges:Array = [];
             var id:String, sid:String, tid:String;
             var obj:Object;
-            var f:DataField;
+            var f:DataField, type:int, defValue:*, mandatoryDefValue:*;
             var directed:Boolean = false;
             
             if (network == null) network = {};
@@ -140,7 +142,18 @@
                     } else {
                         f = schema.getFieldByName(name);
                         if (f == null) {
-                            schema.addField(new DataField(name, obj[TYPE], 
obj[DEF_VALUE], name));
+                            type = toCW_Type(obj[TYPE]);
+                            
+                            // Some types always require a default value, 
because they don't accept null.
+                            switch(type) {
+                                case DataUtil.INT: mandatoryDefValue = 0; 
break;
+                                case DataUtil.BOOLEAN: mandatoryDefValue = 
false; break;
+                                default: mandatoryDefValue = null;
+                            }
+                            
+                            defValue = normalizeDataValue(obj[DEF_VALUE], 
type, mandatoryDefValue);
+                            
+                            schema.addField(new DataField(name, type, 
defValue, name));
                         }
                     }
                 }
@@ -157,24 +170,24 @@
             
             // Nodes
             for each (obj in extNodesData) {
-                id = "" + obj[ID]; // always convert IDs to String!
                 normalizeData(obj, nodeSchema)
+                id = obj[ID];
                 lookup[id] = obj;
                 nodes.push(obj);
             }
             
             // Edges
             for each (obj in extEdgesData) {
-                id  = "" + obj[ID];
-                sid = "" + obj[SOURCE];
-                tid = "" + obj[TARGET];
+                normalizeData(obj, edgeSchema);
+                id  = obj[ID];
+                sid = obj[SOURCE];
+                tid = obj[TARGET];
                 
                 if (!lookup.hasOwnProperty(sid))
                     throw new Error("Edge "+id+" references unknown node: 
"+sid);
                 if (!lookup.hasOwnProperty(tid))
                     throw new Error("Edge "+id+" references unknown node: 
"+tid);
-                
-                normalizeData(obj, edgeSchema) 
+
                 edges.push(obj);
             }
             
@@ -285,9 +298,7 @@
             return obj;
         }
         
-        // ========[ PRIVATE METHODS 
]==============================================================
-        
-        private static function normalizeData(data:Object, 
schema:DataSchema):void {
+        public static function normalizeData(data:Object, 
schema:DataSchema):void {
             var name:String, field:DataField, value:*;
             
             // Set default values, if necessary:
@@ -295,7 +306,7 @@
                 field = schema.getFieldAt(i);
                 name = field.name;
                 value = data[name];
-                if (value === undefined) data[name] = field.defaultValue;
+                data[name] = normalizeDataValue(value, field.type, 
field.defaultValue);
             }
             
             // Look for missing fields:
@@ -307,6 +318,36 @@
             }
         }
         
+        public static function normalizeDataValue(value:*, type:int, 
defValue:*=undefined):* {
+            // Set default value, if necessary:
+            if (value === undefined) value = defValue !== undefined ? defValue 
: null;
+
+            // Validate and normalize numeric values:
+            if (type === DataUtil.INT) {
+                if (value == null || isNaN(value))
+                    throw new CWError("Invalid data type ("+(typeof value)+") 
for field of type 'int': " + value,
+                                      ErrorCodes.INVALID_DATA_CONVERSION);
+            } else if (type === DataUtil.NUMBER) {
+                if (value === undefined) value = null;
+                
+                if (value != null && isNaN(value))
+                    throw new CWError("Invalid data type ("+(typeof value)+") 
for field of type 'number': " + value,
+                                      ErrorCodes.INVALID_DATA_CONVERSION);
+            } else if (type === DataUtil.BOOLEAN) {
+                if (! (value is Boolean))
+                    throw new CWError("Invalid data type ("+(typeof value)+") 
for field of type 'boolean': " + value,
+                                      ErrorCodes.INVALID_DATA_CONVERSION);
+            } else if (type === DataUtil.STRING) {
+                if (value != null && !(value is String))
+                    throw new CWError("Invalid data type ("+(typeof value)+") 
for field of type 'string': " + value,
+                                      ErrorCodes.INVALID_DATA_CONVERSION);
+            }
+            
+            return value
+        }
+        
+        // ========[ PRIVATE METHODS 
]==============================================================
+        
         // -- static helpers --------------------------------------------------
         
         private static function toCW_Type(type:String):int {
@@ -326,8 +367,8 @@
                 case DataUtil.INT:      return INT;
                 case DataUtil.BOOLEAN:  return BOOLEAN;
                 case DataUtil.NUMBER:   return NUMBER;
+                case DataUtil.STRING:   return STRING;
                 case DataUtil.DATE:
-                case DataUtil.STRING:   return STRING;
                 case DataUtil.OBJECT:
                 default:                return OBJECT;
             }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
     2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
     2011-01-05 00:11:24 UTC (rev 23297)
@@ -409,7 +409,7 @@
                 name = attribute.name().toString();
                 field = schema.getFieldByName(name);
                 if (field != null)
-                    data[name] = DataUtil.parseValue(attribute[0].toString(), 
field.type);
+                    data[name] = parseAttValue(attribute[0].toString(), 
field.type);
             }
             
             // get "att" tags:
@@ -446,14 +446,14 @@
                         parseAtt(innerAtt, schema, innerData);
                     } else {
                         var innerType:int = 
toCW_Type(innera...@[type].tostring());
-                        innerData = DataUtil.parseValue(innera...@[value], 
innerType);
+                        innerData = parseAttValue(innera...@[value], 
innerType);
                     }
                     arr.push(innerData);
                 }
                 data[name] = arr;
             } else {
                 // Otherwise, just add the single att data:
-                data[name] = DataUtil.parseValue(a...@[value], type);
+                data[name] = parseAttValue(a...@[value], type);
             }
         }
 
@@ -570,14 +570,14 @@
         private function addAtt(xml:XML, name:String, schema:DataSchema, 
value:*):void {
             var field:DataField = schema.getFieldByName(name);
             var dataType:int = field != null ? field.type : 
Utils.dataType(value);
-            var type:String = fromCW_Type(dataType); // XGMML type
+            var type:String = fromCW_Type(dataType, value); // XGMML type
             
             var att:XML = <{ATTRIBUTE}/>;
             a...@[type] = type;
             if (name != null) a...@[name] = name;
 
             // Add <att> tags data:
-            if (typeof value === "object") {
+            if (typeof value === "object" && !(value is Date)) {
                 // If it is an object or array, the att value is a list of 
other att tags:
                 for (var k:String in value) {
                     var entryValue:* = value[k];
@@ -655,14 +655,28 @@
                     vp.vizMapper = dm;
                 }
 
-                value = parseValue(propName, value);
+                value = parseGraphicsValue(propName, value);
                 dm.addEntry(id, value);
             }
         }
         
         // -- static helpers --------------------------------------------------
         
-        internal static function parseValue(propName:String, value:*):* {
+        internal static function parseAttValue(value:String, type:int):* {
+            var val:*;
+            
+            if (type === DataUtil.BOOLEAN) {
+                // XGMML's boolean type is 0 or 1, but Cytoscape uses 
true/false, so let's
+                // accept both:
+                val = value != null && (value === TRUE || value.toLowerCase() 
=== "true"); 
+            } else {
+                val = DataUtil.parseValue(value, type);
+            }
+            
+            return val;
+        }
+        
+        internal static function parseGraphicsValue(propName:String, 
value:*):* {
             if (value != null) {
                 switch (propName) {
                     case VisualProperties.EDGE_SOURCE_ARROW_SHAPE:
@@ -713,6 +727,7 @@
             switch (type) {
                 case INTEGER: return DataUtil.INT;
                 case REAL:    return DataUtil.NUMBER;
+                case BOOLEAN: return DataUtil.BOOLEAN;
                 case LIST:    return DataUtil.OBJECT;
                 case STRING:
                 default:      return DataUtil.STRING;
@@ -722,7 +737,9 @@
         /**
          * Converts from Flare data types to XGMML types.
          */
-        private static function fromCW_Type(type:int):String {         
+        private static function fromCW_Type(type:int, value:*=null):String {   
        
+            if (value is Date) return STRING;
+
             switch (type) {
                 case DataUtil.INT:      return INTEGER;
                 case DataUtil.NUMBER:   return REAL;

Added: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/error/CWError.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/error/CWError.as 
                        (rev 0)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/error/CWError.as 
2011-01-05 00:11:24 UTC (rev 23297)
@@ -0,0 +1,41 @@
+/*
+  This file is part of Cytoscape Web.
+  Copyright (c) 2009, The Cytoscape Consortium (www.cytoscape.org)
+
+  The Cytoscape Consortium is:
+    - Agilent Technologies
+    - Institut Pasteur
+    - Institute for Systems Biology
+    - Memorial Sloan-Kettering Cancer Center
+    - National Center for Integrative Biomedical Informatics
+    - Unilever
+    - University of California San Diego
+    - University of California San Francisco
+    - University of Toronto
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+package org.cytoscapeweb.model.error {
+    public class CWError extends Error {
+        
+        public var code:String;
+        
+        public function CWError(message:String="", code:String=null) {
+            super(message);
+            this.code = code;
+            this.name = "Cytoscape Web Error";
+        }
+    }
+}
\ No newline at end of file

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/methods/error.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/methods/error.as 
2011-01-04 20:59:57 UTC (rev 23296)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/methods/error.as 
2011-01-05 00:11:24 UTC (rev 23297)
@@ -29,14 +29,23 @@
 */
 package org.cytoscapeweb.model.methods {
     import org.cytoscapeweb.ApplicationFacade;
+    import org.cytoscapeweb.model.error.CWError;
     import org.puremvc.as3.patterns.observer.Notification;
 
     /**
      * Gets a resource bundle string.
      */
-    public function error(msg:String, id:*=null, name:String=null, 
stackTrace:String=null):void {
+    public function error(err:Error):void {
+        var id:* = (err is CWError) ? CWError(err).code : err.errorID;
+        id = id != null ? ""+id : null;
+        
+        var msg:String = err.message;
+        var name:String = err.name;
+        var stackTrace:String = err.getStackTrace();
+        
         var b:Object = { msg: msg, id: id, name: name, stackTrace: stackTrace 
};
         var n:Notification = new Notification(ApplicationFacade.ERROR, b);
+        
         ApplicationFacade.getInstance().notifyObservers(n);
     }
 }
\ No newline at end of file

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/ErrorCodes.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/ErrorCodes.as     
2011-01-04 20:59:57 UTC (rev 23296)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/ErrorCodes.as     
2011-01-05 00:11:24 UTC (rev 23297)
@@ -36,6 +36,7 @@
         
         // ========[ CONSTANTS 
]====================================================================
 
+        public static const INVALID_DATA_CONVERSION:String = "dat001";
         public static const BROKEN_IMAGE:String = "img001";
 
         // ========[ CONSTRUCTOR 
]==================================================================

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as   
    2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as   
    2011-01-05 00:11:24 UTC (rev 23297)
@@ -136,7 +136,7 @@
                     else
                         return ExternalInterface.call(functionName, argument);
                 } catch (err:Error) {
-                    error(err.message, err.errorID, err.name, 
err.getStackTrace());
+                    error(err);
                 }
             } else {
                 trace("Error [callExternalInterface]: ExternalInterface is NOT 
available!");
@@ -374,7 +374,7 @@
 
             } catch (err:Error) {
                 trace("[ERROR]: addNode: " + err.getStackTrace());
-                error(err.message, err.errorID, err.name, err.getStackTrace());
+                error(err);
             }
 
             return o;
@@ -394,7 +394,7 @@
                 
             } catch (err:Error) {
                 trace("[ERROR]: addEdge: " + err.getStackTrace());
-                error(err.message, err.errorID, err.name, err.getStackTrace());
+                error(err);
             }
             
             return o;

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/ImageCache.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/ImageCache.as  
    2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/ImageCache.as  
    2011-01-05 00:11:24 UTC (rev 23297)
@@ -44,10 +44,10 @@
     import org.cytoscapeweb.model.data.VisualStyleBypassVO;
     import org.cytoscapeweb.model.data.VisualStyleVO;
     import org.cytoscapeweb.model.data.VizMapperVO;
+    import org.cytoscapeweb.model.error.CWError;
     import org.cytoscapeweb.model.methods.error;
     import org.cytoscapeweb.util.ErrorCodes;
     import org.cytoscapeweb.util.VisualProperties;
-    import org.cytoscapeweb.util.methods.$each;
     
     
     public class ImageCache {
@@ -190,7 +190,7 @@
                 
                 
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, 
function(e:IOErrorEvent):void {trace("ImageCache - Error loading image: " + e);
                     _broken[url] = true;
-                    error("Image cannot be loaded: " + url, 
ErrorCodes.BROKEN_IMAGE, e.type, e.text);
+                    error(new CWError("Image cannot be loaded: "+url+" 
("+e.type+"--"+e.text+")", ErrorCodes.BROKEN_IMAGE));
                     checkOnLoadingEnd();
                 });
                 

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/ExternalObjectConverterTest.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/ExternalObjectConverterTest.as
   2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/ExternalObjectConverterTest.as
   2011-01-05 00:11:24 UTC (rev 23297)
@@ -46,7 +46,7 @@
         public function testConvertToDataSet():void {
             // Empty networks:
             // --------------------------------------------------------------
-            var n:*, ds:DataSet, ns:DataSchema, es:DataSchema, nodes:Array, 
nd:Array, ed:Array;
+            var network:*, ds:DataSet, ns:DataSchema, es:DataSchema, 
nodes:Array, nd:Array, ed:Array;
             
             var networks:Array = [ null, 
                                   {},
@@ -54,8 +54,8 @@
                                   { schema: { nodes: [], edges: [] }, data: { 
nodes: [], edges: [] } } 
                                  ];
             
-            for each (n in networks) {
-                ds = ExternalObjectConverter.convertToDataSet(n);
+            for each (network in networks) {
+                ds = ExternalObjectConverter.convertToDataSet(network);
                 assertMinNodesSchema(ds.nodes.schema);
                 assertMinEdgesSchema(ds.edges.schema);
                 assertEmptyGraph(ds);
@@ -63,11 +63,16 @@
         
             // A simple network:
             // --------------------------------------------------------------
-            n = {
+            var now:Date = new Date();
+            
+            network = {
                 dataSchema: {
                     nodes: [
                         { name: "id", type: "number" }, // WRONG! Should be 
string and will be ignored
-                        { name: "score", type: "number", defValue: -1 }
+                        { name: "label", type: "string" },
+                        { name: "score", type: "number", defValue: -1 },
+                        { name: "ranking", type: "int" },
+                        { name: "date", type: "object", defValue: now }
                     ],
                     edges: [
                         { name: "source", type: "string", defValue: "1" },    
// Should ignore defValue
@@ -77,46 +82,72 @@
                 },
                 data: {
                     nodes: [
-                        { id: 1, score: 1.11 }, // Should convert id to string
-                        { id: "2", score: 2.22 },
-                        { id: "3", score: 3.33 }
+                        { id: "1", label: "Node 1", score: 1.11, date: new 
Date(2010, 1, 1) },
+                        { id: "2", label: "Node 2", score: 2.22 },
+                        { id: "3", label: "Node 3", score: 3.33 }
                     ],
                     edges: [
                         { id: "e1", source: "1", target: "2", weight: 0.5 },
-                        { id: "e2", source: "2", target: 3, weight: 0.5 }, // 
Should convert target to string
-                        { id: "e3", source: 3, target: "3", weight: 0.25, 
directed: false } // Should convert source to string
+                        { id: "e2", source: "2", target: "3", weight: 0.5 },
+                        { id: "e3", source: "3", target: "3", weight: 0.25, 
directed: false }
                     ]
                 }
             };
             
-            ds = ExternalObjectConverter.convertToDataSet(n);
+            ds = ExternalObjectConverter.convertToDataSet(network);
             
-            // Schema:
+            // Test schema:
+            // --------------------
             ns = ds.nodes.schema;
             es = ds.edges.schema;
             
+            // Nodes Schema:
             assertMinNodesSchema(ns);
+            
             assertEquals(DataUtil.NUMBER, ns.getFieldByName("score").type);
             assertEquals(-1, ns.getFieldByName("score").defaultValue);
             
+            assertEquals(DataUtil.INT, ns.getFieldByName("ranking").type);
+            assertEquals(0, ns.getFieldByName("ranking").defaultValue);
+            
+            assertEquals(DataUtil.STRING, ns.getFieldByName("label").type);
+            assertTrue(null === ns.getFieldByName("label").defaultValue);
+            
+            assertEquals(DataUtil.OBJECT, ns.getFieldByName("date").type);
+            assertTrue(now === ns.getFieldByName("date").defaultValue);
+            
+            // Edges schema
             assertMinEdgesSchema(es, true);
-            assertEquals(undefined, 
es.getFieldByName(ExternalObjectConverter.SOURCE).defaultValue);
+            
+            assertTrue(null === 
es.getFieldByName(ExternalObjectConverter.SOURCE).defaultValue);
+            
             assertEquals(DataUtil.NUMBER, es.getFieldByName("weight").type);
+            assertTrue(null === es.getFieldByName("weight").defaultValue);
+            
             assertEquals(DataUtil.BOOLEAN, 
es.getFieldByName(ExternalObjectConverter.DIRECTED).type);
             
-            // Data
+            // Test Data:
+            // --------------------
             nd = ds.nodes.data;
             ed = ds.edges.data;
             
-            assertEquals(n.data.nodes.length, nd.length);
-            assertEquals(n.data.edges.length, ed.length);
+            assertEquals(network.data.nodes.length, nd.length);
+            assertEquals(network.data.edges.length, ed.length);
             
+            for each (var n:Object in nd) {
+                assertTrue(n.id is String);
+                assertTrue(n.label is String);
+                assertTrue(n.score is Number);
+                assertTrue(n.ranking is int);
+                assertTrue(n.date is Date);
+                assertEquals((n.id !== "1"), (n.date == now));
+            }
             for each (var e:Object in ed) {
+                assertTrue(e.id is String);
+                assertTrue(e.weight is Number);
+                assertTrue(e.directed is Boolean);
                 assertEquals(e.id !== "e3", e.directed);
             }
-            
-                        
-            // TODO: test values!
         }
         
         public function testToExtObject():void {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/XGMMLConverterTest.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/XGMMLConverterTest.as
    2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/XGMMLConverterTest.as
    2011-01-05 00:11:24 UTC (rev 23297)
@@ -31,6 +31,7 @@
     
     import flare.data.DataSet;
     import flare.data.DataTable;
+    import flare.data.DataUtil;
     import flare.vis.data.Data;
     
     import flash.utils.IDataOutput;
@@ -89,7 +90,7 @@
             }
         }
         
-        public function testParseValue():void {
+        public function testParseGraphicsValue():void {
             // Device fonts:
             const F1:String = "Default-0-12";
             const F2:String = "SansSerif-0-08";
@@ -144,9 +145,25 @@
             ];
             
             for each (var t:Object in tests) {
-                var v:* = XGMMLConverter.parseValue(t.prop, t.value);
+                var v:* = XGMMLConverter.parseGraphicsValue(t.prop, t.value);
                 assertEquals(t.res, v);
             }
         }
+        
+        public function testParseAttValue():void {
+            var tests:Array = [
+                { value: "0",     type: DataUtil.BOOLEAN, res: false },
+                { value: "false", type: DataUtil.BOOLEAN, res: false },
+                { value: "FALSE", type: DataUtil.BOOLEAN, res: false },
+                { value: "1",     type: DataUtil.BOOLEAN, res: true },
+                { value: "true",  type: DataUtil.BOOLEAN, res: true },
+                { value: "TRUE",  type: DataUtil.BOOLEAN, res: true }
+            ];
+            
+            for each (var t:Object in tests) {
+                var v:* = XGMMLConverter.parseAttValue(t.value, t.type);
+                assertEquals(t.res, v);
+            }
+        }
     }
 }
\ No newline at end of file

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/view/render/ImageCacheTest.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/view/render/ImageCacheTest.as
     2011-01-04 20:59:57 UTC (rev 23296)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/view/render/ImageCacheTest.as
     2011-01-05 00:11:24 UTC (rev 23297)
@@ -101,13 +101,17 @@
         }
         
         public function testDispose():void {
-            // Initial state:
-            assertEquals(1, _cache.size);
-            assertFalse(_cache.isLoading());
+            function runTest():void {trace(_cache.size)
+                // Initial state:
+                assertTrue(_cache.size > 0);
+                assertFalse(_cache.isLoading());
+                
+                _cache.dispose();
+                assertEquals(0, _cache.size);
+                assertFalse(_cache.isLoading());
+            };
             
-            _cache.dispose();
-            assertEquals(0, _cache.size);
-            assertFalse(_cache.isLoading());
+            _cache.loadImages(_simpleVs, null, addAsync(runTest, 3000));
         }
 
     }

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to