~mahara-contributors/mahara-adminlang/adminlang-master

« back to all changes in this revision

Viewing changes to htdocs/lib/flowplayer/src/actionscript/org/flowplayer/view/PluginLoader.as

  • Committer: Ruslan Kabalin
  • Date: 2011-08-03 14:54:09 UTC
  • Revision ID: git-v1:a3409b53a971ec3bad8b5d1329298046d9596381
Revert back to master brach.

The adminlang-master was mistakingly based on the mahara 1.3_STABLE. This is
required for easy merge with the master.

Command used:
for i in `git rev-list
f731cf9b2cf72b61ed6a317acab23a30b9046c8a..afb5850ba246f41b624c162e8d8e6e72c534f239`;
do git revert -n $i; done

Change-Id: I9db8553a66facfaca81492cd978f974c6e7b8892

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*    
 
2
 *    Copyright 2008 Flowplayer Oy
 
3
 *
 
4
 *    This file is part of Flowplayer.
 
5
 *
 
6
 *    Flowplayer is free software: you can redistribute it and/or modify
 
7
 *    it under the terms of the GNU General Public License as published by
 
8
 *    the Free Software Foundation, either version 3 of the License, or
 
9
 *    (at your option) any later version.
 
10
 *
 
11
 *    Flowplayer is distributed in the hope that it will be useful,
 
12
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *    GNU General Public License for more details.
 
15
 *
 
16
 *    You should have received a copy of the GNU General Public License
 
17
 *    along with Flowplayer.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
