1////////////////////////////////////////////////////////////////////////////////
2//
3//  ADOBE SYSTEMS INCORPORATED
4//  Copyright 2006-2007 Adobe Systems Incorporated
5//  All Rights Reserved.
6//
7//  NOTICE: Adobe permits you to use, modify, and distribute this file
8//  in accordance with the terms of the license agreement accompanying it.
9//
10////////////////////////////////////////////////////////////////////////////////
11
12package mx.rpc.xml
13{
14
15import mx.utils.object_proxy;
16import mx.utils.URLUtil;
17
18use namespace object_proxy;
19
20[ExcludeClass]
21
22/**
23 * This abstract class traverses an XML Schema to assist with marshalling typed
24 * data between XML and ActionScript.
25 *
26 * @private
27 */
28public class SchemaProcessor
29{
30    public function SchemaProcessor()
31    {
32        super();
33    }
34
35    //--------------------------------------------------------------------------
36    //
37    // Properties
38    //
39    //--------------------------------------------------------------------------
40
41    public function get schemaManager():SchemaManager
42    {
43        if (_schemaManager == null)
44            _schemaManager = new SchemaManager();
45
46        return _schemaManager;
47    }
48
49    public function set schemaManager(manager:SchemaManager):void
50    {
51        _schemaManager = manager;
52    }
53
54    protected function get constants():SchemaConstants
55    {
56        return schemaManager.schemaConstants;
57    }
58
59    //--------------------------------------------------------------------------
60    //
61    // Methods
62    //
63    //--------------------------------------------------------------------------
64
65
66
67    /**
68     * Clears the state in preparation for a fresh schema processing operation.
69     */
70    public function reset():void
71    {
72        schemaManager.reset();
73    }
74
75    /**
76     * @private
77     */
78    public function isBuiltInType(type:QName):Boolean
79    {
80        var uri:String = (type != null) ? type.uri : null;
81
82        if (uri != null)
83        {
84            if (URLUtil.urisEqual(uri, SchemaConstants.XSD_URI_1999) ||
85                URLUtil.urisEqual(uri, SchemaConstants.XSD_URI_2000) ||
86                URLUtil.urisEqual(uri, SchemaConstants.XSD_URI_2001))
87            {
88                return true;
89            }
90        }
91
92        return false;
93    }
94
95
96    /**
97     * Determines the length of a given value to check minOccurs/maxOccurs
98     * ranges. If value is an Array, the count of the elements is returned
99     * as the length otherwise the length is considered to be 1.
100     *
101     * @private
102     */
103    public function getValueOccurence(value:*):uint
104    {
105        var result:uint = 1;
106        if (value != null && TypeIterator.isIterable(value))
107        {
108            result = TypeIterator.getLength(value);
109        }
110        else if (value === undefined)
111        {
112            result = 0;
113        }
114        return result;
115    }
116
117
118
119    //--------------------------------------------------------------------------
120    //
121    // Protected Methods
122    //
123    //--------------------------------------------------------------------------
124
125    /**
126     * A utility method to determine whether an attribute actually exists
127     * on a given node.
128     */
129    protected function getAttributeFromNode(name:*, node:XML):String
130    {
131        var value:String;
132        if (node != null)
133        {
134            var attribute:XMLList = node.attribute(name);
135            if (attribute.length() > 0)
136                value = attribute[0];
137        }
138
139        return value;
140    }
141
142    protected function getSingleElementFromNode(node:XML, ...types:Array):XML
143    {
144        var elements:XMLList = node.elements();
145        for each (var element:XML in elements)
146        {
147            if (types != null && types.length > 0)
148            {
149                for each (var type:QName in types)
150                {
151                    if (element.name() == type)
152                    {
153                        return element;
154                    }
155                }
156            }
157            else
158            {
159                return element;
160            }
161        }
162        return null;
163    }
164
165    /**
166     * Looks for a maxOccurs constraint on the given definition. The default
167     * is 1. The constraint value "unbounded" is interpreted as
168     * <code>uint.MAX_VALUE</code>.
169     */
170    protected function getMaxOccurs(definition:XML):uint
171    {
172        var maxOccurs:uint = 1;
173        var attributeValue:String = getAttributeFromNode("maxOccurs", definition);
174        if (attributeValue != null)
175            maxOccurs = (attributeValue == "unbounded") ? uint.MAX_VALUE : parseInt(attributeValue);
176
177        return maxOccurs;
178    }
179
180    /**
181     * Looks for a minOccurs constraint on the given definition. The default
182     * is 1.
183     */
184    protected function getMinOccurs(definition:XML):uint
185    {
186        var minOccurs:uint = 1;
187        var attributeValue:String = getAttributeFromNode("minOccurs", definition);
188        if (attributeValue != null)
189            minOccurs = parseInt(attributeValue);
190
191        return minOccurs;
192    }
193
194
195    //--------------------------------------------------------------------------
196    //
197    // Variables
198    //
199    //--------------------------------------------------------------------------
200
201    //FIXME: expose this as a configuration option
202    protected var strictOccurenceBounds:Boolean = false;
203
204    private var _schemaManager:SchemaManager;
205}
206
207}