Skip to content
Permalink
Browse files
FLEX-35295 - Switch on Windows Ant Get to download using PowerShell b…
…y introducing class PowerShellFileDownloader which using System.Net.WebClient class and method DownloadFileAsync
  • Loading branch information
piotrzarzycki21 committed Nov 12, 2017
1 parent b7b11bb commit 658a49f938667d59739fc1c09e8127f1406427e1
Show file tree
Hide file tree
Showing 2 changed files with 226 additions and 26 deletions.
@@ -31,14 +31,16 @@ 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;
import mx.resources.ResourceManager;

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 {
@@ -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;
}
}
}

0 comments on commit 658a49f

Please sign in to comment.