| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You under the Apache License, Version 2.0 |
| // (the "License"); you may not use this file except in compliance with |
| // the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package |
| { |
| import flash.display.LoaderInfo; |
| import flash.display.Sprite; |
| import flash.events.Event; |
| import flash.trace.Trace; |
| import flash.utils.getTimer;
|
| |
| /** |
| * Main of preload SWF. This SWF listens to the trace of the primary application |
| * and sends the data to a server using a web socket. |
| */ |
| public class CodeCoveragePreloadSWF extends Sprite |
| { |
| //-------------------------------------------------------------------------- |
| // |
| // Class constants |
| // |
| //-------------------------------------------------------------------------- |
| |
| private static const DEFAULT_HOST:String = "localhost"; |
| private static const DEFAULT_DATA_PORT:int = 9097; |
| private static const DEFAULT_POLICY_FILE_PORT:int = 9843; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructor |
| */ |
| public function CodeCoveragePreloadSWF() |
| { |
| createClientSocket(); |
| addEventListener("allComplete", allCompleteHandler); |
| |
| Trace.setLevel(Trace.METHODS_AND_LINES, Trace.LISTENER); |
| Trace.setListener(methodsAndLinesCallback); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Variables |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Map the debug file info to an index number to reduce the amount |
| * of data sent over the port and stored. |
| * |
| * Key debug_file string |
| * Index: unique index representing the key. |
| */ |
| private var stringMap:Object = {}; |
| |
| /** |
| * incremented to provide a unique index for every string. |
| */ |
| private var stringIndex:int = 0; |
| |
| /** |
| * Collection of lines that have been sent to server. |
| * For the purposes of code coverage there is no need to send a debug line |
| * more than once. |
| */ |
| private var lineMap:Object = {}; |
| |
| /** |
| * socket to send trace data to the server. |
| */ |
| private var socket:CodeCoverageClientSocket; |
| |
| /** |
| * If true ignore the trace data. Used to prevent this code from being part of code |
| * coverage. Is this needed if the application is run w/o debug instructions. |
| */ |
| private var ignoreTrace:Boolean; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Create a socket to handle sending trace data to the server. |
| */ |
| private function createClientSocket():void |
| { |
| var key:String; |
| var value:String; |
| var paramObj:Object = LoaderInfo(this.root.loaderInfo).parameters; |
| var host:String = DEFAULT_HOST; |
| var port:int = DEFAULT_DATA_PORT; |
| var policyFilePort:int = DEFAULT_POLICY_FILE_PORT; |
| |
| for (key in paramObj) |
| { |
| value = String(paramObj[key]); |
| if (key == "host") |
| host = value; |
| else if (key == "dataPort") |
| port = int(value); |
| else if (key == "policyFilePort") |
| policyFilePort = int(value); |
| } |
| |
| socket = new CodeCoverageClientSocket(host, port, policyFilePort); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event handlers |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Callback for methods and lines trace data. |
| */ |
| public function methodsAndLinesCallback(filename:String, lineNumber:int, methodName:String, methodArgs:String):void |
| { |
| if (lineNumber <= 0 || ignoreTrace) |
| return; |
| |
| try |
| { |
| // Map file name to and index |
| if (!stringMap.hasOwnProperty(filename)) |
| { |
| socket.sendData("#" + stringIndex + "," + filename + "\n"); |
| stringMap[filename] = stringIndex.toString(); |
| stringIndex++; |
| } |
| |
| var id:String = stringMap[filename]; |
| var line:String = lineNumber.toString(); |
| var data:String = id + "," + line + "\n"; |
| |
| // Only send a debug line once. |
| if (!lineMap.hasOwnProperty(data)) |
| lineMap[data] = 1; |
| else |
| return; |
| |
| socket.sendData(data); |
| } |
| catch (e:Error) |
| { |
| trace("CodeCoveragePreloadSWF Error: " + e.message); |
| } |
| |
| } |
| |
| /** |
| * Called when the main application finishing loading. |
| * This provides us with the name of the SWF. |
| */ |
| private function allCompleteHandler(event:Event):void |
| { |
| ignoreTrace = true; |
| removeEventListener("allComplete", allCompleteHandler); |
| |
| var loaderInfo:LoaderInfo = event.target as LoaderInfo; |
| socket.sendData("@" + loaderInfo.loaderURL + "\n"); |
| ignoreTrace = false; |
| } |
| |
| } |
| } |