1////////////////////////////////////////////////////////////////////////////////
2//
3//  ADOBE SYSTEMS INCORPORATED
4//  Copyright 2009 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.olap
13{
14
15import flash.utils.Dictionary;
16
17import mx.collections.ArrayCollection;
18import mx.collections.ICollectionView;
19import mx.collections.IList;
20import mx.collections.IViewCursor;
21import mx.core.mx_internal;
22import mx.resources.ResourceManager;
23
24use namespace mx_internal;
25
26//--------------------------------------
27//  Excluded APIs
28//--------------------------------------
29
30[Exclude(name="dimension", kind="property")]
31
32//--------------------------------------
33//  metadata
34//--------------------------------------
35
36[DefaultProperty("elements")]
37
38/**
39 *  The OLAPDimension class represents a dimension of an OLAP cube.
40 *
41 *  @mxml
42 *  <p>
43 *  The <code>&lt;mx:OLAPDimension&gt;</code> tag inherits all of the tag attributes
44 *  of its superclass, and adds the following tag attributes:
45 *  </p>
46 *  <pre>
47 *  &lt;mx:OLAPDimension
48 *    <b>Properties</b>
49 *    attributes=""
50 *    elements=""
51 *    hierarchies=""
52  *  /&gt;
53 *
54 *  @see mx.olap.IOLAPDimension
55 *
56 *  @langversion 3.0
57 *  @playerversion Flash 9
58 *  @playerversion AIR 1.1
59 *  @productversion Flex 3
60 */
61public class OLAPDimension extends OLAPElement implements IOLAPDimension
62{
63    include "../core/Version.as";
64
65    //--------------------------------------------------------------------------
66    //
67    //  Constructor
68    //
69    //--------------------------------------------------------------------------
70
71    /**
72     *  Constructor
73     *
74     *  @param name The name of the OLAP dimension that includes the OLAP schema hierarchy of the element.
75     *
76     *  @param displayName The name of the OLAP dimension, as a String, which can be used for display.
77     *
78     *  @langversion 3.0
79     *  @playerversion Flash 9
80     *  @playerversion AIR 1.1
81     *  @productversion Flex 3
82     */
83    public function OLAPDimension(name:String=null, displayName:String=null)
84    {
85        OLAPTrace.traceMsg("Creating dimension: " + name, OLAPTrace.TRACE_LEVEL_3);
86        super(name, displayName);
87    }
88
89    //--------------------------------------------------------------------------
90    //
91    //  Variables
92    //
93    //--------------------------------------------------------------------------
94
95    //map of attributes using name as the key
96    private var attributeMap:Dictionary = new Dictionary(true);
97
98    //map of hierarchies using name as the key
99    private var _hierarchiesMap:Dictionary = new Dictionary(true);
100
101    //--------------------------------------------------------------------------
102    //
103    //  Properties
104    //
105    //--------------------------------------------------------------------------
106
107    //----------------------------------
108    // attributes
109    //----------------------------------
110
111    private var _attributes:IList = new ArrayCollection;
112
113    /**
114     *  @inheritDoc
115     *
116     *  @langversion 3.0
117     *  @playerversion Flash 9
118     *  @playerversion AIR 1.1
119     *  @productversion Flex 3
120     */
121    public function get attributes():IList
122    {
123        return _attributes;
124    }
125
126    /**
127     *  @private
128     */
129    public function set attributes(value:IList):void
130    {
131        _attributes = value;
132        var n:int = value.length;
133        for (var attrIndex:int = 0; attrIndex < n; ++attrIndex)
134        {
135            var attr:OLAPAttribute = value.getItemAt(attrIndex) as OLAPAttribute;
136            attr.dimension = this;
137            attributeMap[attr.name] = attr;
138        }
139    }
140
141    //----------------------------------
142    // cube
143    //----------------------------------
144
145    private var _cube:IOLAPCube;
146
147    /**
148     *  @inheritDoc
149     *
150     *  @langversion 3.0
151     *  @playerversion Flash 9
152     *  @playerversion AIR 1.1
153     *  @productversion Flex 3
154     */
155    public function get cube():IOLAPCube
156    {
157        return _cube;
158    }
159
160    /**
161     *  @private
162     */
163    public function set cube(value:IOLAPCube):void
164    {
165        _cube = value;
166    }
167
168    //----------------------------------
169    // dataProvider
170    //----------------------------------
171
172    mx_internal function get dataProvider():ICollectionView
173    {
174        return OLAPCube(cube).dataProvider;
175    }
176
177    //----------------------------------
178    // defaultMember
179    //----------------------------------
180
181    /**
182     *  @inheritDoc
183     *
184     *  @langversion 3.0
185     *  @playerversion Flash 9
186     *  @playerversion AIR 1.1
187     *  @productversion Flex 3
188     */
189    public function get defaultMember():IOLAPMember
190    {
191        // get the default hierarchy here
192        if ((hierarchies.length + attributes.length) > 1)
193        {
194            var message:String = ResourceManager.getInstance().getString(
195                        "olap", "multipleHierarchies");
196            throw Error(message);
197        }
198
199        return hierarchies[0].defaultMember;
200    }
201
202    //----------------------------------
203    // elements
204    //----------------------------------
205
206    /**
207     *  Processes the input Array and initializes the <code>attributes</code>
208     *  and <code>hierarchies</code> properties based on the elements of the Array.
209     *  Attributes are represented in the Array by instances of the OLAPAttribute class,
210     *  and hierarchies are represented by instances of the OLAPHierarchy class.
211     *
212     *  <p>Use this property to define the attributes and hierarchies of a cube in a single Array.</p>
213     *
214     *  @langversion 3.0
215     *  @playerversion Flash 9
216     *  @playerversion AIR 1.1
217     *  @productversion Flex 3
218     */
219    public function set elements(value:Array):void
220    {
221        var attrs:ArrayCollection = new ArrayCollection();
222        var userHierarchies:ArrayCollection = new ArrayCollection();
223        for each (var element:Object in value)
224        {
225            if (element is OLAPAttribute)
226                attrs.addItem(element);
227            else if (element is OLAPHierarchy)
228                userHierarchies.addItem(element);
229            else
230                OLAPTrace.traceMsg("Invalid element specified for dimension elements");
231        }
232
233        attributes = attrs;
234        hierarchies = userHierarchies;
235    }
236
237    //----------------------------------
238    // hierarchies
239    //----------------------------------
240
241    private var _hierarchies:IList = new ArrayCollection;
242
243    /**
244     *  @inheritDoc
245     *
246     *  @langversion 3.0
247     *  @playerversion Flash 9
248     *  @playerversion AIR 1.1
249     *  @productversion Flex 3
250     */
251    public function get hierarchies():IList
252    {
253        return _hierarchies;
254    }
255
256    /**
257     *  @private
258     */
259    public function set hierarchies(value:IList):void
260    {
261        //limitation till we support multiple hierarchies.
262        if (value.length > 1)
263        {
264            var message:String = ResourceManager.getInstance().getString(
265                        "olap", "multipleHierarchiesNotSupported", [name]);
266            throw Error(message);
267        }
268
269        _hierarchies = value;
270        for (var i:int = 0; i < value.length; ++i)
271        {
272            var h:OLAPHierarchy = value.getItemAt(i) as OLAPHierarchy;
273            h.dimension = this;
274            _hierarchiesMap[h.name] = h;
275        }
276    }
277
278    //----------------------------------
279    // isMeasure
280    //----------------------------------
281
282    private var _isMeasureDimension:Boolean = false;
283
284    /**
285     *  @inheritDoc
286     *
287     *  @langversion 3.0
288     *  @playerversion Flash 9
289     *  @playerversion AIR 1.1
290     *  @productversion Flex 3
291     */
292    public function get isMeasure():Boolean
293    {
294        return _isMeasureDimension;
295    }
296
297    /**
298     *  @private
299     */
300    mx_internal function setAsMeasure(value:Boolean):void
301    {
302        _isMeasureDimension = value;
303    }
304
305    //----------------------------------
306    // members
307    //----------------------------------
308
309    /**
310     *  @inheritDoc
311     *
312     *  @langversion 3.0
313     *  @playerversion Flash 9
314     *  @playerversion AIR 1.1
315     *  @productversion Flex 3
316     */
317    public function get members():IList
318    {
319        var temp:Array = [];
320
321        for (var i:int = 0; i < hierarchies.length; ++i)
322            temp = temp.concat(hierarchies.getItemAt(i).members.toArray());
323
324        return new ArrayCollection(temp);
325    }
326
327    //--------------------------------------------------------------------------
328    //
329    //  Methods
330    //
331    //--------------------------------------------------------------------------
332
333    /**
334     *  @inheritDoc
335     *
336     *  @langversion 3.0
337     *  @playerversion Flash 9
338     *  @playerversion AIR 1.1
339     *  @productversion Flex 3
340     */
341     public function findHierarchy(name:String):IOLAPHierarchy
342    {
343        return _hierarchiesMap[name];
344    }
345
346    /**
347    *  @inheritDoc
348    *
349    *  @langversion 3.0
350    *  @playerversion Flash 9
351    *  @playerversion AIR 1.1
352    *  @productversion Flex 3
353    */
354    public function findAttribute(name:String):IOLAPAttribute
355    {
356        return attributeMap[name];
357    }
358
359    /**
360     *  @inheritDoc
361     *
362     *  @langversion 3.0
363     *  @playerversion Flash 9
364     *  @playerversion AIR 1.1
365     *  @productversion Flex 3
366     */
367    public function findMember(name:String):IOLAPMember
368    {
369        var member:IOLAPMember;
370        var i:int = 0;
371        var h:OLAPHierarchy;
372
373        for (i = 0; i < attributes.length; ++i)
374        {
375            h = attributes.getItemAt(i) as OLAPHierarchy;
376            member = h.findMember(name);
377            if (member)
378                break;
379        }
380
381        if (!member)
382        {
383            for (i = 0; i < hierarchies.length; ++i)
384            {
385                h = hierarchies.getItemAt(i) as OLAPHierarchy;
386                member = h.findMember(name);
387                if (member)
388                    break;
389            }
390        }
391
392        return member;
393    }
394
395    /**
396     *  @private
397     *  Creates a hierarchy of the dimension.
398     *
399     *  @param name The name of the hierarchy.
400     *
401     *  @return An OLAPHierarchy instance that represents the new hierarchy.
402     */
403    mx_internal function createHierarchy(name:String):OLAPHierarchy
404    {
405        var h:OLAPHierarchy = new OLAPHierarchy(name);
406        h.dimension = this;
407        _hierarchies.addItem(h);
408        _hierarchiesMap[h.name] = h;
409        return h;
410    }
411
412    /**
413     *  @private
414     */
415    mx_internal function refresh():void
416    {
417        //if dimension is of measure type we have nothing to do.
418        if (isMeasure)
419            return;
420        var temp:Object;
421        var dataHandlers:Array  =[];
422
423        var i:int = 0;
424        var n:int = attributes.length;
425        for (i = 0; i < n; ++i)
426        {
427            temp = attributes.getItemAt(i);
428            dataHandlers.push(temp);
429        }
430
431        n = hierarchies.length;
432        for (i = 0; i < n; ++i)
433        {
434            temp = hierarchies.getItemAt(i);
435            temp.refresh();
436            dataHandlers.push(temp);
437        }
438
439        for (i = 0; i < n; ++i)
440        {
441            var h:OLAPHierarchy = hierarchies.getItemAt(i) as OLAPHierarchy;
442            var levels:IList = h.levels;
443            var m:int = levels.length;
444            for (var j:int = 0; j < m; ++j)
445            {
446                var level:OLAPLevel = levels[j];
447                //levels doesn't include allLevel
448                //if (level == h.allLevel)
449                //    continue;
450                var a:OLAPAttribute = findAttribute(level.name) as OLAPAttribute;
451                a.userHierarchy = level.hierarchy;
452                a.userHierarchyLevel = level;
453            }
454        }
455
456        // we need to refresh attributes here because we need the userHierarchy
457        // userLevels to be set before refresh can happen.
458        n = attributes.length;
459        for (i = 0; i < n; ++i)
460        {
461            temp = attributes.getItemAt(i);
462            temp.refresh();
463        }
464
465        var iterator:IViewCursor = dataProvider.createCursor();
466
467        while (!iterator.afterLast)
468        {
469            var currentData:Object = iterator.current;
470            for each (temp in dataHandlers)
471                temp.processData(currentData);
472            iterator.moveNext();
473        }
474    }
475
476    /**
477     *  @private
478     */
479    mx_internal function addAttribute(name:String, dataField:String):IOLAPAttribute
480    {
481        var attrHierarchy:OLAPAttribute = attributeMap[name];
482        if (!attrHierarchy)
483        {
484            attrHierarchy = new OLAPAttribute(name);
485            attrHierarchy.dataField = dataField;
486            attrHierarchy.dimension = this;
487            attributeMap[name] = attrHierarchy;
488            _attributes.addItem(attrHierarchy);
489        }
490        return attrHierarchy;
491    }
492
493}
494
495}
496