You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2013/12/10 00:30:03 UTC
[01/14] git commit: [flex-utilities] [refs/heads/develop] - added
Available task
Updated Branches:
refs/heads/develop 2cc92bf16 -> 1d9886ddb
added Available task
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/26b6f4ca
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/26b6f4ca
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/26b6f4ca
Branch: refs/heads/develop
Commit: 26b6f4ca61cff6edcbe04f6437aceb627466d772
Parents: c2f4d93
Author: Alex Harui <ah...@apache.org>
Authored: Sat Dec 7 21:49:08 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Sat Dec 7 21:50:43 2013 -0800
----------------------------------------------------------------------
.../src/org/apache/flex/ant/tags/Available.as | 83 ++++++++++++++++++++
1 file changed, 83 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/26b6f4ca/ant_on_air/src/org/apache/flex/ant/tags/Available.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Available.as b/ant_on_air/src/org/apache/flex/ant/tags/Available.as
new file mode 100644
index 0000000..e3abf87
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Available.as
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags
+{
+ import flash.filesystem.File;
+
+ import mx.core.IFlexModuleFactory;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.supportClasses.IValueTagHandler;
+ import org.apache.flex.ant.tags.supportClasses.TaskHandler;
+
+ [Mixin]
+ public class Available extends TaskHandler implements IValueTagHandler
+ {
+ public static function init(mf:IFlexModuleFactory):void
+ {
+ Ant.antTagProcessors["available"] = Available;
+ }
+
+ public function Available()
+ {
+ super();
+ }
+
+ private var _file:String;
+ private var _type:String;
+ private var _property:String;
+ private var _value:String;
+
+ public function get value():Object
+ {
+ if (_file == null) return false;
+
+ var file:File = new File(_file);
+ if (!file.exists)
+ return false;
+
+ if (_type == "dir" && !file.isDirectory)
+ return false;
+
+ return true;
+ }
+
+ override public function execute():Boolean
+ {
+ super.execute();
+ if (value)
+ if (!context.hasOwnProperty(_property))
+ context[_property] = _value;
+ return true;
+ }
+
+ override protected function processAttribute(name:String, value:String):void
+ {
+ if (name == "file")
+ _file = value;
+ else if (name == "type")
+ _type = value;
+ if (name == "property")
+ _property = value;
+ if (name == "value")
+ _value = value;
+ }
+
+ }
+}
\ No newline at end of file
[14/14] git commit: [flex-utilities] [refs/heads/develop] - add
support for failonerror and reporting failures
Posted by ah...@apache.org.
add support for failonerror and reporting failures
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/1d9886dd
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/1d9886dd
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/1d9886dd
Branch: refs/heads/develop
Commit: 1d9886ddbd2dc91c94ce9190a8a408a2e9990ee5
Parents: a8ab9e1
Author: Alex Harui <ah...@apache.org>
Authored: Mon Dec 9 15:27:45 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Dec 9 15:27:45 2013 -0800
----------------------------------------------------------------------
ant_on_air/src/org/apache/flex/ant/Ant.as | 5 +++-
.../src/org/apache/flex/ant/tags/Condition.as | 12 ++++++--
.../src/org/apache/flex/ant/tags/Project.as | 28 ++++++++++++++++++-
.../src/org/apache/flex/ant/tags/Target.as | 9 ++++++
.../tags/supportClasses/FileSetTaskHandler.as | 22 +++++++++++----
.../flex/ant/tags/supportClasses/TaskHandler.as | 10 +++++++
ant_on_air/tests/TestTarget.as | 6 ++++
ant_on_air/tests/test.xml | 29 ++++++++++++++++++++
8 files changed, 111 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/1d9886dd/ant_on_air/src/org/apache/flex/ant/Ant.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/Ant.as b/ant_on_air/src/org/apache/flex/ant/Ant.as
index 0f487a3..7476daf 100644
--- a/ant_on_air/src/org/apache/flex/ant/Ant.as
+++ b/ant_on_air/src/org/apache/flex/ant/Ant.as
@@ -48,9 +48,12 @@ package org.apache.flex.ant
private var file:File;
/**
- * Open a file, read the XML and create ITagHandlers for every tag
+ * Open a file, read the XML, create ITagHandlers for every tag, then process them.
+ * When finished, check the project's status property. If it is true then all
+ * tasks completed successfully
* @param file File The file to open.
* @param context Object An object containing an optional targets property listing the targets to run.
+ * @return true if XML file was processed synchronously. If false, then add listener for Event.COMPLETE.
*/
public function processXMLFile(file:File, context:Object = null):Boolean
{
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/1d9886dd/ant_on_air/src/org/apache/flex/ant/tags/Condition.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Condition.as b/ant_on_air/src/org/apache/flex/ant/tags/Condition.as
index 7f94d8f..814811d 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Condition.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Condition.as
@@ -46,19 +46,25 @@ package org.apache.flex.ant.tags
// if the property is not already set
if (_property && _value != null && !context.hasOwnProperty(_property))
{
- // get the value from the children
- var val:Object = IValueTagHandler(getChildAt(0)).value;
+ var val:Object = computedValue;
if (val == "true" || val == true)
{
// set it if we should
if (_value != null)
val = _value;
context[_property] = val;
- }
+ }
}
return true;
}
+ public function get computedValue():Object
+ {
+ // get the value from the children
+ var val:Object = IValueTagHandler(getChildAt(0)).value;
+ return val;
+ }
+
private var _property:String;
private var _value:Object;
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/1d9886dd/ant_on_air/src/org/apache/flex/ant/tags/Project.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Project.as b/ant_on_air/src/org/apache/flex/ant/tags/Project.as
index 5136f55..22435f4 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Project.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Project.as
@@ -52,6 +52,13 @@ package org.apache.flex.ant.tags
{
}
+ /**
+ * true if tasks completed successfully.
+ * Do not monitor this property to determine if the project is done executing.
+ * This property is set to true and a failing task sets it to false.
+ */
+ public var status:Boolean;
+
override public function init(xml:XML, context:Object, xmlProcessor:XMLTagProcessor):void
{
context.project = this;
@@ -87,6 +94,8 @@ package org.apache.flex.ant.tags
override public function execute():Boolean
{
+ status = true;
+
if (context.targets == null)
context.targets == _defaultTarget;
@@ -100,6 +109,12 @@ package org.apache.flex.ant.tags
private function executeChildren():Boolean
{
+ if (!status)
+ {
+ dispatchEvent(new Event(Event.COMPLETE));
+ return true;
+ }
+
if (current == numChildren)
return executeTargets();
@@ -116,6 +131,11 @@ package org.apache.flex.ant.tags
task.addEventListener(Event.COMPLETE, childCompleteHandler);
return false;
}
+ if (!status)
+ {
+ dispatchEvent(new Event(Event.COMPLETE));
+ return true;
+ }
}
}
return executeTargets();
@@ -127,7 +147,13 @@ package org.apache.flex.ant.tags
{
var targetName:String = targets.shift();
if (!executeTarget(targetName))
- return false;
+ return false;
+ if (!status)
+ {
+ dispatchEvent(new Event(Event.COMPLETE));
+ return true;
+ }
+
}
if (targets.length == 0)
dispatchEvent(new Event(Event.COMPLETE));
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/1d9886dd/ant_on_air/src/org/apache/flex/ant/tags/Target.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Target.as b/ant_on_air/src/org/apache/flex/ant/tags/Target.as
index df47ffa..0504237 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Target.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Target.as
@@ -111,6 +111,8 @@ package org.apache.flex.ant.tags
private function continueOnToSteps():Boolean
{
+ if (!Ant.project.status)
+ return true;
ant.processChildren(xml, context, this);
return processSteps();
}
@@ -133,6 +135,8 @@ package org.apache.flex.ant.tags
step.addEventListener(Event.COMPLETE, completeHandler);
return false;
}
+ if (!Ant.project.status)
+ return true;
}
dispatchEvent(new Event(Event.COMPLETE));
return true;
@@ -140,6 +144,11 @@ package org.apache.flex.ant.tags
private function completeHandler(event:Event):void
{
+ if (!Ant.project.status)
+ {
+ dispatchEvent(new Event(Event.COMPLETE));
+ return;
+ }
processSteps();
}
}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/1d9886dd/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
index c0320a8..21ffc9b 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
@@ -20,6 +20,7 @@ package org.apache.flex.ant.tags.supportClasses
{
import flash.filesystem.File;
+ import org.apache.flex.ant.Ant;
import org.apache.flex.ant.tags.FileSet;
/**
@@ -46,13 +47,24 @@ package org.apache.flex.ant.tags.supportClasses
var fs:FileSet = getChildAt(i) as FileSet;
if (fs)
{
- var list:Vector.<String> = fs.value as Vector.<String>;
- if (list)
+ try
{
- var dir:File = new File(fs.dir);
- for each (var fileName:String in list)
+ var list:Vector.<String> = fs.value as Vector.<String>;
+ if (list)
{
- actOnFile(dir.nativePath, fileName);
+ var dir:File = new File(fs.dir);
+ for each (var fileName:String in list)
+ {
+ actOnFile(dir.nativePath, fileName);
+ }
+ }
+ }
+ catch (e:Error)
+ {
+ if (failonerror)
+ {
+ Ant.project.status = false;
+ return true;
}
}
}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/1d9886dd/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as
index 910753e..d5fdcba 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as
@@ -28,6 +28,8 @@ package org.apache.flex.ant.tags.supportClasses
{
}
+ public var failonerror:Boolean = true
+
/**
* Do the work.
* TaskHandlers lazily create their children so
@@ -39,5 +41,13 @@ package org.apache.flex.ant.tags.supportClasses
ant.processChildren(this.xml, context, this);
return true;
}
+
+ override protected function processAttribute(name:String, value:String):void
+ {
+ if (name == "failonerror")
+ failonerror = value == "true";
+ else
+ super.processAttribute(name, value);
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/1d9886dd/ant_on_air/tests/TestTarget.as
----------------------------------------------------------------------
diff --git a/ant_on_air/tests/TestTarget.as b/ant_on_air/tests/TestTarget.as
index 722986a..2570c20 100644
--- a/ant_on_air/tests/TestTarget.as
+++ b/ant_on_air/tests/TestTarget.as
@@ -28,11 +28,13 @@ package
import org.apache.flex.ant.tags.Copy; Copy.init(null);
import org.apache.flex.ant.tags.Delete; Delete.init(null);
import org.apache.flex.ant.tags.Echo; Echo.init(null);
+ import org.apache.flex.ant.tags.Fail; Fail.init(null);
import org.apache.flex.ant.tags.FileSet; FileSet.init(null);
import org.apache.flex.ant.tags.FileSetExclude; FileSetExclude.init(null);
import org.apache.flex.ant.tags.FileSetInclude; FileSetInclude.init(null);
import org.apache.flex.ant.tags.IsSet; IsSet.init(null);
import org.apache.flex.ant.tags.Mkdir; Mkdir.init(null);
+ import org.apache.flex.ant.tags.Not; Not.init(null);
import org.apache.flex.ant.tags.OS; OS.init(null);
import org.apache.flex.ant.tags.Project; Project.init(null);
import org.apache.flex.ant.tags.Property; Property.init(null);
@@ -54,6 +56,10 @@ package
private function completeHandler(event:Event):void
{
+ if (Ant.project.status)
+ trace("SUCCESS!");
+ else
+ trace("FAILURE!");
NativeApplication.nativeApplication.exit();
}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/1d9886dd/ant_on_air/tests/test.xml
----------------------------------------------------------------------
diff --git a/ant_on_air/tests/test.xml b/ant_on_air/tests/test.xml
index 8114225..df33ee7 100644
--- a/ant_on_air/tests/test.xml
+++ b/ant_on_air/tests/test.xml
@@ -48,6 +48,13 @@
<mkdir dir="${basedir}/temp" />
<copy file="${basedir}/test.xml" toFile="${basedir}/temp/copied.xml" />
<available file="${basedir}/temp/copied.xml" property="copied.doesnt.exist" value="got copied" />
+ <fail message="test.xml was not copied to temp/copied.xml">
+ <condition>
+ <not>
+ <available file="${basedir}/temp/copied.xml" />
+ </not>
+ </condition>
+ </fail>
<echo>copied ${copied.doesnt.exist}. Should say: got copied</echo>
<copy toDir="${basedir}/temp">
<fileset dir="${basedir}/../src">
@@ -56,14 +63,36 @@
</fileset>
</copy>
<available file="${basedir}/temp/org/apache/flex/ant/Ant.as" property="ant.doesnt.exist" value="got copied" />
+ <fail message="Ant.as was copied to temp">
+ <condition>
+ <available file="${basedir}/temp/org/apache/flex/ant/Ant.as" />
+ </condition>
+ </fail>
<echo>Ant.as ${ant.doesnt.exist}. Should NOT say: got copied</echo>
<available file="${basedir}/temp/org/apache/flex/ant/tags/Project.as" property="project.doesnt.exist" value="got copied" />
+ <fail message="Project.as was not copied to temp">
+ <condition>
+ <not>
+ <available file="${basedir}/temp/org/apache/flex/ant/tags/Project.as" />
+ </not>
+ </condition>
+ </fail>
<echo>Project.as ${project.doesnt.exist}. Should say: got copied</echo>
<delete file="${basedir}/temp/copied.xml" />
<available file="${basedir}/temp/copied.xml" property="copied.doesnt.exist.after.delete" value="didn't get deleted" />
+ <fail message="temp/copied.xml was not deleted">
+ <condition>
+ <available file="${basedir}/temp/copied.xml" />
+ </condition>
+ </fail>
<echo>copied.xml ${copied.doesnt.exist.after.delete}. Should NOT say: didn't get deleted</echo>
<delete dir="${basedir}/temp" />
<available file="${basedir}/temp/org/apache/flex/ant/tags/Project.as" property="project.doesnt.exist.after.delete" value="didn't get deleted" />
+ <fail message="temp/copied.xml was not deleted">
+ <condition>
+ <available file="${basedir}/temp/org/apache/flex/ant/tags/Project.as" />
+ </condition>
+ </fail>
<echo>Project.as ${project.doesnt.exist.after.delete}. Should NOT say: didn't get deleted</echo>
</target>
[04/14] port DirectoryScanner from Ant code base and hook up FileSet
to it
Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/TokenizedPath.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/TokenizedPath.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/TokenizedPath.as
new file mode 100644
index 0000000..f9dc3d2
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/TokenizedPath.as
@@ -0,0 +1,221 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import flash.filesystem.File;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.filesetClasses.FileUtils;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.BuildException;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.IOException;
+
+ /**
+ * Ported from org.apache.tools.ant.types.selectors.TokenizedPath.java on 12/3/13;
+ * Container for a path that has been split into its components.
+ * @since 1.8.0
+ */
+ public class TokenizedPath {
+
+ /**
+ * Instance that holds no tokens at all.
+ */
+ public static const EMPTY_PATH:TokenizedPath =
+ new TokenizedPath("").init("", new Vector.<String>());
+
+ /** Helper. */
+ private static const FILE_UTILS:FileUtils = FileUtils.getFileUtils();
+ /** Helper. */
+ /** iterations for case-sensitive scanning. */
+ private static const CS_SCAN_ONLY:Vector.<Boolean> = new Vector.<Boolean>([true]);
+ /** iterations for non-case-sensitive scanning. */
+ private static const CS_THEN_NON_CS:Vector.<Boolean> = new Vector.<Boolean>([true, false]);
+
+ private var path:String;
+ private var tokenizedPath:Vector.<String>;
+
+ /**
+ * Initialize the TokenizedPath by parsing it.
+ * @param path The path to tokenize. Must not be
+ * <code>null</code>.
+ */
+ public function TokenizedPath(path:String) {
+ init(path, SelectorUtils.tokenizePathAsArray(path));
+ }
+
+ /**
+ * Creates a new path as a child of another path.
+ *
+ * @param parent the parent path
+ * @param child the child, must not contain the file separator
+ */
+ public function initAsChild(parent:TokenizedPath, child:String):TokenizedPath {
+ if (parent.path.length > 0
+ && parent.path.charAt(parent.path.length - 1)
+ != File.separator) {
+ path = parent.path + File.separator + child;
+ } else {
+ path = parent.path + child;
+ }
+ tokenizedPath = parent.tokenizedPath.slice();
+ tokenizedPath.push(child);
+ return this;
+ }
+
+ /* package */ public function init(path:String, tokens:Vector.<String>):TokenizedPath {
+ this.path = path;
+ this.tokenizedPath = tokens;
+ return this;
+ }
+
+ /**
+ * @return The original path String
+ */
+ public function toString():String {
+ return path;
+ }
+
+ /**
+ * The depth (or length) of a path.
+ */
+ public function depth():int {
+ return tokenizedPath.length;
+ }
+
+ /* package */ public function getTokens():Vector.<String> {
+ return tokenizedPath;
+ }
+
+ /**
+ * From <code>base</code> traverse the filesystem in order to find
+ * a file that matches the given name.
+ *
+ * @param base base File (dir).
+ * @param cs whether to scan case-sensitively.
+ * @return File object that points to the file in question or null.
+ */
+ public function findFile(base:File, cs:Boolean):File {
+ var tokens:Vector.<String> = tokenizedPath;
+ if (FileUtils.isAbsolutePath(path)) {
+ if (base == null) {
+ var s:Vector.<String> = FILE_UTILS.dissect(path);
+ base = new File(s[0]);
+ tokens = SelectorUtils.tokenizePathAsArray(s[1]);
+ } else {
+ var f:File = FILE_UTILS.normalize(path);
+ var n:String = FILE_UTILS.removeLeadingPath(base, f);
+ if (n == f.nativePath) {
+ //removing base from path yields no change; path
+ //not child of base
+ return null;
+ }
+ tokens = SelectorUtils.tokenizePathAsArray(n);
+ }
+ }
+ return TokenizedPath.findFile(base, tokens, cs);
+ }
+
+
+ /**
+ * Do we have to traverse a symlink when trying to reach path from
+ * basedir?
+ * @param base base File (dir).
+ */
+ public function isSymlink(base:File):Boolean {
+ for (var i:int = 0; i < tokenizedPath.length; i++) {
+ try {
+ if ((base != null
+ && new File(base.nativePath + File.separator + tokenizedPath[i]).isSymbolicLink)
+ ||
+ (base == null
+ && new File(tokenizedPath[i]).isSymbolicLink)
+ ) {
+ return true;
+ }
+ base = new File(base + File.separator + tokenizedPath[i]);
+ } catch (ioe:IOException) {
+ var msg:String = "IOException caught while checking "
+ + "for links, couldn't get canonical path!";
+ // will be caught and redirected to Ant's logging system
+ Ant.ant.output(msg);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * true if the original paths are equal.
+ */
+ public function equals(o:Object):Boolean {
+ return o is TokenizedPath
+ && path == TokenizedPath(o).path;
+ }
+
+ /**
+ * From <code>base</code> traverse the filesystem in order to find
+ * a file that matches the given stack of names.
+ *
+ * @param base base File (dir) - must not be null.
+ * @param pathElements array of path elements (dirs...file).
+ * @param cs whether to scan case-sensitively.
+ * @return File object that points to the file in question or null.
+ */
+ private static function findFile(base:File, pathElements:Vector.<String>,
+ cs:Boolean):File {
+ for (var current:int = 0; current < pathElements.length; current++) {
+ if (!base.isDirectory) {
+ return null;
+ }
+ var arr:Array = base.getDirectoryListing();
+ var arr2:Array = [];
+ for each (var f:File in arr)
+ arr2.push(f.nativePath);
+ var files:Vector.<String> = Vector.<String>(arr2);
+ if (files == null) {
+ throw new BuildException("IO error scanning directory "
+ + base.nativePath);
+ }
+ var found:Boolean = false;
+ var matchCase:Vector.<Boolean> = cs ? CS_SCAN_ONLY : CS_THEN_NON_CS;
+ for (var i:int = 0; !found && i < matchCase.length; i++) {
+ for (var j:int = 0; !found && j < files.length; j++) {
+ if (matchCase[i]
+ ? files[j] == pathElements[current]
+ : files[j].toUpperCase() == pathElements[current].toUpperCase()) {
+ base = new File(base.nativePath + File.separator + files[j]);
+ found = true;
+ }
+ }
+ }
+ if (!found) {
+ return null;
+ }
+ }
+ return pathElements.length == 0 && !base.isDirectory ? null : base;
+ }
+
+ /**
+ * Creates a TokenizedPattern from the same tokens that make up
+ * this path.
+ */
+ public function toPattern():TokenizedPattern {
+ return new TokenizedPattern(path).init(path, tokenizedPath);
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/TokenizedPattern.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/TokenizedPattern.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/TokenizedPattern.as
new file mode 100644
index 0000000..3055dbb
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/TokenizedPattern.as
@@ -0,0 +1,173 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import flash.filesystem.File;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.IllegalStateException;
+
+ /**
+ * Ported from org.apache.tools.ant.types.selector.TokenizedPattern.java on 12/3/13.
+ * Provides reusable path pattern matching. PathPattern is preferable
+ * to equivalent SelectorUtils methods if you need to execute multiple
+ * matching with the same pattern because here the pattern itself will
+ * be parsed only once.
+ * @see SelectorUtils#matchPath(String, String)
+ * @see SelectorUtils#matchPath(String, String, boolean)
+ * @since 1.8.0
+ */
+ public class TokenizedPattern {
+
+ /**
+ * Instance that holds no tokens at all.
+ */
+ public static const EMPTY_PATTERN:TokenizedPattern =
+ new TokenizedPattern("").init("", new Vector.<String>());
+
+ private var pattern:String;
+ private var tokenizedPattern:Vector.<String>;
+
+ /**
+ * Initialize the PathPattern by parsing it.
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ */
+ public function TokenizedPattern(pattern:String) {
+ init(pattern, SelectorUtils.tokenizePathAsArray(pattern));
+ }
+
+ public function init(pattern:String, tokens:Vector.<String>):TokenizedPattern {
+ this.pattern = pattern;
+ this.tokenizedPattern = tokens;
+ return this;
+ }
+
+ /**
+ * Tests whether or not a given path matches a given pattern.
+ *
+ * @param path The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ public function matchPath(path:TokenizedPath, isCaseSensitive:Boolean):Boolean {
+ return SelectorUtils.matchPathVectors(tokenizedPattern, path.getTokens(),
+ isCaseSensitive);
+ }
+
+ /**
+ * Tests whether or not this pattern matches the start of
+ * a path.
+ */
+ public function matchStartOf(path:TokenizedPath,
+ caseSensitive:Boolean):Boolean {
+ return SelectorUtils.matchPatternStartVectors(tokenizedPattern,
+ path.getTokens(), caseSensitive);
+ }
+
+ /**
+ * @return The pattern String
+ */
+ public function toString():String {
+ return pattern;
+ }
+
+ public function getPattern():String {
+ return pattern;
+ }
+
+ /**
+ * true if the original patterns are equal.
+ */
+ public function equals(o:Object):Boolean {
+ return o is TokenizedPattern
+ && pattern == TokenizedPattern(o).pattern;
+ }
+
+ /**
+ * The depth (or length) of a pattern.
+ */
+ public function depth():int {
+ return tokenizedPattern.length;
+ }
+
+ /**
+ * Does the tokenized pattern contain the given string?
+ */
+ public function containsPattern(pat:String):Boolean {
+ for (var i:int = 0; i < tokenizedPattern.length; i++) {
+ if (tokenizedPattern[i] == pat) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a new TokenizedPath where all tokens of this pattern to
+ * the right containing wildcards have been removed
+ * @return the leftmost part of the pattern without wildcards
+ */
+ public function rtrimWildcardTokens():TokenizedPath {
+ var sb:String = "";
+ var newLen:int = 0;
+ for (; newLen < tokenizedPattern.length; newLen++) {
+ if (SelectorUtils.hasWildcards(tokenizedPattern[newLen])) {
+ break;
+ }
+ if (newLen > 0
+ && sb.charAt(sb.length - 1) != File.separator) {
+ sb += File.separator;
+ }
+ sb += tokenizedPattern[newLen];
+ }
+ if (newLen == 0) {
+ return TokenizedPath.EMPTY_PATH;
+ }
+ var newPats:Vector.<String> = tokenizedPattern.slice(0, newLen);
+ return new TokenizedPath("").init(sb, newPats);
+ }
+
+ /**
+ * true if the last token equals the given string.
+ */
+ public function endsWith(s:String):Boolean {
+ return tokenizedPattern.length > 0
+ && tokenizedPattern[tokenizedPattern.length - 1] == s;
+ }
+
+ /**
+ * Returns a new pattern without the last token of this pattern.
+ */
+ public function withoutLastToken():TokenizedPattern {
+ if (tokenizedPattern.length == 0) {
+ throw new IllegalStateException("cant strip a token from nothing");
+ } else if (tokenizedPattern.length == 1) {
+ return EMPTY_PATTERN;
+ } else {
+ var toStrip:String = tokenizedPattern[tokenizedPattern.length - 1];
+ var index:int = pattern.lastIndexOf(toStrip);
+ var tokens:Vector.<String> = tokenizedPattern.slice(0, tokenizedPattern.length - 1);
+ return new TokenizedPattern("").init(pattern.substring(0, index), tokens);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/BuildException.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/BuildException.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/BuildException.as
new file mode 100644
index 0000000..6be2bc5
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/BuildException.as
@@ -0,0 +1,28 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.filesetClasses.exceptions
+{
+ public class BuildException extends Error
+ {
+ public function BuildException(message:String)
+ {
+ super(message);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/IOException.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/IOException.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/IOException.as
new file mode 100644
index 0000000..0eb329d
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/IOException.as
@@ -0,0 +1,28 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.filesetClasses.exceptions
+{
+ public class IOException extends Error
+ {
+ public function IOException(message:String)
+ {
+ super(message);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/IllegalStateException.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/IllegalStateException.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/IllegalStateException.as
new file mode 100644
index 0000000..5d00f7f
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/IllegalStateException.as
@@ -0,0 +1,28 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.filesetClasses.exceptions
+{
+ public class IllegalStateException extends Error
+ {
+ public function IllegalStateException(message:String)
+ {
+ super(message);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/UnsupportedOperationException.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/UnsupportedOperationException.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/UnsupportedOperationException.as
new file mode 100644
index 0000000..b885fac
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/exceptions/UnsupportedOperationException.as
@@ -0,0 +1,28 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.filesetClasses.exceptions
+{
+ public class UnsupportedOperationException extends Error
+ {
+ public function UnsupportedOperationException()
+ {
+ super("UnsupportedOperationException");
+ }
+ }
+}
\ No newline at end of file
[11/14] git commit: [flex-utilities] [refs/heads/develop] - add mkdir
and delete tasks
Posted by ah...@apache.org.
add mkdir and delete tasks
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/a4728f76
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/a4728f76
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/a4728f76
Branch: refs/heads/develop
Commit: a4728f7629ddda6778a41e7c3cb655e61f759b44
Parents: 00bf3f9
Author: Alex Harui <ah...@apache.org>
Authored: Mon Dec 9 14:01:26 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Dec 9 14:01:26 2013 -0800
----------------------------------------------------------------------
ant_on_air/src/AntClasses.as | 2 +
.../src/org/apache/flex/ant/tags/Delete.as | 88 ++++++++++++++++++++
.../src/org/apache/flex/ant/tags/Mkdir.as | 60 +++++++++++++
3 files changed, 150 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a4728f76/ant_on_air/src/AntClasses.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/AntClasses.as b/ant_on_air/src/AntClasses.as
index 3180f70..cc869ea 100644
--- a/ant_on_air/src/AntClasses.as
+++ b/ant_on_air/src/AntClasses.as
@@ -27,11 +27,13 @@ package
import org.apache.flex.ant.tags.Available; Available;
import org.apache.flex.ant.tags.Condition; Condition;
import org.apache.flex.ant.tags.Copy; Copy;
+ import org.apache.flex.ant.tags.Delete; Delete;
import org.apache.flex.ant.tags.Echo; Echo;
import org.apache.flex.ant.tags.FileSet; FileSet;
import org.apache.flex.ant.tags.FileSetExclude; FileSetExclude;
import org.apache.flex.ant.tags.FileSetInclude; FileSetInclude;
import org.apache.flex.ant.tags.IsSet; IsSet;
+ import org.apache.flex.ant.tags.Mkdir; Mkdir;
import org.apache.flex.ant.tags.OS; OS;
import org.apache.flex.ant.tags.Property; Property;
}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a4728f76/ant_on_air/src/org/apache/flex/ant/tags/Delete.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Delete.as b/ant_on_air/src/org/apache/flex/ant/tags/Delete.as
new file mode 100644
index 0000000..40f697a
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Delete.as
@@ -0,0 +1,88 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags
+{
+ import flash.filesystem.File;
+
+ import mx.core.IFlexModuleFactory;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.supportClasses.FileSetTaskHandler;
+
+ [Mixin]
+ public class Delete extends FileSetTaskHandler
+ {
+ public static function init(mf:IFlexModuleFactory):void
+ {
+ Ant.antTagProcessors["delete"] = Delete;
+ }
+
+ public function Delete()
+ {
+ super();
+ }
+
+ private var fileName:String;
+ private var dirName:String;
+
+ override protected function processAttribute(name:String, value:String):void
+ {
+ if (name == "file")
+ fileName = value;
+ else if (name == "dir")
+ dirName = value;
+ else
+ super.processAttribute(name, value);
+ }
+
+ override protected function actOnFile(dir:String, fileName:String):void
+ {
+ var srcName:String;
+ if (dir)
+ srcName = dir + File.separator + fileName;
+ else
+ srcName = fileName;
+ var delFile:File = File.applicationDirectory.resolvePath(srcName);
+ if (delFile.isDirectory)
+ delFile.deleteDirectory(true);
+ else
+ delFile.deleteFile();
+ }
+
+ override public function execute():Boolean
+ {
+ var retVal:Boolean = super.execute();
+ if (numChildren > 0)
+ return retVal;
+
+ if (fileName)
+ {
+ var delFile:File = File.applicationDirectory.resolvePath(fileName);
+ delFile.deleteFile();
+ }
+ else if (dirName)
+ {
+ var delDir:File = File.applicationDirectory.resolvePath(dirName);
+ delDir.deleteDirectory(true);
+ }
+ return true;
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a4728f76/ant_on_air/src/org/apache/flex/ant/tags/Mkdir.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Mkdir.as b/ant_on_air/src/org/apache/flex/ant/tags/Mkdir.as
new file mode 100644
index 0000000..111b0aa
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Mkdir.as
@@ -0,0 +1,60 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags
+{
+ import flash.filesystem.File;
+
+ import mx.core.IFlexModuleFactory;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.supportClasses.TaskHandler;
+
+ [Mixin]
+ public class Mkdir extends TaskHandler
+ {
+ public static function init(mf:IFlexModuleFactory):void
+ {
+ Ant.antTagProcessors["mkdir"] = Mkdir;
+ }
+
+ public function Mkdir()
+ {
+ super();
+ }
+
+ private var _dir:String;
+
+ override public function execute():Boolean
+ {
+ super.execute();
+
+ var dir:File = new File(_dir);
+ dir.createDirectory();
+
+ return true;
+ }
+
+ override protected function processAttribute(name:String, value:String):void
+ {
+ if (name == "dir")
+ _dir = value;
+ }
+
+ }
+}
\ No newline at end of file
[13/14] git commit: [flex-utilities] [refs/heads/develop] - add
and tags
Posted by ah...@apache.org.
add <not> and <fail> tags
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/a8ab9e14
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/a8ab9e14
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/a8ab9e14
Branch: refs/heads/develop
Commit: a8ab9e1404e1e4da98050d67ca0e9a0d49f4ac9d
Parents: 3a3f232
Author: Alex Harui <ah...@apache.org>
Authored: Mon Dec 9 15:26:53 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Dec 9 15:26:53 2013 -0800
----------------------------------------------------------------------
ant_on_air/src/AntClasses.as | 2 +
ant_on_air/src/org/apache/flex/ant/tags/Fail.as | 78 ++++++++++++++++++++
ant_on_air/src/org/apache/flex/ant/tags/Not.as | 56 ++++++++++++++
3 files changed, 136 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a8ab9e14/ant_on_air/src/AntClasses.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/AntClasses.as b/ant_on_air/src/AntClasses.as
index cc869ea..4e7491c 100644
--- a/ant_on_air/src/AntClasses.as
+++ b/ant_on_air/src/AntClasses.as
@@ -29,11 +29,13 @@ package
import org.apache.flex.ant.tags.Copy; Copy;
import org.apache.flex.ant.tags.Delete; Delete;
import org.apache.flex.ant.tags.Echo; Echo;
+ import org.apache.flex.ant.tags.Fail; Fail;
import org.apache.flex.ant.tags.FileSet; FileSet;
import org.apache.flex.ant.tags.FileSetExclude; FileSetExclude;
import org.apache.flex.ant.tags.FileSetInclude; FileSetInclude;
import org.apache.flex.ant.tags.IsSet; IsSet;
import org.apache.flex.ant.tags.Mkdir; Mkdir;
+ import org.apache.flex.ant.tags.Not; Not;
import org.apache.flex.ant.tags.OS; OS;
import org.apache.flex.ant.tags.Property; Property;
}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a8ab9e14/ant_on_air/src/org/apache/flex/ant/tags/Fail.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Fail.as b/ant_on_air/src/org/apache/flex/ant/tags/Fail.as
new file mode 100644
index 0000000..1016b62
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Fail.as
@@ -0,0 +1,78 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags
+{
+ import mx.core.IFlexModuleFactory;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.supportClasses.IValueTagHandler;
+ import org.apache.flex.ant.tags.supportClasses.TaskHandler;
+ import org.apache.flex.xml.ITextTagHandler;
+
+ [Mixin]
+ public class Fail extends TaskHandler implements ITextTagHandler
+ {
+ public static function init(mf:IFlexModuleFactory):void
+ {
+ Ant.antTagProcessors["fail"] = Fail;
+ }
+
+ public function Fail()
+ {
+ super();
+ }
+
+ private var text:String;
+
+ public function setText(text:String):void
+ {
+ this.text = text;
+ }
+
+ override protected function processAttribute(name:String, value:String):void
+ {
+ if (name == "message")
+ text = value;
+ else
+ super.processAttribute(name, value);
+ }
+
+ override public function execute():Boolean
+ {
+ super.execute();
+ if (numChildren == 1)
+ {
+ var child:Condition = getChildAt(0) as Condition;
+ if (child)
+ {
+ child.execute();
+ var val:Object = child.computedValue;
+ if (!(val == "true" || val == true))
+ {
+ return true;
+ }
+ }
+ }
+ if (text)
+ ant.output(ant.getValue(text, context));
+ Ant.project.status = false;
+ return true;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a8ab9e14/ant_on_air/src/org/apache/flex/ant/tags/Not.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Not.as b/ant_on_air/src/org/apache/flex/ant/tags/Not.as
new file mode 100644
index 0000000..3ea0b7e
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Not.as
@@ -0,0 +1,56 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags
+{
+ import mx.core.IFlexModuleFactory;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.supportClasses.IValueTagHandler;
+ import org.apache.flex.ant.tags.supportClasses.ParentTagHandler;
+
+ [Mixin]
+ public class Not extends ParentTagHandler implements IValueTagHandler
+ {
+ public static function init(mf:IFlexModuleFactory):void
+ {
+ Ant.antTagProcessors["not"] = Not;
+ }
+
+ public function Not()
+ {
+ super();
+ }
+
+ public function get value():Object
+ {
+ ant.processChildren(xml, context, this);
+ if (numChildren == 1)
+ {
+ var value:IValueTagHandler = getChildAt(0) as IValueTagHandler;
+ // get the value from the children
+ var val:Object = IValueTagHandler(value).value;
+ if (!(val == "true" || val == true))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
[07/14] git commit: [flex-utilities] [refs/heads/develop] - port
DirectoryScanner from Ant code base and hook up FileSet to it
Posted by ah...@apache.org.
port DirectoryScanner from Ant code base and hook up FileSet to it
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/3a58a60e
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/3a58a60e
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/3a58a60e
Branch: refs/heads/develop
Commit: 3a58a60e9ad01f5bdf26806bd17f92c409fb360d
Parents: 2cc92bf
Author: Alex Harui <ah...@apache.org>
Authored: Sat Dec 7 21:46:49 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Sat Dec 7 21:50:43 2013 -0800
----------------------------------------------------------------------
.../src/org/apache/flex/ant/tags/FileSet.as | 86 +
.../org/apache/flex/ant/tags/FileSetExclude.as | 40 +
.../org/apache/flex/ant/tags/FileSetInclude.as | 40 +
.../flex/ant/tags/filesetClasses/Character.as | 34 +
.../ant/tags/filesetClasses/CollectionUtils.as | 41 +
.../flex/ant/tags/filesetClasses/DataType.as | 330 ++++
.../ant/tags/filesetClasses/DirectoryScanner.as | 1764 ++++++++++++++++++
.../ant/tags/filesetClasses/FileProvider.as | 27 +
.../ant/tags/filesetClasses/FileResource.as | 146 ++
.../ant/tags/filesetClasses/FileSelector.as | 27 +
.../flex/ant/tags/filesetClasses/FileUtils.as | 657 +++++++
.../ant/tags/filesetClasses/PathTokenizer.as | 118 ++
.../flex/ant/tags/filesetClasses/Reference.as | 106 ++
.../flex/ant/tags/filesetClasses/Resource.as | 349 ++++
.../ant/tags/filesetClasses/SelectorUtils.as | 638 +++++++
.../ant/tags/filesetClasses/StringTokenizer.as | 68 +
.../ant/tags/filesetClasses/TokenizedPath.as | 221 +++
.../ant/tags/filesetClasses/TokenizedPattern.as | 173 ++
.../filesetClasses/exceptions/BuildException.as | 28 +
.../filesetClasses/exceptions/IOException.as | 28 +
.../exceptions/IllegalStateException.as | 28 +
.../exceptions/UnsupportedOperationException.as | 28 +
22 files changed, 4977 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/FileSet.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/FileSet.as b/ant_on_air/src/org/apache/flex/ant/tags/FileSet.as
new file mode 100644
index 0000000..4a01395
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/FileSet.as
@@ -0,0 +1,86 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags
+{
+ import mx.core.IFlexModuleFactory;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.filesetClasses.DirectoryScanner;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.BuildException;
+ import org.apache.flex.ant.tags.supportClasses.IValueTagHandler;
+ import org.apache.flex.ant.tags.supportClasses.NamedTagHandler;
+ import org.apache.flex.ant.tags.supportClasses.ParentTagHandler;
+
+ [Mixin]
+ public class FileSet extends ParentTagHandler implements IValueTagHandler
+ {
+ public static function init(mf:IFlexModuleFactory):void
+ {
+ Ant.antTagProcessors["fileset"] = FileSet;
+ }
+
+ public function FileSet()
+ {
+ super();
+ }
+
+ private var _dir:String;
+
+ public function get dir():String
+ {
+ return _dir;
+ }
+
+ private var _value:Vector.<String>;
+
+ public function get value():Object
+ {
+ if (_value) return _value;
+
+ var ds:DirectoryScanner = new DirectoryScanner();
+ var n:int = numChildren;
+ var includes:Vector.<String> = new Vector.<String>();
+ var excludes:Vector.<String> = new Vector.<String>();
+ for (var i:int = 0; i < n; i++)
+ {
+ var tag:NamedTagHandler = getChildAt(i) as NamedTagHandler;
+ if (tag is FileSetInclude)
+ includes.push(tag.name);
+ else if (tag is FileSetExclude)
+ excludes.push(tag.name);
+ else
+ throw new BuildException("Unsupported Tag at index " + i);
+ }
+ ds.setIncludes(includes);
+ ds.setExcludes(excludes);
+ if (_dir != null)
+ ds.setBasedir(_dir);
+ ds.scan();
+ _value = ds.getIncludedFiles();
+ return _value;
+ }
+
+ override protected function processAttribute(name:String, value:String):void
+ {
+ if (name == "dir")
+ _dir = value;
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/FileSetExclude.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/FileSetExclude.as b/ant_on_air/src/org/apache/flex/ant/tags/FileSetExclude.as
new file mode 100644
index 0000000..e2c0f02
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/FileSetExclude.as
@@ -0,0 +1,40 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags
+{
+ import mx.core.IFlexModuleFactory;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.supportClasses.NamedTagHandler;
+
+ [Mixin]
+ public class FileSetExclude extends NamedTagHandler
+ {
+ public static function init(mf:IFlexModuleFactory):void
+ {
+ Ant.antTagProcessors["exclude"] = FileSetExclude;
+ }
+
+ public function FileSetExclude()
+ {
+ super();
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/FileSetInclude.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/FileSetInclude.as b/ant_on_air/src/org/apache/flex/ant/tags/FileSetInclude.as
new file mode 100644
index 0000000..8c6f98f
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/FileSetInclude.as
@@ -0,0 +1,40 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags
+{
+ import mx.core.IFlexModuleFactory;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.supportClasses.NamedTagHandler;
+
+ [Mixin]
+ public class FileSetInclude extends NamedTagHandler
+ {
+ public static function init(mf:IFlexModuleFactory):void
+ {
+ Ant.antTagProcessors["include"] = FileSetInclude;
+ }
+
+ public function FileSetInclude()
+ {
+ super();
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Character.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Character.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Character.as
new file mode 100644
index 0000000..d2b6b87
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Character.as
@@ -0,0 +1,34 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.filesetClasses
+{
+ public class Character
+ {
+ public function Character()
+ {
+ super();
+ }
+
+ public static function isLetter(c:String):Boolean
+ {
+ return "a" <= c && c <= "z" ||
+ "A" <= c && c <= "Z";
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/CollectionUtils.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/CollectionUtils.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/CollectionUtils.as
new file mode 100644
index 0000000..0717a4e
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/CollectionUtils.as
@@ -0,0 +1,41 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.filesetClasses
+{
+ public class CollectionUtils
+ {
+ public function CollectionUtils()
+ {
+ super();
+ }
+
+ private static var target:String;
+
+ private static function callback(item:String, index:int, list:Vector.<String>):Boolean
+ {
+ return CollectionUtils.target == item;
+ }
+
+ public static function frequency(list:Vector.<String>, c:String):int
+ {
+ target = c;
+ return list.filter(callback).length;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DataType.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DataType.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DataType.as
new file mode 100644
index 0000000..1efa665
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DataType.as
@@ -0,0 +1,330 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import flash.system.ApplicationDomain;
+ import flash.utils.getQualifiedClassName;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.Project;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.BuildException;
+
+ /**
+ * Ported from org.apache.tools.ant.types.DataType.java on 12/3/13
+ * Base class for those classes that can appear inside the build file
+ * as stand alone data types.
+ *
+ * <p>This class handles the common description attribute and provides
+ * a default implementation for reference handling and checking for
+ * circular references that is appropriate for types that can not be
+ * nested inside elements of the same type (i.e. <patternset>
+ * but not <path>).</p>
+ *
+ */
+ public class DataType
+ {
+ // CheckStyle:VisibilityModifier OFF
+
+ /**
+ * Value to the refid attribute.
+ *
+ * @deprecated since 1.7.
+ * The user should not be directly referencing
+ * variable. Please use {@link #getRefid} instead.
+ */
+ protected var ref:Reference;
+
+ /**
+ * Are we sure we don't hold circular references?
+ *
+ * <p>Subclasses are responsible for setting this value to false
+ * if we'd need to investigate this condition (usually because a
+ * child element has been added that is a subclass of
+ * DataType).</p>
+ *
+ * @deprecated since 1.7.
+ * The user should not be directly referencing
+ * variable. Please use {@link #setChecked} or
+ * {@link #isChecked} instead.
+ */
+ protected var checked:Boolean = true;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Has the refid attribute of this element been set?
+ * @return true if the refid attribute has been set
+ */
+ public function isReference():Boolean
+ {
+ return ref != null;
+ }
+
+ /**
+ * Set the value of the refid attribute.
+ *
+ * <p>Subclasses may need to check whether any other attributes
+ * have been set as well or child elements have been created and
+ * thus override this method. if they do the must call
+ * <code>super.setRefid</code>.</p>
+ * @param ref the reference to use
+ */
+ public function setRefid(ref:Reference):void
+ {
+ this.ref = ref;
+ checked = false;
+ }
+
+ /**
+ * Gets as descriptive as possible a name used for this datatype instance.
+ * @return <code>String</code> name.
+ */
+ protected function getDataTypeName():String
+ {
+ return "DataType";
+ }
+
+ /**
+ * Check to see whether any DataType we hold references to is
+ * included in the Stack (which holds all DataType instances that
+ * directly or indirectly reference this instance, including this
+ * instance itself).
+ *
+ * <p>If one is included, throw a BuildException created by {@link
+ * #circularReference circularReference}.</p>
+ *
+ * <p>This implementation is appropriate only for a DataType that
+ * cannot hold other DataTypes as children.</p>
+ *
+ * <p>The general contract of this method is that it shouldn't do
+ * anything if {@link #checked <code>checked</code>} is true and
+ * set it to true on exit.</p>
+ * @param stack the stack of references to check.
+ * @param project the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected function dieOnCircularReference(stack:Vector.<String> = null, project:Project = null):void
+ {
+ if (!project)
+ project = Ant.project;
+
+ if (!stack)
+ stack = new Vector.<String>();
+
+ if (checked || !isReference()) {
+ return;
+ }
+ var o:Object = ref.getReferencedObject(project);
+
+ if (o is DataType) {
+ if (stack.indexOf(o) != -1) {
+ throw circularReference();
+ } else {
+ stack.push(o);
+ DataType(o).dieOnCircularReference(Vector.<String>([id]), project);
+ stack.pop();
+ }
+ }
+ checked = true;
+ }
+
+ /**
+ * Allow DataTypes outside org.apache.tools.ant.types to indirectly call
+ * dieOnCircularReference on nested DataTypes.
+ * @param dt the DataType to check.
+ * @param stk the stack of references to check.
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ * @since Ant 1.7
+ */
+ public static function invokeCircularReferenceCheck(dt:DataType, stk:Vector.<String>,
+ p:Project):void
+ {
+ dt.dieOnCircularReference(stk, p);
+ }
+
+ /**
+ * Allow DataTypes outside org.apache.tools.ant.types to indirectly call
+ * dieOnCircularReference on nested DataTypes.
+ *
+ * <p>Pushes dt on the stack, runs dieOnCircularReference and pops
+ * it again.</p>
+ * @param dt the DataType to check.
+ * @param stk the stack of references to check.
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ * @since Ant 1.8.0
+ */
+ public static function pushAndInvokeCircularReferenceCheck(dt:DataType,
+ stk:Vector.<String>,
+ p:Project):void
+ {
+ stk.push(dt);
+ dt.dieOnCircularReference(stk, p);
+ stk.pop();
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object.
+ * @param p the Ant Project instance against which to resolve references.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
+ * @since Ant 1.7
+ */
+ protected function getCheckedRef(p:Project = null):Object
+ {
+ if (!p)
+ p = Ant.project;
+ return getCheckedRefActual(Class(ApplicationDomain.currentDomain.getDefinition(getQualifiedClassName(this))),
+ getDataTypeName(), p);
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object. This version allows the fallback Project instance to be specified.
+ * @param requiredClass the class that this reference should be a subclass of.
+ * @param dataTypeName the name of the datatype that the reference should be
+ * (error message use only).
+ * @param project the fallback Project instance for dereferencing.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc),
+ * or if <code>project</code> is <code>null</code>.
+ * @since Ant 1.7
+ */
+ protected function getCheckedRefActual(requiredClass:Class,
+ dataTypeName:String, project:Project):Object {
+ if (project == null) {
+ throw new BuildException("No Project specified");
+ }
+ dieOnCircularReference(null, project);
+ var o:Object = ref.getReferencedObject(project);
+ var oClass:Class = ApplicationDomain.currentDomain.getDefinition(getQualifiedClassName(o)) as Class;
+ if (!(requiredClass is oClass)) {
+ Ant.log("Class " + oClass + " is not a subclass of " + requiredClass,
+ Project.MSG_VERBOSE);
+ var msg:String = ref.getRefId() + " doesn\'t denote a " + dataTypeName;
+ throw new BuildException(msg);
+ }
+ return o;
+ }
+
+ /**
+ * Creates an exception that indicates that refid has to be the
+ * only attribute if it is set.
+ * @return the exception to throw
+ */
+ protected function tooManyAttributes():BuildException
+ {
+ return new BuildException("You must not specify more than one "
+ + "attribute when using refid");
+ }
+
+ /**
+ * Creates an exception that indicates that this XML element must
+ * not have child elements if the refid attribute is set.
+ * @return the exception to throw
+ */
+ protected function noChildrenAllowed():BuildException
+ {
+ return new BuildException("You must not specify nested elements "
+ + "when using refid");
+ }
+
+ /**
+ * Creates an exception that indicates the user has generated a
+ * loop of data types referencing each other.
+ * @return the exception to throw
+ */
+ protected function circularReference():BuildException
+ {
+ return new BuildException("This data type contains a circular "
+ + "reference.");
+ }
+
+ /**
+ * The flag that is used to indicate that circular references have been checked.
+ * @return true if circular references have been checked
+ */
+ protected function isChecked():Boolean
+ {
+ return checked;
+ }
+
+ /**
+ * Set the flag that is used to indicate that circular references have been checked.
+ * @param checked if true, if circular references have been checked
+ */
+ protected function setChecked(checked:Boolean):void
+ {
+ this.checked = checked;
+ }
+
+ /**
+ * get the reference set on this object
+ * @return the reference or null
+ */
+ public function getRefid():Reference
+ {
+ return ref;
+ }
+
+ /**
+ * check that it is ok to set attributes, i.e that no reference is defined
+ * @since Ant 1.6
+ * @throws BuildException if not allowed
+ */
+ protected function checkAttributesAllowed():void
+ {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ }
+
+ /**
+ * check that it is ok to add children, i.e that no reference is defined
+ * @since Ant 1.6
+ * @throws BuildException if not allowed
+ */
+ protected function checkChildrenAllowed():void
+ {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ }
+
+ /**
+ * Basic DataType toString().
+ * @return this DataType formatted as a String.
+ */
+ public function toString():String {
+ var d:String = getDescription();
+ return d == null ? getDataTypeName() : getDataTypeName() + " " + d;
+ }
+
+ /**
+ * Basic description
+ */
+ public function getDescription():String
+ {
+ return null;
+ }
+
+ public var id:String;
+ }
+}
[08/14] git commit: [flex-utilities] [refs/heads/develop] - handle
async tasks
Posted by ah...@apache.org.
handle async tasks
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/eef49ca0
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/eef49ca0
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/eef49ca0
Branch: refs/heads/develop
Commit: eef49ca0156b92510a55c49b473d8fc440b559c5
Parents: 26b6f4c
Author: Alex Harui <ah...@apache.org>
Authored: Sat Dec 7 21:49:43 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Sat Dec 7 21:50:44 2013 -0800
----------------------------------------------------------------------
ant_on_air/src/AntClasses.as | 5 +
ant_on_air/src/org/apache/flex/ant/Ant.as | 45 +++-----
.../src/org/apache/flex/ant/tags/Condition.as | 13 +--
ant_on_air/src/org/apache/flex/ant/tags/Echo.as | 3 +-
.../src/org/apache/flex/ant/tags/Project.as | 113 ++++++++++++++++---
.../src/org/apache/flex/ant/tags/Property.as | 59 ++++++----
.../src/org/apache/flex/ant/tags/Target.as | 75 +++++++++---
.../flex/ant/tags/supportClasses/TagHandler.as | 6 +-
.../flex/ant/tags/supportClasses/TaskHandler.as | 3 +-
.../src/org/apache/flex/xml/XMLTagProcessor.as | 4 +-
ant_on_air/tests/TestTarget.as | 11 +-
11 files changed, 241 insertions(+), 96 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/AntClasses.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/AntClasses.as b/ant_on_air/src/AntClasses.as
index 44a09c0..3180f70 100644
--- a/ant_on_air/src/AntClasses.as
+++ b/ant_on_air/src/AntClasses.as
@@ -24,8 +24,13 @@ package
{
import org.apache.flex.ant.Ant; Ant;
import org.apache.flex.ant.tags.Project; Project;
+ import org.apache.flex.ant.tags.Available; Available;
import org.apache.flex.ant.tags.Condition; Condition;
+ import org.apache.flex.ant.tags.Copy; Copy;
import org.apache.flex.ant.tags.Echo; Echo;
+ import org.apache.flex.ant.tags.FileSet; FileSet;
+ import org.apache.flex.ant.tags.FileSetExclude; FileSetExclude;
+ import org.apache.flex.ant.tags.FileSetInclude; FileSetInclude;
import org.apache.flex.ant.tags.IsSet; IsSet;
import org.apache.flex.ant.tags.OS; OS;
import org.apache.flex.ant.tags.Property; Property;
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/org/apache/flex/ant/Ant.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/Ant.as b/ant_on_air/src/org/apache/flex/ant/Ant.as
index af2f1f5..0f487a3 100644
--- a/ant_on_air/src/org/apache/flex/ant/Ant.as
+++ b/ant_on_air/src/org/apache/flex/ant/Ant.as
@@ -19,6 +19,7 @@
package org.apache.flex.ant
{
+ import flash.events.Event;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
@@ -37,6 +38,7 @@ package org.apache.flex.ant
public function Ant()
{
super();
+ ant = this;
}
/**
@@ -50,7 +52,7 @@ package org.apache.flex.ant
* @param file File The file to open.
* @param context Object An object containing an optional targets property listing the targets to run.
*/
- public function processXMLFile(file:File, context:Object = null):void
+ public function processXMLFile(file:File, context:Object = null):Boolean
{
this.file = file;
var fs:FileStream = new FileStream();
@@ -64,39 +66,26 @@ package org.apache.flex.ant
context = {};
this.context = context;
var project:Project = processXMLTag(xml, context) as Project;
- if (waiting == 0)
- project.execute();
- else
- this.project = project;
+ Ant.project = project;
+ if (!project.execute())
+ {
+ project.addEventListener(Event.COMPLETE, completeHandler);
+ return false;
+ }
+ return true;
}
private var context:Object;
- private var project:Project;
-
- private var _waiting:int = 0;
-
- /**
- * A flag used to defer execution if
- * waiting on something async like loading
- * environment variables.
- */
- public function get waiting():int
+ public static var ant:Ant;
+ public static var project:Project;
+ public static function log(msg:String, level:int):void
{
- return _waiting;
+ ant.output(msg);
}
-
- /**
- * @private
- */
- public function set waiting(value:int):void
+
+ private function completeHandler(event:Event):void
{
- if (value >= 0)
- _waiting = value;
-
- if (value == 0)
- if (project)
- project.execute()
-
+ dispatchEvent(event);
}
/**
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/org/apache/flex/ant/tags/Condition.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Condition.as b/ant_on_air/src/org/apache/flex/ant/tags/Condition.as
index 87df06d..7f94d8f 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Condition.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Condition.as
@@ -22,12 +22,12 @@ package org.apache.flex.ant.tags
import org.apache.flex.ant.Ant;
import org.apache.flex.ant.tags.supportClasses.IValueTagHandler;
- import org.apache.flex.ant.tags.supportClasses.ParentTagHandler;
+ import org.apache.flex.ant.tags.supportClasses.TaskHandler;
import org.apache.flex.xml.XMLTagProcessor;
[Mixin]
- public class Condition extends ParentTagHandler
+ public class Condition extends TaskHandler
{
public static function init(mf:IFlexModuleFactory):void
{
@@ -39,12 +39,10 @@ package org.apache.flex.ant.tags
super();
}
- override public function init(xml:XML, context:Object, xmlProcessor:XMLTagProcessor):void
+ override public function execute():Boolean
{
- // process attributes
- super.init(xml, context, xmlProcessor);
- // create child nodes
- ant.processChildren(xml, context, this);
+ super.execute();
+
// if the property is not already set
if (_property && _value != null && !context.hasOwnProperty(_property))
{
@@ -58,6 +56,7 @@ package org.apache.flex.ant.tags
context[_property] = val;
}
}
+ return true;
}
private var _property:String;
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/org/apache/flex/ant/tags/Echo.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Echo.as b/ant_on_air/src/org/apache/flex/ant/tags/Echo.as
index fa43d73..d20e991 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Echo.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Echo.as
@@ -52,10 +52,11 @@ package org.apache.flex.ant.tags
super.processAttribute(name, value);
}
- override public function execute():void
+ override public function execute():Boolean
{
super.execute();
ant.output(ant.getValue(text, context));
+ return true;
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/org/apache/flex/ant/tags/Project.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Project.as b/ant_on_air/src/org/apache/flex/ant/tags/Project.as
index 368f335..5136f55 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Project.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Project.as
@@ -18,10 +18,13 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.ant.tags
{
+ import flash.events.Event;
+
import mx.core.IFlexModuleFactory;
import mx.utils.StringUtil;
import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.filesetClasses.Reference;
import org.apache.flex.ant.tags.supportClasses.TaskHandler;
import org.apache.flex.xml.ITagHandler;
import org.apache.flex.xml.XMLTagProcessor;
@@ -29,6 +32,17 @@ package org.apache.flex.ant.tags
[Mixin]
public class Project extends TaskHandler
{
+ /** Message priority of "error". */
+ public static const MSG_ERR:int = 0;
+ /** Message priority of "warning". */
+ public static const MSG_WARN:int = 1;
+ /** Message priority of "information". */
+ public static const MSG_INFO:int = 2;
+ /** Message priority of "verbose". */
+ public static const MSG_VERBOSE:int = 3;
+ /** Message priority of "debug". */
+ public static const MSG_DEBUG:int = 4;
+
public static function init(mf:IFlexModuleFactory):void
{
Ant.antTagProcessors["project"] = Project;
@@ -59,6 +73,8 @@ package org.apache.flex.ant.tags
return _defaultTarget;
}
+ private var targets:Array;
+
override protected function processAttribute(name:String, value:String):void
{
if (name == "basedir")
@@ -69,23 +85,57 @@ package org.apache.flex.ant.tags
super.processAttribute(name, value);
}
- override public function execute():void
+ override public function execute():Boolean
{
- if (context.target == null)
- context.target == _defaultTarget;
+ if (context.targets == null)
+ context.targets == _defaultTarget;
- var targets:Array;
- var targetList:String = context.targets;
- if (targetList.indexOf(',') != -1)
- targets = targetList.split(",");
- else
- targets = [ targetList ];
+ targets = context.targets.split(",");
+
+ // execute all children in order except for targets
+ return executeChildren();
+ }
+
+ private var current:int = 0;
+
+ private function executeChildren():Boolean
+ {
+ if (current == numChildren)
+ return executeTargets();
+
+ while (current < numChildren)
+ {
+ var child:ITagHandler = getChildAt(current++);
+ if (child is Target)
+ continue;
+ if (child is TaskHandler)
+ {
+ var task:TaskHandler = TaskHandler(child);
+ if (!task.execute())
+ {
+ task.addEventListener(Event.COMPLETE, childCompleteHandler);
+ return false;
+ }
+ }
+ }
+ return executeTargets();
+ }
+
+ private function executeTargets():Boolean
+ {
+ while (targets.length > 0)
+ {
+ var targetName:String = targets.shift();
+ if (!executeTarget(targetName))
+ return false;
+ }
+ if (targets.length == 0)
+ dispatchEvent(new Event(Event.COMPLETE));
- for each (var target:String in targets)
- executeTarget(target);
+ return true;
}
- public function executeTarget(targetName:String):void
+ public function getTarget(targetName:String):Target
{
targetName = StringUtil.trim(targetName);
var n:int = numChildren;
@@ -97,15 +147,48 @@ package org.apache.flex.ant.tags
var t:Target = child as Target;
if (t.name == targetName)
{
- t.execute();
- return;
+ return t;
}
}
}
-
trace("missing target: ", targetName);
throw new Error("missing target: " + targetName);
+ return null;
+ }
+
+ public function executeTarget(targetName:String):Boolean
+ {
+ var t:Target = getTarget(targetName);
+ if (!t.execute())
+ {
+ t.addEventListener(Event.COMPLETE, completeHandler);
+ return false;
+ }
+ return true;
+ }
+
+ private function completeHandler(event:Event):void
+ {
+ executeTargets();
+ }
+
+ private function childCompleteHandler(event:Event):void
+ {
+ executeChildren();
+ }
+
+ private var references:Object = {};
+
+ public function addReference(referenceName:String, value:Object):void
+ {
+ references[referenceName] = value;
+ }
+ public function getReference(referenceName:String):Reference
+ {
+ if (references.hasOwnProperty(referenceName))
+ return references[referenceName];
+ return null;
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/org/apache/flex/ant/tags/Property.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Property.as b/ant_on_air/src/org/apache/flex/ant/tags/Property.as
index 35b899b..a5097cc 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Property.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Property.as
@@ -18,13 +18,14 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.ant.tags
{
- import flash.filesystem.File;
- import flash.filesystem.FileMode;
- import flash.filesystem.FileStream;
import flash.desktop.NativeProcess;
import flash.desktop.NativeProcessStartupInfo;
+ import flash.events.Event;
import flash.events.NativeProcessExitEvent;
import flash.events.ProgressEvent;
+ import flash.filesystem.File;
+ import flash.filesystem.FileMode;
+ import flash.filesystem.FileStream;
import flash.system.Capabilities;
import flash.utils.IDataInput;
@@ -32,11 +33,11 @@ package org.apache.flex.ant.tags
import mx.utils.StringUtil;
import org.apache.flex.ant.Ant;
- import org.apache.flex.ant.tags.supportClasses.NamedTagHandler;
+ import org.apache.flex.ant.tags.supportClasses.TaskHandler;
import org.apache.flex.xml.XMLTagProcessor;
[Mixin]
- public class Property extends NamedTagHandler
+ public class Property extends TaskHandler
{
public static function init(mf:IFlexModuleFactory):void
{
@@ -50,19 +51,14 @@ package org.apache.flex.ant.tags
override public function init(xml:XML, context:Object, xmlProcessor:XMLTagProcessor):void
{
super.init(xml, context, xmlProcessor);
- if (name && value && !context.hasOwnProperty(name))
- context[name] = value;
}
- private var fileName:String;
- private var value:String;
- private var envPrefix:String;
-
- override protected function processAttribute(name:String, value:String):void
+ override public function execute():Boolean
{
- if (name == "file")
+ if (name && value && !context.hasOwnProperty(name))
+ context[name] = value;
+ else if (fileName != null)
{
- fileName = ant.getValue(value, context);
var f:File = new File(fileName);
var fs:FileStream = new FileStream();
fs.open(f, FileMode.READ);
@@ -76,17 +72,36 @@ package org.apache.flex.ant.tags
var key:String = StringUtil.trim(parts[0]);
var val:String;
if (parts.length == 2)
- val = parts[1];
+ val = parts[1];
else
{
parts.shift();
val = parts.join("=");
}
- context[key] = val;
+ if (!context.hasOwnProperty(key))
+ context[key] = val;
}
-
+
}
- fs.close();
+ fs.close();
+ }
+ else if (envPrefix != null)
+ {
+ requestEnvironmentVariables();
+ return false;
+ }
+ return true;
+ }
+
+ private var fileName:String;
+ private var value:String;
+ private var envPrefix:String;
+
+ override protected function processAttribute(name:String, value:String):void
+ {
+ if (name == "file")
+ {
+ fileName = ant.getValue(value, context);
}
else if (name == "value")
{
@@ -95,8 +110,6 @@ package org.apache.flex.ant.tags
else if (name == "environment")
{
envPrefix = value;
- ant.waiting++;
- requestEnvironmentVariables();
}
else
super.processAttribute(name, value);
@@ -129,6 +142,7 @@ package org.apache.flex.ant.tags
private function exitHandler(event:NativeProcessExitEvent):void
{
+ dispatchEvent(new Event(Event.COMPLETE));
}
private function onOutputErrorData(event:ProgressEvent):void
@@ -136,7 +150,6 @@ package org.apache.flex.ant.tags
var stdError:IDataInput = process.standardError;
var data:String = stdError.readUTFBytes(process.standardError.bytesAvailable);
trace("Got Error Output: ", data);
- ant.waiting--;
}
private function onOutputData(event:ProgressEvent):void
@@ -163,10 +176,10 @@ package org.apache.flex.ant.tags
parts.shift();
val = parts.join("=");
}
- context[key] = val;
+ if (!context.hasOwnProperty(key))
+ context[key] = val;
}
}
- ant.waiting--;
}
}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/org/apache/flex/ant/tags/Target.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Target.as b/ant_on_air/src/org/apache/flex/ant/tags/Target.as
index 146942f..df47ffa 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Target.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Target.as
@@ -18,6 +18,8 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.ant.tags
{
+ import flash.events.Event;
+
import mx.core.IFlexModuleFactory;
import org.apache.flex.ant.Ant;
@@ -66,32 +68,79 @@ package org.apache.flex.ant.tags
context.currentTarget = this;
}
- private function processDepends():void
+ private var dependsList:Array;
+
+ private function processDepends():Boolean
{
- if (!_depends)
- return;
+ if (dependsList.length == 0)
+ {
+ continueOnToSteps();
+ return true;
+ }
+
+ while (dependsList.length > 0)
+ {
+ var depend:String = dependsList.shift();
+ var t:Target = project.getTarget(depend);
+ if (!t.execute())
+ {
+ t.addEventListener(Event.COMPLETE, dependCompleteHandler);
+ return false;
+ }
+ }
- var dependsList:Array = _depends.split(",");
- for each (var d:String in dependsList)
- project.executeTarget(d);
+ return continueOnToSteps();
}
- override public function execute():void
+ private function dependCompleteHandler(event:Event):void
{
processDepends();
+ }
+
+ override public function execute():Boolean
+ {
+ if (_depends)
+ {
+ dependsList = _depends.split(",");
+ if (!processDepends())
+ return false;
+ }
+
+ return continueOnToSteps();
+ }
+
+ private function continueOnToSteps():Boolean
+ {
ant.processChildren(xml, context, this);
- processSteps();
+ return processSteps();
}
- private function processSteps():void
+ private var current:int = 0;
+
+ private function processSteps():Boolean
{
- var n:int = numChildren;
- for (var i:int = 0; i < n; i++)
+ if (current == numChildren)
{
- var step:TaskHandler = getChildAt(i) as TaskHandler;
- step.execute();
+ dispatchEvent(new Event(Event.COMPLETE));
+ return true;
}
+
+ while (current < numChildren)
+ {
+ var step:TaskHandler = getChildAt(current++) as TaskHandler;
+ if (!step.execute())
+ {
+ step.addEventListener(Event.COMPLETE, completeHandler);
+ return false;
+ }
+ }
+ dispatchEvent(new Event(Event.COMPLETE));
+ return true;
}
+ private function completeHandler(event:Event):void
+ {
+ processSteps();
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as
index 28db76f..70c215d 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as
@@ -18,14 +18,16 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.ant.tags.supportClasses
{
- import org.apache.flex.xml.XMLTagProcessor;
+ import flash.events.EventDispatcher;
+
import org.apache.flex.ant.Ant;
import org.apache.flex.xml.ITagHandler;
+ import org.apache.flex.xml.XMLTagProcessor;
/**
* The lowest-level base class for ITagHandlers for Ant.
*/
- public class TagHandler implements ITagHandler
+ public class TagHandler extends EventDispatcher implements ITagHandler
{
/**
* Constructor
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as
index 6ddccfb..910753e 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TaskHandler.as
@@ -34,9 +34,10 @@ package org.apache.flex.ant.tags.supportClasses
* super.execute() should be called before
* doing any real work.
*/
- public function execute():void
+ public function execute():Boolean
{
ant.processChildren(this.xml, context, this);
+ return true;
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/src/org/apache/flex/xml/XMLTagProcessor.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/xml/XMLTagProcessor.as b/ant_on_air/src/org/apache/flex/xml/XMLTagProcessor.as
index fc7bdfd..a666f7c 100644
--- a/ant_on_air/src/org/apache/flex/xml/XMLTagProcessor.as
+++ b/ant_on_air/src/org/apache/flex/xml/XMLTagProcessor.as
@@ -18,10 +18,12 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.xml
{
+ import flash.events.EventDispatcher;
+
/**
* Base class for processing XML Tags
*/
- public class XMLTagProcessor
+ public class XMLTagProcessor extends EventDispatcher
{
/**
* Constructor
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/eef49ca0/ant_on_air/tests/TestTarget.as
----------------------------------------------------------------------
diff --git a/ant_on_air/tests/TestTarget.as b/ant_on_air/tests/TestTarget.as
index c541b9b..1235d41 100644
--- a/ant_on_air/tests/TestTarget.as
+++ b/ant_on_air/tests/TestTarget.as
@@ -39,14 +39,15 @@ package
var context:Object = { targets: "test" };
var file:File = File.applicationDirectory;
file = file.resolvePath("test.xml");
- ant.processXMLFile(file, context);
- addEventListener(Event.ENTER_FRAME, enterFrameHandler);
+ if (!ant.processXMLFile(file, context))
+ ant.addEventListener(Event.COMPLETE, completeHandler);
+ else
+ completeHandler(null);
}
- private function enterFrameHandler(event:Event):void
+ private function completeHandler(event:Event):void
{
- if (ant.waiting == 0)
- NativeApplication.nativeApplication.exit();
+ NativeApplication.nativeApplication.exit();
}
private var ant:Ant;
[12/14] git commit: [flex-utilities] [refs/heads/develop] - get basic
filesets to copy
Posted by ah...@apache.org.
get basic filesets to copy
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/3a3f2326
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/3a3f2326
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/3a3f2326
Branch: refs/heads/develop
Commit: 3a3f2326070cadf1cd6b6c14f1a916d74b0ce9df
Parents: a4728f7
Author: Alex Harui <ah...@apache.org>
Authored: Mon Dec 9 14:01:53 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Dec 9 14:01:53 2013 -0800
----------------------------------------------------------------------
ant_on_air/src/org/apache/flex/ant/tags/Copy.as | 36 +++++++--
.../src/org/apache/flex/ant/tags/FileSet.as | 1 +
.../ant/tags/filesetClasses/DirectoryScanner.as | 77 ++++++++++----------
.../flex/ant/tags/filesetClasses/FileUtils.as | 8 +-
.../ant/tags/filesetClasses/StringTokenizer.as | 18 +++--
.../tags/supportClasses/FileSetTaskHandler.as | 5 +-
ant_on_air/tests/TestTarget.as | 7 ++
ant_on_air/tests/test.xml | 20 +++++
8 files changed, 117 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a3f2326/ant_on_air/src/org/apache/flex/ant/tags/Copy.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Copy.as b/ant_on_air/src/org/apache/flex/ant/tags/Copy.as
index 4bdb0cc..3636ad0 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Copy.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Copy.as
@@ -18,6 +18,8 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.ant.tags
{
+ import flash.filesystem.File;
+
import mx.core.IFlexModuleFactory;
import org.apache.flex.ant.Ant;
@@ -46,7 +48,7 @@ package org.apache.flex.ant.tags
if (name == "file")
fileName = value;
else if (name == "toFile")
- toFileName == value;
+ toFileName = value;
else if (name == "toDir")
toDirName = value;
else if (name == "overwrite")
@@ -57,17 +59,37 @@ package org.apache.flex.ant.tags
override protected function actOnFile(dir:String, fileName:String):void
{
+ var srcName:String;
+ if (dir)
+ srcName = dir + File.separator + fileName;
+ else
+ srcName = fileName;
+ var srcFile:File = File.applicationDirectory.resolvePath(srcName);
+ var destName:String;
+ if (toDirName)
+ destName = toDirName + File.separator + fileName;
+ else
+ destName = toFileName;
+ var destFile:File = File.applicationDirectory.resolvePath(destName);
+
+ srcFile.copyTo(destFile, overwrite);
}
- /**
- * Do the work.
- * TaskHandlers lazily create their children so
- * super.execute() should be called before
- * doing any real work.
- */
override public function execute():Boolean
{
+ var retVal:Boolean = super.execute();
+ if (numChildren > 0)
+ return retVal;
+
+ var srcFile:File = File.applicationDirectory.resolvePath(fileName);
+ var destFile:File = File.applicationDirectory.resolvePath(toFileName);;
+ //var destDir:File = destFile.parent;
+ //var resolveName:String = destFile.nativePath.substr(destFile.nativePath.lastIndexOf(File.separator) + 1);
+ //destDir.resolvePath(resolveName);
+
+
+ srcFile.copyTo(destFile, overwrite);
return true;
}
}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a3f2326/ant_on_air/src/org/apache/flex/ant/tags/FileSet.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/FileSet.as b/ant_on_air/src/org/apache/flex/ant/tags/FileSet.as
index 4a01395..c6fb109 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/FileSet.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/FileSet.as
@@ -53,6 +53,7 @@ package org.apache.flex.ant.tags
{
if (_value) return _value;
+ ant.processChildren(xml, context, this);
var ds:DirectoryScanner = new DirectoryScanner();
var n:int = numChildren;
var includes:Vector.<String> = new Vector.<String>();
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a3f2326/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DirectoryScanner.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DirectoryScanner.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DirectoryScanner.as
index e6f1927..379bb6c 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DirectoryScanner.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DirectoryScanner.as
@@ -526,11 +526,14 @@ package org.apache.flex.ant.tags.filesetClasses
* @since Ant 1.6
*/
public static function resetDefaultExcludes():Vector.<String> {
- defaultExcludes.length = 0;
+ var arr:Vector.<String> = defaultExcludes;
+ if (!arr)
+ arr = new Vector.<String>();
+ arr.length = 0;
for (var i:int = 0; i < DEFAULTEXCLUDES.length; i++) {
- defaultExcludes.push(DEFAULTEXCLUDES[i]);
+ arr.push(DEFAULTEXCLUDES[i]);
}
- return defaultExcludes;
+ return arr;
}
/**
@@ -819,6 +822,8 @@ package org.apache.flex.ant.tags.filesetClasses
excludes = nullExcludes ? null : excludes;
} catch (ex:IOException) {
throw new BuildException(ex.message);
+ } catch (e:Error) {
+ throw new BuildException(e.message);
} finally {
basedir = savedBase;
}
@@ -843,14 +848,14 @@ package org.apache.flex.ant.tags.filesetClasses
pattern;
}
}
- for each (var entry:Dictionary in includeNonPatterns.entrySet()) {
+ for each (var entry:Object in includeNonPatterns) {
for (var p:String in entry)
{
pattern = p;
break;
}
if (!shouldSkipPattern(pattern)) {
- newroots[entry.getValue()] = pattern;
+ newroots[entry[pattern]] = pattern;
}
}
@@ -870,13 +875,9 @@ package org.apache.flex.ant.tags.filesetClasses
}
// only scan directories that can include matched files or
// directories
- for each (entry in newroots.entrySet()) {
+ for (entry in newroots) {
var currentPath:TokenizedPath;
- for (p in entry)
- {
- currentPath = p as TokenizedPath;
- break;
- }
+ currentPath = entry as TokenizedPath;
var currentelement:String = currentPath.toString();
if (basedir == null
&& !FileUtils.isAbsolutePath(currentelement)) {
@@ -895,7 +896,7 @@ package org.apache.flex.ant.tags.filesetClasses
? myCanonFile.nativePath
: FILE_UTILS.removeLeadingPath(canonBase,
myCanonFile);
- if (!path == currentelement) {
+ if (path != currentelement) {
myfile = currentPath.findFile(basedir, true);
if (myfile != null && basedir != null) {
currentelement = FILE_UTILS.removeLeadingPath(
@@ -941,10 +942,7 @@ package org.apache.flex.ant.tags.filesetClasses
}
} else {
var originalpattern:String;
- for (var q:* in entry)
- {
- originalpattern = entry[q];
- }
+ originalpattern = newroots[entry] as String;
var included:Boolean = isCaseSensitive()
? originalpattern == currentelement
: originalpattern.toUpperCase() == currentelement.toUpperCase();
@@ -1089,21 +1087,21 @@ package org.apache.flex.ant.tags.filesetClasses
if (dir == null) {
throw new BuildException("dir must not be null.");
}
- var arr:Array = dir.getDirectoryListing();
+ else if (!dir.exists) {
+ throw new BuildException(dir + DOES_NOT_EXIST_POSTFIX);
+ } else if (!dir.isDirectory) {
+ throw new BuildException(dir + " is not a directory.");
+ }
+ try {
+ var arr:Array = dir.getDirectoryListing();
+ } catch (e:Error) {
+ throw new BuildException("IO error scanning directory '"
+ + dir.nativePath + "'");
+ }
var arr2:Array = [];
for each (var f:File in arr)
- arr2.push(f.nativePath);
+ arr2.push(f.name);
var newfiles:Vector.<String> = Vector.<String>(arr2);;
- if (newfiles == null) {
- if (!dir.exists) {
- throw new BuildException(dir + DOES_NOT_EXIST_POSTFIX);
- } else if (!dir.isDirectory) {
- throw new BuildException(dir + " is not a directory.");
- } else {
- throw new BuildException("IO error scanning directory '"
- + dir.nativePath + "'");
- }
- }
_scandir(dir, path, fast, newfiles, new Vector.<String>());
}
@@ -1150,11 +1148,16 @@ package org.apache.flex.ant.tags.filesetClasses
name = vpath + newfiles[i];
var newPath:TokenizedPath = new TokenizedPath("").initAsChild(path, newfiles[i]);
file = new File(dir.nativePath + File.separator + newfiles[i]);
- var arr:Array = file.getDirectoryListing();
+ var arr:Array = null;
var arr2:Array = [];
- for each (var f:File in arr)
- arr2.push(f.nativePath);
- var children:Vector.<String> = Vector.<String>(arr2);
+ var children:Vector.<String> = null;
+ if (file.isDirectory)
+ {
+ arr = file.getDirectoryListing();
+ for each (var f:File in arr)
+ arr2.push(f.name);
+ children = Vector.<String>(arr2);
+ }
if (children == null || (children.length == 0 && !file.isDirectory)) {
if (isIncludedPath(newPath)) {
accountForIncludedFile(newPath, file);
@@ -1272,8 +1275,8 @@ package org.apache.flex.ant.tags.filesetClasses
ensureNonPatternSetsReady();
if (isCaseSensitive()
- ? includeNonPatterns.containsKey(path.toString())
- : includeNonPatterns.containsKey(path.toString().toUpperCase())) {
+ ? includeNonPatterns.hasOwnProperty(path.toString())
+ : includeNonPatterns.hasOwnProperty(path.toString().toUpperCase())) {
return true;
}
for (var i:int = 0; i < includePatterns.length; i++) {
@@ -1668,8 +1671,8 @@ package org.apache.flex.ant.tags.filesetClasses
* @since Ant 1.6
*/
private function clearCaches():void {
- includeNonPatterns.clear();
- excludeNonPatterns.clear();
+ includeNonPatterns = {};
+ excludeNonPatterns = {};
includePatterns = null;
excludePatterns = null;
areNonPatternSetsReady = false;
@@ -1698,7 +1701,7 @@ package org.apache.flex.ant.tags.filesetClasses
* @since Ant 1.8.0
*/
private function fillNonPatternSet(map:Object, patterns:Vector.<String>):Vector.<TokenizedPattern> {
- var al:Vector.<TokenizedPattern> = new Vector.<TokenizedPattern>(patterns.length);
+ var al:Vector.<TokenizedPattern> = new Vector.<TokenizedPattern>();
for (var i:int = 0; i < patterns.length; i++) {
if (!SelectorUtils.hasWildcards(patterns[i])) {
var s:String = isCaseSensitive()
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a3f2326/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileUtils.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileUtils.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileUtils.as
index d0409ca..146b972 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileUtils.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileUtils.as
@@ -175,7 +175,7 @@ package org.apache.flex.ant.tags.filesetClasses
var sep:String = File.separator;
filename = filename.replace(/\//g, sep).replace(/\\/g, sep);
var c:String = filename.charAt(0);
- if (ON_DOS)
+ if (!ON_DOS)
return (c == sep);
if (c == sep) {
@@ -258,7 +258,7 @@ package org.apache.flex.ant.tags.filesetClasses
continue;
}
if (".." == thisToken) {
- if (s.size() < 2) {
+ if (s.length < 2) {
// Cannot resolve it, so skip it.
return new File(path);
}
@@ -268,14 +268,14 @@ package org.apache.flex.ant.tags.filesetClasses
}
}
var sb:String = "";
- var size:int = s.size();
+ var size:int = s.length;
for (var i:int = 0; i < size; i++) {
if (i > 1) {
// not before the filesystem root and not after it, since root
// already contains one
sb += File.separator;
}
- sb += s.elementAt(i);
+ sb += s[i];
}
return new File(sb);
}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a3f2326/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/StringTokenizer.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/StringTokenizer.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/StringTokenizer.as
index fcd97ba..02ddff5 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/StringTokenizer.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/StringTokenizer.as
@@ -27,29 +27,35 @@ package org.apache.flex.ant.tags.filesetClasses
var c1:int = 0;
var c2:int = 0;
var n:int = s.length;
- while (c1 < n)
+ while (c2 < n)
{
var c:String = s.charAt(c2);
if (delims.indexOf(c) != -1)
{
- tokens.push(s.substring(c1, c2 - 1));
+ tokens.push(s.substring(c1, c2));
c1 = c2;
- while (c1 < n)
+ while (c2 < n)
{
c = s.charAt(c2);
if (delims.indexOf(c) == -1)
{
if (returnDelims)
- {
- tokens.push(s.substring(c1, c2 - 1))
- }
+ tokens.push(s.substring(c1, c2))
c1 = c2;
break;
}
+ c2++;
+ }
+ if (returnDelims && c1 < c2)
+ {
+ tokens.push(s.substring(c1, c2));
+ c1 = c2;
}
}
c2++;
}
+ if (c1 < n)
+ tokens.push(s.substring(c1))
}
private var tokens:Vector.<String>;
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a3f2326/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
index c399e52..c0320a8 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
@@ -18,6 +18,8 @@
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.ant.tags.supportClasses
{
+ import flash.filesystem.File;
+
import org.apache.flex.ant.tags.FileSet;
/**
@@ -47,9 +49,10 @@ package org.apache.flex.ant.tags.supportClasses
var list:Vector.<String> = fs.value as Vector.<String>;
if (list)
{
+ var dir:File = new File(fs.dir);
for each (var fileName:String in list)
{
- actOnFile(fs.dir, fileName);
+ actOnFile(dir.nativePath, fileName);
}
}
}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a3f2326/ant_on_air/tests/TestTarget.as
----------------------------------------------------------------------
diff --git a/ant_on_air/tests/TestTarget.as b/ant_on_air/tests/TestTarget.as
index 1235d41..722986a 100644
--- a/ant_on_air/tests/TestTarget.as
+++ b/ant_on_air/tests/TestTarget.as
@@ -23,9 +23,16 @@ package
import flash.events.Event;
import flash.filesystem.File;
import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.Available; Available.init(null);
import org.apache.flex.ant.tags.Condition; Condition.init(null);
+ import org.apache.flex.ant.tags.Copy; Copy.init(null);
+ import org.apache.flex.ant.tags.Delete; Delete.init(null);
import org.apache.flex.ant.tags.Echo; Echo.init(null);
+ import org.apache.flex.ant.tags.FileSet; FileSet.init(null);
+ import org.apache.flex.ant.tags.FileSetExclude; FileSetExclude.init(null);
+ import org.apache.flex.ant.tags.FileSetInclude; FileSetInclude.init(null);
import org.apache.flex.ant.tags.IsSet; IsSet.init(null);
+ import org.apache.flex.ant.tags.Mkdir; Mkdir.init(null);
import org.apache.flex.ant.tags.OS; OS.init(null);
import org.apache.flex.ant.tags.Project; Project.init(null);
import org.apache.flex.ant.tags.Property; Property.init(null);
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a3f2326/ant_on_air/tests/test.xml
----------------------------------------------------------------------
diff --git a/ant_on_air/tests/test.xml b/ant_on_air/tests/test.xml
index 5d55451..8114225 100644
--- a/ant_on_air/tests/test.xml
+++ b/ant_on_air/tests/test.xml
@@ -45,6 +45,26 @@
<target name="test">
<echo>FLEX_HOME is ${FLEX_HOME}. DEBUG is ${DEBUG_FLAG}. The OS is ${theOS}</echo>
+ <mkdir dir="${basedir}/temp" />
+ <copy file="${basedir}/test.xml" toFile="${basedir}/temp/copied.xml" />
+ <available file="${basedir}/temp/copied.xml" property="copied.doesnt.exist" value="got copied" />
+ <echo>copied ${copied.doesnt.exist}. Should say: got copied</echo>
+ <copy toDir="${basedir}/temp">
+ <fileset dir="${basedir}/../src">
+ <include name="**/**" />
+ <exclude name="**/Ant.as" />
+ </fileset>
+ </copy>
+ <available file="${basedir}/temp/org/apache/flex/ant/Ant.as" property="ant.doesnt.exist" value="got copied" />
+ <echo>Ant.as ${ant.doesnt.exist}. Should NOT say: got copied</echo>
+ <available file="${basedir}/temp/org/apache/flex/ant/tags/Project.as" property="project.doesnt.exist" value="got copied" />
+ <echo>Project.as ${project.doesnt.exist}. Should say: got copied</echo>
+ <delete file="${basedir}/temp/copied.xml" />
+ <available file="${basedir}/temp/copied.xml" property="copied.doesnt.exist.after.delete" value="didn't get deleted" />
+ <echo>copied.xml ${copied.doesnt.exist.after.delete}. Should NOT say: didn't get deleted</echo>
+ <delete dir="${basedir}/temp" />
+ <available file="${basedir}/temp/org/apache/flex/ant/tags/Project.as" property="project.doesnt.exist.after.delete" value="didn't get deleted" />
+ <echo>Project.as ${project.doesnt.exist.after.delete}. Should NOT say: didn't get deleted</echo>
</target>
<target name="build" depends="init,compile"
[06/14] port DirectoryScanner from Ant code base and hook up FileSet
to it
Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DirectoryScanner.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DirectoryScanner.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DirectoryScanner.as
new file mode 100644
index 0000000..e6f1927
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/DirectoryScanner.as
@@ -0,0 +1,1764 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import flash.filesystem.File;
+ import flash.utils.Dictionary;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.filesetClasses.Resource;
+ import org.apache.flex.ant.tags.filesetClasses.SelectorUtils;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.BuildException;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.IOException;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.IllegalStateException;
+
+ /**
+ * Ported from org.apache.tools.ant.DirectoryScanner.java on 12/3/13.
+ * Class for scanning a directory for files/directories which match certain
+ * criteria.
+ * <p>
+ * These criteria consist of selectors and patterns which have been specified.
+ * With the selectors you can select which files you want to have included.
+ * Files which are not selected are excluded. With patterns you can include
+ * or exclude files based on their filename.
+ * <p>
+ * The idea is simple. A given directory is recursively scanned for all files
+ * and directories. Each file/directory is matched against a set of selectors,
+ * including special support for matching against filenames with include and
+ * and exclude patterns. Only files/directories which match at least one
+ * pattern of the include pattern list or other file selector, and don't match
+ * any pattern of the exclude pattern list or fail to match against a required
+ * selector will be placed in the list of files/directories found.
+ * <p>
+ * When no list of include patterns is supplied, "**" will be used, which
+ * means that everything will be matched. When no list of exclude patterns is
+ * supplied, an empty list is used, such that nothing will be excluded. When
+ * no selectors are supplied, none are applied.
+ * <p>
+ * The filename pattern matching is done as follows:
+ * The name to be matched is split up in path segments. A path segment is the
+ * name of a directory or file, which is bounded by
+ * <code>File.separator</code> ('/' under UNIX, '\' under Windows).
+ * For example, "abc/def/ghi/xyz.java" is split up in the segments "abc",
+ * "def","ghi" and "xyz.java".
+ * The same is done for the pattern against which should be matched.
+ * <p>
+ * The segments of the name and the pattern are then matched against each
+ * other. When '**' is used for a path segment in the pattern, it matches
+ * zero or more path segments of the name.
+ * <p>
+ * There is a special case regarding the use of <code>File.separator</code>s
+ * at the beginning of the pattern and the string to match:<br>
+ * When a pattern starts with a <code>File.separator</code>, the string
+ * to match must also start with a <code>File.separator</code>.
+ * When a pattern does not start with a <code>File.separator</code>, the
+ * string to match may not start with a <code>File.separator</code>.
+ * When one of these rules is not obeyed, the string will not
+ * match.
+ * <p>
+ * When a name path segment is matched against a pattern path segment, the
+ * following special characters can be used:<br>
+ * '*' matches zero or more characters<br>
+ * '?' matches one character.
+ * <p>
+ * Examples:
+ * <p>
+ * "**\*.class" matches all .class files/dirs in a directory tree.
+ * <p>
+ * "test\a??.java" matches all files/dirs which start with an 'a', then two
+ * more characters and then ".java", in a directory called test.
+ * <p>
+ * "**" matches everything in a directory tree.
+ * <p>
+ * "**\test\**\XYZ*" matches all files/dirs which start with "XYZ" and where
+ * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123").
+ * <p>
+ * Case sensitivity may be turned off if necessary. By default, it is
+ * turned on.
+ * <p>
+ * Example of usage:
+ * <pre>
+ * String[] includes = {"**\\*.class"};
+ * String[] excludes = {"modules\\*\\**"};
+ * ds.setIncludes(includes);
+ * ds.setExcludes(excludes);
+ * ds.setBasedir(new File("test"));
+ * ds.setCaseSensitive(true);
+ * ds.scan();
+ *
+ * System.out.println("FILES:");
+ * String[] files = ds.getIncludedFiles();
+ * for (int i = 0; i < files.length; i++) {
+ * System.out.println(files[i]);
+ * }
+ * </pre>
+ * This will scan a directory called test for .class files, but excludes all
+ * files in all proper subdirectories of a directory called "modules"
+ *
+ */
+ public class DirectoryScanner
+ /* implements FileScanner, SelectorScanner, ResourceFactory*/ {
+
+ /**
+ * Patterns which should be excluded by default.
+ *
+ * <p>Note that you can now add patterns to the list of default
+ * excludes. Added patterns will not become part of this array
+ * that has only been kept around for backwards compatibility
+ * reasons.</p>
+ *
+ * @deprecated since 1.6.x.
+ * Use the {@link #getDefaultExcludes getDefaultExcludes}
+ * method instead.
+ */
+ protected static const DEFAULTEXCLUDES:Vector.<String> = Vector.<String>([
+ // Miscellaneous typical temporary files
+ SelectorUtils.DEEP_TREE_MATCH + "/*~",
+ SelectorUtils.DEEP_TREE_MATCH + "/#*#",
+ SelectorUtils.DEEP_TREE_MATCH + "/.#*",
+ SelectorUtils.DEEP_TREE_MATCH + "/%*%",
+ SelectorUtils.DEEP_TREE_MATCH + "/._*",
+
+ // CVS
+ SelectorUtils.DEEP_TREE_MATCH + "/CVS",
+ SelectorUtils.DEEP_TREE_MATCH + "/CVS/" + SelectorUtils.DEEP_TREE_MATCH,
+ SelectorUtils.DEEP_TREE_MATCH + "/.cvsignore",
+
+ // SCCS
+ SelectorUtils.DEEP_TREE_MATCH + "/SCCS",
+ SelectorUtils.DEEP_TREE_MATCH + "/SCCS/" + SelectorUtils.DEEP_TREE_MATCH,
+
+ // Visual SourceSafe
+ SelectorUtils.DEEP_TREE_MATCH + "/vssver.scc",
+
+ // Subversion
+ SelectorUtils.DEEP_TREE_MATCH + "/.svn",
+ SelectorUtils.DEEP_TREE_MATCH + "/.svn/" + SelectorUtils.DEEP_TREE_MATCH,
+
+ // Git
+ SelectorUtils.DEEP_TREE_MATCH + "/.git",
+ SelectorUtils.DEEP_TREE_MATCH + "/.git/" + SelectorUtils.DEEP_TREE_MATCH,
+ SelectorUtils.DEEP_TREE_MATCH + "/.gitattributes",
+ SelectorUtils.DEEP_TREE_MATCH + "/.gitignore",
+ SelectorUtils.DEEP_TREE_MATCH + "/.gitmodules",
+
+ // Mercurial
+ SelectorUtils.DEEP_TREE_MATCH + "/.hg",
+ SelectorUtils.DEEP_TREE_MATCH + "/.hg/" + SelectorUtils.DEEP_TREE_MATCH,
+ SelectorUtils.DEEP_TREE_MATCH + "/.hgignore",
+ SelectorUtils.DEEP_TREE_MATCH + "/.hgsub",
+ SelectorUtils.DEEP_TREE_MATCH + "/.hgsubstate",
+ SelectorUtils.DEEP_TREE_MATCH + "/.hgtags",
+
+ // Bazaar
+ SelectorUtils.DEEP_TREE_MATCH + "/.bzr",
+ SelectorUtils.DEEP_TREE_MATCH + "/.bzr/" + SelectorUtils.DEEP_TREE_MATCH,
+ SelectorUtils.DEEP_TREE_MATCH + "/.bzrignore",
+
+ // Mac
+ SelectorUtils.DEEP_TREE_MATCH + "/.DS_Store"
+ ]);
+
+ /**
+ * default value for {@link #maxLevelsOfSymlinks maxLevelsOfSymlinks}
+ * @since Ant 1.8.0
+ */
+ public static const MAX_LEVELS_OF_SYMLINKS:int = 5;
+ /**
+ * The end of the exception message if something that should be
+ * there doesn't exist.
+ */
+ public static const DOES_NOT_EXIST_POSTFIX:String = " does not exist.";
+
+ /** Helper. */
+ private static const FILE_UTILS:FileUtils = FileUtils.getFileUtils();
+
+ /**
+ * Patterns which should be excluded by default.
+ *
+ * @see #addDefaultExcludes()
+ */
+ private static const defaultExcludes:Vector.<String> = resetDefaultExcludes();
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /** The base directory to be scanned. */
+ protected var basedir:File;
+
+ /** The patterns for the files to be included. */
+ protected var includes:Vector.<String>;
+
+ /** The patterns for the files to be excluded. */
+ protected var excludes:Vector.<String>;
+
+ /** Selectors that will filter which files are in our candidate list. */
+ protected var selectors:Vector.<FileSelector> = null;
+
+ /**
+ * The files which matched at least one include and no excludes
+ * and were selected.
+ */
+ protected var filesIncluded:Vector.<String>;
+
+ /** The files which did not match any includes or selectors. */
+ protected var filesNotIncluded:Vector.<String>;
+
+ /**
+ * The files which matched at least one include and at least
+ * one exclude.
+ */
+ protected var filesExcluded:Vector.<String>;
+
+ /**
+ * The directories which matched at least one include and no excludes
+ * and were selected.
+ */
+ protected var dirsIncluded:Vector.<String>;
+
+ /** The directories which were found and did not match any includes. */
+ protected var dirsNotIncluded:Vector.<String>;
+
+ /**
+ * The directories which matched at least one include and at least one
+ * exclude.
+ */
+ protected var dirsExcluded:Vector.<String>;
+
+ /**
+ * The files which matched at least one include and no excludes and
+ * which a selector discarded.
+ */
+ protected var filesDeselected:Vector.<String>;
+
+ /**
+ * The directories which matched at least one include and no excludes
+ * but which a selector discarded.
+ */
+ protected var dirsDeselected:Vector.<String>;
+
+ /** Whether or not our results were built by a slow scan. */
+ protected var haveSlowResults:Boolean = false;
+
+ /**
+ * Whether or not the file system should be treated as a case sensitive
+ * one.
+ */
+ protected var _isCaseSensitive:Boolean = true;
+
+ /**
+ * Whether a missing base directory is an error.
+ * @since Ant 1.7.1
+ */
+ protected var errorOnMissingDir:Boolean = true;
+
+ /**
+ * Whether or not symbolic links should be followed.
+ *
+ * @since Ant 1.5
+ */
+ private var followSymlinks:Boolean = true;
+
+ /** Whether or not everything tested so far has been included. */
+ protected var everythingIncluded:Boolean = true;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * List of all scanned directories.
+ *
+ * @since Ant 1.6
+ */
+ private var scannedDirs:Vector.<String> = new Vector.<String>();
+
+ /**
+ * Map of all include patterns that are full file names and don't
+ * contain any wildcards.
+ *
+ * <p>Maps pattern string to TokenizedPath.</p>
+ *
+ * <p>If this instance is not case sensitive, the file names get
+ * turned to upper case.</p>
+ *
+ * <p>Gets lazily initialized on the first invocation of
+ * isIncluded or isExcluded and cleared at the end of the scan
+ * method (cleared in clearCaches, actually).</p>
+ *
+ * @since Ant 1.8.0
+ */
+ private var includeNonPatterns:Object = {}; //new HashMap<String, TokenizedPath>();
+
+ /**
+ * Map of all exclude patterns that are full file names and don't
+ * contain any wildcards.
+ *
+ * <p>Maps pattern string to TokenizedPath.</p>
+ *
+ * <p>If this instance is not case sensitive, the file names get
+ * turned to upper case.</p>
+ *
+ * <p>Gets lazily initialized on the first invocation of
+ * isIncluded or isExcluded and cleared at the end of the scan
+ * method (cleared in clearCaches, actually).</p>
+ *
+ * @since Ant 1.8.0
+ */
+ private var excludeNonPatterns:Object = {}; //new HashMap<String, TokenizedPath>();
+
+ /**
+ * Array of all include patterns that contain wildcards.
+ *
+ * <p>Gets lazily initialized on the first invocation of
+ * isIncluded or isExcluded and cleared at the end of the scan
+ * method (cleared in clearCaches, actually).</p>
+ */
+ private var includePatterns:Vector.<TokenizedPattern>;
+
+ /**
+ * Array of all exclude patterns that contain wildcards.
+ *
+ * <p>Gets lazily initialized on the first invocation of
+ * isIncluded or isExcluded and cleared at the end of the scan
+ * method (cleared in clearCaches, actually).</p>
+ */
+ private var excludePatterns:Vector.<TokenizedPattern>;
+
+ /**
+ * Have the non-pattern sets and pattern arrays for in- and
+ * excludes been initialized?
+ *
+ * @since Ant 1.6.3
+ */
+ private var areNonPatternSetsReady:Boolean = false;
+
+ /**
+ * Scanning flag.
+ *
+ * @since Ant 1.6.3
+ */
+ private var scanning:Boolean = false;
+
+ /**
+ * Scanning lock.
+ *
+ * @since Ant 1.6.3
+ */
+ private var scanLock:Object = new Object();
+
+ /**
+ * Slow scanning flag.
+ *
+ * @since Ant 1.6.3
+ */
+ private var slowScanning:Boolean = false;
+
+ /**
+ * Slow scanning lock.
+ *
+ * @since Ant 1.6.3
+ */
+ private var slowScanLock:Object = new Object();
+
+ /**
+ * Exception thrown during scan.
+ *
+ * @since Ant 1.6.3
+ */
+ private var illegal:IllegalStateException = null;
+
+ /**
+ * The maximum number of times a symbolic link may be followed
+ * during a scan.
+ *
+ * @since Ant 1.8.0
+ */
+ private var maxLevelsOfSymlinks:int = MAX_LEVELS_OF_SYMLINKS;
+
+
+ /**
+ * Absolute paths of all symlinks that haven't been followed but
+ * would have been if followsymlinks had been true or
+ * maxLevelsOfSymlinks had been higher.
+ *
+ * @since Ant 1.8.0
+ */
+ private var notFollowedSymlinks:Vector.<String> = new Vector.<String>();
+
+ /**
+ * Sole constructor.
+ */
+ public function DirectoryScanner() {
+ }
+
+ /**
+ * Test whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ protected static function matchPatternStart(pattern:String, str:String,
+ isCaseSensitive:Boolean = true):Boolean {
+ return SelectorUtils.matchPatternStart(pattern, str, isCaseSensitive);
+ }
+
+ /**
+ * Test whether or not a given path matches a given pattern.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ protected static function matchPath(pattern:String, str:String,
+ isCaseSensitive:Boolean = true):Boolean {
+ return SelectorUtils.matchPath(pattern, str, isCaseSensitive);
+ }
+
+ /**
+ * Test whether or not a string matches against a pattern.
+ * The pattern may contain two special characters:<br>
+ * '*' means zero or more characters<br>
+ * '?' means one and only one character
+ *
+ * @param pattern The pattern to match against.
+ * Must not be <code>null</code>.
+ * @param str The string which must be matched against the pattern.
+ * Must not be <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ *
+ * @return <code>true</code> if the string matches against the pattern,
+ * or <code>false</code> otherwise.
+ */
+ protected static function match(pattern:String, str:String,
+ isCaseSensitive:Boolean = true):Boolean{
+ return SelectorUtils.match(pattern, str, isCaseSensitive);
+ }
+
+
+ /**
+ * Get the list of patterns that should be excluded by default.
+ *
+ * @return An array of <code>String</code> based on the current
+ * contents of the <code>defaultExcludes</code>
+ * <code>Set</code>.
+ *
+ * @since Ant 1.6
+ */
+ public static function getDefaultExcludes():Vector.<String> {
+ return defaultExcludes.slice();
+ }
+
+ /**
+ * Add a pattern to the default excludes unless it is already a
+ * default exclude.
+ *
+ * @param s A string to add as an exclude pattern.
+ * @return <code>true</code> if the string was added;
+ * <code>false</code> if it already existed.
+ *
+ * @since Ant 1.6
+ */
+ public static function addDefaultExclude(s:String):Boolean {
+ if (defaultExcludes.indexOf(s) == -1)
+ {
+ defaultExcludes.push(s);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Remove a string if it is a default exclude.
+ *
+ * @param s The string to attempt to remove.
+ * @return <code>true</code> if <code>s</code> was a default
+ * exclude (and thus was removed);
+ * <code>false</code> if <code>s</code> was not
+ * in the default excludes list to begin with.
+ *
+ * @since Ant 1.6
+ */
+ public static function removeDefaultExclude(s:String):Boolean {
+ var index:int = defaultExcludes.indexOf(s);
+ if (index == -1)
+ return false;
+ defaultExcludes.splice(index, 1);
+ return true;
+ }
+
+ /**
+ * Go back to the hardwired default exclude patterns.
+ *
+ * @since Ant 1.6
+ */
+ public static function resetDefaultExcludes():Vector.<String> {
+ defaultExcludes.length = 0;
+ for (var i:int = 0; i < DEFAULTEXCLUDES.length; i++) {
+ defaultExcludes.push(DEFAULTEXCLUDES[i]);
+ }
+ return defaultExcludes;
+ }
+
+ /**
+ * Set the base directory to be scanned. This is the directory which is
+ * scanned recursively. All '/' and '\' characters are replaced by
+ * <code>File.separatorChar</code>, so the separator used need not match
+ * <code>File.separatorChar</code>.
+ *
+ * @param basedir The base directory to scan.
+ */
+ public function setBasedir(basedir:Object):void {
+ if (basedir is File)
+ setBasedirFile(basedir as File);
+ else
+ setBasedirFile(basedir == null ? null
+ : new File(basedir.replace('/', File.separator).replace(
+ '\\', File.separator)));
+ }
+
+ /**
+ * Set the base directory to be scanned. This is the directory which is
+ * scanned recursively.
+ *
+ * @param basedir The base directory for scanning.
+ */
+ public function setBasedirFile(basedir:File):void {
+ this.basedir = basedir;
+ }
+
+ /**
+ * Return the base directory to be scanned.
+ * This is the directory which is scanned recursively.
+ *
+ * @return the base directory to be scanned.
+ */
+ public function getBasedir():File {
+ return basedir;
+ }
+
+ /**
+ * Find out whether include exclude patterns are matched in a
+ * case sensitive way.
+ * @return whether or not the scanning is case sensitive.
+ * @since Ant 1.6
+ */
+ public function isCaseSensitive():Boolean {
+ return _isCaseSensitive;
+ }
+
+ /**
+ * Set whether or not include and exclude patterns are matched
+ * in a case sensitive way.
+ *
+ * @param isCaseSensitive whether or not the file system should be
+ * regarded as a case sensitive one.
+ */
+ public function setCaseSensitive(isCaseSensitive:Boolean):void {
+ _isCaseSensitive = isCaseSensitive;
+ }
+
+ /**
+ * Sets whether or not a missing base directory is an error
+ *
+ * @param errorOnMissingDir whether or not a missing base directory
+ * is an error
+ * @since Ant 1.7.1
+ */
+ public function setErrorOnMissingDir(errorOnMissingDir:Boolean):void {
+ this.errorOnMissingDir = errorOnMissingDir;
+ }
+
+ /**
+ * Get whether or not a DirectoryScanner follows symbolic links.
+ *
+ * @return flag indicating whether symbolic links should be followed.
+ *
+ * @since Ant 1.6
+ */
+ public function isFollowSymlinks():Boolean {
+ return followSymlinks;
+ }
+
+ /**
+ * Set whether or not symbolic links should be followed.
+ *
+ * @param followSymlinks whether or not symbolic links should be followed.
+ */
+ public function setFollowSymlinks(followSymlinks:Boolean):void {
+ this.followSymlinks = followSymlinks;
+ }
+
+ /**
+ * The maximum number of times a symbolic link may be followed
+ * during a scan.
+ *
+ * @since Ant 1.8.0
+ */
+ public function setMaxLevelsOfSymlinks(max:int):void {
+ maxLevelsOfSymlinks = max;
+ }
+
+ /**
+ * Set the list of include patterns to use. All '/' and '\' characters
+ * are replaced by <code>File.separator</code>, so the separator used
+ * need not match <code>File.separator</code>.
+ * <p>
+ * When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @param includes A list of include patterns.
+ * May be <code>null</code>, indicating that all files
+ * should be included. If a non-<code>null</code>
+ * list is given, all elements must be
+ * non-<code>null</code>.
+ */
+ public function setIncludes(includes:Vector.<String>):void {
+ if (includes == null) {
+ this.includes = null;
+ } else {
+ this.includes = new Vector.<String>(includes.length);
+ for (var i:int = 0; i < includes.length; i++) {
+ this.includes[i] = normalizePattern(includes[i]);
+ }
+ }
+ }
+
+ /**
+ * Set the list of exclude patterns to use. All '/' and '\' characters
+ * are replaced by <code>File.separator</code>, so the separator used
+ * need not match <code>File.separator</code>.
+ * <p>
+ * When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @param excludes A list of exclude patterns.
+ * May be <code>null</code>, indicating that no files
+ * should be excluded. If a non-<code>null</code> list is
+ * given, all elements must be non-<code>null</code>.
+ */
+ public function setExcludes(excludes:Vector.<String>):void {
+ if (excludes == null) {
+ this.excludes = null;
+ } else {
+ this.excludes = new Vector.<String>(excludes.length);
+ for (var i:int = 0; i < excludes.length; i++) {
+ this.excludes[i] = normalizePattern(excludes[i]);
+ }
+ }
+ }
+
+ /**
+ * Add to the list of exclude patterns to use. All '/' and '\'
+ * characters are replaced by <code>File.separator</code>, so
+ * the separator used need not match <code>File.separator</code>.
+ * <p>
+ * When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @param excludes A list of exclude patterns.
+ * May be <code>null</code>, in which case the
+ * exclude patterns don't get changed at all.
+ *
+ * @since Ant 1.6.3
+ */
+ public function addExcludes(excludes:Vector.<String>):void {
+ if (excludes != null && excludes.length > 0) {
+ if (this.excludes != null && this.excludes.length > 0) {
+ var tmp:Vector.<String> = this.excludes.slice();
+ for (var i:int = 0; i < excludes.length; i++) {
+ tmp.push(
+ normalizePattern(excludes[i]));
+ }
+ this.excludes = tmp;
+ } else {
+ setExcludes(excludes);
+ }
+ }
+ }
+
+ /**
+ * All '/' and '\' characters are replaced by
+ * <code>File.separator</code>, so the separator used need not
+ * match <code>File.separator</code>.
+ *
+ * <p> When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @since Ant 1.6.3
+ */
+ private function normalizePattern(p:String):String {
+ var pattern:String = p.replace(/\//g, File.separator)
+ .replace(/\\/g, File.separator);
+ if (pattern.charAt(pattern.length - 1) == File.separator) {
+ pattern += SelectorUtils.DEEP_TREE_MATCH;
+ }
+ return pattern;
+ }
+
+ /**
+ * Set the selectors that will select the filelist.
+ *
+ * @param selectors specifies the selectors to be invoked on a scan.
+ */
+ public function setSelectors(selectors:Vector.<FileSelector>):void {
+ this.selectors = selectors;
+ }
+
+ /**
+ * Return whether or not the scanner has included all the files or
+ * directories it has come across so far.
+ *
+ * @return <code>true</code> if all files and directories which have
+ * been found so far have been included.
+ */
+ public function isEverythingIncluded():Boolean {
+ return everythingIncluded;
+ }
+
+ /**
+ * Scan for files which match at least one include pattern and don't match
+ * any exclude patterns. If there are selectors then the files must pass
+ * muster there, as well. Scans under basedir, if set; otherwise the
+ * include patterns without leading wildcards specify the absolute paths of
+ * the files that may be included.
+ *
+ * @exception IllegalStateException if the base directory was set
+ * incorrectly (i.e. if it doesn't exist or isn't a directory).
+ */
+ public function scan():void
+ {
+ var savedBase:File = basedir;
+ try {
+ illegal = null;
+ clearResults();
+
+ // set in/excludes to reasonable defaults if needed:
+ var nullIncludes:Boolean = (includes == null);
+ includes = nullIncludes
+ ? Vector.<String>([SelectorUtils.DEEP_TREE_MATCH]) : includes;
+ var nullExcludes:Boolean = (excludes == null);
+ excludes = nullExcludes ? new Vector.<String>(0) : excludes;
+
+ if (basedir != null && !followSymlinks
+ && basedir.isSymbolicLink) {
+ notFollowedSymlinks.push(basedir.nativePath);
+ basedir = null;
+ }
+
+ if (basedir == null) {
+ // if no basedir and no includes, nothing to do:
+ if (nullIncludes) {
+ return;
+ }
+ } else {
+ if (!basedir.exists) {
+ if (errorOnMissingDir) {
+ illegal = new IllegalStateException("basedir "
+ + basedir
+ + DOES_NOT_EXIST_POSTFIX);
+ } else {
+ // Nothing to do - basedir does not exist
+ return;
+ }
+ } else if (!basedir.isDirectory) {
+ illegal = new IllegalStateException("basedir "
+ + basedir
+ + " is not a"
+ + " directory.");
+ }
+ if (illegal != null) {
+ throw illegal;
+ }
+ }
+ if (isIncludedPath(TokenizedPath.EMPTY_PATH)) {
+ if (!isExcludedPath(TokenizedPath.EMPTY_PATH)) {
+ if (isSelected("", basedir)) {
+ dirsIncluded.push("");
+ } else {
+ dirsDeselected.push("");
+ }
+ } else {
+ dirsExcluded.push("");
+ }
+ } else {
+ dirsNotIncluded.push("");
+ }
+ checkIncludePatterns();
+ clearCaches();
+ includes = nullIncludes ? null : includes;
+ excludes = nullExcludes ? null : excludes;
+ } catch (ex:IOException) {
+ throw new BuildException(ex.message);
+ } finally {
+ basedir = savedBase;
+ }
+ }
+
+ /**
+ * This routine is actually checking all the include patterns in
+ * order to avoid scanning everything under base dir.
+ * @since Ant 1.6
+ */
+ private function checkIncludePatterns():void
+ {
+ ensureNonPatternSetsReady();
+ var newroots:Dictionary = new Dictionary();
+
+ // put in the newroots map the include patterns without
+ // wildcard tokens
+ for (var i:int = 0; i < includePatterns.length; i++) {
+ var pattern:String = includePatterns[i].toString();
+ if (!shouldSkipPattern(pattern)) {
+ newroots[includePatterns[i].rtrimWildcardTokens()] =
+ pattern;
+ }
+ }
+ for each (var entry:Dictionary in includeNonPatterns.entrySet()) {
+ for (var p:String in entry)
+ {
+ pattern = p;
+ break;
+ }
+ if (!shouldSkipPattern(pattern)) {
+ newroots[entry.getValue()] = pattern;
+ }
+ }
+
+ if (newroots.hasOwnProperty(TokenizedPath.EMPTY_PATH)
+ && basedir != null) {
+ // we are going to scan everything anyway
+ scandir(basedir, "", true);
+ } else {
+ var canonBase:File = null;
+ if (basedir != null) {
+ try {
+ canonBase = new File(basedir.nativePath);
+ canonBase.canonicalize();
+ } catch (ex:IOException) {
+ throw new BuildException(ex.message);
+ }
+ }
+ // only scan directories that can include matched files or
+ // directories
+ for each (entry in newroots.entrySet()) {
+ var currentPath:TokenizedPath;
+ for (p in entry)
+ {
+ currentPath = p as TokenizedPath;
+ break;
+ }
+ var currentelement:String = currentPath.toString();
+ if (basedir == null
+ && !FileUtils.isAbsolutePath(currentelement)) {
+ continue;
+ }
+ var myfile:File = new File(basedir.nativePath + File.separator + currentelement);
+
+ if (myfile.exists) {
+ // may be on a case insensitive file system. We want
+ // the results to show what's really on the disk, so
+ // we need to double check.
+ try {
+ var myCanonFile:File = new File(myfile.nativePath);
+ myCanonFile.canonicalize();
+ var path:String = (basedir == null)
+ ? myCanonFile.nativePath
+ : FILE_UTILS.removeLeadingPath(canonBase,
+ myCanonFile);
+ if (!path == currentelement) {
+ myfile = currentPath.findFile(basedir, true);
+ if (myfile != null && basedir != null) {
+ currentelement = FILE_UTILS.removeLeadingPath(
+ basedir, myfile);
+ if (!currentPath.toString()
+ == currentelement) {
+ currentPath =
+ new TokenizedPath(currentelement);
+ }
+ }
+ }
+ } catch (ex:IOException) {
+ throw new BuildException(ex.message);
+ }
+ }
+
+ if ((myfile == null || !myfile.exists) && !isCaseSensitive()) {
+ var f:File = currentPath.findFile(basedir, false);
+ if (f != null && f.exists) {
+ // adapt currentelement to the case we've
+ // actually found
+ currentelement = (basedir == null)
+ ? f.nativePath
+ : FILE_UTILS.removeLeadingPath(basedir, f);
+ myfile = f;
+ currentPath = new TokenizedPath(currentelement);
+ }
+ }
+
+ if (myfile != null && myfile.exists) {
+ if (!followSymlinks && currentPath.isSymlink(basedir)) {
+ if (!isExcludedPath(currentPath)) {
+ notFollowedSymlinks.push(myfile.nativePath);
+ }
+ continue;
+ }
+ if (myfile.isDirectory) {
+ if (isIncludedPath(currentPath)
+ && currentelement.length > 0) {
+ accountForIncludedDir(currentPath, myfile, true);
+ } else {
+ scandirTokenizedPath(myfile, currentPath, true);
+ }
+ } else {
+ var originalpattern:String;
+ for (var q:* in entry)
+ {
+ originalpattern = entry[q];
+ }
+ var included:Boolean = isCaseSensitive()
+ ? originalpattern == currentelement
+ : originalpattern.toUpperCase() == currentelement.toUpperCase();
+ if (included) {
+ accountForIncludedFile(currentPath, myfile);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * true if the pattern specifies a relative path without basedir
+ * or an absolute path not inside basedir.
+ *
+ * @since Ant 1.8.0
+ */
+ private function shouldSkipPattern(pattern:String):Boolean {
+ if (FileUtils.isAbsolutePath(pattern)) {
+ //skip abs. paths not under basedir, if set:
+ if (basedir != null
+ && !SelectorUtils.matchPatternStart(pattern,
+ basedir.nativePath,
+ isCaseSensitive())) {
+ return true;
+ }
+ } else if (basedir == null) {
+ //skip non-abs. paths if basedir == null:
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Clear the result caches for a scan.
+ */
+ protected function clearResults():void {
+ filesIncluded = new Vector.<String>();
+ filesNotIncluded = new Vector.<String>();
+ filesExcluded = new Vector.<String>();
+ filesDeselected = new Vector.<String>();
+ dirsIncluded = new Vector.<String>();
+ dirsNotIncluded = new Vector.<String>();
+ dirsExcluded = new Vector.<String>();
+ dirsDeselected = new Vector.<String>();
+ everythingIncluded = (basedir != null);
+ scannedDirs.length = 0;
+ notFollowedSymlinks.length = 0;
+ }
+
+ /**
+ * Top level invocation for a slow scan. A slow scan builds up a full
+ * list of excluded/included files/directories, whereas a fast scan
+ * will only have full results for included files, as it ignores
+ * directories which can't possibly hold any included files/directories.
+ * <p>
+ * Returns immediately if a slow scan has already been completed.
+ */
+ protected function slowScan():void
+ {
+ try {
+ // set in/excludes to reasonable defaults if needed:
+ var nullIncludes:Boolean = (includes == null);
+ includes = nullIncludes
+ ? Vector.<String>([SelectorUtils.DEEP_TREE_MATCH]) : includes;
+ var nullExcludes:Boolean = (excludes == null);
+ excludes = nullExcludes ? new Vector.<String>(0) : excludes;
+
+ var excl:Vector.<String> = dirsExcluded.slice();
+
+ var notIncl:Vector.<String> = dirsNotIncluded.slice();
+
+ ensureNonPatternSetsReady();
+
+ processSlowScan(excl);
+ processSlowScan(notIncl);
+ clearCaches();
+ includes = nullIncludes ? null : includes;
+ excludes = nullExcludes ? null : excludes;
+ } finally {
+ haveSlowResults = true;
+ slowScanning = false;
+ slowScanLock.notifyAll();
+ }
+ }
+
+ private function processSlowScan(arr:Vector.<String>):void {
+ for (var i:int = 0; i < arr.length; i++) {
+ var path:TokenizedPath = new TokenizedPath(arr[i]);
+ if (!couldHoldIncludedPath(path) || contentsExcluded(path)) {
+ scandirTokenizedPath(new File(basedir.nativePath + File.separator + arr[i]), path, false);
+ }
+ }
+ }
+
+ /**
+ * Scan the given directory for files and directories. Found files and
+ * directories are placed in their respective collections, based on the
+ * matching of includes, excludes, and the selectors. When a directory
+ * is found, it is scanned recursively.
+ *
+ * @param dir The directory to scan. Must not be <code>null</code>.
+ * @param vpath The path relative to the base directory (needed to
+ * prevent problems with an absolute path when using
+ * dir). Must not be <code>null</code>.
+ * @param fast Whether or not this call is part of a fast scan.
+ *
+ * @see #filesIncluded
+ * @see #filesNotIncluded
+ * @see #filesExcluded
+ * @see #dirsIncluded
+ * @see #dirsNotIncluded
+ * @see #dirsExcluded
+ * @see #slowScan
+ */
+ protected function scandir(dir:File, vpath:String, fast:Boolean):void {
+ scandirTokenizedPath(dir, new TokenizedPath(vpath), fast);
+ }
+
+ /**
+ * Scan the given directory for files and directories. Found files and
+ * directories are placed in their respective collections, based on the
+ * matching of includes, excludes, and the selectors. When a directory
+ * is found, it is scanned recursively.
+ *
+ * @param dir The directory to scan. Must not be <code>null</code>.
+ * @param path The path relative to the base directory (needed to
+ * prevent problems with an absolute path when using
+ * dir). Must not be <code>null</code>.
+ * @param fast Whether or not this call is part of a fast scan.
+ *
+ * @see #filesIncluded
+ * @see #filesNotIncluded
+ * @see #filesExcluded
+ * @see #dirsIncluded
+ * @see #dirsNotIncluded
+ * @see #dirsExcluded
+ * @see #slowScan
+ */
+ private function scandirTokenizedPath(dir:File, path:TokenizedPath, fast:Boolean):void {
+ if (dir == null) {
+ throw new BuildException("dir must not be null.");
+ }
+ var arr:Array = dir.getDirectoryListing();
+ var arr2:Array = [];
+ for each (var f:File in arr)
+ arr2.push(f.nativePath);
+ var newfiles:Vector.<String> = Vector.<String>(arr2);;
+ if (newfiles == null) {
+ if (!dir.exists) {
+ throw new BuildException(dir + DOES_NOT_EXIST_POSTFIX);
+ } else if (!dir.isDirectory) {
+ throw new BuildException(dir + " is not a directory.");
+ } else {
+ throw new BuildException("IO error scanning directory '"
+ + dir.nativePath + "'");
+ }
+ }
+ _scandir(dir, path, fast, newfiles, new Vector.<String>());
+ }
+
+ private function _scandir(dir:File, path:TokenizedPath, fast:Boolean,
+ newfiles:Vector.<String>, directoryNamesFollowed:Vector.<String>):void {
+ var vpath:String = path.toString();
+ if (vpath.length > 0 && vpath.charAt(vpath.length - 1) != File.separator) {
+ vpath += File.separator;
+ }
+
+ // avoid double scanning of directories, can only happen in fast mode
+ if (fast && hasBeenScanned(vpath)) {
+ return;
+ }
+ if (!followSymlinks) {
+ var noLinks:Vector.<String> = new Vector.<String>();
+ for (i = 0; i < newfiles.length; i++) {
+ try {
+ if (new File(dir + File.separator + newfiles[i]).isSymbolicLink) {
+ var name:String = vpath + newfiles[i];
+ var file:File = new File(dir.nativePath + File.separator + newfiles[i]);
+ (file.isDirectory
+ ? dirsExcluded : filesExcluded).push(name);
+ if (!isExcluded(name)) {
+ notFollowedSymlinks.push(file.nativePath);
+ }
+ } else {
+ noLinks.push(newfiles[i]);
+ }
+ } catch (ioe:IOException) {
+ var msg:String = "IOException caught while checking "
+ + "for links, couldn't get canonical path!";
+ // will be caught and redirected to Ant's logging system
+ Ant.ant.output(msg);
+ noLinks.push(newfiles[i]);
+ }
+ }
+ newfiles = noLinks.slice();
+ } else {
+ directoryNamesFollowed.unshift(dir.nativePath);
+ }
+
+ for (var i:int = 0; i < newfiles.length; i++) {
+ name = vpath + newfiles[i];
+ var newPath:TokenizedPath = new TokenizedPath("").initAsChild(path, newfiles[i]);
+ file = new File(dir.nativePath + File.separator + newfiles[i]);
+ var arr:Array = file.getDirectoryListing();
+ var arr2:Array = [];
+ for each (var f:File in arr)
+ arr2.push(f.nativePath);
+ var children:Vector.<String> = Vector.<String>(arr2);
+ if (children == null || (children.length == 0 && !file.isDirectory)) {
+ if (isIncludedPath(newPath)) {
+ accountForIncludedFile(newPath, file);
+ } else {
+ everythingIncluded = false;
+ filesNotIncluded.push(name);
+ }
+ } else { // dir
+
+ if (followSymlinks
+ && causesIllegalSymlinkLoop(newfiles[i], dir,
+ directoryNamesFollowed)) {
+ // will be caught and redirected to Ant's logging system
+ Ant.ant.output("skipping symbolic link "
+ + file.nativePath
+ + " -- too many levels of symbolic"
+ + " links.");
+ notFollowedSymlinks.push(file.nativePath);
+ continue;
+ }
+
+ if (isIncludedPath(newPath)) {
+ accountForIncludedDir(newPath, file, fast, children,
+ directoryNamesFollowed);
+ } else {
+ everythingIncluded = false;
+ dirsNotIncluded.push(name);
+ if (fast && couldHoldIncludedPath(newPath)
+ && !contentsExcluded(newPath)) {
+ _scandir(file, newPath, fast, children,
+ directoryNamesFollowed);
+ }
+ }
+ if (!fast) {
+ _scandir(file, newPath, fast, children, directoryNamesFollowed);
+ }
+ }
+ }
+
+ if (followSymlinks) {
+ directoryNamesFollowed.shift();
+ }
+ }
+
+ /**
+ * Process included file.
+ * @param name path of the file relative to the directory of the FileSet.
+ * @param file included File.
+ */
+ private function accountForIncludedFile(name:TokenizedPath, file:File):void {
+ processIncluded(name, file, filesIncluded, filesExcluded,
+ filesDeselected);
+ }
+
+ /**
+ * Process included directory.
+ * @param name path of the directory relative to the directory of
+ * the FileSet.
+ * @param file directory as File.
+ * @param fast whether to perform fast scans.
+ */
+ private function accountForIncludedDir(name:TokenizedPath,
+ file:File, fast:Boolean,
+ children:Vector.<String> = null,
+ directoryNamesFollowed:Vector.<String> = null):void {
+ processIncluded(name, file, dirsIncluded, dirsExcluded, dirsDeselected);
+ if (fast && couldHoldIncludedPath(name) && !contentsExcluded(name)) {
+ _scandir(file, name, fast, children, directoryNamesFollowed);
+ }
+ }
+
+ private function processIncluded(path:TokenizedPath,
+ file:File, inc:Vector.<String>, exc:Vector.<String>,
+ des:Vector.<String>):void {
+ var name:String = path.toString();
+ if (inc.indexOf(name) != -1 ||
+ exc.indexOf(name) != -1 ||
+ des.indexOf(name) != -1) {
+ return;
+ }
+
+ var included:Boolean = false;
+ if (isExcludedPath(path)) {
+ exc.push(name);
+ } else if (isSelected(name, file)) {
+ included = true;
+ inc.push(name);
+ } else {
+ des.push(name);
+ }
+ everythingIncluded = everythingIncluded || included;
+ }
+
+ /**
+ * Test whether or not a name matches against at least one include
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * include pattern, or <code>false</code> otherwise.
+ */
+ protected function isIncluded(name:String):Boolean {
+ return isIncludedPath(new TokenizedPath(name));
+ }
+
+ /**
+ * Test whether or not a name matches against at least one include
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * include pattern, or <code>false</code> otherwise.
+ */
+ private function isIncludedPath(path:TokenizedPath):Boolean {
+ ensureNonPatternSetsReady();
+
+ if (isCaseSensitive()
+ ? includeNonPatterns.containsKey(path.toString())
+ : includeNonPatterns.containsKey(path.toString().toUpperCase())) {
+ return true;
+ }
+ for (var i:int = 0; i < includePatterns.length; i++) {
+ if (includePatterns[i].matchPath(path, isCaseSensitive())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test whether or not a name matches the start of at least one include
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against the start of at
+ * least one include pattern, or <code>false</code> otherwise.
+ */
+ protected function couldHoldIncluded(name:String):Boolean {
+ return couldHoldIncludedPath(new TokenizedPath(name));
+ }
+
+ /**
+ * Test whether or not a name matches the start of at least one include
+ * pattern.
+ *
+ * @param tokenizedName The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against the start of at
+ * least one include pattern, or <code>false</code> otherwise.
+ */
+ private function couldHoldIncludedPath(tokenizedName:TokenizedPath):Boolean {
+ for (var i:int = 0; i < includePatterns.length; i++) {
+ if (couldHoldIncludedWithIncludes(tokenizedName, includePatterns[i])) {
+ return true;
+ }
+ }
+ for each (var iter:TokenizedPath in includeNonPatterns) {
+ if (couldHoldIncludedWithIncludes(tokenizedName,
+ iter.toPattern())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test whether or not a name matches the start of the given
+ * include pattern.
+ *
+ * @param tokenizedName The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against the start of the
+ * include pattern, or <code>false</code> otherwise.
+ */
+ private function couldHoldIncludedWithIncludes(tokenizedName:TokenizedPath,
+ tokenizedInclude:TokenizedPattern):Boolean {
+ return tokenizedInclude.matchStartOf(tokenizedName, isCaseSensitive())
+ && isMorePowerfulThanExcludes(tokenizedName.toString())
+ && isDeeper(tokenizedInclude, tokenizedName);
+ }
+
+ /**
+ * Verify that a pattern specifies files deeper
+ * than the level of the specified file.
+ * @param pattern the pattern to check.
+ * @param name the name to check.
+ * @return whether the pattern is deeper than the name.
+ * @since Ant 1.6.3
+ */
+ private function isDeeper(pattern:TokenizedPattern, name:TokenizedPath):Boolean {
+ return pattern.containsPattern(SelectorUtils.DEEP_TREE_MATCH)
+ || pattern.depth() > name.depth();
+ }
+
+ /**
+ * Find out whether one particular include pattern is more powerful
+ * than all the excludes.
+ * Note: the power comparison is based on the length of the include pattern
+ * and of the exclude patterns without the wildcards.
+ * Ideally the comparison should be done based on the depth
+ * of the match; that is to say how many file separators have been matched
+ * before the first ** or the end of the pattern.
+ *
+ * IMPORTANT : this function should return false "with care".
+ *
+ * @param name the relative path to test.
+ * @return true if there is no exclude pattern more powerful than
+ * this include pattern.
+ * @since Ant 1.6
+ */
+ private function isMorePowerfulThanExcludes(name:String):Boolean {
+ const soughtexclude:String =
+ name + File.separator + SelectorUtils.DEEP_TREE_MATCH;
+ for (var counter:int = 0; counter < excludePatterns.length; counter++) {
+ if (excludePatterns[counter].toString() == soughtexclude) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Test whether all contents of the specified directory must be excluded.
+ * @param path the path to check.
+ * @return whether all the specified directory's contents are excluded.
+ */
+ /* package */ private function contentsExcluded(path:TokenizedPath):Boolean {
+ for (var i:int = 0; i < excludePatterns.length; i++) {
+ if (excludePatterns[i].endsWith(SelectorUtils.DEEP_TREE_MATCH)
+ && excludePatterns[i].withoutLastToken()
+ .matchPath(path, isCaseSensitive())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test whether or not a name matches against at least one exclude
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * exclude pattern, or <code>false</code> otherwise.
+ */
+ protected function isExcluded(name:String):Boolean {
+ return isExcludedPath(new TokenizedPath(name));
+ }
+
+ /**
+ * Test whether or not a name matches against at least one exclude
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * exclude pattern, or <code>false</code> otherwise.
+ */
+ private function isExcludedPath(name:TokenizedPath):Boolean {
+ ensureNonPatternSetsReady();
+
+ if (isCaseSensitive()
+ ? excludeNonPatterns.hasOwnProperty(name.toString())
+ : excludeNonPatterns.hasOwnProperty(name.toString().toUpperCase())) {
+ return true;
+ }
+ for (var i:int = 0; i < excludePatterns.length; i++) {
+ if (excludePatterns[i].matchPath(name, isCaseSensitive())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test whether a file should be selected.
+ *
+ * @param name the filename to check for selecting.
+ * @param file the java.io.File object for this filename.
+ * @return <code>false</code> when the selectors says that the file
+ * should not be selected, <code>true</code> otherwise.
+ */
+ protected function isSelected(name:String, file:File):Boolean {
+ if (selectors != null) {
+ for (var i:int = 0; i < selectors.length; i++) {
+ if (!selectors[i].isSelected(basedir, name, file)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ public function getIncludedFiles():Vector.<String> {
+ var files:Vector.<String>;
+ files = filesIncluded.slice();
+ files.sort(0);
+ return files;
+ }
+
+ /**
+ * Return the count of included files.
+ * @return <code>int</code>.
+ * @since Ant 1.6.3
+ */
+ public function getIncludedFilesCount():int {
+ if (filesIncluded == null) {
+ throw new IllegalStateException("Must call scan() first");
+ }
+ return filesIncluded.length;
+ }
+
+ /**
+ * Return the names of the files which matched none of the include
+ * patterns. The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the files which matched none of the include
+ * patterns.
+ *
+ * @see #slowScan
+ */
+ public function getNotIncludedFiles():Vector.<String> {
+ slowScan();
+ var files:Vector.<String> = filesNotIncluded.slice();
+ return files;
+ }
+
+ /**
+ * Return the names of the files which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ * The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the files which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ *
+ * @see #slowScan
+ */
+ public function getExcludedFiles():Vector.<String> {
+ slowScan();
+ var files:Vector.<String> = filesExcluded.slice();
+ return files;
+ }
+
+ /**
+ * <p>Return the names of the files which were selected out and
+ * therefore not ultimately included.</p>
+ *
+ * <p>The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.</p>
+ *
+ * @return the names of the files which were deselected.
+ *
+ * @see #slowScan
+ */
+ public function getDeselectedFiles():Vector.<String> {
+ slowScan();
+ var files:Vector.<String> = filesDeselected.slice();
+ return files;
+ }
+
+ /**
+ * Return the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ public function getIncludedDirectories():Vector.<String> {
+ var directories:Vector.<String>;
+ directories = dirsIncluded.slice();
+ directories.sort(0);
+ return directories;
+ }
+
+ /**
+ * Return the count of included directories.
+ * @return <code>int</code>.
+ * @since Ant 1.6.3
+ */
+ public function getIncludedDirsCount():int {
+ if (dirsIncluded == null) {
+ throw new IllegalStateException("Must call scan() first");
+ }
+ return dirsIncluded.length;
+ }
+
+ /**
+ * Return the names of the directories which matched none of the include
+ * patterns. The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the directories which matched none of the include
+ * patterns.
+ *
+ * @see #slowScan
+ */
+ public function getNotIncludedDirectories():Vector.<String> {
+ slowScan();
+ var directories:Vector.<String> = dirsNotIncluded.slice();
+ return directories;
+ }
+
+ /**
+ * Return the names of the directories which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ * The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the directories which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ *
+ * @see #slowScan
+ */
+ public function getExcludedDirectories():Vector.<String> {
+ slowScan();
+ var directories:Vector.<String> = dirsExcluded.slice();
+ return directories;
+ }
+
+ /**
+ * <p>Return the names of the directories which were selected out and
+ * therefore not ultimately included.</p>
+ *
+ * <p>The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.</p>
+ *
+ * @return the names of the directories which were deselected.
+ *
+ * @see #slowScan
+ */
+ public function getDeselectedDirectories():Vector.<String> {
+ slowScan();
+ var directories:Vector.<String> = dirsDeselected.slice();
+ return directories;
+ }
+
+ /**
+ * Absolute paths of all symbolic links that haven't been followed
+ * but would have been followed had followsymlinks been true or
+ * maxLevelsOfSymlinks been bigger.
+ *
+ * @since Ant 1.8.0
+ */
+ public function getNotFollowedSymlinks():Vector.<String> {
+ var links:Vector.<String>;
+ links = notFollowedSymlinks.slice();
+ links.sort(0);
+ return links;
+ }
+
+ /**
+ * Add default exclusions to the current exclusions set.
+ */
+ public function addDefaultExcludes():void
+ {
+ var excludesLength:int = excludes == null ? 0 : excludes.length;
+ var newExcludes:Vector.<String>;
+ var defaultExcludesTemp:Vector.<String> = getDefaultExcludes();
+ newExcludes = defaultExcludesTemp.slice();
+ for (var i:int = 0; i < defaultExcludesTemp.length; i++) {
+ newExcludes.push(
+ defaultExcludesTemp[i].replace(/\//g, File.separator)
+ .replace(/\\/g, File.separator));
+ }
+ excludes = newExcludes;
+ }
+
+ /**
+ * Get the named resource.
+ * @param name path name of the file relative to the dir attribute.
+ *
+ * @return the resource with the given name.
+ * @since Ant 1.5.2
+ */
+ public function getResource(name:String):Resource {
+ return new FileResource(basedir, name);
+ }
+
+ /**
+ * Has the directory with the given path relative to the base
+ * directory already been scanned?
+ *
+ * <p>Registers the given directory as scanned as a side effect.</p>
+ *
+ * @since Ant 1.6
+ */
+ private function hasBeenScanned(vpath:String):Boolean {
+ return !scannedDirs.push(vpath);
+ }
+
+ /**
+ * This method is of interest for testing purposes. The returned
+ * Set is live and should not be modified.
+ * @return the Set of relative directory names that have been scanned.
+ */
+ /* package-private */private function getScannedDirs():Vector.<String> {
+ return scannedDirs;
+ }
+
+ /**
+ * Clear internal caches.
+ *
+ * @since Ant 1.6
+ */
+ private function clearCaches():void {
+ includeNonPatterns.clear();
+ excludeNonPatterns.clear();
+ includePatterns = null;
+ excludePatterns = null;
+ areNonPatternSetsReady = false;
+ }
+
+ /**
+ * Ensure that the in|exclude "patterns"
+ * have been properly divided up.
+ *
+ * @since Ant 1.6.3
+ */
+ /* package */private function ensureNonPatternSetsReady():void {
+ if (!areNonPatternSetsReady) {
+ includePatterns = fillNonPatternSet(includeNonPatterns, includes);
+ excludePatterns = fillNonPatternSet(excludeNonPatterns, excludes);
+ areNonPatternSetsReady = true;
+ }
+ }
+
+ /**
+ * Add all patterns that are not real patterns (do not contain
+ * wildcards) to the set and returns the real patterns.
+ *
+ * @param map Map to populate.
+ * @param patterns String[] of patterns.
+ * @since Ant 1.8.0
+ */
+ private function fillNonPatternSet(map:Object, patterns:Vector.<String>):Vector.<TokenizedPattern> {
+ var al:Vector.<TokenizedPattern> = new Vector.<TokenizedPattern>(patterns.length);
+ for (var i:int = 0; i < patterns.length; i++) {
+ if (!SelectorUtils.hasWildcards(patterns[i])) {
+ var s:String = isCaseSensitive()
+ ? patterns[i] : patterns[i].toUpperCase();
+ map[s] = new TokenizedPath(s);
+ } else {
+ al.push(new TokenizedPattern(patterns[i]));
+ }
+ }
+ return al;
+ }
+
+ /**
+ * Would following the given directory cause a loop of symbolic
+ * links deeper than allowed?
+ *
+ * <p>Can only happen if the given directory has been seen at
+ * least more often than allowed during the current scan and it is
+ * a symbolic link and enough other occurences of the same name
+ * higher up are symbolic links that point to the same place.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ private function causesIllegalSymlinkLoop(dirName:String, parent:File,
+ directoryNamesFollowed:Vector.<String>):Boolean {
+ try {
+ if (directoryNamesFollowed.length >= maxLevelsOfSymlinks
+ && CollectionUtils.frequency(directoryNamesFollowed, dirName)
+ >= maxLevelsOfSymlinks
+ && new File(parent.nativePath + File.separator + dirName).isSymbolicLink) {
+
+ var files:Vector.<String> = new Vector.<String>();
+ var f:File = FILE_UTILS.resolveFile(parent, dirName);
+ f.canonicalize();
+ var target:String = f.nativePath;
+ files.push(target);
+
+ var relPath:String = "";
+ for each (var dir:String in directoryNamesFollowed) {
+ relPath += "../";
+ if (dirName == dir) {
+ f = FILE_UTILS.resolveFile(parent, relPath + dir);
+ f.canonicalize();
+ files.push(f.nativePath);
+ if (files.length > maxLevelsOfSymlinks
+ && CollectionUtils.frequency(files, target)
+ > maxLevelsOfSymlinks) {
+ return true;
+ }
+ }
+ }
+
+ }
+ return false;
+ } catch (ex:IOException) {
+ throw new BuildException("Caught error while checking for"
+ + " symbolic links" + ex.message);
+ }
+ return false;
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileProvider.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileProvider.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileProvider.as
new file mode 100644
index 0000000..e8a4773
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileProvider.as
@@ -0,0 +1,27 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.filesetClasses
+{
+ import flash.filesystem.File;
+
+ public interface FileProvider
+ {
+ function getFile():File;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileResource.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileResource.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileResource.as
new file mode 100644
index 0000000..3d00d27
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileResource.as
@@ -0,0 +1,146 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import flash.filesystem.File;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.BuildException;
+
+ /**
+ * Ported from org.apache.tools.ant.types.Resource.java on 12/3/13.
+ * Describes a "File-like" resource (File, ZipEntry, etc.).
+ *
+ * This class is meant to be used by classes needing to record path
+ * and date/time information about a file, a zip entry or some similar
+ * resource (URL, archive in a version control repository, ...).
+ *
+ * @since Ant 1.5.2
+ * @see org.apache.tools.ant.types.resources.Touchable
+ */
+ public class FileResource extends Resource implements FileProvider
+ {
+ private static const FILE_UTILS:FileUtils = FileUtils.getFileUtils();
+
+ private var file:File;
+ private var baseDir:File;
+
+ /**
+ * Construct a new FileResource using the specified basedir and relative name.
+ * @param b the basedir as File.
+ * @param name the relative filename.
+ */
+ public function FileResource(b:File, name:String) {
+ super(name);
+ this.baseDir = b;
+ this.file = FILE_UTILS.resolveFile(b, name);
+ }
+
+ /**
+ * Set the File for this FileResource.
+ * @param f the File to be represented.
+ */
+ public function setFile(f:File):void {
+ checkAttributesAllowed();
+ file = f;
+ if (f != null && (getBaseDir() == null || !FILE_UTILS.isLeadingPath(getBaseDir(), f))) {
+ setBaseDir(f.parent);
+ }
+ }
+
+ /**
+ * Get the file represented by this FileResource.
+ * @return the File.
+ */
+ public function getFile():File {
+ if (isReference()) {
+ return FileResource(getCheckedRef()).getFile();
+ }
+ dieOnCircularReference();
+ if (file == null) {
+ //try to resolve file set via basedir/name property setters:
+ var d:File = getBaseDir();
+ var n:String = super.getName();
+ if (n != null) {
+ setFile(FILE_UTILS.resolveFile(d, n));
+ }
+ }
+ return file;
+ }
+
+ /**
+ * Set the basedir for this FileResource.
+ * @param b the basedir as File.
+ */
+ public function setBaseDir(b:File):void {
+ checkAttributesAllowed();
+ baseDir = b;
+ }
+
+ /**
+ * Return the basedir to which the name is relative.
+ * @return the basedir as File.
+ */
+ public function getBaseDir():File {
+ if (isReference()) {
+ return FileResource(getCheckedRef()).getBaseDir();
+ }
+ dieOnCircularReference();
+ return baseDir;
+ }
+
+ /**
+ * Overrides the super version.
+ * @param r the Reference to set.
+ */
+ override public function setRefid(r:Reference):void {
+ if (file != null || baseDir != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Get the name of this FileResource. If the basedir is set,
+ * the name will be relative to that. Otherwise the basename
+ * only will be returned.
+ * @return the name of this resource.
+ */
+ override public function getName():String {
+ if (isReference()) {
+ return Resource(getCheckedRef()).getName();
+ }
+ var b:File = getBaseDir();
+ return b == null ? getNotNullFile().name
+ : FILE_UTILS.removeLeadingPath(b, getNotNullFile());
+ }
+
+ /**
+ * Get the file represented by this FileResource, ensuring it is not null.
+ * @return the not-null File.
+ * @throws BuildException if file is null.
+ */
+ protected function getNotNullFile():File {
+ if (getFile() == null) {
+ throw new BuildException("file attribute is null!");
+ }
+ dieOnCircularReference();
+ return getFile();
+ }
+
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileSelector.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileSelector.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileSelector.as
new file mode 100644
index 0000000..92c9376
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileSelector.as
@@ -0,0 +1,27 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.filesetClasses
+{
+ import flash.filesystem.File;
+
+ public interface FileSelector
+ {
+ function isSelected(base:File, name:String, file:File):Boolean;
+ }
+}
\ No newline at end of file
[10/14] git commit: [flex-utilities] [refs/heads/develop] - do token
replacement on all attributes
Posted by ah...@apache.org.
do token replacement on all attributes
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/00bf3f95
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/00bf3f95
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/00bf3f95
Branch: refs/heads/develop
Commit: 00bf3f958cd78d6cc0e80c3961abc9579fd86edb
Parents: 1f7c230
Author: Alex Harui <ah...@apache.org>
Authored: Mon Dec 9 14:00:12 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Dec 9 14:00:12 2013 -0800
----------------------------------------------------------------------
ant_on_air/src/org/apache/flex/ant/tags/Property.as | 4 ++--
.../src/org/apache/flex/ant/tags/supportClasses/TagHandler.as | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/00bf3f95/ant_on_air/src/org/apache/flex/ant/tags/Property.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Property.as b/ant_on_air/src/org/apache/flex/ant/tags/Property.as
index a5097cc..73fb2c1 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/Property.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Property.as
@@ -101,11 +101,11 @@ package org.apache.flex.ant.tags
{
if (name == "file")
{
- fileName = ant.getValue(value, context);
+ fileName = value;
}
else if (name == "value")
{
- this.value = ant.getValue(value, context);
+ this.value = value;
}
else if (name == "environment")
{
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/00bf3f95/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as
index 70c215d..3b3b1d2 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/TagHandler.as
@@ -71,7 +71,7 @@ package org.apache.flex.ant.tags.supportClasses
{
var n:int = xmlList.length();
for (var i:int = 0; i < n; i++)
- processAttribute(xmlList[i].name().toString(), xmlList[i].toString());
+ processAttribute(xmlList[i].name().toString(), ant.getValue(xmlList[i].toString(), context));
}
/**
[09/14] git commit: [flex-utilities] [refs/heads/develop] - if no
children were created, return 0
Posted by ah...@apache.org.
if no children were created, return 0
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/1f7c230b
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/1f7c230b
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/1f7c230b
Branch: refs/heads/develop
Commit: 1f7c230ba1db90edb58736e1e5c61ef3efe3d6f4
Parents: eef49ca
Author: Alex Harui <ah...@apache.org>
Authored: Mon Dec 9 13:58:59 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Dec 9 13:58:59 2013 -0800
----------------------------------------------------------------------
.../org/apache/flex/ant/tags/supportClasses/ParentTagHandler.as | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/1f7c230b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/ParentTagHandler.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/ParentTagHandler.as b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/ParentTagHandler.as
index f6c2941..81e6cc3 100644
--- a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/ParentTagHandler.as
+++ b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/ParentTagHandler.as
@@ -44,6 +44,8 @@ package org.apache.flex.ant.tags.supportClasses
public function get numChildren():int
{
+ if (!children) return 0;
+
return children.length;
}
}
[05/14] port DirectoryScanner from Ant code base and hook up FileSet
to it
Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileUtils.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileUtils.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileUtils.as
new file mode 100644
index 0000000..d0409ca
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/FileUtils.as
@@ -0,0 +1,657 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import flash.filesystem.File;
+ import flash.system.Capabilities;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.BuildException;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.IOException;
+
+ /**
+ * Ported from org.apache.tools.ant.util on 12/3/13. File copying
+ * was removed. So was tempfile, newfile, readfully and contentEquals.
+ *
+ * This class also encapsulates methods which allow Files to be
+ * referred to using abstract path names which are translated to native
+ * system file paths at runtime as well as copying files or setting
+ * their last modification time.
+ *
+ */
+ public class FileUtils {
+ private static const PRIMARY_INSTANCE:FileUtils = new FileUtils();
+
+ private static const ON_WINDOWS:Boolean = Capabilities.os.indexOf("Win") != -1;
+ private static const ON_DOS:Boolean = Capabilities.os.indexOf("Win") != -1;
+
+ /**
+ * The granularity of timestamps under Unix.
+ */
+ public static const UNIX_FILE_TIMESTAMP_GRANULARITY:int = 1000;
+
+ /**
+ * The granularity of timestamps under the NT File System.
+ * NTFS has a granularity of 100 nanoseconds, which is less
+ * than 1 millisecond, so we round this up to 1 millisecond.
+ */
+ public static const NTFS_FILE_TIMESTAMP_GRANULARITY:int = 1;
+
+ /**
+ * Method to retrieve The FileUtils, which is shared by all users of this
+ * method.
+ * @return an instance of FileUtils.
+ * @since Ant 1.6.3
+ */
+ public static function getFileUtils():FileUtils {
+ return PRIMARY_INSTANCE;
+ }
+
+ /**
+ * Empty constructor.
+ */
+ public function FileUtils() {
+ }
+
+ /**
+ * Get the URL for a file taking into account # characters.
+ *
+ * @param file the file whose URL representation is required.
+ * @return The FileURL value.
+ * @throws MalformedURLException if the URL representation cannot be
+ * formed.
+ public URL getFileURL(File file) throws MalformedURLException {
+ return new URL(file.toURI().toASCIIString());
+ }
+ */
+
+ /**
+ * Calls File.setLastModified(long time). Originally written to
+ * to dynamically bind to that call on Java1.2+.
+ *
+ * @param file the file whose modified time is to be set
+ * @param time the time to which the last modified time is to be set.
+ * if this is -1, the current time is used.
+ */
+ public function setFileLastModified(file:File, time:Number):void {
+ throw new Error("not supported in AIR");
+ }
+
+ /**
+ * Interpret the filename as a file relative to the given file
+ * unless the filename already represents an absolute filename.
+ * Differs from <code>new File(file, filename)</code> in that
+ * the resulting File's path will always be a normalized,
+ * absolute pathname. Also, if it is determined that
+ * <code>filename</code> is context-relative, <code>file</code>
+ * will be discarded and the reference will be resolved using
+ * available context/state information about the filesystem.
+ *
+ * @param file the "reference" file for relative paths. This
+ * instance must be an absolute file and must not contain
+ * "./" or "../" sequences (same for \ instead
+ * of /). If it is null, this call is equivalent to
+ * <code>new java.io.File(filename).getAbsoluteFile()</code>.
+ *
+ * @param filename a file name.
+ *
+ * @return an absolute file.
+ * @throws java.lang.NullPointerException if filename is null.
+ */
+ public function resolveFile(file:File, filename:String):File {
+ if (!isAbsolutePath(filename)) {
+ var sep:String = File.separator;
+ filename = filename.replace(/\//g, sep).replace(/\\/g, sep);
+ if (isContextRelativePath(filename)) {
+ file = null;
+ // on cygwin, our current directory can be a UNC;
+ // assume user.dir is absolute or all hell breaks loose...
+ var udir:String = File.userDirectory.nativePath;
+ if (filename.charAt(0) == sep && udir.charAt(0) == sep) {
+ filename = dissect(udir)[0] + filename.substring(1);
+ }
+ }
+ filename = new File(file.nativePath + File.separator + filename).nativePath;
+ }
+ return normalize(filename);
+ }
+
+ /**
+ * On DOS and NetWare, the evaluation of certain file
+ * specifications is context-dependent. These are filenames
+ * beginning with a single separator (relative to current root directory)
+ * and filenames with a drive specification and no intervening separator
+ * (relative to current directory of the specified root).
+ * @param filename the filename to evaluate.
+ * @return true if the filename is relative to system context.
+ * @throws java.lang.NullPointerException if filename is null.
+ * @since Ant 1.7
+ */
+ public static function isContextRelativePath(filename:String):Boolean {
+ if (!ON_DOS || filename.length == 0) {
+ return false;
+ }
+ var sep:String = File.separator;
+ filename = filename.replace(/\//g, sep).replace(/\\/g, sep);
+ var c:String = filename.charAt(0);
+ var len:int = filename.length;
+ return (c == sep && (len == 1 || filename.charAt(1) != sep))
+ || (Character.isLetter(c) && len > 1
+ && filename.indexOf(':') == 1
+ && (len == 2 || filename.charAt(2) != sep));
+ }
+
+
+ /**
+ * Verifies that the specified filename represents an absolute path.
+ * Differs from new java.io.File("filename").isAbsolute() in that a path
+ * beginning with a double file separator--signifying a Windows UNC--must
+ * at minimum match "\\a\b" to be considered an absolute path.
+ * @param filename the filename to be checked.
+ * @return true if the filename represents an absolute path.
+ * @throws java.lang.NullPointerException if filename is null.
+ * @since Ant 1.6.3
+ */
+ public static function isAbsolutePath(filename:String):Boolean {
+ var len:int = filename.length;
+ if (len == 0) {
+ return false;
+ }
+ var sep:String = File.separator;
+ filename = filename.replace(/\//g, sep).replace(/\\/g, sep);
+ var c:String = filename.charAt(0);
+ if (ON_DOS)
+ return (c == sep);
+
+ if (c == sep) {
+ // CheckStyle:MagicNumber OFF
+ if (!(ON_DOS && len > 4 && filename.charAt(1) == sep)) {
+ return false;
+ }
+ // CheckStyle:MagicNumber ON
+ var nextsep:int = filename.indexOf(sep, 2);
+ return nextsep > 2 && nextsep + 1 < len;
+ }
+ var colon:int = filename.indexOf(':');
+ return (Character.isLetter(c) && colon == 1
+ && filename.length > 2 && filename.charAt(2) == sep);
+ }
+
+ /**
+ * Translate a path into its native (platform specific) format.
+ * <p>
+ * This method uses PathTokenizer to separate the input path
+ * into its components. This handles DOS style paths in a relatively
+ * sensible way. The file separators are then converted to their platform
+ * specific versions.
+ *
+ * @param toProcess The path to be translated.
+ * May be <code>null</code>.
+ *
+ * @return the native version of the specified path or
+ * an empty string if the path is <code>null</code> or empty.
+ *
+ * @since ant 1.7
+ * @see PathTokenizer
+ */
+ public static function translatePath(toProcess:String):String {
+ if (toProcess == null || toProcess.length == 0) {
+ return "";
+ }
+ var path:String = "";
+ var tokenizer:PathTokenizer = new PathTokenizer(toProcess);
+ while (tokenizer.hasMoreTokens()) {
+ var pathComponent:String = tokenizer.nextToken();
+ pathComponent = pathComponent.replace(/\//g, File.separator);
+ pathComponent = pathComponent.replace(/\\/g, File.separator);
+ if (path.length != 0) {
+ path += File.separator;
+ }
+ path += pathComponent;
+ }
+ return path;
+ }
+
+ /**
+ * "Normalize" the given absolute path.
+ *
+ * <p>This includes:
+ * <ul>
+ * <li>Uppercase the drive letter if there is one.</li>
+ * <li>Remove redundant slashes after the drive spec.</li>
+ * <li>Resolve all ./, .\, ../ and ..\ sequences.</li>
+ * <li>DOS style paths that start with a drive letter will have
+ * \ as the separator.</li>
+ * </ul>
+ * Unlike {@link File#getCanonicalPath()} this method
+ * specifically does not resolve symbolic links.
+ *
+ * @param path the path to be normalized.
+ * @return the normalized version of the path.
+ *
+ * @throws java.lang.NullPointerException if path is null.
+ */
+ public function normalize(path:String):File {
+ var s:Array = new Array();
+ var dissect:Vector.<String> = dissect(path);
+ s.push(dissect[0]);
+
+ var tok:StringTokenizer = new StringTokenizer(dissect[1], File.separator);
+ while (tok.hasMoreTokens()) {
+ var thisToken:String = tok.nextToken();
+ if ("." == thisToken) {
+ continue;
+ }
+ if (".." == thisToken) {
+ if (s.size() < 2) {
+ // Cannot resolve it, so skip it.
+ return new File(path);
+ }
+ s.pop();
+ } else { // plain component
+ s.push(thisToken);
+ }
+ }
+ var sb:String = "";
+ var size:int = s.size();
+ for (var i:int = 0; i < size; i++) {
+ if (i > 1) {
+ // not before the filesystem root and not after it, since root
+ // already contains one
+ sb += File.separator;
+ }
+ sb += s.elementAt(i);
+ }
+ return new File(sb);
+ }
+
+ /**
+ * Dissect the specified absolute path.
+ * @param path the path to dissect.
+ * @return String[] {root, remaining path}.
+ * @throws java.lang.NullPointerException if path is null.
+ * @since Ant 1.7
+ */
+ public function dissect(path:String):Vector.<String> {
+ var sep:String = File.separator;
+ path = path.replace(/\//g, sep).replace(/\\/g, sep);
+
+ // make sure we are dealing with an absolute path
+ if (!isAbsolutePath(path)) {
+ throw new BuildException(path + " is not an absolute path");
+ }
+ var root:String = null;
+ var colon:int = path.indexOf(':');
+ if (colon > 0 && ON_DOS) {
+
+ var next:int = colon + 1;
+ root = path.substring(0, next);
+ var ca:Vector.<String> = Vector.<String>(path.split());
+ root += sep;
+ //remove the initial separator; the root has it.
+ next = (ca[next] == sep) ? next + 1 : next;
+
+ var sbPath:String = "";
+ // Eliminate consecutive slashes after the drive spec:
+ for (var i:int = next; i < ca.length; i++) {
+ if (ca[i] != sep || ca[i - 1] != sep) {
+ sbPath += ca[i];
+ }
+ }
+ path = sbPath;
+ } else if (path.length > 1 && path.charAt(1) == sep) {
+ // UNC drive
+ var nextsep:int = path.indexOf(sep, 2);
+ nextsep = path.indexOf(sep, nextsep + 1);
+ root = (nextsep > 2) ? path.substring(0, nextsep + 1) : path;
+ path = path.substring(root.length);
+ } else {
+ root = File.separator;
+ path = path.substring(1);
+ }
+ return Vector.<String>([root, path]);
+ }
+
+
+ /**
+ * This was originally an emulation of {@link File#getParentFile} for JDK 1.1, but it is now
+ * implemented using that method (Ant 1.6.3 onwards).
+ *
+ * @param f the file whose parent is required.
+ * @return the given file's parent, or null if the file does not have a parent.
+ * @since 1.10
+ * @deprecated since 1.7. Just use {@link File#getParentFile} directly.
+ */
+ public function getParentFile(f:File):File {
+ return (f == null) ? null : f.parent;
+ }
+
+ /**
+ * Checks whether a given file is a symbolic link.
+ *
+ * <p>It doesn't really test for symbolic links but whether the
+ * canonical and absolute paths of the file are identical--this
+ * may lead to false positives on some platforms.</p>
+ *
+ * @param parent the parent directory of the file to test
+ * @param name the name of the file to test.
+ *
+ * @return true if the file is a symbolic link.
+ * @throws IOException on error.
+ * @since Ant 1.5
+ * @deprecated use SymbolicLinkUtils instead
+ */
+ public function isSymbolicLink(parent:File, name:String):Boolean
+ {
+ if (parent == null) {
+ return new File(name).isSymbolicLink;
+ }
+ return new File(parent.nativePath + File.separator + name).isSymbolicLink;
+ }
+
+ /**
+ * Removes a leading path from a second path.
+ *
+ * @param leading The leading path, must not be null, must be absolute.
+ * @param path The path to remove from, must not be null, must be absolute.
+ *
+ * @return path's normalized absolute if it doesn't start with
+ * leading; path's path with leading's path removed otherwise.
+ *
+ * @since Ant 1.5
+ */
+ public function removeLeadingPath(leading:File, path:File):String {
+ var l:String = normalize(leading.nativePath).nativePath;
+ var p:String = normalize(path.nativePath).nativePath;
+ if (l == p) {
+ return "";
+ }
+ // ensure that l ends with a /
+ // so we never think /foo was a parent directory of /foobar
+ if (l.charAt(l.length - 1) != File.separator) {
+ l += File.separator;
+ }
+ return (p.indexOf(l) == 0) ? p.substring(l.length) : p;
+ }
+
+ /**
+ * Learn whether one path "leads" another.
+ * @param leading The leading path, must not be null, must be absolute.
+ * @param path The path to remove from, must not be null, must be absolute.
+ * @return true if path starts with leading; false otherwise.
+ * @since Ant 1.7
+ */
+ public function isLeadingPath(leading:File, path:File):Boolean {
+ var l:String = normalize(leading.nativePath).nativePath;
+ var p:String = normalize(path.nativePath).nativePath;
+ if (l == p) {
+ return true;
+ }
+ // ensure that l ends with a /
+ // so we never think /foo was a parent directory of /foobar
+ if (l.charAt(l.length - 1) != File.separator) {
+ l += File.separator;
+ }
+ return p.indexOf(l) == 0;
+ }
+
+ /**
+ * Compares two filenames.
+ *
+ * <p>Unlike java.io.File#equals this method will try to compare
+ * the absolute paths and "normalize" the filenames
+ * before comparing them.</p>
+ *
+ * @param f1 the file whose name is to be compared.
+ * @param f2 the other file whose name is to be compared.
+ *
+ * @return true if the file are for the same file.
+ *
+ * @since Ant 1.5.3
+ */
+ public function fileNameEquals(f1:File, f2:File):Boolean {
+ return normalize(f1.nativePath).nativePath ==
+ normalize(f2.nativePath).nativePath;
+ }
+
+ /**
+ * Are the two File instances pointing to the same object on the
+ * file system?
+ * @since Ant 1.8.2
+ */
+ public function areSame(f1:File, f2:File):Boolean {
+ if (f1 == null && f2 == null) {
+ return true;
+ }
+ if (f1 == null || f2 == null) {
+ return false;
+ }
+ var f1Normalized:File = normalize(f1.nativePath);
+ var f2Normalized:File = normalize(f2.nativePath);
+ if (f1Normalized.nativePath == f2Normalized.nativePath)
+ return true;
+ f1Normalized.canonicalize();
+ f2Normalized.canonicalize();
+ return f1Normalized.nativePath == f2Normalized.nativePath;
+ }
+
+ /**
+ * Renames a file, even if that involves crossing file system boundaries.
+ *
+ * <p>This will remove <code>to</code> (if it exists), ensure that
+ * <code>to</code>'s parent directory exists and move
+ * <code>from</code>, which involves deleting <code>from</code> as
+ * well.</p>
+ *
+ * @param from the file to move.
+ * @param to the new file name.
+ *
+ * @throws IOException if anything bad happens during this
+ * process. Note that <code>to</code> may have been deleted
+ * already when this happens.
+ *
+ * @since Ant 1.6
+ */
+ public function rename(from:File, to:File):void {
+ // identical logic lives in Move.renameFile():
+ from.canonicalize()
+ from = normalize(from.nativePath);
+ to = normalize(to.nativePath);
+ if (!from.exists) {
+ Ant.ant.output("Cannot rename nonexistent file " + from);
+ return;
+ }
+ if (from.nativePath == to.nativePath) {
+ Ant.ant.output("Rename of " + from + " to " + to + " is a no-op.");
+ return;
+ }
+ if (to.exists)
+ to.deleteFile();
+ if (to.exists && !(areSame(from, to))) {
+ throw new IOException("Failed to delete " + to + " while trying to rename " + from);
+ }
+ var parent:File = to.parent;
+ if (parent != null && !parent.exists && !parent.createDirectory()) {
+ throw new IOException("Failed to create directory " + parent
+ + " while trying to rename " + from);
+ }
+ if (!from.moveTo(to)) {
+ from.copyTo(to);
+ from.deleteFile();
+ if (from.exists) {
+ throw new IOException("Failed to delete " + from + " while trying to rename it.");
+ }
+ }
+ }
+
+ /**
+ * Get the granularity of file timestamps. The choice is made based on OS, which is
+ * incorrect--it should really be by filesystem. We do not have an easy way to probe for file
+ * systems, however, so this heuristic gives us a decent default.
+ *
+ * @return the difference, in milliseconds, which two file timestamps must have in order for the
+ * two files to be considered to have different timestamps.
+ */
+ public function getFileTimestampGranularity():Number {
+ if (ON_WINDOWS) {
+ return NTFS_FILE_TIMESTAMP_GRANULARITY;
+ }
+ return UNIX_FILE_TIMESTAMP_GRANULARITY;
+ }
+
+
+ /**
+ * Returns true if the source is older than the dest.
+ * If the dest file does not exist, then the test returns false; it is
+ * implicitly not up do date.
+ * @param source source file (should be the older).
+ * @param dest dest file (should be the newer).
+ * @param granularity an offset added to the source time.
+ * @return true if the source is older than the dest after accounting
+ * for granularity.
+ * @since Ant 1.6.3
+ */
+ public function isUpToDate(source:File, dest:File, granularity:Object = null):Boolean {
+ if (granularity == null)
+ granularity = getFileTimestampGranularity();
+ //do a check for the destination file existing
+ if (!dest.exists) {
+ //if it does not, then the file is not up to date.
+ return false;
+ }
+ var sourceTime:Date = source.modificationDate;
+ var destTime:Date = dest.modificationDate;
+ return isUpToDateDate(sourceTime.time, destTime.time, granularity as Number);
+ }
+
+ /**
+ * Compare two timestamps for being up to date using
+ * the specified granularity.
+ *
+ * @param sourceTime timestamp of source file.
+ * @param destTime timestamp of dest file.
+ * @param granularity os/filesys granularity.
+ * @return true if the dest file is considered up to date.
+ */
+ public function isUpToDateDate(sourceTime:Number, destTime:Number, granularity:Number = NaN):Boolean {
+ if (isNaN(granularity))
+ granularity = getFileTimestampGranularity();
+ return destTime != -1 && destTime >= sourceTime + granularity;
+ }
+
+
+ /**
+ * Calculates the relative path between two files.
+ * <p>
+ * Implementation note:<br/> This function may throw an IOException if an I/O error occurs
+ * because its use of the canonical pathname may require filesystem queries.
+ * </p>
+ *
+ * @param fromFile the <code>File</code> to calculate the path from
+ * @param toFile the <code>File</code> to calculate the path to
+ * @return the relative path between the files
+ * @throws Exception for undocumented reasons
+ * @see File#getCanonicalPath()
+ *
+ * @since Ant 1.7
+ */
+ public static function getRelativePath(fromFile:File, toFile:File):String {
+ fromFile.canonicalize();
+ toFile.canonicalize();
+ var fromPath:String = fromFile.nativePath;
+ var toPath:String = toFile.nativePath;
+
+ // build the path stack info to compare
+ var fromPathStack:Vector.<String> = getPathStack(fromPath);
+ var toPathStack:Vector.<String> = getPathStack(toPath);
+
+ if (0 < toPathStack.length && 0 < fromPathStack.length) {
+ if (!fromPathStack[0] == toPathStack[0]) {
+ // not the same device (would be "" on Linux/Unix)
+
+ return getPath(toPathStack);
+ }
+ } else {
+ // no comparison possible
+ return getPath(toPathStack);
+ }
+
+ var minLength:int = Math.min(fromPathStack.length, toPathStack.length);
+ var same:int = 1; // Used outside the for loop
+
+ // get index of parts which are equal
+ for (;
+ same < minLength && fromPathStack[same] == toPathStack[same];
+ same++) {
+ // Do nothing
+ }
+
+ var relativePathStack:Vector.<String> = new Vector.<String>();
+
+ // if "from" part is longer, fill it up with ".."
+ // to reach path which is equal to both paths
+ for (var i:int = same; i < fromPathStack.length; i++) {
+ relativePathStack.push("..");
+ }
+
+ // fill it up path with parts which were not equal
+ for (i = same; i < toPathStack.length; i++) {
+ relativePathStack.push(toPathStack[i]);
+ }
+
+ return getPath(relativePathStack);
+ }
+
+ /**
+ * Gets all names of the path as an array of <code>String</code>s.
+ *
+ * @param path to get names from
+ * @return <code>String</code>s, never <code>null</code>
+ *
+ * @since Ant 1.7
+ */
+ public static function getPathStack(path:String):Vector.<String> {
+ var normalizedPath:String = path.replace(new RegExp(File.separator, "g"), '/');
+
+ return Vector.<String>(normalizedPath.split("/"));
+ }
+
+ /**
+ * Gets path from a <code>List</code> of <code>String</code>s.
+ *
+ * @param pathStack <code>List</code> of <code>String</code>s to be concated as a path.
+ * @param separatorChar <code>char</code> to be used as separator between names in path
+ * @return <code>String</code>, never <code>null</code>
+ *
+ * @since Ant 1.7
+ */
+ public static function getPath(pathStack:Vector.<String>, separatorChar:String = "/"):String {
+ var buffer:String = ""
+
+ if (pathStack.length) {
+ buffer += pathStack.shift();
+ }
+ while (pathStack.length) {
+ buffer += separatorChar;
+ buffer += pathStack.shift();
+ }
+ return buffer;
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/PathTokenizer.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/PathTokenizer.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/PathTokenizer.as
new file mode 100644
index 0000000..3e04911
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/PathTokenizer.as
@@ -0,0 +1,118 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import flash.system.Capabilities;
+
+ import mx.utils.StringUtil;
+
+ /**
+ * Ported from org.apache.tools.ant.PathTokenizer.java on 12/3/13.
+ * A Path tokenizer takes a path and returns the components that make up
+ * that path.
+ *
+ * The path can use path separators of either ':' or ';' and file separators
+ * of either '/' or '\'.
+ *
+ */
+ public class PathTokenizer {
+ /**
+ * A tokenizer to break the string up based on the ':' or ';' separators.
+ */
+ private var tokenizer:StringTokenizer;
+
+ /**
+ * A String which stores any path components which have been read ahead
+ * due to DOS filesystem compensation.
+ */
+ private var lookahead:String = null;
+
+ /**
+ * Flag to indicate whether or not we are running on a platform with a
+ * DOS style filesystem
+ */
+ private var dosStyleFilesystem:Boolean;
+
+ /**
+ * Constructs a path tokenizer for the specified path.
+ *
+ * @param path The path to tokenize. Must not be <code>null</code>.
+ */
+ public function PathTokenizer(path:String) {
+ // on Windows and Unix, we can ignore delimiters and still have
+ // enough information to tokenize correctly.
+ tokenizer = new StringTokenizer(path, ":;", false);
+ dosStyleFilesystem = Capabilities.os.indexOf("Win") != -1;
+ }
+
+ /**
+ * Tests if there are more path elements available from this tokenizer's
+ * path. If this method returns <code>true</code>, then a subsequent call
+ * to nextToken will successfully return a token.
+ *
+ * @return <code>true</code> if and only if there is at least one token
+ * in the string after the current position; <code>false</code> otherwise.
+ */
+ public function hasMoreTokens():Boolean {
+ if (lookahead != null) {
+ return true;
+ }
+
+ return tokenizer.hasMoreTokens();
+ }
+
+ /**
+ * Returns the next path element from this tokenizer.
+ *
+ * @return the next path element from this tokenizer.
+ *
+ * @exception NoSuchElementException if there are no more elements in this
+ * tokenizer's path.
+ */
+ public function nextToken():String {
+ var token:String = null;
+ if (lookahead != null) {
+ token = lookahead;
+ lookahead = null;
+ } else {
+ token = StringUtil.trim(tokenizer.nextToken());
+ }
+
+ if (token.length == 1 && Character.isLetter(token.charAt(0))
+ && dosStyleFilesystem
+ && tokenizer.hasMoreTokens()) {
+ // we are on a dos style system so this path could be a drive
+ // spec. We look at the next token
+ var nextToken:String = StringUtil.trim(tokenizer.nextToken());
+ if (nextToken.indexOf("\\") == 0 || nextToken.indexOf("/") == 0) {
+ // we know we are on a DOS style platform and the next path
+ // starts with a slash or backslash, so we know this is a
+ // drive spec
+ token += ":" + nextToken;
+ } else {
+ // store the token just read for next time
+ lookahead = nextToken;
+ }
+ }
+ return token;
+ }
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Reference.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Reference.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Reference.as
new file mode 100644
index 0000000..1e9ce09
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Reference.as
@@ -0,0 +1,106 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import org.apache.flex.ant.tags.Project;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.BuildException;
+
+ /**
+ * Ported from org.apache.tools.ant.types.Reference.java on 12/3/13.
+ * Class to hold a reference to another object in the project.
+ *
+ */
+ public class Reference {
+
+ private var refid:String;
+ private var project:Project;
+
+ /**
+ * Create a reference to a named ID in a particular project.
+ * @param p the project this reference is associated with
+ * @param id the name of this reference
+ * @since Ant 1.6.3
+ */
+ public function Reference(p:Project, id:String) {
+ setRefId(id);
+ setProject(p);
+ }
+
+ /**
+ * Set the reference id. Should not normally be necessary;
+ * use {@link Reference#Reference(Project, String)}.
+ * @param id the reference id to use
+ */
+ public function setRefId(id:String):void {
+ refid = id;
+ }
+
+ /**
+ * Get the reference id of this reference.
+ * @return the reference id
+ */
+ public function getRefId():String {
+ return refid;
+ }
+
+ /**
+ * Set the associated project. Should not normally be necessary;
+ * use {@link Reference#Reference(Project,String)}.
+ * @param p the project to use
+ * @since Ant 1.6.3
+ */
+ public function setProject(p:Project):void {
+ this.project = p;
+ }
+
+ /**
+ * Get the associated project, if any; may be null.
+ * @return the associated project
+ * @since Ant 1.6.3
+ */
+ public function getProject():Project {
+ return project;
+ }
+
+ /**
+ * Resolve the reference, using the associated project if
+ * it set, otherwise use the passed in project.
+ * @param fallback the fallback project to use if the project attribute of
+ * reference is not set.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference cannot be dereferenced.
+ */
+ public function getReferencedObject(fallback:Project = null):Object {
+ if (refid == null) {
+ throw new BuildException("No reference specified");
+ }
+ if (fallback == null)
+ {
+ if (project == null) {
+ throw new BuildException("No project set on reference to " + refid);
+ }
+ }
+
+ var o:Object = project == null ? fallback.getReference(refid) : project.getReference(refid);
+ if (o == null) {
+ throw new BuildException("Reference " + refid + " not found.");
+ }
+ return o;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Resource.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Resource.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Resource.as
new file mode 100644
index 0000000..0ea7b85
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/Resource.as
@@ -0,0 +1,349 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import flash.filesystem.FileStream;
+ import org.apache.flex.ant.tags.filesetClasses.exceptions.UnsupportedOperationException;
+
+ /**
+ * Ported from org.apache.tools.ant.types.Resource.java on 12/3/13.
+ * Describes a "File-like" resource (File, ZipEntry, etc.).
+ *
+ * This class is meant to be used by classes needing to record path
+ * and date/time information about a file, a zip entry or some similar
+ * resource (URL, archive in a version control repository, ...).
+ *
+ * @since Ant 1.5.2
+ * @see org.apache.tools.ant.types.resources.Touchable
+ */
+ public class Resource extends DataType
+ {
+
+ /** Constant unknown size */
+ public static const UNKNOWN_SIZE:int = -1;
+
+ /** Constant unknown datetime for getLastModified */
+ public static const UNKNOWN_DATETIME:int = 0;
+
+ private var name:String;
+ private var exists:Boolean = true;
+ private var lastmodified:Number;
+ private var directory:Boolean;
+ private var _size:int;
+ private var nameSet:Boolean;
+ private var existsSet:Boolean;
+ private var lastmodifiedSet:Boolean;
+ private var directorySet:Boolean;
+ private var sizeSet:Boolean;
+
+
+ /**
+ * Sets the name, lastmodified flag, exists flag, directory flag, and size.
+ *
+ * @param name relative path of the resource. Expects
+ * "/" to be used as the directory separator.
+ * @param exists if true the resource exists
+ * @param lastmodified the last modification time of the resource
+ * @param directory if true, this resource is a directory
+ * @param size the size of this resource.
+ */
+ public function Resource(name:String, exists:Boolean = false, lastmodified:Number = NaN,
+ directory:Boolean = false, size:int = UNKNOWN_SIZE) {
+ this.name = name;
+ setName(name);
+ setExists(exists);
+ setLastModified(lastmodified);
+ setDirectory(directory);
+ setSize(size);
+ }
+
+ /**
+ * Name attribute will contain the path of a file relative to the
+ * root directory of its fileset or the recorded path of a zip
+ * entry.
+ *
+ * <p>example for a file with fullpath /var/opt/adm/resource.txt
+ * in a file set with root dir /var/opt it will be
+ * adm/resource.txt.</p>
+ *
+ * <p>"/" will be used as the directory separator.</p>
+ * @return the name of this resource.
+ */
+ public function getName():String
+ {
+ return isReference() ? Resource(getCheckedRef()).getName() : name;
+ }
+
+ /**
+ * Set the name of this Resource.
+ * @param name relative path of the resource. Expects
+ * "/" to be used as the directory separator.
+ */
+ public function setName(name:String):void
+ {
+ checkAttributesAllowed();
+ this.name = name;
+ nameSet = true;
+ }
+
+ /**
+ * The exists attribute tells whether a resource exists.
+ * @return true if this resource exists.
+ */
+ public function isExists():Boolean
+ {
+ if (isReference()) {
+ return Resource(getCheckedRef()).isExists();
+ }
+ //default true:
+ return exists;
+ }
+
+ /**
+ * Set the exists attribute.
+ * @param exists if true, this resource exists.
+ */
+ public function setExists(exists:Boolean):void
+ {
+ checkAttributesAllowed();
+ this.exists = exists;
+ existsSet = true;
+ }
+
+ /**
+ * Tells the modification time in milliseconds since 01.01.1970 (the "epoch").
+ *
+ * @return the modification time, if that is meaningful
+ * (e.g. for a file resource which exists);
+ * 0 if the resource does not exist, to mirror the behavior
+ * of {@link java.io.File#lastModified};
+ * or 0 if the notion of modification time is meaningless for this class
+ * of resource (e.g. an inline string)
+ */
+ public function getLastModified():Number
+ {
+ if (isReference()) {
+ return Resource(getCheckedRef()).getLastModified();
+ }
+ if (!isExists() || !lastmodifiedSet) {
+ return UNKNOWN_DATETIME;
+ }
+ var result:Number = lastmodified;
+ return result < UNKNOWN_DATETIME ? UNKNOWN_DATETIME : result;
+ }
+
+ /**
+ * Set the last modification attribute.
+ * @param lastmodified the modification time in milliseconds since 01.01.1970.
+ */
+ public function setLastModified(lastmodified:Number):void
+ {
+ checkAttributesAllowed();
+ this.lastmodified = lastmodified;
+ lastmodifiedSet = true;
+ }
+
+ /**
+ * Tells if the resource is a directory.
+ * @return boolean flag indicating if the resource is a directory.
+ */
+ public function isDirectory():Boolean
+ {
+ if (isReference()) {
+ return Resource(getCheckedRef()).isDirectory();
+ }
+ //default false:
+ return directory;
+ }
+
+ /**
+ * Set the directory attribute.
+ * @param directory if true, this resource is a directory.
+ */
+ public function setDirectory(directory:Boolean):void
+ {
+ checkAttributesAllowed();
+ this.directory = directory;
+ directorySet = true;
+ }
+
+ /**
+ * Set the size of this Resource.
+ * @param size the size, as a long.
+ * @since Ant 1.6.3
+ */
+ public function setSize(size:int):void
+ {
+ checkAttributesAllowed();
+ _size = size > UNKNOWN_SIZE ? size : UNKNOWN_SIZE;
+ sizeSet = true;
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the size, as a long, 0 if the Resource does not exist (for
+ * compatibility with java.io.File), or UNKNOWN_SIZE if not known.
+ * @since Ant 1.6.3
+ */
+ public function getSize():int
+ {
+ if (isReference()) {
+ return Resource(getCheckedRef()).getSize();
+ }
+ return isExists()
+ ? (sizeSet ? _size : UNKNOWN_SIZE)
+ : 0;
+ }
+
+ /**
+ * Delegates to a comparison of names.
+ * @param other the object to compare to.
+ * @return a negative integer, zero, or a positive integer as this Resource
+ * is less than, equal to, or greater than the specified Resource.
+ * @since Ant 1.6
+ */
+ public function compareTo(other:Resource):int {
+ if (isReference()) {
+ return Resource(getCheckedRef()).compareTo(other);
+ }
+ return toString().localeCompare(other.toString());
+ }
+
+ /**
+ * Implement basic Resource equality.
+ * @param other the object to check against.
+ * @return true if the specified Object is equal to this Resource.
+ * @since Ant 1.7
+ */
+ public function equals(other:Object):Boolean {
+ if (isReference()) {
+ return getCheckedRef().equals(other);
+ }
+ return compareTo(Resource(other)) == 0;
+ }
+
+ /**
+ * Get an InputStream for the Resource.
+ * @return an InputStream containing this Resource's content.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if InputStreams are not
+ * supported for this Resource type.
+ * @since Ant 1.7
+ */
+ public function getInputStream():FileStream
+ {
+ if (isReference()) {
+ return Resource(getCheckedRef()).getInputStream();
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ * @since Ant 1.7
+ */
+ public function getOutputStream():FileStream
+ {
+ if (isReference()) {
+ return Resource(getCheckedRef()).getOutputStream();
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ * @since Ant 1.7
+ */
+ public function iterator():Vector.<Resource>
+ {
+ return isReference() ? Resource(getCheckedRef()).iterator()
+ : Vector.<Resource>([this]);
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return the size of this ResourceCollection.
+ * @since Ant 1.7
+ */
+ public function size():int {
+ return isReference() ? Resource(getCheckedRef()).size() : 1;
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this Resource is a FileProvider.
+ * @since Ant 1.7
+ */
+ public function isFilesystemOnly():Boolean
+ {
+ return (isReference() && Resource(getCheckedRef()).isFilesystemOnly())
+ || this is FileProvider;
+ }
+
+ /**
+ * Get the string representation of this Resource.
+ * @return this Resource formatted as a String.
+ * @since Ant 1.7
+ */
+ override public function toString():String
+ {
+ if (isReference()) {
+ return getCheckedRef().toString();
+ }
+ var n:String = getName();
+ return n == null ? "(anonymous)" : n;
+ }
+
+ /**
+ * Get a long String representation of this Resource.
+ * This typically should be the value of <code>toString()</code>
+ * prefixed by a type description.
+ * @return this Resource formatted as a long String.
+ * @since Ant 1.7
+ */
+ public function toLongString():String
+ {
+ return isReference() ? Resource(getCheckedRef()).toLongString()
+ : getDataTypeName() + " \"" + toString() + '"';
+ }
+
+ /**
+ * Overrides the base version.
+ * @param r the Reference to set.
+ */
+ override public function setRefid(r:Reference):void
+ {
+ if (nameSet
+ || existsSet
+ || lastmodifiedSet
+ || directorySet
+ || sizeSet) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/SelectorUtils.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/SelectorUtils.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/SelectorUtils.as
new file mode 100644
index 0000000..b1d3056
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/SelectorUtils.as
@@ -0,0 +1,638 @@
+/*
+* 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.ant.tags.filesetClasses
+{
+ import flash.filesystem.File;
+
+ /**
+ * Ported from org.apache.tools.ant.types.selectors.SelectorUtils.java on 12/03/13.
+ * <p>This is a utility class used by selectors and DirectoryScanner. The
+ * functionality more properly belongs just to selectors, but unfortunately
+ * DirectoryScanner exposed these as protected methods. Thus we have to
+ * support any subclasses of DirectoryScanner that may access these methods.
+ * </p>
+ * <p>This is a Singleton.</p>
+ *
+ * @since 1.5
+ */
+ public final class SelectorUtils
+ {
+
+ /**
+ * The pattern that matches an arbitrary number of directories.
+ * @since Ant 1.8.0
+ */
+ public static const DEEP_TREE_MATCH:String = "**";
+
+ private static const instance:SelectorUtils = new SelectorUtils();
+ private static const FILE_UTILS:FileUtils = FileUtils.getFileUtils();
+
+ /**
+ * Private Constructor
+ */
+ public function SelectorUtils() {
+ }
+
+ /**
+ * Retrieves the instance of the Singleton.
+ * @return singleton instance
+ */
+ public static function getInstance():SelectorUtils {
+ return instance;
+ }
+
+ /**
+ * Tests whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ public static function matchPatternStart(pattern:String, str:String,
+ isCaseSensitive:Boolean = true):Boolean
+ {
+ // When str starts with a File.separator, pattern has to start with a
+ // File.separator.
+ // When pattern starts with a File.separator, str has to start with a
+ // File.separator.
+ if (str.indexOf(File.separator) == 0
+ != pattern.indexOf(File.separator) == 0) {
+ return false;
+ }
+
+ var patDirs:Vector.<String> = tokenizePathAsArray(pattern);
+ var strDirs:Vector.<String> = tokenizePathAsArray(str);
+ return matchPatternStartVectors(patDirs, strDirs, isCaseSensitive);
+ }
+
+
+ /**
+ * Tests whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param patDirs The tokenized pattern to match against. Must not be
+ * <code>null</code>.
+ * @param strDirs The tokenized path to match. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ public static function matchPatternStartVectors(patDirs:Vector.<String>,
+ strDirs:Vector.<String>,
+ isCaseSensitive:Boolean):Boolean {
+ var patIdxStart:int = 0;
+ var patIdxEnd:int = patDirs.length - 1;
+ var strIdxStart:int = 0;
+ var strIdxEnd:int = strDirs.length - 1;
+
+ // up to first '**'
+ while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
+ var patDir:String = patDirs[patIdxStart];
+ if (patDir == DEEP_TREE_MATCH) {
+ break;
+ }
+ if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
+ return false;
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+
+ // CheckStyle:SimplifyBooleanReturnCheck OFF
+ // Check turned off as the code needs the comments for the various
+ // code paths.
+ if (strIdxStart > strIdxEnd) {
+ // String is exhausted
+ return true;
+ } else if (patIdxStart > patIdxEnd) {
+ // String not exhausted, but pattern is. Failure.
+ return false;
+ } else {
+ // pattern now holds ** while string is not exhausted
+ // this will generate false positives but we can live with that.
+ return true;
+ }
+ }
+
+ /**
+ * Tests whether or not a given path matches a given pattern.
+ *
+ * If you need to call this method multiple times with the same
+ * pattern you should rather use TokenizedPattern
+ *
+ * @see TokenizedPattern
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ public static function matchPath(pattern:String, str:String,
+ isCaseSensitive:Boolean = true):Boolean
+ {
+ var patDirs:Vector.<String> = tokenizePathAsArray(pattern);
+ return matchPathVectors(patDirs, tokenizePathAsArray(str), isCaseSensitive);
+ }
+
+ /**
+ * Core implementation of matchPath. It is isolated so that it
+ * can be called from TokenizedPattern.
+ */
+ public static function matchPathVectors(tokenizedPattern:Vector.<String>,
+ strDirs:Vector.<String>,
+ isCaseSensitive:Boolean):Boolean
+ {
+ var patIdxStart:int = 0;
+ var patIdxEnd:int = tokenizedPattern.length - 1;
+ var strIdxStart:int = 0;
+ var strIdxEnd:int = strDirs.length - 1;
+
+ // up to first '**'
+ while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
+ var patDir:String = tokenizedPattern[patIdxStart];
+ if (patDir == DEEP_TREE_MATCH) {
+ break;
+ }
+ if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
+ return false;
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+ if (strIdxStart > strIdxEnd) {
+ // String is exhausted
+ for (i = patIdxStart; i <= patIdxEnd; i++) {
+ if (tokenizedPattern[i] != DEEP_TREE_MATCH) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ if (patIdxStart > patIdxEnd) {
+ // String not exhausted, but pattern is. Failure.
+ return false;
+ }
+ }
+
+ // up to last '**'
+ while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
+ patDir = tokenizedPattern[patIdxEnd];
+ if (patDir == DEEP_TREE_MATCH) {
+ break;
+ }
+ if (!match(patDir, strDirs[strIdxEnd], isCaseSensitive)) {
+ return false;
+ }
+ patIdxEnd--;
+ strIdxEnd--;
+ }
+ if (strIdxStart > strIdxEnd) {
+ // String is exhausted
+ for (i = patIdxStart; i <= patIdxEnd; i++) {
+ if (!tokenizedPattern[i] == DEEP_TREE_MATCH) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
+ var patIdxTmp:int = -1;
+ for (i = patIdxStart + 1; i <= patIdxEnd; i++) {
+ if (tokenizedPattern[i] == DEEP_TREE_MATCH) {
+ patIdxTmp = i;
+ break;
+ }
+ }
+ if (patIdxTmp == patIdxStart + 1) {
+ // '**/**' situation, so skip one
+ patIdxStart++;
+ continue;
+ }
+ // Find the pattern between padIdxStart & padIdxTmp in str between
+ // strIdxStart & strIdxEnd
+ var patLength:int = (patIdxTmp - patIdxStart - 1);
+ var strLength:int = (strIdxEnd - strIdxStart + 1);
+ var foundIdx:int = -1;
+ strLoop:
+ for (i = 0; i <= strLength - patLength; i++) {
+ for (var j:int = 0; j < patLength; j++) {
+ var subPat:String = tokenizedPattern[patIdxStart + j + 1];
+ var subStr:String = strDirs[strIdxStart + i + j];
+ if (!match(subPat, subStr, isCaseSensitive)) {
+ continue strLoop;
+ }
+ }
+
+ foundIdx = strIdxStart + i;
+ break;
+ }
+
+ if (foundIdx == -1) {
+ return false;
+ }
+
+ patIdxStart = patIdxTmp;
+ strIdxStart = foundIdx + patLength;
+ }
+
+ for (var i:int = patIdxStart; i <= patIdxEnd; i++) {
+ if (!tokenizedPattern[i] == DEEP_TREE_MATCH) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Tests whether or not a string matches against a pattern.
+ * The pattern may contain two special characters:<br>
+ * '*' means zero or more characters<br>
+ * '?' means one and only one character
+ *
+ * @param pattern The pattern to match against.
+ * Must not be <code>null</code>.
+ * @param str The string which must be matched against the pattern.
+ * Must not be <code>null</code>.
+ * @param caseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ *
+ * @return <code>true</code> if the string matches against the pattern,
+ * or <code>false</code> otherwise.
+ */
+ public static function match(pattern:String, str:String,
+ caseSensitive:Boolean = true):Boolean
+ {
+ var patArr:Vector.<String> = Vector.<String>(pattern.split());
+ var strArr:Vector.<String> = Vector.<String>(str.split());
+ var patIdxStart:int = 0;
+ var patIdxEnd:int = patArr.length - 1;
+ var strIdxStart:int = 0;
+ var strIdxEnd:int = strArr.length - 1;
+ var ch:String;
+
+ var containsStar:Boolean = false;
+ for (var i:int = 0; i < patArr.length; i++) {
+ if (patArr[i] == '*') {
+ containsStar = true;
+ break;
+ }
+ }
+
+ if (!containsStar) {
+ // No '*'s, so we make a shortcut
+ if (patIdxEnd != strIdxEnd) {
+ return false; // Pattern and string do not have the same size
+ }
+ for (i = 0; i <= patIdxEnd; i++) {
+ ch = patArr[i];
+ if (ch != '?') {
+ if (different(caseSensitive, ch, strArr[i])) {
+ return false; // Character mismatch
+ }
+ }
+ }
+ return true; // String matches against pattern
+ }
+
+ if (patIdxEnd == 0) {
+ return true; // Pattern contains only '*', which matches anything
+ }
+
+ // Process characters before first star
+ while (true) {
+ ch = patArr[patIdxStart];
+ if (ch == '*' || strIdxStart > strIdxEnd) {
+ break;
+ }
+ if (ch != '?') {
+ if (different(caseSensitive, ch, strArr[strIdxStart])) {
+ return false; // Character mismatch
+ }
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+ if (strIdxStart > strIdxEnd) {
+ // All characters in the string are used. Check if only '*'s are
+ // left in the pattern. If so, we succeeded. Otherwise failure.
+ return allStars(patArr, patIdxStart, patIdxEnd);
+ }
+
+ // Process characters after last star
+ while (true) {
+ ch = patArr[patIdxEnd];
+ if (ch == '*' || strIdxStart > strIdxEnd) {
+ break;
+ }
+ if (ch != '?') {
+ if (different(caseSensitive, ch, strArr[strIdxEnd])) {
+ return false; // Character mismatch
+ }
+ }
+ patIdxEnd--;
+ strIdxEnd--;
+ }
+ if (strIdxStart > strIdxEnd) {
+ // All characters in the string are used. Check if only '*'s are
+ // left in the pattern. If so, we succeeded. Otherwise failure.
+ return allStars(patArr, patIdxStart, patIdxEnd);
+ }
+
+ // process pattern between stars. padIdxStart and patIdxEnd point
+ // always to a '*'.
+ while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
+ var patIdxTmp:int = -1;
+ for (i = patIdxStart + 1; i <= patIdxEnd; i++) {
+ if (patArr[i] == '*') {
+ patIdxTmp = i;
+ break;
+ }
+ }
+ if (patIdxTmp == patIdxStart + 1) {
+ // Two stars next to each other, skip the first one.
+ patIdxStart++;
+ continue;
+ }
+ // Find the pattern between padIdxStart & padIdxTmp in str between
+ // strIdxStart & strIdxEnd
+ var patLength:int = (patIdxTmp - patIdxStart - 1);
+ var strLength:int = (strIdxEnd - strIdxStart + 1);
+ var foundIdx:int = -1;
+ strLoop:
+ for (i = 0; i <= strLength - patLength; i++) {
+ for (var j:int = 0; j < patLength; j++) {
+ ch = patArr[patIdxStart + j + 1];
+ if (ch != '?') {
+ if (different(caseSensitive, ch,
+ strArr[strIdxStart + i + j])) {
+ continue strLoop;
+ }
+ }
+ }
+
+ foundIdx = strIdxStart + i;
+ break;
+ }
+
+ if (foundIdx == -1) {
+ return false;
+ }
+
+ patIdxStart = patIdxTmp;
+ strIdxStart = foundIdx + patLength;
+ }
+
+ // All characters in the string are used. Check if only '*'s are left
+ // in the pattern. If so, we succeeded. Otherwise failure.
+ return allStars(patArr, patIdxStart, patIdxEnd);
+ }
+
+ private static function allStars(chars:Vector.<String>, start:int, end:int):Boolean
+ {
+ for (var i:int = start; i <= end; ++i) {
+ if (chars[i] != '*') {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static function different(
+ caseSensitive:Boolean, ch:String, other:String):Boolean
+ {
+ return caseSensitive
+ ? ch != other
+ : ch.toUpperCase() != other.toUpperCase();
+ }
+
+ /**
+ * Breaks a path up into a Vector of path elements, tokenizing on
+ *
+ * @param path Path to tokenize. Must not be <code>null</code>.
+ * @param separator the separator against which to tokenize.
+ *
+ * @return a Vector of path elements from the tokenized path
+ * @since Ant 1.6
+ */
+ public static function tokenizePath(path:String,
+ separator:String = null):Vector.<String>
+ {
+ if (separator == null)
+ separator = File.separator;
+
+ var ret:Vector.<String> = new Vector.<String>();
+ if (FileUtils.isAbsolutePath(path)) {
+ var s:Vector.<String> = FILE_UTILS.dissect(path);
+ ret.push(s[0]);
+ path = s[1];
+ }
+ var st:StringTokenizer = new StringTokenizer(path, separator);
+ while (st.hasMoreTokens()) {
+ ret.push(st.nextToken());
+ }
+ return ret;
+ }
+
+ /**
+ * Same as {@link #tokenizePath tokenizePath} but hopefully faster.
+ */
+ /*package*/public static function tokenizePathAsArray(path:String):Vector.<String>
+ {
+ var root:String = null;
+ if (FileUtils.isAbsolutePath(path)) {
+ var s:Vector.<String> = FILE_UTILS.dissect(path);
+ root = s[0];
+ path = s[1];
+ }
+ var sep:String = File.separator;
+ var start:int = 0;
+ var len:int = path.length;
+ var count:int = 0;
+ for (var pos:int = 0; pos < len; pos++) {
+ if (path.charAt(pos) == sep) {
+ if (pos != start) {
+ count++;
+ }
+ start = pos + 1;
+ }
+ }
+ if (len != start) {
+ count++;
+ }
+ var l:Vector.<String> = Vector.<String>(new Array(count + ((root == null) ? 0 : 1)));
+
+ if (root != null) {
+ l[0] = root;
+ count = 1;
+ } else {
+ count = 0;
+ }
+ start = 0;
+ for (pos = 0; pos < len; pos++) {
+ if (path.charAt(pos) == sep) {
+ if (pos != start) {
+ var tok:String = path.substring(start, pos);
+ l[count++] = tok;
+ }
+ start = pos + 1;
+ }
+ }
+ if (len != start) {
+ tok = path.substring(start);
+ l[count/*++*/] = tok;
+ }
+ return l;
+ }
+
+ /**
+ * Returns dependency information on these two files. If src has been
+ * modified later than target, it returns true. If target doesn't exist,
+ * it likewise returns true. Otherwise, target is newer than src and
+ * is not out of date, thus the method returns false. It also returns
+ * false if the src file doesn't even exist, since how could the
+ * target then be out of date.
+ *
+ * @param src the original file
+ * @param target the file being compared against
+ * @param granularity the amount in seconds of slack we will give in
+ * determining out of dateness
+ * @return whether the target is out of date
+ */
+ private static function isOutOfDateFile(src:File, target:File, granularity:int):Boolean {
+ if (!src.exists) {
+ return false;
+ }
+ if (!target.exists) {
+ return true;
+ }
+ if ((src.modificationDate.time - granularity) > target.modificationDate.time) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns dependency information on these two resources. If src has been
+ * modified later than target, it returns true. If target doesn't exist,
+ * it likewise returns true. Otherwise, target is newer than src and
+ * is not out of date, thus the method returns false. It also returns
+ * false if the src file doesn't even exist, since how could the
+ * target then be out of date.
+ *
+ * @param src the original resource
+ * @param target the resource being compared against
+ * @param granularity the int amount in seconds of slack we will give in
+ * determining out of dateness
+ * @return whether the target is out of date
+ */
+ public static function isOutOfDate(src:Object, target:Object,
+ granularity:int):Boolean {
+ if (src is File)
+ return isOutOfDateFile(src as File, target as File, granularity);
+ return isOutOfDateResource(src as Resource, target as Resource, granularity);
+ }
+
+ /**
+ * Returns dependency information on these two resources. If src has been
+ * modified later than target, it returns true. If target doesn't exist,
+ * it likewise returns true. Otherwise, target is newer than src and
+ * is not out of date, thus the method returns false. It also returns
+ * false if the src file doesn't even exist, since how could the
+ * target then be out of date.
+ *
+ * @param src the original resource
+ * @param target the resource being compared against
+ * @param granularity the long amount in seconds of slack we will give in
+ * determining out of dateness
+ * @return whether the target is out of date
+ */
+ private static function isOutOfDateResource(src:Resource, target:Resource,
+ granularity:int):Boolean {
+ var sourceLastModified:Number = src.getLastModified();
+ var targetLastModified:Number = target.getLastModified();
+ return src.isExists()
+ && (sourceLastModified == Resource.UNKNOWN_DATETIME
+ || targetLastModified == Resource.UNKNOWN_DATETIME
+ || (sourceLastModified - granularity) > targetLastModified);
+ }
+
+ /**
+ * "Flattens" a string by removing all whitespace (space, tab, linefeed,
+ * carriage return, and formfeed). This uses StringTokenizer and the
+ * default set of tokens as documented in the single argument constructor.
+ *
+ * @param input a String to remove all whitespace.
+ * @return a String that has had all whitespace removed.
+ */
+ public static function removeWhitespace(input:String):String {
+ var result:String = "";
+ if (input != null) {
+ var st:StringTokenizer = new StringTokenizer(input);
+ while (st.hasMoreTokens()) {
+ result += st.nextToken();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Tests if a string contains stars or question marks
+ * @param input a String which one wants to test for containing wildcard
+ * @return true if the string contains at least a star or a question mark
+ */
+ public static function hasWildcards(input:String):Boolean {
+ return (input.indexOf('*') != -1 || input.indexOf('?') != -1);
+ }
+
+ /**
+ * removes from a pattern all tokens to the right containing wildcards
+ * @param input the input string
+ * @return the leftmost part of the pattern without wildcards
+ */
+ public static function rtrimWildcardTokens(input:String):String {
+ return new TokenizedPattern(input).rtrimWildcardTokens().toString();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/3a58a60e/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/StringTokenizer.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/StringTokenizer.as b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/StringTokenizer.as
new file mode 100644
index 0000000..fcd97ba
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/filesetClasses/StringTokenizer.as
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.filesetClasses
+{
+ // an approximation of the Java StringTokenizer
+ public class StringTokenizer
+ {
+ public function StringTokenizer(s:String, delims:String = "\t\r\n\f", returnDelims:Boolean = false)
+ {
+ tokens = new Vector.<String>();
+ var c1:int = 0;
+ var c2:int = 0;
+ var n:int = s.length;
+ while (c1 < n)
+ {
+ var c:String = s.charAt(c2);
+ if (delims.indexOf(c) != -1)
+ {
+ tokens.push(s.substring(c1, c2 - 1));
+ c1 = c2;
+ while (c1 < n)
+ {
+ c = s.charAt(c2);
+ if (delims.indexOf(c) == -1)
+ {
+ if (returnDelims)
+ {
+ tokens.push(s.substring(c1, c2 - 1))
+ }
+ c1 = c2;
+ break;
+ }
+ }
+ }
+ c2++;
+ }
+ }
+
+ private var tokens:Vector.<String>;
+ private var index:int = 0;
+
+ public function hasMoreTokens():Boolean
+ {
+ return index < tokens.length;
+ }
+
+ public function nextToken():String
+ {
+ return tokens[index++];
+ }
+ }
+}
\ No newline at end of file
[03/14] git commit: [flex-utilities] [refs/heads/develop] - create
base class for FileSet handling tasks
Posted by ah...@apache.org.
create base class for FileSet handling tasks
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/7f8af60c
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/7f8af60c
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/7f8af60c
Branch: refs/heads/develop
Commit: 7f8af60cdd2d8b9cb2108994678571b0a221c396
Parents: 3a58a60
Author: Alex Harui <ah...@apache.org>
Authored: Sat Dec 7 21:47:41 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Sat Dec 7 21:50:43 2013 -0800
----------------------------------------------------------------------
.../tags/supportClasses/FileSetTaskHandler.as | 65 ++++++++++++++++++++
1 file changed, 65 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/7f8af60c/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
new file mode 100644
index 0000000..c399e52
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/supportClasses/FileSetTaskHandler.as
@@ -0,0 +1,65 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags.supportClasses
+{
+ import org.apache.flex.ant.tags.FileSet;
+
+ /**
+ * The base class for ITagHandlers that do work with filesets
+ */
+ public class FileSetTaskHandler extends TaskHandler
+ {
+ public function FileSetTaskHandler()
+ {
+ }
+
+ /**
+ * Do the work.
+ * TaskHandlers lazily create their children so
+ * super.execute() should be called before
+ * doing any real work.
+ */
+ override public function execute():Boolean
+ {
+ ant.processChildren(this.xml, context, this);
+ var n:int = numChildren;
+ for (var i:int = 0; i < n; i++)
+ {
+ var fs:FileSet = getChildAt(i) as FileSet;
+ if (fs)
+ {
+ var list:Vector.<String> = fs.value as Vector.<String>;
+ if (list)
+ {
+ for each (var fileName:String in list)
+ {
+ actOnFile(fs.dir, fileName);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ protected function actOnFile(dir:String, fileName:String):void
+ {
+
+ }
+ }
+}
\ No newline at end of file
[02/14] git commit: [flex-utilities] [refs/heads/develop] - place
holder for Copy task
Posted by ah...@apache.org.
place holder for Copy task
Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/c2f4d939
Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/c2f4d939
Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/c2f4d939
Branch: refs/heads/develop
Commit: c2f4d939b358435b103c1758c9ee229b5f87f92b
Parents: 7f8af60
Author: Alex Harui <ah...@apache.org>
Authored: Sat Dec 7 21:48:34 2013 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Sat Dec 7 21:50:43 2013 -0800
----------------------------------------------------------------------
ant_on_air/src/org/apache/flex/ant/tags/Copy.as | 74 ++++++++++++++++++++
1 file changed, 74 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/c2f4d939/ant_on_air/src/org/apache/flex/ant/tags/Copy.as
----------------------------------------------------------------------
diff --git a/ant_on_air/src/org/apache/flex/ant/tags/Copy.as b/ant_on_air/src/org/apache/flex/ant/tags/Copy.as
new file mode 100644
index 0000000..4bdb0cc
--- /dev/null
+++ b/ant_on_air/src/org/apache/flex/ant/tags/Copy.as
@@ -0,0 +1,74 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.ant.tags
+{
+ import mx.core.IFlexModuleFactory;
+
+ import org.apache.flex.ant.Ant;
+ import org.apache.flex.ant.tags.supportClasses.FileSetTaskHandler;
+
+ [Mixin]
+ public class Copy extends FileSetTaskHandler
+ {
+ public static function init(mf:IFlexModuleFactory):void
+ {
+ Ant.antTagProcessors["copy"] = Copy;
+ }
+
+ public function Copy()
+ {
+ super();
+ }
+
+ private var fileName:String;
+ private var toFileName:String;
+ private var toDirName:String;
+ private var overwrite:Boolean;
+
+ override protected function processAttribute(name:String, value:String):void
+ {
+ if (name == "file")
+ fileName = value;
+ else if (name == "toFile")
+ toFileName == value;
+ else if (name == "toDir")
+ toDirName = value;
+ else if (name == "overwrite")
+ overwrite = value == "true";
+ else
+ super.processAttribute(name, value);
+ }
+
+ override protected function actOnFile(dir:String, fileName:String):void
+ {
+
+ }
+
+ /**
+ * Do the work.
+ * TaskHandlers lazily create their children so
+ * super.execute() should be called before
+ * doing any real work.
+ */
+ override public function execute():Boolean
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file