Repository: flex-utilities Updated Branches: refs/heads/develop b7b11bbed -> 658a49f93
FLEX-35295 - Switch on Windows Ant Get to download using PowerShell by introducing class PowerShellFileDownloader which using System.Net.WebClient class and method DownloadFileAsync Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/658a49f9 Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/658a49f9 Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/658a49f9 Branch: refs/heads/develop Commit: 658a49f938667d59739fc1c09e8127f1406427e1 Parents: b7b11bb Author: Piotr Zarzycki <[email protected]> Authored: Sun Nov 12 20:19:26 2017 +0100 Committer: Piotr Zarzycki <[email protected]> Committed: Sun Nov 12 20:19:26 2017 +0100 ---------------------------------------------------------------------- .../src/org/apache/flex/ant/tags/Get.as | 107 ++++++++++---- .../flex/utils/PowerShellFileDownloader.as | 145 +++++++++++++++++++ 2 files changed, 226 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/658a49f9/flex-installer/ant_on_air/src/org/apache/flex/ant/tags/Get.as ---------------------------------------------------------------------- diff --git a/flex-installer/ant_on_air/src/org/apache/flex/ant/tags/Get.as b/flex-installer/ant_on_air/src/org/apache/flex/ant/tags/Get.as index b8d76b6..21709de 100644 --- a/flex-installer/ant_on_air/src/org/apache/flex/ant/tags/Get.as +++ b/flex-installer/ant_on_air/src/org/apache/flex/ant/tags/Get.as @@ -31,6 +31,7 @@ package org.apache.flex.ant.tags import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.net.URLRequestHeader; + import flash.system.Capabilities; import flash.utils.ByteArray; import mx.core.IFlexModuleFactory; @@ -38,7 +39,8 @@ package org.apache.flex.ant.tags import org.apache.flex.ant.Ant; import org.apache.flex.ant.tags.supportClasses.TaskHandler; - + import org.apache.flex.utils.PowerShellFileDownloader; + [ResourceBundle("ant")] [Mixin] public class Get extends TaskHandler @@ -81,7 +83,8 @@ package org.apache.flex.ant.tags private var urlLoader:URLLoader; private var lastProgress:ProgressEvent; - + private var powerShellFileDownloader:PowerShellFileDownloader; + override public function execute(callbackMode:Boolean, context:Object):Boolean { super.execute(callbackMode, context); @@ -97,18 +100,20 @@ package org.apache.flex.ant.tags catch (error:Error) { } - + + var destFile:File = getDestFile(); + if (skipexisting) { - var destFile:File = getDestFile(); if (destFile.exists) return true; } + var s:String = ResourceManager.getInstance().getString('ant', 'GETTING'); s = s.replace("%1", src); ant.output(ant.formatOutput("get", s)); s = ResourceManager.getInstance().getString('ant', 'GETTO'); - s = s.replace("%1", getDestFile().nativePath); + s = s.replace("%1", destFile.nativePath); ant.output(ant.formatOutput("get", s)); var actualSrc:String = src; @@ -119,14 +124,14 @@ package org.apache.flex.ant.tags urlLoader = new URLLoader(); urlLoader.load(urlRequest); urlLoader.dataFormat = URLLoaderDataFormat.BINARY; - urlLoader.addEventListener(Event.COMPLETE, completeHandler); + urlLoader.addEventListener(Event.COMPLETE, urlLoaderCompleteHandler); urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, statusHandler); urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler); urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler); urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); return false; } - + private function statusHandler(event:HTTPStatusEvent):void { if (event.status >= 300 && event.status < 400) @@ -136,7 +141,7 @@ package org.apache.flex.ant.tags urlLoader.close(); // remove handlers from old request - urlLoader.removeEventListener(Event.COMPLETE, completeHandler); + urlLoader.removeEventListener(Event.COMPLETE, urlLoaderCompleteHandler); urlLoader.removeEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, statusHandler); urlLoader.removeEventListener(ProgressEvent.PROGRESS, progressHandler); urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler); @@ -167,24 +172,54 @@ package org.apache.flex.ant.tags newlocation += src.substring(DOWNLOADS_SOURCEFORGE_NET.length); } ant.output(ant.formatOutput("get", "Redirected to: " + newlocation)); - var urlRequest:URLRequest = new URLRequest(newlocation); - var refHeader:URLRequestHeader = new URLRequestHeader("Referer", src); - urlRequest.requestHeaders.push(refHeader); - urlRequest.manageCookies = false; - urlRequest.followRedirects = false; - urlRequest.userAgent = "Java"; // required to get sourceforge redirects to do the right thing - urlLoader = new URLLoader(); - urlLoader.load(urlRequest); - urlLoader.dataFormat = URLLoaderDataFormat.BINARY; - urlLoader.addEventListener(Event.COMPLETE, completeHandler); - urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, statusHandler); - urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler); - urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler); - urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); + + if (Capabilities.os.indexOf("Win") != -1) + { + var destination:String = getDestFile().nativePath; + powerShellFileDownloader = new PowerShellFileDownloader(); + powerShellFileDownloader.addEventListener(ProgressEvent.PROGRESS, progressHandler); + powerShellFileDownloader.addEventListener(Event.COMPLETE, powershellDownloadCompleteHandler); + powerShellFileDownloader.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, standardErrorDataHandler); + powerShellFileDownloader.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, ioErrorEventHandler); + powerShellFileDownloader.download(newlocation, destination); + } + else + { + var urlRequest:URLRequest = new URLRequest(newlocation); + var refHeader:URLRequestHeader = new URLRequestHeader("Referer", src); + urlRequest.requestHeaders.push(refHeader); + urlRequest.manageCookies = false; + urlRequest.followRedirects = false; + urlRequest.userAgent = "Java"; // required to get sourceforge redirects to do the right thing + urlLoader = new URLLoader(); + urlLoader.load(urlRequest); + urlLoader.dataFormat = URLLoaderDataFormat.BINARY; + urlLoader.addEventListener(Event.COMPLETE, urlLoaderCompleteHandler); + urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, statusHandler); + urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler); + urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler); + urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); + } } } } - + + private function standardErrorDataHandler(event:ProgressEvent):void + { + if (lastProgress) + ant.output("ioError at: " + lastProgress.bytesLoaded + " of " + lastProgress.bytesTotal); + + ant.output(event.toString()); + if (!ignoreerrors) + { + ant.project.failureMessage = ant.formatOutput("get", event.toString()); + ant.project.status = false; + } + dispatchEvent(new Event(Event.COMPLETE)); + event.preventDefault(); + cleanUpPowerShellFileDownloader(); + } + private function ioErrorEventHandler(event:IOErrorEvent):void { if (lastProgress) @@ -198,7 +233,8 @@ package org.apache.flex.ant.tags } dispatchEvent(new Event(Event.COMPLETE)); event.preventDefault(); - urlLoader = null; + urlLoader = null; + cleanUpPowerShellFileDownloader(); } private function securityErrorHandler(event:SecurityErrorEvent):void @@ -221,7 +257,7 @@ package org.apache.flex.ant.tags ant.dispatchEvent(event); } - private function completeHandler(event:Event):void + private function urlLoaderCompleteHandler(event:Event):void { var destFile:File = getDestFile(); if (destFile) @@ -233,9 +269,28 @@ package org.apache.flex.ant.tags } dispatchEvent(new Event(Event.COMPLETE)); - urlLoader = null; + urlLoader = null; } + private function powershellDownloadCompleteHandler(event:Event):void + { + ant.output("PowerShell download completed."); + dispatchEvent(new Event(Event.COMPLETE)); + cleanUpPowerShellFileDownloader(); + } + + private function cleanUpPowerShellFileDownloader():void + { + if (powerShellFileDownloader) + { + powerShellFileDownloader.removeEventListener(ProgressEvent.PROGRESS, progressHandler); + powerShellFileDownloader.removeEventListener(Event.COMPLETE, powershellDownloadCompleteHandler); + powerShellFileDownloader.removeEventListener(ProgressEvent.STANDARD_ERROR_DATA, standardErrorDataHandler); + powerShellFileDownloader.removeEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, ioErrorEventHandler); + powerShellFileDownloader = null; + } + } + private function getDestFile():File { try { http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/658a49f9/flex-installer/ant_on_air/src/org/apache/flex/utils/PowerShellFileDownloader.as ---------------------------------------------------------------------- diff --git a/flex-installer/ant_on_air/src/org/apache/flex/utils/PowerShellFileDownloader.as b/flex-installer/ant_on_air/src/org/apache/flex/utils/PowerShellFileDownloader.as new file mode 100644 index 0000000..5f1db51 --- /dev/null +++ b/flex-installer/ant_on_air/src/org/apache/flex/utils/PowerShellFileDownloader.as @@ -0,0 +1,145 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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 org.apache.flex.utils +{ + import flash.events.IOErrorEvent; + + import flash.desktop.NativeProcess; + import flash.desktop.NativeProcessStartupInfo; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.NativeProcessExitEvent; + import flash.events.ProgressEvent; + import flash.filesystem.File; + + [Event(name="complete",type="flash.events.Event")] + [Event(name="progress",type="flash.events.ProgressEvent")] + [Event(name="standardErrorData",type="flash.events.ProgressEvent")] + [Event(name="standardOutputIoError",type="flash.events.IOErrorEvent")] + public class PowerShellFileDownloader extends EventDispatcher + { + private var _process:NativeProcess; + private var _url:String; + private var _downloadDestination:String; + + public function download(url:String, downloadDestination:String):void + { + cleanUpPowerShellDownloader(); + + _url = url; + _downloadDestination = downloadDestination; + + var startupInfo:NativeProcessStartupInfo = getNativeProcessStartupInfoDownload(); + + _process = new NativeProcess(); + _process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onDownloadProgress); + _process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onDownloadError); + _process.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError); + _process.addEventListener(Event.STANDARD_OUTPUT_CLOSE, onStandardOutputClose); + _process.addEventListener(NativeProcessExitEvent.EXIT, onDownloadComplete); + _process.start(startupInfo); + } + + private function onStandardOutputClose(event:Event):void + { + dispatchEvent(new Event(Event.COMPLETE)); + cleanUpPowerShellDownloader(); + } + + private function onIOError(event:IOErrorEvent):void + { + dispatchEvent(event.clone()); + cleanUpPowerShellDownloader(); + } + + private function onDownloadComplete(event:NativeProcessExitEvent):void + { + dispatchEvent(new Event(Event.COMPLETE)); + cleanUpPowerShellDownloader(); + } + + private function onDownloadError(event:ProgressEvent):void + { + dispatchEvent(new ProgressEvent(ProgressEvent.STANDARD_ERROR_DATA)); + cleanUpPowerShellDownloader(); + } + + private function onDownloadProgress(event:ProgressEvent):void + { + dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, event.bubbles, + event.cancelable, event.bytesLoaded, event.bytesTotal)); + } + + private function getNativeProcessStartupInfoDownload():NativeProcessStartupInfo + { + var executable:File = new File("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"); + var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); + var arguments:Vector.<String> = new Vector.<String>(); + + var command:String = getPowerShellDownloadCommand(); + arguments.push("-Command"); + arguments.push(command); + + startupInfo.executable = executable; + startupInfo.arguments = arguments; + + return startupInfo; + } + + private function getPowerShellDownloadCommand():String + { + var command:String = "& {"; + command += "Param([string]$url,[string]$outPath) "; + command += "$url = [System.Uri]$url; "; + command += "$webClient = New-Object System.Net.WebClient; "; + command += "$webClient.DownloadFileAsync($url, $outPath); "; + command += "while ($webClient.IsBusy) { Start-Sleep -Milliseconds 10 } "; + command += "[Environment]::Exit(0);"; + command += "}"; + command += " "; + command += "\""; + command += _url; + command += "\""; + command += " "; + command += "\""; + command += _downloadDestination; + command += "\""; + + return command; + } + + private function cleanUpPowerShellDownloader():void + { + if (_process) + { + _process.closeInput(); + _process.removeEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onDownloadProgress); + _process.removeEventListener(ProgressEvent.STANDARD_ERROR_DATA, onDownloadError); + _process.removeEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError); + _process.removeEventListener(Event.STANDARD_OUTPUT_CLOSE, onStandardOutputClose); + _process.removeEventListener(NativeProcessExitEvent.EXIT, onDownloadComplete); + + _process = null; + } + + _url = null; + _downloadDestination = null; + } + } +}