package org.flowplayer.view {
 
21
    import flash.display.AVM1Movie;
 
22
import flash.system.Security;
 
23
 
 
24
    import org.flowplayer.model.ErrorCode;
 
25
    import org.flowplayer.model.Plugin;
 
26
        import org.flowplayer.controller.NetStreamControllingStreamProvider;    
 
27
        
 
28
        import com.adobe.utils.StringUtil;
 
29
        
 
30
        import org.flowplayer.config.ExternalInterfaceHelper;
 
31
        import org.flowplayer.controller.StreamProvider;
 
32
        import org.flowplayer.model.Callable;
 
33
        import org.flowplayer.model.DisplayPluginModel;
 
34
        import org.flowplayer.model.FontProvider;
 
35
        import org.flowplayer.model.Loadable;
 
36
        import org.flowplayer.model.PlayerError;
 
37
    import org.flowplayer.model.PluginError;
 
38
    import org.flowplayer.model.PluginEvent;
 
39
    import org.flowplayer.model.PluginModel;
 
40
        import org.flowplayer.model.ProviderModel;
 
41
        import org.flowplayer.util.Log;
 
42
        import org.flowplayer.util.URLUtil;
 
43
        
 
44
        import flash.display.DisplayObject;
 
45
        import flash.display.Loader;
 
46
        import flash.display.LoaderInfo;
 
47
        import flash.events.Event;
 
48
        import flash.events.EventDispatcher;
 
49
        import flash.events.IOErrorEvent;
 
50
        import flash.events.ProgressEvent;
 
51
        import flash.net.URLRequest;
 
52
        import flash.system.ApplicationDomain;
 
53
        import flash.system.LoaderContext;
 
54
        import flash.system.SecurityDomain;
 
55
        import flash.utils.Dictionary;
 
56
        import flash.utils.getDefinitionByName;
 
57
        import flash.utils.getQualifiedClassName;
 
58
 
 
59
 
 
60
    /**
 
61
         * @author api
 
62
         */
 
63
        public class PluginLoader extends EventDispatcher {
 
64
 
 
65
                private var log:Log = new Log(this);
 
66
                private var _loadables:Array;
 
67
                private var _loadedPlugins:Dictionary;
 
68
                private var _loadedCount:int;
 
69
                private var _errorHandler:ErrorHandler;
 
70
                private var _swiffsToLoad:Array;
 
71
                private var _pluginRegistry:PluginRegistry;
 
72
                private var _providers:Dictionary;
 
73
                private var _callback:Function;
 
74
                private var _baseUrl:String;
 
75
                private var _useExternalInterface:Boolean;
 
76
                private var _loadErrorListener:Function;
 
77
                private var _loadListener:Function;
 
78
        private var _loadComplete:Boolean;
 
79
        private var _allPlugins:Array;
 
80
        private var _loaderContext:LoaderContext;
 
81
        private var _loadStartedCount:int = 0;
 
82
 
 
83
                public function PluginLoader(baseUrl:String, pluginRegistry:PluginRegistry, errorHandler:ErrorHandler, useExternalInterface:Boolean) {
 
84
                        _baseUrl = baseUrl;
 
85
                        _pluginRegistry = pluginRegistry;
 
86
                        _errorHandler = errorHandler;
 
87
                        _useExternalInterface = useExternalInterface;
 
88
                        _loadedCount = 0;
 
89
                }
 
90
 
 
91
                private function constructUrl(url:String):String {
 
92
                        if (url.indexOf("..") >= 0) return url;
 
93
                        if (url.indexOf("/") >= 0) return url;
 
94
                        return URLUtil.addBaseURL(_baseUrl, url);
 
95
                }
 
96
 
 
97
                public function loadPlugin(model:Loadable, callback:Function = null):void {
 
98
                        _callback = callback;
 
99
            _loadListener = null;
 
100
            _loadErrorListener = null;
 
101
                        load([model]);
 
102
                }
 
103
 
 
104
                public function load(plugins:Array, loadListener:Function = null, loadErrorListener:Function = null):void {
 
105
                        log.debug("load()");
 
106
            _loadListener = loadListener;
 
107
            _loadErrorListener = loadErrorListener;
 
108
 
 
109
            Security.allowDomain("*");
 
110
 
 
111
                        _providers = new Dictionary();
 
112
            _allPlugins = plugins.concat([]);
 
113
                        _loadables = plugins.filter(function(plugin:*, index:int, array:Array):Boolean {
 
114
                return plugin.url && String(plugin.url).toLocaleLowerCase().indexOf(".swf") > 0;
 
115
            });
 
116
                        _swiffsToLoad = getPluginSwiffUrls(plugins);
 
117
 
 
118
                        _loadedPlugins = new Dictionary();
 
119
                        _loadedCount = 0;
 
120
            _loadStartedCount = 0;
 
121
 
 
122
                        _loaderContext = new LoaderContext();
 
123
                        _loaderContext.applicationDomain = ApplicationDomain.currentDomain;
 
124
                        if (!URLUtil.localDomain(_baseUrl)) {
 
125
                                _loaderContext.securityDomain = SecurityDomain.currentDomain;
 
126
                        }
 
127
 
 
128
            for (var i:Number = 0; i < _loadables.length; i++) {
 
129
                Loadable(_loadables[i]).onError(_loadErrorListener);
 
130
            }
 
131
 
 
132
            intitializeBuiltInPlugins(plugins);
 
133
            if (_swiffsToLoad.length == 0) {
 
134
                setConfigPlugins();
 
135
                dispatchEvent(new Event(Event.COMPLETE, true, false));
 
136
                return;
 
137
            }
 
138
 
 
139
            loadNext();
 
140
                }
 
141
 
 
142
        private function loadNext():Boolean {
 
143
            if (_loadStartedCount >= _swiffsToLoad.length) {
 
144
                log.debug("loadNext(): all plugins loaded");
 
145
                return false;
 
146
            }
 
147
 
 
148
            var loader:Loader = new Loader();
 
149
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
 
150
            var url:String = _swiffsToLoad[_loadStartedCount];
 
151
 
 
152
            loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, createIOErrorListener(url));
 
153
            loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
 
154
            log.debug("starting to load plugin from url " + _swiffsToLoad[_loadStartedCount]);
 
155
            loader.load(new URLRequest(url), _loaderContext);
 
156
            _loadStartedCount++;
 
157
            return true;
 
158
        }
 
159
 
 
160
        private function getPluginSwiffUrls(plugins:Array):Array {
 
161
            var result:Array = new Array();
 
162
            for (var i:Number = 0; i < plugins.length; i++) {
 
163
                var loadable:Loadable = Loadable(plugins[i]);
 
164
                if (! loadable.isBuiltIn && loadable.url && result.indexOf(loadable.url) < 0) {
 
165
                    result.push(constructUrl(loadable.url));
 
166
                }
 
167
            }
 
168
            return result;
 
169
        }
 
170
 
 
171
        private function intitializeBuiltInPlugins(plugins:Array):void {
 
172
            for (var i:int = 0; i < plugins.length; i++) {
 
173
                var loadable:Loadable = plugins[i] as Loadable;
 
174
                log.debug("intitializeBuiltInPlugins() " + loadable);
 
175
                if (loadable.isBuiltIn) {
 
176
                    log.info("intitializeBuiltInPlugins(), instantiating from loadable " + loadable + ", with config ", loadable.config);
 
177
                    var instance:Object = loadable.instantiate();
 
178
                    var model:PluginModel = createPluginModel(loadable, instance);
 
179
                    model.isBuiltIn = true;
 
180
//                    if (instance.hasOwnProperty("onConfig")) {
 
181
//                        instance.onConfig(model);
 
182
//                    }
 
183
                    initializePlugin(model, instance);
 
184
                }
 
185
            }
 
186
        }
 
187
                
 
188
        private function createIOErrorListener(url:String):Function {
 
189
            return function(event:IOErrorEvent):void {
 
190
                log.error("onIoError " + url);
 
191
                _loadables.forEach(function(loadable:Loadable, index:int, array:Array):void {
 
192
                    if (! loadable.loadFailed && hasSwiff(url, loadable.url)) {
 
193
                        log.debug("onIoError: this is the swf for loadable " + loadable);
 
194
                        loadable.loadFailed = true;
 
195
                        loadable.dispatchError(PluginError.INIT_FAILED);
 
196
                        incrementLoadedCountAndFireEventIfNeeded();
 
197
                    }
 
198
                });
 
199
            };
 
200
        }
 
201
 
 
202
                private function onProgress(event:ProgressEvent):void {
 
203
                        log.debug("load in progress");
 
204
                }
 
205
 
 
206
 
 
207
                public function get plugins():Dictionary {
 
208
                        return _loadedPlugins;
 
209
                }
 
210
 
 
211
                private function loaded(event:Event):void {
 
212
                        var info:LoaderInfo = event.target as LoaderInfo;
 
213
                        log.debug("loaded class name " + getQualifiedClassName(info.content));
 
214
 
 
215
                        var instanceUsed:Boolean = false;
 
216
                        _loadables.forEach(function(loadable:Loadable, index:int, array:Array):void {
 
217
                                if (! loadable.plugin && hasSwiff(info.url, loadable.url)) {
 
218
                                        log.debug("this is the swf for loadable " + loadable);
 
219
                                        if (loadable.type == "classLibrary") {
 
220
                                                initializeClassLibrary(loadable, info);
 
221
                                        } else {
 
222
                        var plugin:Object = info.content is AVM1Movie ? info.loader : createPluginInstance(instanceUsed, info.content);
 
223
                                                initializePlugin(createPluginModel(loadable, plugin), plugin);
 
224
                                                //initializePlugin(loadable, instanceUsed, info);
 
225
                                                instanceUsed = true;
 
226
                                        }
 
227
                                }
 
228
                        });
 
229
            incrementLoadedCountAndFireEventIfNeeded();
 
230
                        if (_callback != null) {
 
231
                                _callback();
 
232
                        }
 
233
            loadNext();
 
234
                }
 
235
 
 
236
        private function incrementLoadedCountAndFireEventIfNeeded():void {
 
237
            if (++_loadedCount == _swiffsToLoad.length) {
 
238
                log.debug("all plugin SWFs loaded. loaded total " + loadedCount + " plugins");
 
239
                setConfigPlugins();
 
240
                dispatchEvent(new Event(Event.COMPLETE, true, false));
 
241
            }
 
242
        }
 
243
 
 
244
                private function initializeClassLibrary(loadable:Loadable, info:LoaderInfo):void {
 
245
            log.debug("initializing class library " + info.applicationDomain);
 
246
            _loadedPlugins[loadable] = info.applicationDomain;
 
247
                        _pluginRegistry.registerGenericPlugin(loadable.createPlugin(info.applicationDomain));
 
248
                }
 
249
 
 
250
                private function createPluginModel(loadable:Loadable, pluginInstance:Object):PluginModel {
 
251
                        log.debug("creating model for loadable " + loadable + ", instance " + pluginInstance);
 
252
                                
 
253
                        _loadedPlugins[loadable] = pluginInstance;
 
254
                
 
255
                        log.debug("pluginInstance " + pluginInstance);
 
256
                        if (pluginInstance is DisplayObject) {
 
257
                                return Loadable(loadable).createDisplayPlugin(pluginInstance as DisplayObject);
 
258
 
 
259
                        } else if (pluginInstance is StreamProvider) {
 
260
                                return Loadable(loadable).createProvider(pluginInstance);
 
261
                        } else {
 
262
                                return Loadable(loadable).createPlugin(pluginInstance);
 
263
                        }
 
264
                }
 
265
 
 
266
        private function initializePlugin(model:PluginModel, pluginInstance:Object):void {
 
267
            if (pluginInstance is FontProvider) {
 
268
                _pluginRegistry.registerFont(FontProvider(pluginInstance).fontFamily);
 
269
 
 
270
            } else if (pluginInstance is DisplayObject) {
 
271
                _pluginRegistry.registerDisplayPlugin(model as DisplayPluginModel, pluginInstance as DisplayObject);
 
272
 
 
273
            } else if (pluginInstance is StreamProvider) {
 
274
                _providers[model.name] = pluginInstance;
 
275
                _pluginRegistry.registerProvider(model as ProviderModel);
 
276
            } else {
 
277
                _pluginRegistry.registerGenericPlugin(model);
 
278
            }
 
279
            if (pluginInstance is Plugin) {
 
280
                if (_loadListener != null) {
 
281
                    model.onLoad(_loadListener);
 
282
                }
 
283
                model.onError(onPluginError);
 
284
            }
 
285
            if (model is Callable && _useExternalInterface) {
 
286
                ExternalInterfaceHelper.initializeInterface(model as Callable, pluginInstance);
 
287
            }
 
288
        }
 
289
 
 
290
        private function onPluginError(event:PluginEvent):void {
 
291
            log.debug("onPluginError() " + event.error);
 
292
            if (event.error) {
 
293
                _errorHandler.handleError(event.error, event.info + ", " + event.info2, true);
 
294
            }
 
295
        }
 
296
 
 
297
                private function createPluginInstance(instanceUsed:Boolean, instance:DisplayObject):Object {
 
298
                        if (instance.hasOwnProperty("newPlugin")) return instance["newPlugin"](); 
 
299
                        
 
300
                        if (! instanceUsed) {
 
301
                                log.debug("using existing instance " + instance);
 
302
                                return instance; 
 
303
                        }
 
304
                        var className:String = getQualifiedClassName(instance);
 
305
                        log.info("creating new " + className);
 
306
                        var PluginClass:Class = Class(getDefinitionByName(className));
 
307
                        return new PluginClass() as DisplayObject;
 
308
                }
 
309
                
 
310
                public function setConfigPlugins():void {
 
311
                        _allPlugins.forEach(function(loadable:Loadable, index:int, array:Array):void {
 
312
                if (! loadable.loadFailed) {
 
313
                    var pluginInstance:Object = plugins[loadable];
 
314
                    log.info(index + ": setting config to " + pluginInstance + ", " + loadable);
 
315
                    if (pluginInstance is NetStreamControllingStreamProvider) {
 
316
                        log.debug("NetStreamControllingStreamProvider(pluginInstance).config = " +loadable.plugin);
 
317
                            NetStreamControllingStreamProvider(pluginInstance).model = ProviderModel(loadable.plugin);
 
318
                    } else {
 
319
                        if (pluginInstance.hasOwnProperty("onConfig")) {
 
320
                            pluginInstance.onConfig(loadable.plugin);
 
321
                        }
 
322
                    }
 
323
                }
 
324
                        });
 
325
                }
 
326
 
 
327
                private function hasSwiff(infoUrl:String, modelUrl:String):Boolean {
 
328
            if (! modelUrl) return false;
 
329
                        var slashPos:int = modelUrl.lastIndexOf("/");
 
330
                        var swiffUrl:String = slashPos >= 0 ? modelUrl.substr(slashPos) : modelUrl;
 
331
                        return StringUtil.endsWith(infoUrl, swiffUrl);
 
332
                }
 
333
                
 
334
                public function get providers():Dictionary {
 
335
                        return _providers;
 
336
                }
 
337
                
 
338
                public function get loadedCount():int {
 
339
                        return _loadedCount;
 
340
                }
 
341
        
 
342
        public function get loadComplete():Boolean {
 
343
            return _loadComplete;
 
344
        }
 
345
    }
 
346
}