From elliot at rpath.com Thu Apr 14 11:33:38 2011 From: elliot at rpath.com (Elliot Peele) Date: Thu, 14 Apr 2011 15:33:38 +0000 Subject: xobj: Allow for more generalized ICollectionView handling not just ArrayCollection handling Message-ID: <201104141533.p3EFXcRN011605@scc.eng.rpath.com> changeset: 6a4a738de013 user: Brett Adam date: Mon, 24 May 2010 17:04:44 -0400 Allow for more generalized ICollectionView handling not just ArrayCollection handling diff --git a/as3/xobjas3/src/com/rpath/xobj/XObjUtils.as b/as3/xobjas3/src/com/rpath/xobj/XObjUtils.as --- a/as3/xobjas3/src/com/rpath/xobj/XObjUtils.as +++ b/as3/xobjas3/src/com/rpath/xobj/XObjUtils.as @@ -19,9 +19,12 @@ import flash.xml.XMLNode; import mx.collections.ArrayCollection; + import mx.collections.ArrayList; + import mx.collections.ICollectionView; import mx.utils.DescribeTypeCache; import mx.utils.ObjectProxy; import mx.utils.object_proxy; + use namespace object_proxy; public class XObjUtils @@ -137,11 +140,11 @@ { // TODO: better way to detect an arry subclass? var foo:* = new type(); - result = (foo is Array); + result = (foo is Array || foo is ArrayList || foo is Vector); arrayTypeCache[type] = result; // do the array collection test while we're here, to save time - arrayCollectionTypeCache[type] = (foo is ArrayCollection) || (foo is IXObjCollection); + arrayCollectionTypeCache[type] = (foo is ICollectionView) || (foo is IXObjCollection); } return result; } @@ -161,7 +164,7 @@ { // TODO: better way to detect an arry subclass? var foo:* = new type(); - result = (foo is ArrayCollection) || (foo is IXObjCollection); + result = (foo is ICollectionView) || (foo is IXObjCollection); arrayCollectionTypeCache[type] = result; // do the array test while we're here, to save time diff --git a/as3/xobjas3/src/com/rpath/xobj/XObjXMLDecoder.as b/as3/xobjas3/src/com/rpath/xobj/XObjXMLDecoder.as --- a/as3/xobjas3/src/com/rpath/xobj/XObjXMLDecoder.as +++ b/as3/xobjas3/src/com/rpath/xobj/XObjXMLDecoder.as @@ -53,6 +53,7 @@ import flash.xml.XMLNodeType; import mx.collections.ArrayCollection; +import mx.collections.ICollectionView; import mx.rpc.xml.*; import mx.utils.ObjectProxy; @@ -485,7 +486,7 @@ var existing:* = result[partName]; if (existing && (existing is Object) && !((existing is Array) - || (existing is ArrayCollection) + || (existing is ICollectionView) || (existing is String) || (existing is Boolean) || (existing is Number) From elliot at rpath.com Thu Apr 14 11:33:43 2011 From: elliot at rpath.com (Elliot Peele) Date: Thu, 14 Apr 2011 15:33:43 +0000 Subject: xobj: Branch merge Message-ID: <201104141533.p3EFXhut013044@scc.eng.rpath.com> changeset: 842fd3aa97f2 user: Brad Murphy date: Fri, 10 Dec 2010 05:12:53 +0000 Branch merge diff --git a/as3/xobjas3/.actionScriptProperties b/as3/xobjas3/.actionScriptProperties --- a/as3/xobjas3/.actionScriptProperties +++ b/as3/xobjas3/.actionScriptProperties @@ -2,7 +2,7 @@ - + diff --git a/as3/xobjas3/.flexLibProperties b/as3/xobjas3/.flexLibProperties --- a/as3/xobjas3/.flexLibProperties +++ b/as3/xobjas3/.flexLibProperties @@ -1,5 +1,5 @@ - + @@ -19,6 +19,7 @@ + diff --git a/as3/xobjas3/src/com/rpath/xobj/IXObjCollection.as b/as3/xobjas3/src/com/rpath/xobj/IXObjCollection.as --- a/as3/xobjas3/src/com/rpath/xobj/IXObjCollection.as +++ b/as3/xobjas3/src/com/rpath/xobj/IXObjCollection.as @@ -9,6 +9,8 @@ function addItem(value:Object):void; function addItemIfAbsent(value:Object):Boolean; function removeItemIfPresent(object:Object):Boolean; + + function isElementMember(propname:String):Boolean; } } \ No newline at end of file diff --git a/as3/xobjas3/src/com/rpath/xobj/IXObjHref.as b/as3/xobjas3/src/com/rpath/xobj/IXObjHref.as new file mode 100644 --- /dev/null +++ b/as3/xobjas3/src/com/rpath/xobj/IXObjHref.as @@ -0,0 +1,7 @@ +package com.rpath.xobj +{ +public interface IXObjHref +{ + // marker interface +} +} \ No newline at end of file diff --git a/as3/xobjas3/src/com/rpath/xobj/XObjTypeInfo.as b/as3/xobjas3/src/com/rpath/xobj/XObjTypeInfo.as --- a/as3/xobjas3/src/com/rpath/xobj/XObjTypeInfo.as +++ b/as3/xobjas3/src/com/rpath/xobj/XObjTypeInfo.as @@ -23,7 +23,8 @@ public var typeName:String; public var isArray:Boolean; public var isCollection:Boolean; - + public var isMember:Boolean; + public var arrayElementTypeName:String; public var arrayElementClass:Class; } diff --git a/as3/xobjas3/src/com/rpath/xobj/XObjUtils.as b/as3/xobjas3/src/com/rpath/xobj/XObjUtils.as --- a/as3/xobjas3/src/com/rpath/xobj/XObjUtils.as +++ b/as3/xobjas3/src/com/rpath/xobj/XObjUtils.as @@ -13,6 +13,7 @@ package com.rpath.xobj { + import flash.errors.StackOverflowError; import flash.utils.Dictionary; import flash.utils.getDefinitionByName; import flash.utils.getQualifiedClassName; @@ -21,12 +22,10 @@ import mx.collections.ArrayCollection; import mx.collections.ArrayList; import mx.collections.ICollectionView; + import mx.collections.IList; import mx.utils.DescribeTypeCache; import mx.utils.ObjectProxy; import mx.utils.object_proxy; - import mx.collections.IList; - - import flash.errors.StackOverflowError; use namespace object_proxy; @@ -272,6 +271,13 @@ { typeInfo.type = XObjUtils.getClassByName(typeInfo.typeName); } + + // ask if this is a member of not + if (object is IXObjCollection) + { + typeInfo.isMember = (object as IXObjCollection).isElementMember(propName); + } + // cache the result for next time typePropertyCache[propertyCacheKey] = typeInfo; } diff --git a/as3/xobjas3/src/com/rpath/xobj/XObjXMLDecoder.as b/as3/xobjas3/src/com/rpath/xobj/XObjXMLDecoder.as --- a/as3/xobjas3/src/com/rpath/xobj/XObjXMLDecoder.as +++ b/as3/xobjas3/src/com/rpath/xobj/XObjXMLDecoder.as @@ -489,7 +489,7 @@ propertyName = elementName; propertyIsArray = false; propertyIsCollection = false; - + // record the order we see the elements in for encoding purposes // this is an attempt to "fake" XMLSchema sequence constraint of // ordered elements. Collapse sequenced repetitions to a single entry @@ -517,6 +517,7 @@ partClassName = typeInfo.typeName; propertyIsArray = typeInfo.isArray; propertyIsCollection = typeInfo.isCollection; + isMember = typeInfo.isMember; // make sure we can pass on an [ArrayElementType()] metadata // we observe on this property (which will not be visible @@ -530,8 +531,8 @@ partObj = rootObject; partClass = XObjUtils.getClass(partObj); partClassName = XObjUtils.getClassName(partObj); - propertyIsArray = XObjUtils.isTypeArray(partClass); - propertyIsCollection = XObjUtils.isTypeCollection(partClass); + //propertyIsArray = XObjUtils.isTypeArray(partClass); + //propertyIsCollection = XObjUtils.isTypeCollection(partClass); } // else should we reuse an existing property object? else if (result.hasOwnProperty(propertyName)) @@ -578,6 +579,16 @@ partObj = existing; } } + else + { + // we have the property, but no value + if (!partClass) + { + // must be plain old Object, but our TypeInfo + // method ignores them...compensate + partClass = Object; + } + } } @@ -591,39 +602,17 @@ // assigned to the property, not made a member of the // collection) - isMember = false; - if (!partObj && !partClass) { - // important: are we *in* an array or collection object? + // important: are we *in* an generic array or collection object? - if (isArray || isCollection) + if (!(result is IXObjCollection) + && (isArray || isCollection)) { // we need to handle collection type objects with special care // since if the element doesn't map to a property, it's a member isMember = true; - - // we were told what type to use on the way in? - if (memberClass) - { - // parent object determined type for us. let it trump - partClass = memberClass; - } - - if (!partClass) - { - // if we're an xobj ref, it's supposed to be able to tell - // us what types to use for members - var xobjRef:IXObjReference = result as IXObjReference; - - // XObjRefs can tell us their desired member types - if (xobjRef) - { - // ask the IXObjReference for the type it wants to use - partClass = xobjRef.elementTypeForElementName(elementName); - } - } } else { @@ -631,6 +620,31 @@ } } + if (isMember) + { + // we were told what type to use on the way in? + if (memberClass) + { + // parent object determined type for us. let it trump + partClass = memberClass; + } + + } + + if (!partClass) + { + // if we're an xobj ref, it's supposed to be able to tell + // us what types to use for members + var xobjRef:IXObjReference = result as IXObjReference; + + // XObjRefs can tell us their desired member types + if (xobjRef) + { + // ask the IXObjReference for the type it wants to use + partClass = xobjRef.elementTypeForElementName(elementName); + } + } + if (!partClass) { // if we still don't know, fall all the way back to global @@ -810,10 +824,20 @@ //result.setPropertyIsEnumerable(attrName, false); } } + catch (e:TypeError) + { + if ((result[attrName] is IXObjHref) + && (attr is String)) + { + result[attrName].id = attr; + } + else + throw e; + } catch (e:Error) { //throw new Error("Failed to set attribute "+attrName+"("+attr+") on "+resultTypeName+". Check that class is dynamic or attribute name is spelled correctly"); - trace("Failed to set attribute "+attrName+"("+attr+") on "+resultTypeName+". Check that class is dynamic or attribute name is spelled correctly"); + trace("Failed to set attribute "+attrName+"("+attr+") on "+resultTypeName+". " + e + ". Check that class is dynamic or attribute name is spelled correctly"); } } @@ -875,9 +899,6 @@ return result; } - import flash.utils.flash_proxy; - - private function assignToProperty(result:*, propName:String, value:*, seenBefore:Boolean, makeArray:Boolean, makeCollection:Boolean, makeBindable:Boolean):* { diff --git a/as3/xobjas3/src/com/rpath/xobj/XSmartURL.as b/as3/xobjas3/src/com/rpath/xobj/XSmartURL.as --- a/as3/xobjas3/src/com/rpath/xobj/XSmartURL.as +++ b/as3/xobjas3/src/com/rpath/xobj/XSmartURL.as @@ -17,6 +17,7 @@ import flash.utils.Dictionary; import mx.collections.SortField; +[Bindable] public class XSmartURL extends URL { public function XSmartURL(s:*=null) @@ -35,7 +36,6 @@ } - public function get baseURL():URL { return _baseURL; @@ -72,12 +72,37 @@ [xobjTransient] public var rangeRequest:Boolean; + [xobjTransient] - public var startIndex:Number; + private var _startIndex:Number; + + public function get startIndex():Number + { + return _startIndex; + } + + public function set startIndex(value:Number):void + { + _startIndex = value; + rangeRequest = true; + recomputeQualifiedURL(); + } + [xobjTransient] - public var limit:Number; - [xobjTransient] - public var rangeUsingHeaders:Boolean; + private var _limit:Number; + + public function get limit():Number + { + return _limit; + } + + public function set limit(value:Number):void + { + _limit = value; + rangeRequest = true; + recomputeQualifiedURL(); + } + /** filterTerms is an array of (field, operator, value) clauses * that are assumed to be AND clauses @@ -140,7 +165,6 @@ // TODO: optimize this via setter/getter pairs on query terms [xobjTransient] - [Bindable] public function get qualifiedURL():String { return _qualifiedURL; @@ -166,13 +190,13 @@ if (queryFrag) { - if (baseURL.hasQuery()) + if (fullURL.indexOf(descriptor.paramDelimiter) != -1) { - fullURL = fullURL + "&" + queryFrag; + fullURL = fullURL + descriptor.paramDelimiter + queryFrag; } else { - fullURL = fullURL + "?" + queryFrag; + fullURL = fullURL + descriptor.paramMarker + queryFrag; } } @@ -191,18 +215,10 @@ if (rangeRequest) { - if (descriptor.rangeUsingHeaders) - { - // DAMN HTTPService won't pass RANGE header - setHeader("X-Range", "rows "+startIndex+"-"+(startIndex+ limit -1)); - } - else - { - if (descriptor.startKey) - params[descriptor.startKey] = startIndex; - if (descriptor.limitKey) - params[descriptor.limitKey] = limit; - } + if (descriptor.startKey) + params[descriptor.startKey] = startIndex; + if (descriptor.limitKey) + params[descriptor.limitKey] = limit; } // TODO: use descriptor to tell us how to express sort @@ -263,7 +279,7 @@ first = true; for (var param:String in params) { - query = query + (first ? "" : "&") + param + "=" + params[param]; + query = query + (first ? "" : descriptor.paramDelimiter) + param + "=" + params[param]; first = false; } diff --git a/as3/xobjas3/src/com/rpath/xobj/XSmartURLDescriptor.as b/as3/xobjas3/src/com/rpath/xobj/XSmartURLDescriptor.as --- a/as3/xobjas3/src/com/rpath/xobj/XSmartURLDescriptor.as +++ b/as3/xobjas3/src/com/rpath/xobj/XSmartURLDescriptor.as @@ -12,6 +12,8 @@ */ package com.rpath.xobj { + +[Bindable] public class XSmartURLDescriptor { public function XSmartURLDescriptor() @@ -20,14 +22,16 @@ } // keys used in constructing URLs - public var startKey:String = "start"; + public var paramMarker:String = ":"; + public var paramDelimiter:String = ";"; + + public var startKey:String = "start_index"; public var limitKey:String = "limit"; public var sortKey:String = "order_by"; public var sortConjunction:String = ","; public var sortDescMarker:String = "-"; public var sortAscMarker:String = ""; - public var rangeUsingHeaders:Boolean = false; public var filterKey:String = "filter_by"; public var filterTermStart:String = "[";