summaryrefslogtreecommitdiff
path: root/buildscripts/phing/classes/phing/types
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts/phing/classes/phing/types')
-rw-r--r--buildscripts/phing/classes/phing/types/AbstractFileSet.php570
-rw-r--r--buildscripts/phing/classes/phing/types/Commandline.php467
-rw-r--r--buildscripts/phing/classes/phing/types/DataType.php182
-rw-r--r--buildscripts/phing/classes/phing/types/Description.php53
-rw-r--r--buildscripts/phing/classes/phing/types/DirSet.php49
-rw-r--r--buildscripts/phing/classes/phing/types/FileList.php223
-rw-r--r--buildscripts/phing/classes/phing/types/FileSet.php56
-rw-r--r--buildscripts/phing/classes/phing/types/FilterChain.php164
-rw-r--r--buildscripts/phing/classes/phing/types/Mapper.php207
-rw-r--r--buildscripts/phing/classes/phing/types/Parameter.php99
-rw-r--r--buildscripts/phing/classes/phing/types/Parameterizable.php32
-rw-r--r--buildscripts/phing/classes/phing/types/Path.php456
-rw-r--r--buildscripts/phing/classes/phing/types/PatternSet.php449
-rw-r--r--buildscripts/phing/classes/phing/types/PhingFilterReader.php136
-rw-r--r--buildscripts/phing/classes/phing/types/Reference.php56
-rw-r--r--buildscripts/phing/classes/phing/types/RegularExpression.php105
-rw-r--r--buildscripts/phing/classes/phing/types/TokenReader.php66
-rw-r--r--buildscripts/phing/classes/phing/types/TokenSource.php157
-rw-r--r--buildscripts/phing/classes/phing/types/defaults.properties13
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/AndSelector.php67
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/BaseExtendSelector.php62
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/BaseSelector.php84
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/BaseSelectorContainer.php270
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/ContainsRegexpSelector.php164
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/ContainsSelector.php151
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/DateSelector.php214
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/DependSelector.php151
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/DepthSelector.php158
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/ExtendFileSelector.php43
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/ExtendSelector.php127
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/FileSelector.php47
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/FilenameSelector.php157
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/MajoritySelector.php92
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/NoneSelector.php71
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/NotSelector.php59
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/OrSelector.php72
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/PresentSelector.php154
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/SelectSelector.php124
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/SelectorContainer.php141
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/SelectorScanner.php55
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/SelectorUtils.php440
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/SizeSelector.php228
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/TypeSelector.php113
43 files changed, 6784 insertions, 0 deletions
diff --git a/buildscripts/phing/classes/phing/types/AbstractFileSet.php b/buildscripts/phing/classes/phing/types/AbstractFileSet.php
new file mode 100644
index 00000000..6d640705
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/AbstractFileSet.php
@@ -0,0 +1,570 @@
+<?php
+/*
+ * $Id: AbstractFileSet.php,v 1.15 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/types/DataType.php';
+include_once 'phing/types/PatternSet.php';
+include_once 'phing/types/selectors/BaseSelector.php';
+include_once 'phing/types/selectors/SelectorContainer.php';
+include_once 'phing/types/selectors/BaseSelectorContainer.php';
+
+// Load all of the selectors (not really necessary but
+// helps reveal parse errors right away)
+
+include_once 'phing/types/selectors/AndSelector.php';
+include_once 'phing/types/selectors/ContainsSelector.php';
+include_once 'phing/types/selectors/ContainsRegexpSelector.php';
+include_once 'phing/types/selectors/DateSelector.php';
+include_once 'phing/types/selectors/DependSelector.php';
+include_once 'phing/types/selectors/DepthSelector.php';
+include_once 'phing/types/selectors/ExtendSelector.php';
+include_once 'phing/types/selectors/FilenameSelector.php';
+include_once 'phing/types/selectors/MajoritySelector.php';
+include_once 'phing/types/selectors/NoneSelector.php';
+include_once 'phing/types/selectors/NotSelector.php';
+include_once 'phing/types/selectors/OrSelector.php';
+include_once 'phing/types/selectors/PresentSelector.php';
+include_once 'phing/types/selectors/SizeSelector.php';
+include_once 'phing/types/selectors/TypeSelector.php';
+
+include_once 'phing/util/DirectoryScanner.php';
+
+/**
+ * The FileSet class provides methods and properties for accessing
+ * and managing filesets. It extends ProjectComponent and thus inherits
+ * all methods and properties (not explicitly declared). See ProjectComponent
+ * for further detail.
+ *
+ * TODO:
+ * - merge this with patternsets: FileSet extends PatternSet !!!
+ * requires additional mods to the parsing algo
+ * [HL] .... not sure if that really makes so much sense. I think
+ * that perhaps they should use common utility class if there really
+ * is that much shared functionality
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.15 $ $Date: 2005/05/26 13:10:53 $
+ * @see ProjectComponent
+ * @package phing.types
+ */
+class AbstractFileSet extends DataType implements SelectorContainer {
+
+ // These vars are public for cloning purposes
+
+ /**
+ * @var boolean
+ */
+ public $useDefaultExcludes = true;
+
+ /**
+ * @var PatternSet
+ */
+ public $defaultPatterns;
+
+ public $additionalPatterns = array();
+ public $dir;
+ public $isCaseSensitive = true;
+ public $selectors = array();
+
+ function __construct($fileset = null) {
+ if ($fileset !== null && ($fileset instanceof FileSet)) {
+ $this->dir = $fileset->dir;
+ $this->defaultPatterns = $fileset->defaultPatterns;
+ $this->additionalPatterns = $fileset->additionalPatterns;
+ $this->useDefaultExcludes = $fileset->useDefaultExcludes;
+ $this->isCaseSensitive = $fileset->isCaseSensitive;
+ $this->selectors = $fileset->selectors;
+ }
+ $this->defaultPatterns = new PatternSet();
+ }
+
+
+ /**
+ * Makes this instance in effect a reference to another PatternSet
+ * instance.
+ * You must not set another attribute or nest elements inside
+ * this element if you make it a reference.
+ */
+ function setRefid(Reference $r) {
+ if ((isset($this->dir) && !is_null($this->dir)) || $this->defaultPatterns->hasPatterns()) {
+ throw $this->tooManyAttributes();
+ }
+ if (!empty($this->additionalPatterns)) {
+ throw $this->noChildrenAllowed();
+ }
+ if (!empty($this->selectors)) {
+ throw $this->noChildrenAllowed();
+ }
+ parent::setRefid($r);
+ }
+
+
+ function setDir($dir) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if ($dir instanceof PhingFile) {
+ $dir = $dir->getPath();
+ }
+ $this->dir = new PhingFile((string) $dir);
+ }
+
+
+ function getDir(Project $p) {
+ if ($this->isReference()) {
+ return $this->getRef($p)->getDir($p);
+ }
+ return $this->dir;
+ }
+
+
+ function createPatternSet() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ $num = array_push($this->additionalPatterns, new PatternSet());
+ return $this->additionalPatterns[$num-1];
+ }
+
+ /**
+ * add a name entry on the include list
+ */
+ function createInclude() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ return $this->defaultPatterns->createInclude();
+ }
+
+ /**
+ * add a name entry on the include files list
+ */
+ function createIncludesFile() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ return $this->defaultPatterns->createIncludesFile();
+ }
+
+ /**
+ * add a name entry on the exclude list
+ */
+ function createExclude() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ return $this->defaultPatterns->createExclude();
+ }
+
+ /**
+ * add a name entry on the include files list
+ */
+ function createExcludesFile() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ return;
+ }
+ return $this->defaultPatterns->createExcludesFile();
+ }
+
+ /**
+ * Sets the set of include patterns. Patterns may be separated by a comma
+ * or a space.
+ */
+ function setIncludes($includes) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->defaultPatterns->setIncludes($includes);
+ }
+
+ /**
+ * Sets the set of exclude patterns. Patterns may be separated by a comma
+ * or a space.
+ */
+ function setExcludes($excludes) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->defaultPatterns->setExcludes($excludes);
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param $incl The file to fetch the include patterns from.
+ * @throws BE
+ */
+ function setIncludesfile($incl) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->defaultPatterns->setIncludesfile($incl);
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param $excl The file to fetch the exclude patterns from.
+ * @throws BE
+ */
+ function setExcludesfile($excl) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->defaultPatterns->setExcludesfile($excl);
+ }
+
+ /**
+ * Sets whether default exclusions should be used or not.
+ *
+ * @param $useDefaultExcludes "true"|"on"|"yes" when default exclusions
+ * should be used, "false"|"off"|"no" when they
+ * shouldn't be used.
+ */
+ function setDefaultexcludes($useDefaultExcludes) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->useDefaultExcludes = $useDefaultExcludes;
+ }
+
+ /**
+ * Sets case sensitivity of the file system
+ */
+ function setCaseSensitive($isCaseSensitive) {
+ $this->isCaseSensitive = $isCaseSensitive;
+ }
+
+ /** returns a reference to the dirscanner object belonging to this fileset */
+ function getDirectoryScanner(Project $p) {
+ if ($this->isReference()) {
+ $o = $this->getRef($p);
+ return $o->getDirectoryScanner($p);
+ }
+
+ if ($this->dir === null) {
+ throw new BuildException("No directory specified for fileset.");
+ }
+ if (!$this->dir->exists()) {
+ throw new BuildException("Directory ".$this->dir->getAbsolutePath()." not found.");
+ }
+ if (!$this->dir->isDirectory()) {
+ throw new BuildException($this->dir->getAbsolutePath()." is not a directory.");
+ }
+ $ds = new DirectoryScanner();
+ $this->setupDirectoryScanner($ds, $p);
+ $ds->scan();
+ return $ds;
+ }
+
+ /** feed dirscanner with infos defined by this fileset */
+ protected function setupDirectoryScanner(DirectoryScanner $ds, Project $p) {
+ if ($ds === null) {
+ throw new Exception("DirectoryScanner cannot be null");
+ }
+ // FIXME - pass dir directly wehn dirscanner supports File
+ $ds->setBasedir($this->dir->getPath());
+
+ foreach($this->additionalPatterns as $addPattern) {
+ $this->defaultPatterns->append($addPattern, $p);
+ }
+
+ $ds->setIncludes($this->defaultPatterns->getIncludePatterns($p));
+ $ds->setExcludes($this->defaultPatterns->getExcludePatterns($p));
+
+ $p->log("FileSet: Setup file scanner in dir " . $this->dir->__toString() . " with " . $this->defaultPatterns->toString(), PROJECT_MSG_DEBUG);
+
+ if ($ds instanceof SelectorScanner) {
+ $ds->setSelectors($this->getSelectors($p));
+ }
+
+ if ($this->useDefaultExcludes) {
+ $ds->addDefaultExcludes();
+ }
+ $ds->setCaseSensitive($this->isCaseSensitive);
+ }
+
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced FileSet.
+ */
+ function getRef(Project $p) {
+ if (!$this->checked) {
+ $stk = array();
+ array_push($stk, $this);
+ $this->dieOnCircularReference($stk, $p);
+ }
+
+ $o = $this->ref->getReferencedObject($p);
+ if (!($o instanceof FileSet)) {
+ $msg = $this->ref->getRefId()." doesn't denote a fileset";
+ throw new BuildException($msg);
+ } else {
+ return $o;
+ }
+ }
+
+ // SelectorContainer methods
+
+ /**
+ * Indicates whether there are any selectors here.
+ *
+ * @return boolean Whether any selectors are in this container
+ */
+ public function hasSelectors() {
+ if ($this->isReference() && $this->getProject() !== null) {
+ return $this->getRef($this->getProject())->hasSelectors();
+ }
+ return !empty($this->selectors);
+ }
+
+ /**
+ * Indicates whether there are any patterns here.
+ *
+ * @return boolean Whether any patterns are in this container.
+ */
+ public function hasPatterns() {
+
+ if ($this->isReference() && $this->getProject() !== null) {
+ return $this->getRef($this->getProject())->hasPatterns();
+ }
+
+ if ($this->defaultPatterns->hasPatterns($this->getProject())) {
+ return true;
+ }
+
+ for($i=0,$size=count($this->additionalPatterns); $i < $size; $i++) {
+ $ps = $this->additionalPatterns[$i];
+ if ($ps->hasPatterns($this->getProject())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container
+ *
+ * @return int The number of selectors in this container
+ */
+ public function selectorCount() {
+ if ($this->isReference() && $this->getProject() !== null) {
+ try {
+ return $this->getRef($this->getProject())->selectorCount();
+ } catch (Exception $e) {
+ throw $e;
+ }
+ }
+ return count($this->selectors);
+ }
+
+ /**
+ * Returns the set of selectors as an array.
+ *
+ * @return an array of selectors in this container
+ */
+ public function getSelectors(Project $p) {
+ if ($this->isReference()) {
+ return $this->getRef($p)->getSelectors($p);
+ } else {
+ // *copy* selectors
+ $result = array();
+ for($i=0,$size=count($this->selectors); $i < $size; $i++) {
+ $result[] = clone $this->selectors[$i];
+ }
+ return $result;
+ }
+ }
+
+ /**
+ * Returns an array for accessing the set of selectors.
+ *
+ * @return array The array of selectors
+ */
+ public function selectorElements() {
+ if ($this->isReference() && $this->getProject() !== null) {
+ return $this->getRef($this->getProject())->selectorElements();
+ }
+ return $this->selectors;
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new selector to add
+ */
+ public function appendSelector(FileSelector $selector) {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ $this->selectors[] = $selector;
+ }
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * add a "Select" selector entry on the selector list
+ */
+ public function createSelector() {
+ $o = new SelectSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add an "And" selector entry on the selector list
+ */
+ public function createAnd() {
+ $o = new AndSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add an "Or" selector entry on the selector list
+ */
+ public function createOr() {
+ $o = new OrSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a "Not" selector entry on the selector list
+ */
+ public function createNot() {
+ $o = new NotSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a "None" selector entry on the selector list
+ */
+ public function createNone() {
+ $o = new NoneSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a majority selector entry on the selector list
+ */
+ public function createMajority() {
+ $o = new MajoritySelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a selector date entry on the selector list
+ */
+ public function createDate() {
+ $o = new DateSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a selector size entry on the selector list
+ */
+ public function createSize() {
+ $o = new SizeSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a selector filename entry on the selector list
+ */
+ public function createFilename() {
+ $o = new FilenameSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add an extended selector entry on the selector list
+ */
+ public function createCustom() {
+ $o = new ExtendSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a contains selector entry on the selector list
+ */
+ public function createContains() {
+ $o = new ContainsSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a contains selector entry on the selector list
+ */
+ public function createContainsRegexp() {
+ $o = new ContainsRegexpSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a present selector entry on the selector list
+ */
+ public function createPresent() {
+ $o = new PresentSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a depth selector entry on the selector list
+ */
+ public function createDepth() {
+ $o = new DepthSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a depends selector entry on the selector list
+ */
+ public function createDepend() {
+ $o = new DependSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a type selector entry on the selector list
+ */
+ public function createType() {
+ $o = new TypeSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/types/Commandline.php b/buildscripts/phing/classes/phing/types/Commandline.php
new file mode 100644
index 00000000..877179d0
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Commandline.php
@@ -0,0 +1,467 @@
+<?php
+/*
+ * $Id: Commandline.php,v 1.11 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * Commandline objects help handling command lines specifying processes to
+ * execute.
+ *
+ * The class can be used to define a command line as nested elements or as a
+ * helper to define a command line by an application.
+ * <p>
+ * <code>
+ * &lt;someelement&gt;<br>
+ * &nbsp;&nbsp;&lt;acommandline executable="/executable/to/run"&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 1" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument line="argument_1 argument_2 argument_3" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 4" /&gt;<br>
+ * &nbsp;&nbsp;&lt;/acommandline&gt;<br>
+ * &lt;/someelement&gt;<br>
+ * </code>
+ * The element <code>someelement</code> must provide a method
+ * <code>createAcommandline</code> which returns an instance of this class.
+ *
+ * @author thomas.haas@softwired-inc.com
+ * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
+ */
+class Commandline {
+
+ /**
+ * @var array CommandlineArguments[]
+ */
+ public $arguments = array(); // public so "inner" class can access
+
+ /**
+ * Full path (if not on %PATH% env var) to executable program.
+ * @var string
+ */
+ public $executable; // public so "inner" class can access
+
+ const DISCLAIMER = "The ' characters around the executable and arguments are not part of the command.";
+
+ public function __construct($to_process = null) {
+ if ($to_process !== null) {
+ $tmp = $this->translateCommandline($to_process);
+ if ($tmp) {
+ $this->setExecutable(array_shift($tmp)); // removes first el
+ foreach($tmp as $arg) { // iterate through remaining elements
+ $this->createArgument()->setValue($arg);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Creates an argument object and adds it to our list of args.
+ *
+ * <p>Each commandline object has at most one instance of the
+ * argument class.</p>
+ *
+ * @param boolean $insertAtStart if true, the argument is inserted at the
+ * beginning of the list of args, otherwise it is appended.
+ * @return CommandlineArgument
+ */
+ public function createArgument($insertAtStart = false) {
+ $argument = new CommandlineArgument($this);
+ if ($insertAtStart) {
+ array_unshift($this->arguments, $argument);
+ } else {
+ array_push($this->arguments, $argument);
+ }
+ return $argument;
+ }
+
+ /**
+ * Sets the executable to run.
+ */
+ public function setExecutable($executable) {
+ if (!$executable) {
+ return;
+ }
+ $this->executable = $executable;
+ $this->executable = strtr($this->executable, '/', DIRECTORY_SEPARATOR);
+ $this->executable = strtr($this->executable, '\\', DIRECTORY_SEPARATOR);
+ }
+
+ public function getExecutable() {
+ return $this->executable;
+ }
+
+ public function addArguments($line) {
+ foreach($line as $arg) {
+ $this->createArgument()->setValue($arg);
+ }
+ }
+
+ /**
+ * Returns the executable and all defined arguments.
+ * @return array
+ */
+ public function getCommandline() {
+ $args = $this->getArguments();
+ if ($this->executable === null) {
+ return $args;
+ }
+ return array_merge(array($this->executable), $args);
+ }
+
+
+ /**
+ * Returns all arguments defined by <code>addLine</code>,
+ * <code>addValue</code> or the argument object.
+ */
+ public function getArguments() {
+ $result = array();
+ foreach($this->arguments as $arg) {
+ $parts = $arg->getParts();
+ if ($parts !== null) {
+ foreach($parts as $part) {
+ $result[] = $part;
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function __toString() {
+ return self::toString($this->getCommandline());
+ }
+
+ /**
+ * Put quotes around the given String if necessary.
+ *
+ * <p>If the argument doesn't include spaces or quotes, return it
+ * as is. If it contains double quotes, use single quotes - else
+ * surround the argument by double quotes.</p>
+ *
+ * @exception BuildException if the argument contains both, single
+ * and double quotes.
+ */
+ public static function quoteArgument($argument) {
+ if (strpos($argument, "\"") !== false) {
+ if (strpos($argument, "'") !== false) {
+ throw new BuildException("Can't handle single and double quotes in same argument");
+ } else {
+ return escapeshellarg($argument);
+ }
+ } elseif (strpos($argument, "'") !== false || strpos($argument, " ") !== false) {
+ return escapeshellarg($argument);
+ //return '\"' . $argument . '\"';
+ } else {
+ return $argument;
+ }
+ }
+
+ /**
+ * Quotes the parts of the given array in way that makes them
+ * usable as command line arguments.
+ */
+ public static function toString($lines) {
+ // empty path return empty string
+ if (!$lines) {
+ return "";
+ }
+
+ // path containing one or more elements
+ $result = "";
+ for ($i = 0, $len=count($lines); $i < $len; $i++) {
+ if ($i > 0) {
+ $result .= ' ';
+ }
+ $result .= self::quoteArgument($lines[$i]);
+ }
+ return $result;
+ }
+
+ /**
+ *
+ * @param string $to_process
+ * @return array
+ */
+ public static function translateCommandline($to_process) {
+
+ if (!$to_process) {
+ return array();
+ }
+
+ // parse with a simple finite state machine
+
+ $normal = 0;
+ $inQuote = 1;
+ $inDoubleQuote = 2;
+
+ $state = $normal;
+ $args = array();
+ $current = "";
+ $lastTokenHasBeenQuoted = false;
+
+ $tok = strtok($to_process, "");
+ $tokens = preg_split('/(["\' ])/', $to_process, -1, PREG_SPLIT_DELIM_CAPTURE);
+ while(($nextTok = array_shift($tokens)) !== null) {
+ switch ($state) {
+ case $inQuote:
+ if ("'" == $nextTok) {
+ $lastTokenHasBeenQuoted = true;
+ $state = $normal;
+ } else {
+ $current .= $nextTok;
+ }
+ break;
+ case $inDoubleQuote:
+ if ("\"" == $nextTok) {
+ $lastTokenHasBeenQuoted = true;
+ $state = $normal;
+ } else {
+ $current .= $nextTok;
+ }
+ break;
+ default:
+ if ("'" == $nextTok) {
+ $state = $inQuote;
+ } elseif ("\"" == $nextTok) {
+ $state = $inDoubleQuote;
+ } elseif (" " == $nextTok) {
+ if ($lastTokenHasBeenQuoted || strlen($current) != 0) {
+ $args[] = $current;
+ $current = "";
+ }
+ } else {
+ $current .= $nextTok;
+ }
+ $lastTokenHasBeenQuoted = false;
+ break;
+ }
+ }
+
+ if ($lastTokenHasBeenQuoted || strlen($current) != 0) {
+ $args[] = $current;
+ }
+
+ if ($state == $inQuote || $state == $inDoubleQuote) {
+ throw new BuildException("unbalanced quotes in " . $to_process);
+ }
+
+ return $args;
+ }
+
+ /**
+ * @return int Number of components in current commandline.
+ */
+ public function size() {
+ return count($this->getCommandline());
+ }
+
+ public function __copy() {
+ $c = new Commandline();
+ $c->setExecutable($this->executable);
+ $c->addArguments($this->getArguments());
+ return $c;
+ }
+
+ /**
+ * Clear out the whole command line. */
+ public function clear() {
+ $this->executable = null;
+ $this->arguments->removeAllElements();
+ }
+
+ /**
+ * Clear out the arguments but leave the executable in place for
+ * another operation.
+ */
+ public function clearArgs() {
+ $this->arguments = array();
+ }
+
+ /**
+ * Return a marker.
+ *
+ * <p>This marker can be used to locate a position on the
+ * commandline - to insert something for example - when all
+ * parameters have been set.</p>
+ * @return CommandlineMarker
+ */
+ public function createMarker() {
+ return new CommandlineMarker($this, count($this->arguments));
+ }
+
+ /**
+ * Returns a String that describes the command and arguments
+ * suitable for verbose output before a call to
+ * <code>Runtime.exec(String[])<code>.
+ *
+ * <p>This method assumes that the first entry in the array is the
+ * executable to run.</p>
+ * @param array $args CommandlineArgument[] to use
+ * @return string
+ */
+ public function describeCommand($args = null) {
+
+ if ($args === null) {
+ $args = $this->getCommandline();
+ }
+
+ if (!$args) {
+ return "";
+ }
+
+ $buf = "Executing '";
+ $buf .= $args[0];
+ $buf .= "'";
+ if (count($args) > 0) {
+ $buf .= " with ";
+ $buf .= $this->describeArguments($args, 1);
+ } else {
+ $buf .= self::DISCLAIMER;
+ }
+ return $buf;
+ }
+
+ /**
+ * Returns a String that describes the arguments suitable for
+ * verbose output before a call to
+ * <code>Runtime.exec(String[])<code>
+ * @param $args arguments to use (default is to use current class args)
+ * @param $offset ignore entries before this index
+ * @return string
+ */
+ protected function describeArguments($args = null, $offset = 0) {
+ if ($args === null) {
+ $args = $this->getArguments();
+ }
+
+ if ($args === null || count($args) <= $offset) {
+ return "";
+ }
+
+ $buf = "argument";
+ if (count($args) > $offset) {
+ $buf .= "s";
+ }
+ $buf .= ":" . Phing::getProperty("line.separator");
+ for ($i = $offset, $alen=count($args); $i < $alen; $i++) {
+ $buf .= "'" . $args[$i] . "'" . Phing::getProperty("line.separator");
+ }
+ $buf .= self::DISCLAIMER;
+ return $buf;
+ }
+}
+
+
+/**
+ * "Inner" class used for nested xml command line definitions.
+ */
+class CommandlineArgument {
+
+ private $parts = array();
+ private $outer;
+
+ public function __construct(Commandline $outer) {
+ $this->outer = $outer;
+ }
+
+ /**
+ * Sets a single commandline argument.
+ *
+ * @param string $value a single commandline argument.
+ */
+ public function setValue($value) {
+ $this->parts = array($value);
+ }
+
+ /**
+ * Line to split into several commandline arguments.
+ *
+ * @param line line to split into several commandline arguments
+ */
+ public function setLine($line) {
+ if ($line === null) {
+ return;
+ }
+ $this->parts = $this->outer->translateCommandline($line);
+ }
+
+ /**
+ * Sets a single commandline argument and treats it like a
+ * PATH - ensures the right separator for the local platform
+ * is used.
+ *
+ * @param value a single commandline argument.
+ */
+ public function setPath($value) {
+ $this->parts = array( (string) $value );
+ }
+
+ /**
+ * Sets a single commandline argument to the absolute filename
+ * of the given file.
+ *
+ * @param value a single commandline argument.
+ */
+ public function setFile(PhingFile $value) {
+ $this->parts = array($value->getAbsolutePath());
+ }
+
+ /**
+ * Returns the parts this Argument consists of.
+ * @return array string[]
+ */
+ public function getParts() {
+ return $this->parts;
+ }
+}
+
+/**
+ * Class to keep track of the position of an Argument.
+ */
+// <p>This class is there to support the srcfile and targetfile
+// elements of &lt;execon&gt; and &lt;transform&gt; - don't know
+// whether there might be additional use cases.</p> --SB
+class CommandlineMarker {
+
+ private $position;
+ private $realPos = -1;
+ private $outer;
+
+ public function __construct(Comandline $outer, $position) {
+ $this->outer = $outer;
+ $this->position = $position;
+ }
+
+ /**
+ * Return the number of arguments that preceeded this marker.
+ *
+ * <p>The name of the executable - if set - is counted as the
+ * very first argument.</p>
+ */
+ public function getPosition() {
+ if ($this->realPos == -1) {
+ $realPos = ($this->outer->executable === null ? 0 : 1);
+ for ($i = 0; $i < $position; $i++) {
+ $arg = $this->arguments[$i];
+ $realPos += count($arg->getParts());
+ }
+ }
+ return $this->realPos;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/types/DataType.php b/buildscripts/phing/classes/phing/types/DataType.php
new file mode 100644
index 00000000..2c06b80d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/DataType.php
@@ -0,0 +1,182 @@
+<?php
+/*
+ * $Id: DataType.php,v 1.9 2005/11/02 13:55:34 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/ProjectComponent.php';
+include_once 'phing/BuildException.php';
+
+/**
+ * Base class for those classes that can appear inside the build file
+ * as stand alone data types.
+ *
+ * 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)
+ *
+ * @package phing.types
+ */
+class DataType extends ProjectComponent {
+
+ /** The descriptin the user has set. */
+ public $description = null;
+
+ /** Value to the refid attribute. Type of Reference*/
+ public $ref = null;
+
+ /**
+ * Are we sure we don't hold circular references?
+ *
+ * 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).
+ * @var boolean
+ */
+ protected $checked = true;
+
+ /**
+ * Sets a description of the current data type. It will be useful
+ * in commenting what we are doing.
+ */
+ function setDescription($desc) {
+ $this->description = (string) $desc;
+ }
+
+ /** Return the description for the current data type. */
+ function getDescription() {
+ return $this->description;
+ }
+
+ /** Has the refid attribute of this element been set? */
+ function isReference() {
+ return ($this->ref !== null);
+ }
+
+ /**
+ * Set the value of the refid attribute.
+ *
+ * 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 they must call parent::setRefid()
+ *
+ * @param Reference $r
+ * @return void
+ */
+ function setRefid(Reference $r) {
+ $this->ref = $r;
+ $this->checked = false;
+ }
+
+ /**
+ * 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).
+ *
+ * If one is included, throw a BuildException created by circularReference
+ *
+ * This implementation is appropriate only for a DataType that
+ * cannot hold other DataTypes as children.
+ *
+ * The general contract of this method is that it shouldn't do
+ * anything if checked is true and set it to true on exit.
+ */
+ function dieOnCircularReference(&$stk, Project $p) {
+ if ($this->checked || !$this->isReference()) {
+ return;
+ }
+
+ $o = $this->ref->getReferencedObject($p);
+
+ if ($o instanceof DataType) {
+
+ // TESTME - make sure that in_array() works just as well here
+ //
+ // check if reference is in stack
+ //$contains = false;
+ //for ($i=0, $size=count($stk); $i < $size; $i++) {
+ // if ($stk[$i] === $o) {
+ // $contains = true;
+ // break;
+ // }
+ //}
+
+ if (in_array($o, $stk, true)) {
+ // throw build exception
+ throw $this->circularReference();
+ } else {
+ array_push($stk, $o);
+ $o->dieOnCircularReference($stk, $p);
+ array_pop($stk);
+ }
+ }
+ $this->checked = true;
+ }
+
+ /** Performs the check for circular references and returns the referenced object. */
+ function getCheckedRef($requiredClass, $dataTypeName) {
+
+ if (!$this->checked) {
+ // should be in stack
+ $stk = array();
+ $stk[] = $this;
+ $this->dieOnCircularReference($stk, $this->getProject());
+ }
+
+ $o = $this->ref->getReferencedObject($this->getProject());
+ if (!($o instanceof $requiredClass) ) {
+ throw new BuildException($this->ref->getRefId()." doesn't denote a " . $dataTypeName);
+ } else {
+ return $o;
+ }
+ }
+
+ /**
+ * Creates an exception that indicates that refid has to be the
+ * only attribute if it is set.
+ */
+ function tooManyAttributes() {
+ 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.
+ */
+ function noChildrenAllowed() {
+ 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.
+ */
+ function circularReference() {
+ return new BuildException("This data type contains a circular reference.");
+ }
+
+ /**
+ * Template method being called when the data type has been
+ * parsed completely.
+ * @return void
+ */
+ function parsingComplete() {}
+}
+
diff --git a/buildscripts/phing/classes/phing/types/Description.php b/buildscripts/phing/classes/phing/types/Description.php
new file mode 100644
index 00000000..e69f8da4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Description.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * $Id: Description.php,v 1.4 2003/12/24 12:38:42 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Description is used to provide a project-wide description element
+ * (that is, a description that applies to a buildfile as a whole).
+ * If present, the &lt;description&gt; element is printed out before the
+ * target descriptions.
+ *
+ * Description has no attributes, only text. There can only be one
+ * project description per project. A second description element will
+ * overwrite the first.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Craeg Strong <cstrong@arielpartners.com> (Ant)
+ * @package phing.types
+ */
+class Description extends DataType {
+
+ /**
+ * Adds descriptive text to the project.
+ *
+ * @return void
+ */
+ public function addText($text) {
+ $currentDescription = $this->project->getDescription();
+ if ($currentDescription === null) {
+ $this->project->setDescription($text);
+ } else {
+ $this->project->setDescription($currentDescription . $text);
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/types/DirSet.php b/buildscripts/phing/classes/phing/types/DirSet.php
new file mode 100644
index 00000000..45bcc636
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/DirSet.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * $Id: DirSet.php,v 1.3 2003/11/19 05:48:30 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/types/AbstractFileSet.php';
+
+/**
+ * Subclass as hint for supporting tasks that the included directories
+ * instead of files should be used.
+ *
+ * @package phing.types
+ */
+class DirSet extends AbstractFileSet {
+
+ public function __construct($dirset = null) {
+ parent::__construct($dirset);
+ }
+
+ /**
+ * Return a DirSet that has the same basedir and same patternsets
+ * as this one.
+ */
+ public function __clone() {
+ if ($this->isReference()) {
+ return new DirSet($this->getRef($this->getProject()));
+ } else {
+ return new DirSet($this);
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/types/FileList.php b/buildscripts/phing/classes/phing/types/FileList.php
new file mode 100644
index 00000000..1ec1273f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/FileList.php
@@ -0,0 +1,223 @@
+<?php
+/*
+ * $Id: FileList.php,v 1.10 2005/11/01 15:26:09 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/DataType.php';
+include_once 'phing/system/io/PhingFile.php';
+
+/**
+ * FileList represents an explicitly named list of files. FileLists
+ * are useful when you want to capture a list of files regardless of
+ * whether they currently exist.
+ *
+ * <filelist
+ * id="docfiles"
+ * dir="${phing.docs.dir}"
+ * files="chapters/Installation.html,chapters/Setup.html"/>
+ *
+ * OR
+ *
+ * <filelist
+ * dir="${doc.src.dir}"
+ * listfile="${phing.docs.dir}/PhingGuide.book"/>
+ *
+ * (or a mixture of files="" and listfile="" can be used)
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.10 $
+ * @package phing.types
+ */
+class FileList extends DataType {
+
+ // public for "cloning" purposes
+
+ /** Array containing all filenames. */
+ public $filenames = array();
+
+ /** Base directory for this file list. */
+ public $dir;
+
+ /** PhingFile that contains a list of files (one per line). */
+ public $listfile;
+
+ /**
+ * Construct a new FileList.
+ * @param array $filelist;
+ */
+ function __construct($filelist = null) {
+ if ($filelist !== null) {
+ $this->dir = $filelist->dir;
+ $this->filenames = $filelist->filenames;
+ $this->listfile = $filelist->listfile;
+ }
+ }
+
+ /**
+ * Makes this instance in effect a reference to another FileList
+ * instance.
+ */
+ function setRefid(Reference $r) {
+ if ($this->dir !== null || count($this->filenames) !== 0) {
+ throw $this->tooManyAttributes();
+ }
+ parent::setRefid($r);
+ }
+
+ /**
+ * Base directory for files in list.
+ * @param PhingFile $dir
+ */
+ function setDir(PhingFile $dir) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if (!($dir instanceof PhingFile)) {
+ $dir = new PhingFile($dir);
+ }
+ $this->dir = $dir;
+ }
+
+ /**
+ * Get the basedir for files in list.
+ * @return PhingFile
+ */
+ function getDir(Project $p) {
+ if ($this->isReference()) {
+ $ref = $this->getRef($p);
+ return $ref->getDir($p);
+ }
+ return $this->dir;
+ }
+
+ /**
+ * Set the array of files in list.
+ * @param array $filenames
+ */
+ function setFiles($filenames) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if (!empty($filenames)) {
+ $tok = strtok($filenames, ", \t\n\r");
+ while ($tok !== false) {
+ $fname = trim($tok);
+ if ($fname !== "") {
+ $this->filenames[] = $tok;
+ }
+ $tok = strtok(", \t\n\r");
+ }
+ }
+ }
+
+ /**
+ * Sets a source "list" file that contains filenames to add -- one per line.
+ * @param string $file
+ */
+ function setListFile($file) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if (!($file instanceof PhingFile)) {
+ $file = new PhingFile($file);
+ }
+ $this->listfile = $file;
+ }
+
+ /**
+ * Get the source "list" file that contains file names.
+ * @return PhingFile
+ */
+ function getListFile() {
+ if ($this->isReference()) {
+ $ref = $this->getRef($p);
+ return $ref->getListFile($p);
+ }
+ return $this->listfile;
+ }
+
+ /**
+ * Returns the list of files represented by this FileList.
+ * @param Project $p
+ * @return array
+ */
+ function getFiles(Project $p) {
+
+ if ($this->isReference()) {
+ $ret = $this->getRef($p);
+ $ret = $ret->getFiles($p);
+ return $ret;
+ }
+
+ if ($this->listfile !== null) {
+ $this->readListFile($p);
+ }
+
+ return $this->filenames;
+ }
+
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced FileSet.
+ * @param Project $p
+ */
+ function getRef(Project $p) {
+ if (!$this->checked) {
+ $stk = array();
+ array_push($stk, $this);
+ $this->dieOnCircularReference($stk, $p);
+ }
+
+ $o = $this->ref->getReferencedObject($p);
+ if (!($o instanceof FileList)) {
+ throw new BuildException($this->ref->getRefId()." doesn't denote a filelist");
+ } else {
+ return $o;
+ }
+ }
+
+ /**
+ * Reads file names from a file and adds them to the files array.
+ * @param Project $p
+ */
+ private function readListFile(Project $p) {
+ $listReader = null;
+ try {
+ // Get a FileReader
+ $listReader = new BufferedReader(new FileReader($this->listfile));
+
+ $line = $listReader->readLine();
+ while ($line !== null) {
+ if (!empty($line)) {
+ $line = $p->replaceProperties($line);
+ $this->filenames[] = trim($line);
+ }
+ $line = $listReader->readLine();
+ }
+ } catch (Exception $e) {
+ if ($listReader) $listReader->close();
+ throw new BuildException("An error occured while reading from list file " . $this->listfile->__toString() . ": " . $e->getMessage());
+ }
+
+ $listReader->close();
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/FileSet.php b/buildscripts/phing/classes/phing/types/FileSet.php
new file mode 100644
index 00000000..8cfb54dc
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/FileSet.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * $Id: FileSet.php,v 1.5 2003/12/24 12:38:42 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/AbstractFileSet.php';
+
+/**
+ * Moved out of MatchingTask to make it a standalone object that could
+ * be referenced (by scripts for example).
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Arnout J. Kuiper <ajkuiper@wxs.nl> (Ant)
+ * @author Stefano Mazzocchi <stefano@apache.org> (Ant)
+ * @author Sam Ruby <rubys@us.ibm.com> (Ant)
+ * @author Jon S. Stevens <jon@clearink.com> (Ant)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @author Magesh Umasankar (Ant)
+ * @package phing.types
+ */
+class FileSet extends AbstractFileSet {
+
+ function __construct($fileset = null) {
+ parent::__construct($fileset);
+ }
+
+ /**
+ * Return a FileSet that has the same basedir and same patternsets
+ * as this one.
+ */
+ public function __clone() {
+ if ($this->isReference()) {
+ return new FileSet($this->getRef($this->getProject()));
+ } else {
+ return new FileSet($this);
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/types/FilterChain.php b/buildscripts/phing/classes/phing/types/FilterChain.php
new file mode 100644
index 00000000..4f2d702b
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/FilterChain.php
@@ -0,0 +1,164 @@
+<?php
+/*
+ * $Id: FilterChain.php,v 1.11 2005/12/08 16:03:49 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/types/DataType.php';
+include_once 'phing/filters/HeadFilter.php';
+include_once 'phing/filters/TailFilter.php';
+include_once 'phing/filters/LineContains.php';
+include_once 'phing/filters/LineContainsRegexp.php';
+include_once 'phing/filters/ExpandProperties.php';
+include_once 'phing/filters/PrefixLines.php';
+include_once 'phing/filters/ReplaceRegexp.php';
+include_once 'phing/filters/ReplaceTokens.php';
+include_once 'phing/filters/StripPhpComments.php';
+include_once 'phing/filters/StripLineBreaks.php';
+include_once 'phing/filters/StripLineComments.php';
+include_once 'phing/filters/TabToSpaces.php';
+include_once 'phing/filters/TidyFilter.php';
+include_once 'phing/filters/TranslateGettext.php';
+include_once 'phing/filters/XsltFilter.php';
+
+/*
+ * FilterChain may contain a chained set of filter readers.
+ *
+ * @author Yannick Lecaillez <yl@seasonfive.com>
+ * @version $Revision: 1.11 $
+ * @package phing.types
+ */
+class FilterChain extends DataType {
+
+ private $filterReaders = array();
+
+ function __construct(Project $project) {
+ $this->project = $project;
+ }
+
+ function getFilterReaders() {
+ return $this->filterReaders;
+ }
+
+ function addExpandProperties(ExpandProperties $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addGettext(TranslateGettext $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addHeadFilter(HeadFilter $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addTailFilter(TailFilter $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addLineContains(LineContains $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addLineContainsRegExp(LineContainsRegExp $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addPrefixLines(PrefixLines $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addReplaceTokens(ReplaceTokens $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addReplaceRegexp(ReplaceRegexp $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addStripPhpComments(StripPhpComments $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addStripLineBreaks(StripLineBreaks $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addStripLineComments(StripLineComments $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addTidyFilter(TidyFilter $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addTabToSpaces(TabToSpaces $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addXsltFilter(XsltFilter $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ function addFilterReader(PhingFilterReader $o) {
+ $o->setProject($this->project);
+ $this->filterReaders[] = $o;
+ }
+
+ /*
+ * Makes this instance in effect a reference to another FilterChain
+ * instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ *
+ * @param r the reference to which this instance is associated
+ * @throw BuildException if this instance already has been configured.
+ */
+ function setRefid(Reference $r) {
+
+ if ( count($this->filterReaders) === 0 ) {
+ throw $this->tooManyAttributes();
+ }
+
+ // change this to get the objects from the other reference
+ $o = $r->getReferencedObject($this->getProject());
+ if ( $o instanceof FilterChain ) {
+ $this->filterReaders = $o->getFilterReaders();
+ } else {
+ throw new BuildException($r->getRefId()." doesn't refer to a FilterChain");
+ }
+ parent::setRefid($r);
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/types/Mapper.php b/buildscripts/phing/classes/phing/types/Mapper.php
new file mode 100644
index 00000000..f0df6d24
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Mapper.php
@@ -0,0 +1,207 @@
+<?php
+/*
+ * $Id: Mapper.php,v 1.11 2004/03/15 17:11:16 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/types/DataType.php';
+include_once 'phing/types/Path.php';
+
+/**
+ * Filename Mapper maps source file name(s) to target file name(s).
+ *
+ * Built-in mappers can be accessed by specifying they "type" attribute:
+ * <code>
+ * <mapper type="glob" from="*.php" to="*.php.bak"/>
+ * </code>
+ * Custom mappers can be specified by providing a dot-path to a include_path-relative
+ * class:
+ * <code>
+ * <mapper classname="myapp.mappers.DevToProdMapper" from="*.php" to="*.php"/>
+ * <!-- maps all PHP files from development server to production server, for example -->
+ * </code>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.types
+ */
+class Mapper extends DataType {
+
+ protected $type;
+ protected $classname;
+ protected $from;
+ protected $to;
+ protected $classpath;
+ protected $classpathId;
+
+
+ function __construct(Project $project) {
+ $this->project = $project;
+ }
+
+ /**
+ * Set the classpath to be used when searching for component being defined
+ *
+ * @param Path $classpath An Path object containing the classpath.
+ */
+ public function setClasspath(Path $classpath) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if ($this->classpath === null) {
+ $this->classpath = $classpath;
+ } else {
+ $this->classpath->append($classpath);
+ }
+ }
+
+ /**
+ * Create the classpath to be used when searching for component being defined
+ */
+ public function createClasspath() {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if ($this->classpath === null) {
+ $this->classpath = new Path($this->project);
+ }
+ return $this->classpath->createPath();
+ }
+
+ /**
+ * Reference to a classpath to use when loading the files.
+ */
+ public function setClasspathRef(Reference $r) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->classpathId = $r->getRefId();
+ $this->createClasspath()->setRefid($r);
+ }
+
+ /** Set the type of FileNameMapper to use. */
+ function setType($type) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->type = $type;
+ }
+
+ /** Set the class name of the FileNameMapper to use. */
+ function setClassname($classname) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->classname = $classname;
+ }
+
+ /**
+ * Set the argument to FileNameMapper.setFrom
+ */
+ function setFrom($from) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->from = $from;
+ }
+
+ /**
+ * Set the argument to FileNameMapper.setTo
+ */
+ function setTo($to) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->to = $to;
+ }
+
+ /**
+ * Make this Mapper instance a reference to another Mapper.
+ *
+ * You must not set any other attribute if you make it a reference.
+ */
+ function setRefid($r) {
+ if ($this->type !== null || $this->from !== null || $this->to !== null) {
+ throw DataType::tooManyAttributes();
+ }
+ parent::setRefid($r);
+ }
+
+ /** Factory, returns inmplementation of file name mapper as new instance */
+ function getImplementation() {
+ if ($this->isReference()) {
+ $tmp = $this->getRef();
+ return $tmp->getImplementation();
+ }
+
+ if ($this->type === null && $this->classname === null) {
+ throw new BuildException("either type or classname attribute must be set for <mapper>");
+ }
+
+ if ($this->type !== null) {
+ switch($this->type) {
+ case 'identity':
+ $this->classname = 'phing.mappers.IdentityMapper';
+ break;
+ case 'flatten':
+ $this->classname = 'phing.mappers.FlattenMapper';
+ break;
+ case 'glob':
+ $this->classname = 'phing.mappers.GlobMapper';
+ break;
+ case 'regexp':
+ case 'regex':
+ $this->classname = 'phing.mappers.RegexpMapper';
+ break;
+ case 'merge':
+ $this->classname = 'phing.mappers.MergeMapper';
+ break;
+ default:
+ throw new BuildException("Mapper type {$this->type} not known");
+ break;
+ }
+ }
+
+ // get the implementing class
+ $cls = Phing::import($this->classname, $this->classpath);
+
+ $m = new $cls;
+ $m->setFrom($this->from);
+ $m->setTo($this->to);
+
+ return $m;
+ }
+
+ /** Performs the check for circular references and returns the referenced Mapper. */
+ private function getRef() {
+ if (!$this->checked) {
+ $stk = array();
+ $stk[] = $this;
+ $this->dieOnCircularReference($stk, $this->project);
+ }
+
+ $o = $this->ref->getReferencedObject($this->project);
+ if (!($o instanceof Mapper)) {
+ $msg = $this->ref->getRefId()." doesn't denote a mapper";
+ throw new BuildException($msg);
+ } else {
+ return $o;
+ }
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/types/Parameter.php b/buildscripts/phing/classes/phing/types/Parameter.php
new file mode 100644
index 00000000..6892ed7e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Parameter.php
@@ -0,0 +1,99 @@
+<?php
+/*
+ * $Id: Parameter.php,v 1.6 2005/10/05 20:23:22 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/types/DataType.php';
+
+/*
+ * A parameter is composed of a name, type and value. Nested
+ * Parameters are also possible, but the using task/type has
+ * to support them
+ *
+ * @author Manuel Holtgrewe
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @package phing.types
+*/
+class Parameter extends DataType {
+
+ /** Parameter name */
+ protected $name;
+
+ /** Paramter type */
+ protected $type;
+
+ /** Parameter value */
+ protected $value;
+
+ /** Nested parameters */
+ protected $parameters = array();
+
+ function setName($name) {
+ $this->name = (string) $name;
+ }
+
+ function setType($type) {
+ $this->type = (string) $type;
+ }
+
+ /**
+ * Sets value to dynamic register slot.
+ * @param RegisterSlot $value
+ */
+ public function setListeningValue(RegisterSlot $value) {
+ $this->value = $value;
+ }
+
+ function setValue($value) {
+ $this->value = (string) $value;
+ }
+
+ function getName() {
+ return $this->name;
+ }
+
+ function getType() {
+ return $this->type;
+ }
+
+ function getValue() {
+ if ($this->value instanceof RegisterSlot) {
+ return $this->value->getValue();
+ } else {
+ return $this->value;
+ }
+ }
+
+ /**
+ * @return Parameter
+ */
+ function createParam() {
+ $num = array_push($this->parameters, new Parameter());
+ return $this->parameters[$num-1];
+ }
+
+ /**
+ * @return array Nested parameters.
+ */
+ function getParams() {
+ return $this->parameters;
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/types/Parameterizable.php b/buildscripts/phing/classes/phing/types/Parameterizable.php
new file mode 100644
index 00000000..b24aa38b
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Parameterizable.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * $Id: Parameterizable.php,v 1.3 2003/11/19 05:48:30 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Parameterizable objects take genric key value pairs.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Magesh Umasankar (Ant)
+ * @package phing.types
+ */
+interface Parameterizable {
+ function setParameters($parameters);
+}
diff --git a/buildscripts/phing/classes/phing/types/Path.php b/buildscripts/phing/classes/phing/types/Path.php
new file mode 100644
index 00000000..196fe9c4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Path.php
@@ -0,0 +1,456 @@
+<?php
+/*
+ * $Id: Path.php,v 1.13 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/DataType.php';
+include_once 'phing/util/PathTokenizer.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ * This object represents a path as used by include_path or PATH
+ * environment variable.
+ *
+ * This class has been adopted from the Java Ant equivalent. The ability have
+ * path structures in Phing is important; however, because of how PHP classes interact
+ * the ability to specify CLASSPATHs makes less sense than Java.Rather than providing
+ * CLASSPATH for any tasks that take classes as parameters, perhaps a better
+ * solution in PHP is to have an IncludePath task, which prepends paths to PHP's include_path
+ * INI variable. This gets around the problem that simply using a path to load the initial
+ * PHP class is not enough (in most cases the loaded class may assume that it is on the global
+ * PHP include_path, and will try to load dependent classes accordingly). The other option is
+ * to provide a way for this class to add paths to the include path, if desired -- or to create
+ * an IncludePath subclass. Once added, though, when would a path be removed from the include path?
+ *
+ * <p>
+ * <code>
+ * &lt;sometask&gt;<br>
+ * &nbsp;&nbsp;&lt;somepath&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement path="/path/to/class2;/path/to/class3" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file3" /&gt;<br>
+ * &nbsp;&nbsp;&lt;/somepath&gt;<br>
+ * &lt;/sometask&gt;<br>
+ * </code>
+ * <p>
+ * The object implemention <code>sometask</code> must provide a method called
+ * <code>createSomepath</code> which returns an instance of <code>Path</code>.
+ * Nested path definitions are handled by the Path object and must be labeled
+ * <code>pathelement</code>.<p>
+ *
+ * The path element takes a parameter <code>path</code> which will be parsed
+ * and split into single elements. It will usually be used
+ * to define a path from an environment variable.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Thomas.Haas@softwired-inc.com (Ant)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @package phing.types
+ */
+class Path extends DataType {
+
+ private $elements = array();
+
+ /**
+ * Constructor for internally instantiated objects sets project.
+ * @param Project $project
+ * @param string $path (for use by IntrospectionHelper)
+ */
+ public function __construct($project = null, $path = null) {
+ if ($project !== null) {
+ $this->setProject($project);
+ }
+ if ($path !== null) {
+ $this->createPathElement()->setPath($path);
+ }
+ }
+
+ /**
+ * Adds a element definition to the path.
+ * @param $location the location of the element to add (must not be
+ * <code>null</code> nor empty.
+ * @throws BuildException
+ */
+ public function setDir(PhingFile $location) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->createPathElement()->setDir($location);
+ }
+
+ /**
+ * Parses a path definition and creates single PathElements.
+ * @param path the path definition.
+ * @throws BuildException
+ */
+ public function setPath($path) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ $this->createPathElement()->setPath($path);
+ }
+
+ /**
+ * Makes this instance in effect a reference to another Path instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @throws BuildException
+ */
+ public function setRefid(Reference $r) {
+ if (!empty($this->elements)) {
+ throw $this->tooManyAttributes();
+ }
+ $this->elements[] = $r;
+ parent::setRefid($r);
+ }
+
+ /**
+ * Creates the nested <code>&lt;pathelement&gt;</code> element.
+ * @throws BuildException
+ */
+ public function createPathElement() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ $pe = new PathElement($this);
+ $this->elements[] = $pe;
+ return $pe;
+ }
+
+ /**
+ * Adds a nested <code>&lt;fileset&gt;</code> element.
+ * @throws BuildException
+ */
+ public function addFileset(FileSet $fs) {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ $this->elements[] = $fs;
+ $this->checked = false;
+ }
+
+ /**
+ * Adds a nested <code>&lt;dirset&gt;</code> element.
+ * @throws BuildException
+ */
+ public function addDirset(DirSet $dset) {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ $this->elements[] = $dset;
+ $this->checked = false;
+ }
+
+ /**
+ * Creates a nested <code>&lt;path&gt;</code> element.
+ * @throws BuildException
+ */
+ public function createPath() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ $p = new Path($this->project);
+ $this->elements[] = $p;
+ $this->checked = false;
+ return $p;
+ }
+
+ /**
+ * Append the contents of the other Path instance to this.
+ */
+ public function append(Path $other) {
+ if ($other === null) {
+ return;
+ }
+ $l = $other->listPaths();
+ foreach($l as $path) {
+ if (!in_array($path, $this->elements, true)) {
+ $this->elements[] = $path;
+ }
+ }
+ }
+
+ /**
+ * Adds the components on the given path which exist to this
+ * Path. Components that don't exist, aren't added.
+ *
+ * @param Path $source - Source path whose components are examined for existence.
+ */
+ public function addExisting(Path $source) {
+ $list = $source->listPaths();
+ foreach($list as $el) {
+ $f = null;
+ if ($this->project !== null) {
+ $f = $this->project->resolveFile($el);
+ } else {
+ $f = new PhingFile($el);
+ }
+
+ if ($f->exists()) {
+ $this->setDir($f);
+ } else {
+ $this->log("dropping " . $f->__toString() . " from path as it doesn't exist",
+ PROJECT_MSG_VERBOSE);
+ }
+ }
+ }
+
+ /**
+ * Returns all path elements defined by this and nested path objects.
+ * @return array List of path elements.
+ */
+ public function listPaths() {
+ if (!$this->checked) {
+ // make sure we don't have a circular reference here
+ $stk = array();
+ array_push($stk, $this);
+ $this->dieOnCircularReference($stk, $this->project);
+ }
+
+ $result = array();
+ for ($i = 0, $elSize=count($this->elements); $i < $elSize; $i++) {
+ $o = $this->elements[$i];
+ if ($o instanceof Reference) {
+ $o = $o->getReferencedObject($this->project);
+ // we only support references to paths right now
+ if (!($o instanceof Path)) {
+ $msg = $r->getRefId() . " doesn't denote a path";
+ throw new BuildException($msg);
+ }
+ }
+
+ if (is_string($o)) {
+ $result[] = $o;
+ } elseif ($o instanceof PathElement) {
+ $parts = $o->getParts();
+ if ($parts === null) {
+ throw new BuildException("You must either set location or"
+ . " path on <pathelement>");
+ }
+ foreach($parts as $part) {
+ $result[] = $part;
+ }
+ } elseif ($o instanceof Path) {
+ $p = $o;
+ if ($p->getProject() === null) {
+ $p->setProject($this->getProject());
+ }
+ $parts = $p->listPaths();
+ foreach($parts as $part) {
+ $result[] = $part;
+ }
+ } elseif ($o instanceof DirSet) {
+ $dset = $o;
+ $ds = $dset->getDirectoryScanner($this->project);
+ $dirstrs = $ds->getIncludedDirectories();
+ $dir = $dset->getDir($this->project);
+ $this->addUnlessPresent($result, $dir, $s);
+
+ foreach($dirstrs as $dstr) {
+ $d = new PhingFile($dir, $dstr);
+ $result[] = $d->getAbsolutePath();
+ }
+
+ } elseif ($o instanceof FileList) {
+ $fl = $o;
+ $dirstrs = $fl->getFiles($this->project);
+ $dir = $fl->getDir($this->project);
+ foreach($dirstrs as $dstr) {
+ $d = new PhingFile($dir, $dstr);
+ $result[] = $d->getAbsolutePath();
+ }
+ }
+ }
+
+ return array_unique($result);
+ }
+
+
+ /**
+ * Returns a textual representation of the path, which can be used as
+ * CLASSPATH or PATH environment variable definition.
+ * @return string A textual representation of the path.
+ */
+ public function __toString() {
+
+ $list = $this->listPaths();
+
+ // empty path return empty string
+ if (empty($list)) {
+ return "";
+ }
+
+ return implode(PATH_SEPARATOR, $list);
+ }
+
+ /**
+ * Splits a PATH (with : or ; as separators) into its parts.
+ * @param Project $project
+ * @param string $source
+ */
+ public static function translatePath(Project $project, $source) {
+ $result = array();
+ if ($source == null) {
+ return "";
+ }
+
+ $tok = new PathTokenizer($source);
+ $element = "";
+ while ($tok->hasMoreTokens()) {
+ $pathElement = $tok->nextToken();
+ try {
+ $element .= self::resolveFile($project, $pathElement);
+ } catch (BuildException $e) {
+ $this->project->log("Dropping path element " . $pathElement
+ . " as it is not valid relative to the project",
+ PROJECT_MSG_VERBOSE);
+ }
+
+ for ($i = 0, $_i=strlen($element); $i < $_i; $i++) {
+ self::translateFileSep($element, $i);
+ }
+ $result[] = $element;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns its argument with all file separator characters
+ * replaced so that they match the local OS conventions.
+ */
+ public static function translateFile($source) {
+ if ($source == null) {
+ return "";
+ }
+
+ $result = $source;
+ for ($i = 0, $_i=strlen($source); $i < $_i; $i++) {
+ self::translateFileSep($result, $i);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Translates all occurrences of / or \ to correct separator of the
+ * current platform and returns whether it had to do any
+ * replacements.
+ */
+ protected static function translateFileSep(&$buffer, $pos) {
+ if ($buffer{$pos} == '/' || $buffer{$pos} == '\\') {
+ $buffer{$pos} = DIRECTORY_SEPARATOR;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * How many parts does this Path instance consist of.
+ * DEV NOTE: expensive call! list is generated, counted, and then
+ * discareded.
+ * @return int
+ */
+ public function size() {
+ return count($this->listPaths());
+ }
+
+ /**
+ * Return a Path that holds the same elements as this instance.
+ */
+ public function __clone() {
+ $p = new Path($this->project);
+ $p->append($this);
+ return $p;
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @throws BuildException
+ */
+ public function dieOnCircularReference(&$stk, Project $p) {
+
+ if ($this->checked) {
+ return;
+ }
+
+ // elements can contain strings, FileSets, Reference, etc.
+ foreach($this->elements as $o) {
+
+ if ($o instanceof Reference) {
+ $o = $o->getReferencedObject($p);
+ }
+
+ if ($o instanceof DataType) {
+ if (in_array($o, $stk, true)) {
+ throw $this->circularReference();
+ } else {
+ array_push($stk, $o);
+ $o->dieOnCircularReference($stk, $p);
+ array_pop($stk);
+ }
+ }
+ }
+
+ $this->checked = true;
+ }
+
+ /**
+ * Resolve a filename with Project's help - if we know one that is.
+ *
+ * <p>Assume the filename is absolute if project is null.</p>
+ */
+ private static function resolveFile(Project $project, $relativeName) {
+ if ($project !== null) {
+ $f = $project->resolveFile($relativeName);
+ return $f->getAbsolutePath();
+ }
+ return $relativeName;
+ }
+
+}
+
+
+/**
+ * Helper class, holds the nested <code>&lt;pathelement&gt;</code> values.
+ */
+class PathElement {
+
+ private $parts = array();
+ private $outer;
+
+ public function __construct(Path $outer) {
+ $this->outer = $outer;
+ }
+
+ public function setDir(PhingFile $loc) {
+ $this->parts = array(Path::translateFile($loc->getAbsolutePath()));
+ }
+
+ public function setPath($path) {
+ $this->parts = Path::translatePath($this->outer->getProject(), $path);
+ }
+
+ public function getParts() {
+ return $this->parts;
+ }
+}
+?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/types/PatternSet.php b/buildscripts/phing/classes/phing/types/PatternSet.php
new file mode 100644
index 00000000..2963ab9e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/PatternSet.php
@@ -0,0 +1,449 @@
+<?php
+/*
+ * $Id: PatternSet.php,v 1.8 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/io/FileReader.php';
+include_once 'phing/types/DataType.php';
+
+/**
+ * The patternset storage component. Carries all necessary data and methods
+ * for the patternset stuff.
+ *
+ * @author Andreas Aderhold, andi@binarycloud.com
+ * @version $Revision: 1.8 $
+ * @package phing.types
+ */
+class PatternSet extends DataType {
+
+ private $includeList = array();
+ private $excludeList = array();
+ private $includesFileList = array();
+ private $excludesFileList = array();
+
+ /**
+ * Makes this instance in effect a reference to another PatternSet
+ * instance.
+ * You must not set another attribute or nest elements inside
+ * this element if you make it a reference.
+ */
+ function setRefid(Reference $r) {
+ if (!empty($this->includeList) || !empty($this->excludeList)) {
+ throw $this->tooManyAttributes();
+ }
+ parent::setRefid($r);
+ }
+
+
+ /**
+ * Add a name entry on the include list
+ *
+ * @returns PatternSetNameEntry Reference to object
+ * @throws BuildException
+ */
+ function createInclude() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ return $this->addPatternToList($this->includeList);
+ }
+
+
+ /**
+ * Add a name entry on the include files list
+ *
+ * @returns PatternSetNameEntry Reference to object
+ * @throws BuildException
+ */
+ function createIncludesFile() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ return $this->addPatternToList($this->includesFileList);
+ }
+
+ /**
+ * Add a name entry on the exclude list
+ *
+ * @returns PatternSetNameEntry Reference to object
+ * @throws BuildException
+ */
+ function createExclude() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ return $this->addPatternToList($this->excludeList);
+ }
+
+ /**
+ * add a name entry on the exclude files list
+ *
+ * @returns PatternSetNameEntry Reference to object
+ * @throws BuildException
+ */
+
+ function createExcludesFile() {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ return;
+ }
+ return $this->addPatternToList($this->excludesFileList);
+ }
+
+
+ /**
+ * Sets the set of include patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param string the string containing the include patterns
+ * @returns void
+ * @throws BuildException
+ */
+ function setIncludes($includes) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if ($includes !== null && strlen($includes) > 0) {
+ $tok = strtok($includes, ", ");
+ while ($tok !== false) {
+ $o = $this->createInclude();
+ $o->setName($tok);
+ $tok = strtok(", ");
+ }
+ }
+ }
+
+
+ /**
+ * Sets the set of exclude patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param string the string containing the exclude patterns
+ * @returns void
+ * @throws BuildException
+ */
+
+ function setExcludes($excludes) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if ($excludes !== null && strlen($excludes) > 0) {
+ $tok = strtok($excludes, ", ");
+ while ($tok !== false) {
+ $o = $this->createExclude();
+ $o->setName($tok);
+ $tok = strtok(", ");
+ }
+ }
+ }
+
+ /**
+ * add a name entry to the given list
+ *
+ * @param array List onto which the nameentry should be added
+ * @returns PatternSetNameEntry Reference to the created PsetNameEntry instance
+ */
+ private function addPatternToList(&$list) {
+ $num = array_push($list, new PatternSetNameEntry());
+ return $list[$num-1];
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param includesFile The file to fetch the include patterns from.
+ */
+ function setIncludesFile($includesFile) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if ($includesFile instanceof File) {
+ $includesFile = $includesFile->getPath();
+ }
+ $o = $this->createIncludesFile();
+ $o->setName($includesFile);
+ }
+
+ /**
+ * Sets the name of the file containing the excludes patterns.
+ *
+ * @param excludesFile The file to fetch the exclude patterns from.
+ */
+ function setExcludesFile($excludesFile) {
+ if ($this->isReference()) {
+ throw $this->tooManyAttributes();
+ }
+ if ($excludesFile instanceof File) {
+ $excludesFile = $excludesFile->getPath();
+ }
+ $o = $this->createExcludesFile();
+ $o->setName($excludesFile);
+ }
+
+
+ /**
+ * Reads path matching patterns from a file and adds them to the
+ * includes or excludes list
+ */
+ private function readPatterns(PhingFile $patternfile, &$patternlist, Project $p) {
+ $patternReader = null;
+ try {
+ // Get a FileReader
+ $patternReader = new BufferedReader(new FileReader($patternfile));
+
+ // Create one NameEntry in the appropriate pattern list for each
+ // line in the file.
+ $line = $patternReader->readLine();
+ while ($line !== null) {
+ if (!empty($line)) {
+ $line = $p->replaceProperties($line);
+ $this->addPatternToList($patternlist)->setName($line);
+ }
+ $line = $patternReader->readLine();
+ }
+
+ } catch (IOException $ioe) {
+ $msg = "An error occured while reading from pattern file: " . $patternfile->__toString();
+ if($patternReader) $patternReader->close();
+ throw new BuildException($msg, $ioe);
+ }
+
+ $patternReader->close();
+ }
+
+
+ /** Adds the patterns of the other instance to this set. */
+ function append($other, $p) {
+ if ($this->isReference()) {
+ throw new BuildException("Cannot append to a reference");
+ }
+
+ $incl = $other->getIncludePatterns($p);
+ if ($incl !== null) {
+ foreach($incl as $incl_name) {
+ $o = $this->createInclude();
+ $o->setName($incl_name);
+ }
+ }
+
+ $excl = $other->getExcludePatterns($p);
+ if ($excl !== null) {
+ foreach($excl as $excl_name) {
+ $o = $this->createExclude();
+ $o->setName($excl_name);
+ }
+ }
+ }
+
+ /** Returns the filtered include patterns. */
+ function getIncludePatterns(Project $p) {
+ if ($this->isReference()) {
+ $o = $this->getRef($p);
+ return $o->getIncludePatterns($p);
+ } else {
+ $this->readFiles($p);
+ return $this->makeArray($this->includeList, $p);
+ }
+ }
+
+ /** Returns the filtered exclude patterns. */
+ function getExcludePatterns(Project $p) {
+ if ($this->isReference()) {
+ $o = $this->getRef($p);
+ return $o->getExcludePatterns($p);
+ } else {
+ $this->readFiles($p);
+ return $this->makeArray($this->excludeList, $p);
+ }
+ }
+
+ /** helper for FileSet. */
+ function hasPatterns() {
+ return (boolean) count($this->includesFileList) > 0 || count($this->excludesFileList) > 0
+ || count($this->includeList) > 0 || count($this->excludeList) > 0;
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced PatternSet.
+ */
+ function getRef(Project $p) {
+ if (!$this->checked) {
+ $stk = array();
+ array_push($stk, $this);
+ $this->dieOnCircularReference($stk, $p);
+ }
+ $o = $this->ref->getReferencedObject($p);
+ if (!($o instanceof PatternSet)) {
+ $msg = $this->ref->getRefId()." doesn't denote a patternset";
+ throw new BuildException($msg);
+ } else {
+ return $o;
+ }
+ }
+
+ /** Convert a array of PatternSetNameEntry elements into an array of Strings. */
+ private function makeArray(&$list, Project $p) {
+
+ if (count($list) === 0) {
+ return null;
+ }
+
+ $tmpNames = array();
+ foreach($list as $ne) {
+ $pattern = (string) $ne->evalName($p);
+ if ($pattern !== null && strlen($pattern) > 0) {
+ array_push($tmpNames, $pattern);
+ }
+ }
+ return $tmpNames;
+ }
+
+ /** Read includesfile or excludesfile if not already done so. */
+ private function readFiles(Project $p) {
+ if (!empty($this->includesFileList)) {
+ foreach($this->includesFileList as $ne) {
+ $fileName = (string) $ne->evalName($p);
+ if ($fileName !== null) {
+ $inclFile = $p->resolveFile($fileName);
+ if (!$inclFile->exists()) {
+ throw new BuildException("Includesfile ".$inclFile->getAbsolutePath()." not found.");
+ }
+ $this->readPatterns($inclFile, $this->includeList, $p);
+ }
+ }
+ $this->includesFileList = array();
+ }
+
+ if (!empty($this->excludesFileList)) {
+ foreach($this->excludesFileList as $ne) {
+ $fileName = (string) $ne->evalName($p);
+ if ($fileName !== null) {
+ $exclFile = $p->resolveFile($fileName);
+ if (!$exclFile->exists()) {
+ throw new BuildException("Excludesfile ".$exclFile->getAbsolutePath()." not found.");
+ return;
+ }
+ $this->readPatterns($exclFile, $this->excludeList, $p);
+ }
+ }
+ $this->excludesFileList = array();
+ }
+ }
+
+
+ function toString() {
+
+ // We can't compile includeList into array because, toString() does
+ // not know about project:
+ //
+ // $includes = $this->makeArray($this->includeList, $this->project);
+ // $excludes = $this->makeArray($this->excludeList, $this->project);
+
+ if (empty($this->includeList)) {
+ $includes = "empty";
+ } else {
+ $includes = "";
+ foreach($this->includeList as $ne) {
+ $includes .= $ne->toString() . ",";
+ }
+ $includes = rtrim($includes, ",");
+ }
+
+ if (empty($this->excludeList)) {
+ $excludes = "empty";
+ } else {
+ $excludes = "";
+ foreach($this->excludeList as $ne) {
+ $excludes .= $ne->toString() . ",";
+ }
+ $excludes = rtrim($excludes, ",");
+ }
+
+ return "patternSet{ includes: $includes excludes: $excludes }";
+ }
+}
+
+
+/*
+ * Note, this class here should become a nested class to
+ * PatternSet (PatternSet:NameEntry) as it is only needed
+ * internally.
+ * This is not possible with php 4.x right now so we place
+ * this class (against good style) in this file.
+ */
+
+class PatternSetNameEntry {
+
+ private $name = null;
+ private $ifCond = null;
+ private $unlessCond = null;
+
+ function setName($name) {
+ $this->name = (string) $name;
+ }
+
+
+ function setIf($cond) {
+ $this->ifCond = (string) $cond;
+ }
+
+
+ function setUnless($cond) {
+ $this->unlessCond = (string) $cond;
+ }
+
+
+ function getName() {
+ return $this->name;
+ }
+
+
+ function evalName($project) {
+ return $this->valid($project) ? $this->name : null;
+ }
+
+
+ function valid($project) {
+ if ($this->ifCond !== null && $project->getProperty($this->ifCond) === null) {
+ return false;
+ } else if ($this->unlessCond !== null && $project->getProperty($this->unlessCond) !== null) {
+ return false;
+ }
+ return true;
+ }
+
+
+ function toString() {
+ $buf = $this->name;
+ if (($this->ifCond !== null) || ($this->unlessCond !== null)) {
+ $buf .= ":";
+ $connector = "";
+
+ if ($this->ifCond !== null) {
+ $buf .= "if->{$this->ifCond}";
+ $connector = ";";
+ }
+ if ($this->unlessCond !== null) {
+ $buf .= "$connector unless->{$this->unlessCond}";
+ }
+ }
+ return $buf;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/types/PhingFilterReader.php b/buildscripts/phing/classes/phing/types/PhingFilterReader.php
new file mode 100644
index 00000000..eb45f894
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/PhingFilterReader.php
@@ -0,0 +1,136 @@
+<?php
+/*
+ * $Id: PhingFilterReader.php,v 1.9 2005/10/05 20:23:22 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/types/DataType.php';
+include_once 'phing/types/Parameter.php';
+
+/*
+ * A PhingFilterReader is a wrapper class that encloses the className
+ * and configuration of a Configurable FilterReader.
+ *
+ * @author Yannick Lecaillez <yl@seasonfive.com>
+ * @version $Revision: 1.9 $
+ * @see FilterReader
+ * @package phing.types
+*/
+class PhingFilterReader extends DataType {
+
+ private $className;
+ private $parameters = array();
+ private $classPath;
+
+ function setClassName($className) {
+ $this->className = $className;
+ }
+
+ function getClassName() {
+ return $this->className;
+ }
+
+ /**
+ * Set the classpath to load the FilterReader through (attribute).
+ * @param Path $classpath
+ */
+ function setClasspath(Path $classpath) {
+ if ( $this->isReference() ) {
+ throw $this->tooManyAttributes();
+ }
+ if ( $this->classPath === null ) {
+ $this->classPath = $classpath;
+ } else {
+ $this->classPath->append($classpath);
+ }
+ }
+
+ /*
+ * Set the classpath to load the FilterReader through (nested element).
+ */
+ function createClasspath() {
+ if ( $this->isReference() ) {
+ throw $this->noChildrenAllowed();
+ }
+ if ( $this->classPath === null ) {
+ $this->classPath = new Path($this->project);
+ }
+ return $this->classPath->createPath();
+ }
+
+ function getClasspath() {
+ return $this->classPath;
+ }
+
+ function setClasspathRef(Reference $r) {
+ if ( $this->isReference() ) {
+ throw $this->tooManyAttributes();
+ }
+ $o = $this->createClasspath();
+ $o->setRefid($r);
+ }
+
+ function addParam(Parameter $param) {
+ $this->parameters[] = $param;
+ }
+
+ function createParam() {
+ $num = array_push($this->parameters, new Parameter());
+ return $this->parameters[$num-1];
+ }
+
+ function getParams() {
+ // We return a COPY
+ $ret = array();
+ for($i=0,$size=count($this->parameters); $i < $size; $i++) {
+ $ret[] = clone $this->parameters[$i];
+ }
+ return $ret;
+ }
+
+ /*
+ * Makes this instance in effect a reference to another PhingFilterReader
+ * instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ *
+ * @param Reference $r the reference to which this instance is associated
+ * @exception BuildException if this instance already has been configured.
+ */
+ function setRefid(Reference $r) {
+ if ( (count($this->parameters) !== 0) || ($this->className !== null) ) {
+ throw $this->tooManyAttributes();
+ }
+ $o = $r->getReferencedObject($this->getProject());
+ if ( $o instanceof PhingFilterReader ) {
+ $this->setClassName($o->getClassName());
+ $this->setClasspath($o->getClassPath());
+ foreach($o->getParams() as $p) {
+ $this->addParam($p);
+ }
+ } else {
+ $msg = $r->getRefId()." doesn\'t refer to a PhingFilterReader";
+ throw new BuildException($msg);
+ }
+
+ parent::setRefid($r);
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/types/Reference.php b/buildscripts/phing/classes/phing/types/Reference.php
new file mode 100644
index 00000000..c226917d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Reference.php
@@ -0,0 +1,56 @@
+<?php
+/*
+ * $Id: Reference.php,v 1.4 2003/12/24 12:38:42 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/** Class to hold a reference to another object in the project.
+ * @package phing.types
+ */
+class Reference {
+
+ protected $refid;
+
+ function __construct($id = null) {
+ if ($id !== null) {
+ $this->setRefId($id);
+ }
+ }
+
+ function setRefId($id) {
+ $this->refid = (string) $id;
+ }
+
+ function getRefId() {
+ return $this->refid;
+ }
+
+ /** returns reference to object in references container of project */
+ function getReferencedObject($project) {
+ if ($this->refid === null) {
+ throw new BuildException("No reference specified");
+ }
+ $refs = $project->getReferences();
+ $o = @$refs[$this->refid];
+ if (!is_object($o)) {
+ throw new BuildException("Reference {$this->refid} not found.");
+ }
+ return $o;
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/types/RegularExpression.php b/buildscripts/phing/classes/phing/types/RegularExpression.php
new file mode 100644
index 00000000..67850c23
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/RegularExpression.php
@@ -0,0 +1,105 @@
+<?php
+/*
+ * $Id: RegularExpression.php,v 1.6 2003/12/24 12:38:42 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/types/DataType.php';
+include_once 'phing/Project.php';
+include_once 'phing/util/regexp/Regexp.php';
+
+/*
+ * A regular expression datatype. Keeps an instance of the
+ * compiled expression for speed purposes. This compiled
+ * expression is lazily evaluated (it is compiled the first
+ * time it is needed). The syntax is the dependent on which
+ * regular expression type you are using.
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @version $Revision: 1.6 $ $Date: 2003/12/24 12:38:42 $
+ * @access public
+ * @see phing.util.regex.RegexMatcher
+ * @package phing.types
+*/
+class RegularExpression extends DataType {
+
+ private $regexp = null;
+ private $ignoreCase = false;
+
+ function __construct() {
+ $this->regexp = new Regexp();
+ }
+
+ function setPattern($pattern) {
+ $this->regexp->setPattern($pattern);
+ }
+
+ function setReplace($replace) {
+ $this->regexp->setReplace($replace);
+ }
+
+ function getPattern($p) {
+ if ( $this->isReference() ) {
+ $ref = $this->getRef($p);
+ return $ref->getPattern($p);
+ }
+ return $this->regexp->getPattern();
+ }
+
+ function getReplace($p) {
+ if ( $this->isReference() ) {
+ $ref = $this->getRef($p);
+ return $ref->getReplace($p);
+ }
+
+ return $this->regexp->getReplace();
+ }
+
+ function setIgnoreCase($bit) {
+ $this->regexp->setIgnoreCase($bit);
+ }
+
+ function getIgnoreCase() {
+ return $this->regexp->getIgnoreCase();
+ }
+
+ function getRegexp(Project $p) {
+ if ( $this->isReference() ) {
+ $ref = $this->getRef($p);
+ return $ref->getRegexp($p);
+ }
+ return $this->regexp;
+ }
+
+ function getRef(Project $p) {
+ if ( !$this->checked ) {
+ $stk = array();
+ array_push($stk, $this);
+ $this->dieOnCircularReference($stk, $p);
+ }
+
+ $o = $this->ref->getReferencedObject($p);
+ if ( !($o instanceof RegularExpression) ) {
+ throw new BuildException($this->ref->getRefId()." doesn't denote a RegularExpression");
+ } else {
+ return $o;
+ }
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/types/TokenReader.php b/buildscripts/phing/classes/phing/types/TokenReader.php
new file mode 100644
index 00000000..acd7d616
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/TokenReader.php
@@ -0,0 +1,66 @@
+<?php
+/*
+ * $Id: TokenReader.php,v 1.5 2003/12/24 12:38:42 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+// include_once 'phing/system/io/Reader.php'; // really this is unrelated to Reader
+include_once 'phing/system/io/IOException.php';
+include_once 'phing/filters/ReplaceTokens.php'; // For class Token
+
+/**
+ * Abstract class for TokenReaders.
+ *
+ * @author Manuel Holtgewe
+ * @version $Revision: 1.5 $
+ * @package phing.filters.util
+ */
+abstract class TokenReader {
+
+ /**
+ * Reference to the Project the TokenReader is used in.
+ * @var Project
+ */
+ protected $project;
+
+ /**
+ * Constructor
+ * @param object Reference to the project the TokenReader is used in.
+ */
+ function __construct(Project $project) {
+ $this->project = $project;
+ }
+
+ /**
+ * Utility function for logging
+ */
+ function log($level, $msg) {
+ $this->project->log($level, $msg);
+ }
+
+ /**
+ * Reads the next token from the Reader
+ *
+ * @throws IOException - On error
+ * @return string
+ */
+ abstract public function readToken();
+
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/types/TokenSource.php b/buildscripts/phing/classes/phing/types/TokenSource.php
new file mode 100644
index 00000000..c073ece0
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/TokenSource.php
@@ -0,0 +1,157 @@
+<?php
+/*
+ * $Id: TokenSource.php,v 1.7 2004/03/18 20:44:26 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/types/DataType.php';
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * A parameter is composed of a name, type and value.
+ *
+ * Example of usage:
+ *
+ * <replacetokens>
+ * <tokensource classname="phing.filters.util.IniFileTokenReader">
+ * <!-- all params for the TokenReader here -->
+ * <param name="file" value="tokens.ini" />
+ * </tokensource>
+ * </replacetokens>
+ *
+ * or:
+ *
+ * <filterreader classname="phing.filters.ReplaceTokens">
+ * <param type="tokensource>
+ * <param name="classname" value="phing.filters.util.IniFileTokenReader" />
+ * <param name="file" value="tokens.ini" />
+ * </param>
+ * </filterreader>
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @package phing.types
+ */
+class TokenSource extends DataType {
+
+ /**
+ * String to hold the path to the TokenReader
+ * @var string
+ */
+ protected $classname = null;
+
+ /**
+ * Array holding parameters for the wrapped TokenReader.
+ * @var array
+ */
+ protected $parameters = array();
+
+ /**
+ * Reference to the TokenReader used by this TokenSource
+ * @var TokenReader
+ */
+ protected $reader;
+
+ /**
+ * Array with key/value pairs of tokens
+ */
+ protected $tokens = array();
+
+ /**
+ * This method is called to load the sources from the reader
+ * into the buffer of the source.
+ */
+ function load() {
+ // Create new Reader
+ if ($this->classname === null) {
+ throw new BuildException("No Classname given to TokenSource.");
+ }
+
+ $classname = Phing::import($this->classname);
+ $this->reader = new $classname($this->project);
+
+ // Configure Reader
+ $this->configureTokenReader($this->reader);
+
+ // Load Tokens
+ try {
+ while ($token = $this->reader->readToken()) {
+ $this->tokens[] = $token;
+ }
+ } catch (BuildException $e) {
+ $this->log("Error reading TokenSource: " . $e->getMessage(), PROJECT_MSG_WARN);
+ } catch (IOException $e) {
+ $this->log("Error reading TokenSource: " . $e->getMessage(), PROJECT_MSG_WARN);
+ }
+ }
+
+ /**
+ * This function uses the wrapper to read the tokens and then
+ * returns them.
+ *
+ * @access public
+ */
+ function getTokens() {
+ if ($this->tokens === null)
+ $this->Load();
+
+ return $this->tokens;
+ }
+
+ /**
+ * Configures a TokenReader with the parameters passed to the
+ * TokenSource.
+ * @param TokenReader $reader
+ */
+ private function configureTokenReader(TokenReader $reader) {
+ $count = count($this->parameters);
+ for ($i = 0; $i < $count; $i++) {
+ $method_name = "Set" . $this->parameters[$i]->getName();
+ $value = $this->parameters[$i]->getValue();
+ $reader->$method_name($value);
+ }
+ }
+
+ /**
+ * Set the classname (dot-path) to use for handling token replacement.
+ * @param string $c
+ */
+ function setClassname($c) {
+ $this->classname = $c;
+ }
+
+ /**
+ * Returns the qualified classname (dot-path) to use for handling token replacement.
+ * @return string
+ */
+ function getClassname() {
+ return $this->classname;
+ }
+
+ /**
+ * Create nested <param> tag.
+ * Uses standard name/value Parameter class.
+ * @return Parameter
+ */
+ function createParam() {
+ $num = array_push($this->parameters, new Parameter());
+ return $this->parameters[$num-1];
+ }
+}
+
+
+?>
diff --git a/buildscripts/phing/classes/phing/types/defaults.properties b/buildscripts/phing/classes/phing/types/defaults.properties
new file mode 100644
index 00000000..a2d86350
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/defaults.properties
@@ -0,0 +1,13 @@
+# phing default types
+commandline=phing.types.Commandline
+fileset=phing.types.FileSet
+dirset=phing.types.DirSet
+filelist=phing.types.FileList
+patternset=phing.types.PatternSet
+mapper=phing.types.Mapper
+filterchain=phing.types.FilterChain
+filterreader=phing.types.PhingFilterReader
+regexp=phing.types.RegularExpression
+param=phing.types.Parameter
+path=phing.types.Path
+selector=phing.types.selectors.SelectSelector \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/types/selectors/AndSelector.php b/buildscripts/phing/classes/phing/types/selectors/AndSelector.php
new file mode 100644
index 00000000..3801091f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/AndSelector.php
@@ -0,0 +1,67 @@
+<?php
+/*
+ * $Id: AndSelector.php,v 1.9 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseSelectorContainer.php';
+
+/**
+ * This selector has a collection of other selectors, all of which have to
+ * select a file in order for this selector to select it.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> (Ant)
+ * @package phing.types.selectors
+ */
+class AndSelector extends BaseSelectorContainer {
+
+ public function toString() {
+ $buf = "";
+ if ($this->hasSelectors()) {
+ $buf .= "{andselect: ";
+ $buf .= parent::toString();
+ $buf .= "}";
+ }
+ return $buf;
+ }
+
+ /**
+ * Returns true (the file is selected) only if all other selectors
+ * agree that the file should be selected.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename the name of the file to check
+ * @param file a PhingFile object for the filename that the selector
+ * can use
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+ $this->validate();
+ $selectors = $this->selectorElements();
+ for($i=0,$size=count($selectors); $i < $size; $i++) {
+ $result = $selectors[$i]->isSelected($basedir, $filename, $file);
+ if (!$result) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/BaseExtendSelector.php b/buildscripts/phing/classes/phing/types/selectors/BaseExtendSelector.php
new file mode 100644
index 00000000..5acc54dd
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/BaseExtendSelector.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * $Id: BaseExtendSelector.php,v 1.5 2004/02/16 05:28:40 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/ExtendFileSelector.php';
+require_once 'phing/types/selectors/BaseSelector.php';
+include_once 'phing/types/Parameter.php';
+
+/**
+ * Convenience base class for all selectors accessed through ExtendSelector.
+ * It provides support for gathering the parameters together as well as for
+ * assigning an error message and throwing a build exception if an error is
+ * detected.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Bruce Atherton, bruce@callenish.com (Ant)
+ * @package phing.types.selectors
+ */
+abstract class BaseExtendSelector extends BaseSelector implements ExtendFileSelector {
+
+ /** The passed in parameter array. */
+ protected $parameters = null;
+
+ /**
+ * Set all the Parameters for this custom selector, collected by
+ * the ExtendSelector class.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public function setParameters($parameters) {
+ $this->parameters = $parameters;
+ }
+
+ /**
+ * Allows access to the parameters gathered and set within the
+ * &lt;custom&gt; tag.
+ *
+ * @return the set of parameters defined for this selector
+ */
+ protected function getParameters() {
+ return $this->parameters;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/BaseSelector.php b/buildscripts/phing/classes/phing/types/selectors/BaseSelector.php
new file mode 100644
index 00000000..e229fc24
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/BaseSelector.php
@@ -0,0 +1,84 @@
+<?php
+/*
+ * $Id: BaseSelector.php,v 1.4 2004/02/16 04:56:24 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/FileSelector.php';
+
+/**
+ * A convenience base class that you can subclass Selectors from. It
+ * provides some helpful common behaviour. Note that there is no need
+ * for Selectors to inherit from this class, it is only necessary that
+ * they implement FileSelector.
+ *
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
+ * @package phing.types.selectors
+ */
+abstract class BaseSelector extends DataType implements FileSelector {
+
+ private $errmsg = null;
+
+ /**
+ * Allows all selectors to indicate a setup error. Note that only
+ * the first error message is recorded.
+ *
+ * @param msg The error message any BuildException should throw.
+ */
+ public function setError($msg) {
+ if ($this->errmsg === null) {
+ $this->errmsg = $msg;
+ }
+ }
+
+ /**
+ * Returns any error messages that have been set.
+ *
+ * @return the error condition
+ */
+ public function getError() {
+ return $this->errmsg;
+ }
+
+
+ /**
+ * <p>Subclasses can override this method to provide checking of their
+ * state. So long as they call validate() from isSelected(), this will
+ * be called automatically (unless they override validate()).</p>
+ * <p>Implementations should check for incorrect settings and call
+ * setError() as necessary.</p>
+ */
+ public function verifySettings() {
+ }
+
+ /**
+ * Subclasses can use this to throw the requisite exception
+ * in isSelected() in the case of an error condition.
+ */
+ public function validate() {
+ if ($this->getError() === null) {
+ $this->verifySettings();
+ }
+ if ($this->getError() !== null) {
+ throw new BuildException($this->errmsg);
+ }
+ }
+
+}
+
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/BaseSelectorContainer.php b/buildscripts/phing/classes/phing/types/selectors/BaseSelectorContainer.php
new file mode 100644
index 00000000..19b84b00
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/BaseSelectorContainer.php
@@ -0,0 +1,270 @@
+<?php
+
+/*
+ * $Id: BaseSelectorContainer.php,v 1.9 2004/02/16 04:56:24 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/SelectorContainer.php';
+require_once 'phing/types/selectors/BaseSelector.php';
+
+/**
+ * This is the base class for selectors that can contain other selectors.
+ *
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> (Ant)
+ * @package phing.types.selectors
+ */
+abstract class BaseSelectorContainer extends BaseSelector implements SelectorContainer {
+
+ private $selectorsList = array();
+
+ /**
+ * Indicates whether there are any selectors here.
+ */
+ public function hasSelectors() {
+ return !(empty($this->selectorsList));
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container
+ */
+ public function selectorCount() {
+ return count($this->selectorsList);
+ }
+
+ /**
+ * Returns a copy of the selectors as an array.
+ */
+ public function getSelectors(Project $p) {
+ $result = array();
+ for($i=0,$size=count($this->selectorsList); $i < $size; $i++) {
+ $result[] = clone $this->selectorsList[$i];
+ }
+ return $result;
+ }
+
+ /**
+ * Returns an array for accessing the set of selectors (not a copy).
+ */
+ public function selectorElements() {
+ return $this->selectorsList;
+ }
+
+ /**
+ * Convert the Selectors within this container to a string. This will
+ * just be a helper class for the subclasses that put their own name
+ * around the contents listed here.
+ *
+ * @return comma separated list of Selectors contained in this one
+ */
+ public function toString() {
+ $buf = "";
+ $arr = $this->selectorElements();
+ for($i=0,$size=count($arr); $i < $size; $i++) {
+ $buf .= $arr[$i]->toString() . (isset($arr[$i+1]) ? ', ' : '');
+ }
+ return $buf;
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new selector to add
+ * @return the selector that was added
+ */
+ public function appendSelector(FileSelector $selector) {
+ $this->selectorsList[] = $selector;
+ }
+
+ /**
+ * <p>This implementation validates the container by calling
+ * verifySettings() and then validates each contained selector
+ * provided that the selector implements the validate interface.
+ * </p>
+ * <p>Ordinarily, this will validate all the elements of a selector
+ * container even if the isSelected() method of some elements is
+ * never called. This has two effects:</p>
+ * <ul>
+ * <li>Validation will often occur twice.
+ * <li>Since it is not required that selectors derive from
+ * BaseSelector, there could be selectors in the container whose
+ * error conditions are not detected if their isSelected() call
+ * is never made.
+ * </ul>
+ */
+ public function validate() {
+ $this->verifySettings();
+ $errmsg = $this->getError();
+ if ($errmsg !== null) {
+ throw new BuildException($errmsg);
+ }
+ foreach($this->selectorsList as $o) {
+ if ($o instanceof BaseSelector) {
+ $o->validate();
+ }
+ }
+ }
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * add a "Select" selector entry on the selector list
+ */
+ public function createSelector() {
+ $o = new SelectSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add an "And" selector entry on the selector list
+ */
+ public function createAnd() {
+ $o = new AndSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add an "Or" selector entry on the selector list
+ */
+ public function createOr() {
+ $o = new OrSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a "Not" selector entry on the selector list
+ */
+ public function createNot() {
+ $o = new NotSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a "None" selector entry on the selector list
+ */
+ public function createNone() {
+ $o = new NoneSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a majority selector entry on the selector list
+ */
+ public function createMajority() {
+ $o = new MajoritySelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a selector date entry on the selector list
+ */
+ public function createDate() {
+ $o = new DateSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a selector size entry on the selector list
+ */
+ public function createSize() {
+ $o = new SizeSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a selector filename entry on the selector list
+ */
+ public function createFilename() {
+ $o = new FilenameSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add an extended selector entry on the selector list
+ */
+ public function createCustom() {
+ $o = new ExtendSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a contains selector entry on the selector list
+ */
+ public function createContains() {
+ $o = new ContainsSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a contains selector entry on the selector list
+ */
+ public function createContainsRegexp() {
+ $o = new ContainsRegexpSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a present selector entry on the selector list
+ */
+ public function createPresent() {
+ $o = new PresentSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a depth selector entry on the selector list
+ */
+ public function createDepth() {
+ $o = new DepthSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a depends selector entry on the selector list
+ */
+ public function createDepend() {
+ $o = new DependSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+ /**
+ * add a type selector entry on the selector list
+ */
+ public function createType() {
+ $o = new TypeSelector();
+ $this->appendSelector($o);
+ return $o;
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/ContainsRegexpSelector.php b/buildscripts/phing/classes/phing/types/selectors/ContainsRegexpSelector.php
new file mode 100644
index 00000000..39afd2fa
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/ContainsRegexpSelector.php
@@ -0,0 +1,164 @@
+<?php
+
+/*
+ * $Id: ContainsRegexpSelector.php,v 1.3 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseExtendSelector.php';
+include_once 'phing/types/RegularExpression.php';
+
+/**
+ * Selector that filters files based on whether they contain a
+ * particular string using regexp.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version $Revision: 1.3 $
+ * @package phing.types.selectors
+ */
+class ContainsRegexpSelector extends BaseExtendSelector {
+
+ /** @var string The expression set from XML. */
+ private $userProvidedExpression;
+
+ /** @var Regexp */
+ private $myExpression;
+
+ private $casesensitive = true;
+
+ /** @var RegularExpression */
+ private $myRegExp;
+
+ const EXPRESSION_KEY = "expression";
+
+ const CASE_KEY = "casesensitive";
+
+ public function toString() {
+ $buf = "{containsregexpselector expression: ";
+ $buf .= $this->userProvidedExpression;
+ $buf .= " casesensitive: ";
+ if ($this->casesensitive) {
+ $buf .= "true";
+ } else {
+ $buf .= "false";
+ }
+ $buf .= "}";
+ return $buf;
+ }
+
+ /**
+ * The expression to match on within a file.
+ *
+ * @param string $exp the string that a file must contain to be selected.
+ */
+ public function setExpression($exp) {
+ $this->userProvidedExpression = $exp;
+ }
+
+ /**
+ * Whether to ignore case in the regex match.
+ *
+ * @param boolean $casesensitive whether to pay attention to case sensitivity
+ */
+ public function setCasesensitive($casesensitive) {
+ $this->casesensitive = $casesensitive;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param array $parameters the complete set of parameters for this selector
+ */
+ public function setParameters($parameters) {
+ parent::setParameters($parameters);
+ if ($parameters !== null) {
+ for ($i=0,$size=count($parameters); $i < $size; $i++) {
+ $paramname = $parameters[$i]->getName();
+ switch(strtolower($paramname)) {
+ case self::EXPRESSION_KEY:
+ $this->setExpression($parameters[$i]->getValue());
+ break;
+ case self::CASE_KEY:
+ $this->setCasesensitive($parameters[$i]->getValue());
+ break;
+ default:
+ $this->setError("Invalid parameter " . $paramname);
+ }
+ } // for each param
+ } // if params
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the pattern attribute has been set.
+ *
+ */
+ public function verifySettings() {
+ if ($this->userProvidedExpression === null) {
+ $this->setError("The expression attribute is required");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file a PhingFile object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ if ($file->isDirectory()) {
+ return true;
+ }
+
+ if ($this->myRegExp === null) {
+ $this->myRegExp = new RegularExpression();
+ $this->myRegExp->setPattern($this->userProvidedExpression);
+ if (!$this->casesensitive) {
+ $this->myRegExp->setIgnoreCase(true);
+ }
+ $this->myExpression = $this->myRegExp->getRegexp($this->getProject());
+ }
+
+ $in = null;
+ try {
+ $in = new BufferedReader(new FileReader($file));
+ $teststr = $in->readLine();
+ while ($teststr !== null) {
+ if ($this->myExpression->matches($teststr)) {
+ return true;
+ }
+ $teststr = $in->readLine();
+ }
+ return false;
+ } catch (IOException $ioe) {
+ if ($in) $in->close();
+ throw new BuildException("Could not read file " . $filename);
+ }
+ $in->close();
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/ContainsSelector.php b/buildscripts/phing/classes/phing/types/selectors/ContainsSelector.php
new file mode 100644
index 00000000..d00ce995
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/ContainsSelector.php
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * $Id: ContainsSelector.php,v 1.9 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that filters files based on whether they contain a
+ * particular string.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class ContainsSelector extends BaseExtendSelector {
+
+ private $contains = null;
+ private $casesensitive = true;
+ const CONTAINS_KEY = "text";
+ const CASE_KEY = "casesensitive";
+
+ public function toString() {
+ $buf = "{containsselector text: ";
+ $buf .= $this->contains;
+ $buf .= " casesensitive: ";
+ if ($this->casesensitive) {
+ $buf .= "true";
+ } else {
+ $buf .= "false";
+ }
+ $buf .= "}";
+ return $buf;
+ }
+
+ /**
+ * The string to search for within a file.
+ *
+ * @param string $contains the string that a file must contain to be selected.
+ */
+ public function setText($contains) {
+ $this->contains = $contains;
+ }
+
+ /**
+ * Whether to ignore case in the string being searched.
+ *
+ * @param boolean $casesensitive whether to pay attention to case sensitivity
+ */
+ public function setCasesensitive($casesensitive) {
+ $this->casesensitive = $casesensitive;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param array $parameters the complete set of parameters for this selector
+ */
+ public function setParameters($parameters) {
+ parent::setParameters($parameters);
+ if ($parameters !== null) {
+ for ($i=0,$size=count($parameters); $i < $size; $i++) {
+ $paramname = $parameters[$i]->getName();
+ switch(strtolower($paramname)) {
+ case self::CONTAINS_KEY:
+ $this->setText($parameters[$i]->getValue());
+ break;
+ case self::CASE_KEY:
+ $this->setCasesensitive($parameters[$i]->getValue());
+ break;
+ default:
+ $this->setError("Invalid parameter " . $paramname);
+ }
+ } // for each param
+ } // if params
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the pattern attribute has been set.
+ *
+ */
+ public function verifySettings() {
+ if ($this->contains === null) {
+ $this->setError("The text attribute is required");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file a PhingFile object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ if ($file->isDirectory()) {
+ return true;
+ }
+
+ $userstr = $this->contains;
+ if (!$this->casesensitive) {
+ $userstr = strtolower($this->contains);
+ }
+
+ $in = null;
+ try {
+ $in = new BufferedReader(new FileReader($file));
+ $teststr = $in->readLine();
+ while ($teststr !== null) {
+ if (!$this->casesensitive) {
+ $teststr = strtolower($teststr);
+ }
+ if (strpos($teststr, $userstr) !== false) {
+ return true;
+ }
+ $teststr = $in->readLine();
+ }
+ return false;
+ } catch (IOException $ioe) {
+ if ($in) $in->close();
+ throw new BuildException("Could not read file " . $filename);
+ }
+ $in->close();
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/DateSelector.php b/buildscripts/phing/classes/phing/types/selectors/DateSelector.php
new file mode 100644
index 00000000..96e5c3ba
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/DateSelector.php
@@ -0,0 +1,214 @@
+<?php
+
+/*
+ * $Id: DateSelector.php,v 1.10 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that chooses files based on their last modified date. Ant uses
+ * millisecond precision (thanks to Java); PHP is forced to use only seconds
+ * precision.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version $Revision: 1.10 $
+ * @package phing.types.selecctors
+ */
+class DateSelector extends BaseExtendSelector {
+
+ private $seconds = -1; // millis in Ant, but PHP doesn't support that level of precision
+ private $dateTime = null;
+ private $includeDirs = false;
+ private $granularity = 0;
+ private $cmp = 2;
+ const MILLIS_KEY = "millis";
+ const DATETIME_KEY = "datetime";
+ const CHECKDIRS_KEY = "checkdirs";
+ const GRANULARITY_KEY = "granularity";
+ const WHEN_KEY = "when";
+ private static $timeComparisons = array("before", "after", "equal");
+
+ public function __construct() {
+ //if (Os.isFamily("dos")) {
+ // granularity = 2000;
+ //}
+ }
+
+ public function toString() {
+ $buf = "{dateselector date: ";
+ $buf .= $this->dateTime;
+ $buf .= " compare: ";
+ if ($this->cmp === 0) {
+ $buf .= "before";
+ } elseif ($this->cmp === 1) {
+ $buf .= "after";
+ } else {
+ $buf .= "equal";
+ }
+ $buf .= " granularity: ";
+ $buf .= $this->granularity;
+ $buf .= "}";
+ return $buf;
+ }
+
+ /**
+ * For users that prefer to express time in seconds since 1970
+ *
+ * @param int $seconds the time to compare file's last modified date to,
+ * expressed in milliseconds
+ */
+ public function setSeconds($seconds) {
+ $this->seconds = (int) $seconds;
+ }
+
+ /**
+ * Returns the seconds value the selector is set for.
+ */
+ public function getSeconds() {
+ return $this->seconds;
+ }
+
+ /**
+ * Sets the date. The user must supply it in MM/DD/YYYY HH:MM AM_PM
+ * format
+ *
+ * @param string $dateTime a string in MM/DD/YYYY HH:MM AM_PM format
+ */
+ public function setDatetime($dateTime) {
+ $dt = strtotime($dateTime);
+ if ($dt == -1) {
+ $this->setError("Date of " . $dateTime
+ . " Cannot be parsed correctly. It should be in"
+ . " a format parsable by PHP's strtotime() function.");
+ } else {
+ $this->dateTime = $dateTime;
+ $this->setSeconds($dt);
+ }
+ }
+
+ /**
+ * Should we be checking dates on directories?
+ *
+ * @param boolean $includeDirs whether to check the timestamp on directories
+ */
+ public function setCheckdirs($includeDirs) {
+ $this->includeDirs = (boolean) $includeDirs;
+ }
+
+ /**
+ * Sets the number of milliseconds leeway we will give before we consider
+ * a file not to have matched a date.
+ * @param int $granularity
+ */
+ public function setGranularity($granularity) {
+ $this->granularity = (int) $granularity;
+ }
+
+ /**
+ * Sets the type of comparison to be done on the file's last modified
+ * date.
+ *
+ * @param string $cmp The comparison to perform
+ */
+ public function setWhen($cmp) {
+ $idx = array_search($cmp, self::$timeComparisons, true);
+ if ($idx === null) {
+ $this->setError("Invalid value for ".WHEN_KEY.": ".$cmp);
+ } else {
+ $this->cmp = $idx;
+ }
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param array $parameters the complete set of parameters for this selector
+ */
+ public function setParameters($parameters) {
+ parent::setParameters($parameters);
+ if ($parameters !== null) {
+ for ($i=0,$size=count($parameters); $i < $size; $i++) {
+ $paramname = $parameters[$i]->getName();
+ switch(strtolower($paramname)) {
+ case self::MILLIS_KEY:
+ $this->setMillis($parameters[$i]->getValue());
+ break;
+ case self::DATETIME_KEY:
+ $this->setDatetime($parameters[$i]->getValue());
+ break;
+ case self::CHECKDIRS_KEY:
+ $this->setCheckdirs($parameters[$i]->getValue());
+ break;
+ case self::GRANULARITY_KEY:
+ $this->setGranularity($parameters[$i]->getValue());
+ break;
+ case self::WHEN_KEY:
+ $this->setWhen($parameters[$i]->getValue());
+ break;
+ default:
+ $this->setError("Invalid parameter " . $paramname);
+ } // switch
+ }
+ }
+ }
+
+ /**
+ * This is a consistency check to ensure the selector's required
+ * values have been set.
+ */
+ public function verifySettings() {
+ if ($this->dateTime === null && $this->seconds < 0) {
+ $this->setError("You must provide a datetime or the number of "
+ . "seconds.");
+ } elseif ($this->seconds < 0) {
+ $this->setError("Date of " . $this->dateTime
+ . " results in negative seconds"
+ . " value relative to epoch (January 1, 1970, 00:00:00 GMT).");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param PhingFile $basedir the base directory the scan is being done from
+ * @param string $filename is the name of the file to check
+ * @param PhingFile $file is a PhingFile object the selector can use
+ * @return boolean Whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+ $this->validate();
+ if ($file->isDirectory() && ($this->includeDirs === false)) {
+ return true;
+ }
+ if ($this->cmp === 0) {
+ return (($file->lastModified() - $this->granularity) < $this->seconds);
+ } elseif ($this->cmp === 1) {
+ return (($file->lastModified() . $this->granularity) > $this->seconds);
+ } else {
+ return (abs($file->lastModified() - $this->seconds) <= $this->granularity);
+ }
+ }
+
+}
+
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/DependSelector.php b/buildscripts/phing/classes/phing/types/selectors/DependSelector.php
new file mode 100644
index 00000000..db73c512
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/DependSelector.php
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * $Id: DependSelector.php,v 1.8 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseSelector.php';
+
+/**
+ * Selector that filters files based on whether they are newer than
+ * a matching file in another directory tree. It can contain a mapper
+ * element, so isn't available as an ExtendSelector (since those
+ * parameters can't hold other elements).
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version $Revision: 1.8 $
+ * @package phing.types.selectors
+ */
+class DependSelector extends BaseSelector {
+
+ private $targetdir = null;
+ private $mapperElement = null;
+ private $map = null;
+ private $granularity = 0;
+
+ public function __construct() {
+ // not yet supported:
+ //if (Os.isFamily("dos")) {
+ // $this->granularity = 2000;
+ //}
+ }
+
+ public function toString() {
+ $buf = "{dependselector targetdir: ";
+ if ($this->targetdir === null) {
+ $buf .= "NOT YET SET";
+ } else {
+ $buf .= $this->targetdir->getName();
+ }
+ $buf .= " granularity: ";
+ $buf .= $this->granularity;
+ if ($this->map !== null) {
+ $buf .= " mapper: ";
+ $buf .= $this->map->toString();
+ } elseif ($this->mapperElement !== null) {
+ $buf .= " mapper: ";
+ $buf .= $this->mapperElement->toString();
+ }
+ $buf .= "}";
+ return $buf;
+ }
+
+ /**
+ * The name of the file or directory which is checked for out-of-date
+ * files.
+ *
+ * @param targetdir the directory to scan looking for files.
+ */
+ public function setTargetdir(PhingFile $targetdir) {
+ $this->targetdir = $targetdir;
+ }
+
+ /**
+ * Sets the number of milliseconds leeway we will give before we consider
+ * a file out of date.
+ */
+ public function setGranularity($granularity) {
+ $this->granularity = (int) granularity;
+ }
+
+ /**
+ * Defines the FileNameMapper to use (nested mapper element).
+ * @throws BuildException
+ */
+ public function createMapper() {
+ if ($this->mapperElement !== null) {
+ throw new BuildException("Cannot define more than one mapper");
+ }
+ $this->mapperElement = new Mapper($this->project);
+ return $this->mapperElement;
+ }
+
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the dest attribute has been set and we have a mapper.
+ */
+ public function verifySettings() {
+ if ($this->targetdir === null) {
+ $this->setError("The targetdir attribute is required.");
+ }
+ if ($this->mapperElement === null) {
+ $this->map = new IdentityMapper();
+ } else {
+ $this->map = $this->mapperElement->getImplementation();
+ }
+ if ($this->map === null) {
+ $this->setError("Could not set <mapper> element.");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a PhingFile object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ // Determine file whose out-of-dateness is to be checked
+ $destfiles = $this->map->main($filename);
+
+ // If filename does not match the To attribute of the mapper
+ // then filter it out of the files we are considering
+ if ($destfiles === null) {
+ return false;
+ }
+ // Sanity check
+ if (count($destfiles) !== 1 || $destfiles[0] === null) {
+ throw new BuildException("Invalid destination file results for " . $this->targetdir . " with filename " . $filename);
+ }
+ $destname = $destfiles[0];
+ $destfile = new PhingFile($this->targetdir, $destname);
+
+ return SelectorUtils::isOutOfDate($file, $destfile, $this->granularity);
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/DepthSelector.php b/buildscripts/phing/classes/phing/types/selectors/DepthSelector.php
new file mode 100644
index 00000000..3faafe96
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/DepthSelector.php
@@ -0,0 +1,158 @@
+<?php
+/*
+ * $Id: DepthSelector.php,v 1.7 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that filters files based on the how deep in the directory
+ * tree they are.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version $Revision: 1.7 $
+ * @package phing.types.selectors
+ */
+class DepthSelector extends BaseExtendSelector {
+
+ public $min = -1;
+ public $max = -1;
+ const MIN_KEY = "min";
+ const MAX_KEY = "max";
+
+ public function toString() {
+ $buf = "{depthselector min: ";
+ $buf .= $this->min;
+ $buf .= " max: ";
+ $buf .= $this->max;
+ $buf .= "}";
+ return $buf;
+ }
+
+ /**
+ * The minimum depth below the basedir before a file is selected.
+ *
+ * @param min minimum directory levels below basedir to go
+ */
+ public function setMin($min) {
+ $this->min = (int) $min;
+ }
+
+ /**
+ * The minimum depth below the basedir before a file is selected.
+ *
+ * @param min maximum directory levels below basedir to go
+ */
+ public function setMax($max) {
+ $this->max = (int) $max;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public function setParameters($parameters) {
+ parent::setParameters($parameters);
+ if ($parameters !== null) {
+ for ($i = 0, $size=count($parameters); $i < $size; $i++) {
+ $paramname = $parameters[$i]->getName();
+ switch(strtolower($paramname)) {
+ case self::MIN_KEY:
+ $this->setMin($parameters[$i]->getValue());
+ break;
+ case self::MAX_KEY:
+ $this->setMax($parameters[$i]->getValue());
+ break;
+
+ default:
+ $this->setError("Invalud parameter " . $paramname);
+ } // switch
+ }
+ }
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the max depth is not lower than the min depth.
+ */
+ public function verifySettings() {
+ if ($this->min < 0 && $this->max < 0) {
+ $this->setError("You must set at least one of the min or the " .
+ "max levels.");
+ }
+ if ($this->max < $this->min && $this->max > -1) {
+ $this->setError("The maximum depth is lower than the minimum.");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset. Most of the work
+ * for this selector is offloaded into SelectorUtils, a static class
+ * that provides the same services for both FilenameSelector and
+ * DirectoryScanner.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a PhingFile object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ $depth = -1;
+ // If you felt daring, you could cache the basedir absolute path
+ $abs_base = $basedir->getAbsolutePath();
+ $abs_file = $file->getAbsolutePath();
+
+ $tok_base = explode(DIRECTORY_SEPARATOR, $abs_base);
+ $tok_file = explode(DIRECTORY_SEPARATOR, $abs_file);
+
+ for($i=0,$size=count($tok_file); $i < $size; $i++) {
+ $filetoken = $tok_file[$i];
+ if (isset($tok_base[$i])) {
+ $basetoken = $tok_base[$i];
+ // Sanity check. Ditch it if you want faster performance
+ if ($basetoken !== $filetoken) {
+ throw new BuildException("File " . $filename .
+ " does not appear within " . $abs_base . "directory");
+ }
+ } else { // no more basepath tokens
+ $depth++;
+ if ($this->max > -1 && $depth > $this->max) {
+ return false;
+ }
+ }
+ }
+ if (isset($tok_base[$i + 1])) {
+ throw new BuildException("File " . $filename .
+ " is outside of " . $abs_base . "directory tree");
+ }
+ if ($this->min > -1 && $depth < $this->min) {
+ return false;
+ }
+ return true;
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/ExtendFileSelector.php b/buildscripts/phing/classes/phing/types/selectors/ExtendFileSelector.php
new file mode 100644
index 00000000..84a3ee5b
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/ExtendFileSelector.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * $Id: ExtendFileSelector.php,v 1.5 2004/02/16 05:28:40 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/Parameterizable.php';
+require_once 'phing/types/selectors/FileSelector.php';
+
+/**
+ * This is the interface to be used by all custom selectors, those that are
+ * called through the &lt;custom&gt; tag. It is the amalgamation of two
+ * interfaces, the FileSelector and the Paramterizable interface. Note that
+ * you will almost certainly want the default behaviour for handling
+ * Parameters, so you probably want to use the BaseExtendSelector class
+ * as the base class for your custom selector rather than implementing
+ * this interface from scratch.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+interface ExtendFileSelector extends Parameterizable, FileSelector {
+ // No further methods necessary. This is just an amalgamation of two other
+ // interfaces.
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/ExtendSelector.php b/buildscripts/phing/classes/phing/types/selectors/ExtendSelector.php
new file mode 100644
index 00000000..cc939254
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/ExtendSelector.php
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ * $Id: ExtendSelector.php,v 1.10 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * Selector that selects files by forwarding the request on to other classes.
+ *
+ * TODO:
+ * Consider adding Path (org.apache.tools.ant.types.Path) support to this class
+ * and to the Mappers class. See Ant versions for implimentation details.
+ *
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
+ * @package phing.types.selectors
+ */
+class ExtendSelector extends BaseSelector {
+
+ private $classname;
+ private $dynselector;
+ private $parameters = array();
+
+ /**
+ * Sets the classname of the custom selector.
+ *
+ * @param classname is the class which implements this selector
+ */
+ public function setClassname($classname) {
+ $this->classname = $classname;
+ }
+
+ /**
+ * Instantiates the identified custom selector class.
+ */
+ public function selectorCreate() {
+ if ($this->classname !== null && $this->classname !== "") {
+ try {
+ // assume it's fully qualified, import it
+ $cls = Phing::import($this->classname);
+
+ // make sure class exists
+ if (class_exists($cls)) {
+ $this->dynselector = new $cls();
+ } else {
+ $this->setError("Selector " . $this->classname . " not initialized, no such class");
+ }
+ } catch (Exception $e) {
+ $this->setError("Selector " . $this->classname . " not initialized, could not create class: " . $e->getMessage());
+ }
+ } else {
+ $this->setError("There is no classname specified");
+ }
+ }
+
+ /**
+ * Create new parameters to pass to custom selector.
+ *
+ * @param p The new Parameter object
+ */
+ public function addParam(Parameter $p) {
+ $this->parameters[] = $p;
+ }
+
+ /**
+ * These are errors specific to ExtendSelector only. If there are
+ * errors in the custom selector, it should throw a BuildException
+ * when isSelected() is called.
+ */
+ public function verifySettings() {
+ // Creation is done here rather than in isSelected() because some
+ // containers may do a validation pass before running isSelected(),
+ // but we need to check for the existence of the created class.
+ if ($this->dynselector === null) {
+ $this->selectorCreate();
+ }
+
+ if (empty($this->classname)) {
+ $this->setError("The classname attribute is required");
+ } elseif ($this->dynselector === null) {
+ $this->setError("Internal Error: The custom selector was not created");
+ } elseif ( !($this->dynselector instanceof ExtendFileSelector) && (count($this->parameters) > 0)) {
+ $this->setError("Cannot set parameters on custom selector that does not "
+ . "implement ExtendFileSelector.");
+ }
+ }
+
+
+ /**
+ * Allows the custom selector to choose whether to select a file. This
+ * is also where the Parameters are passed to the custom selector,
+ * since we know we must have them all by now. And since we must know
+ * both classpath and classname, creating the class is deferred to here
+ * as well.
+ *
+ * @throws BuildException
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ if (count($this->parameters) > 0 && $this->dynselector instanceof ExtendFileSelector) {
+ // We know that dynselector must be non-null if no error message
+ $this->dynselector->setParameters($this->parameters);
+ }
+ return $this->dynselector->isSelected($basedir, $filename, $file);
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/FileSelector.php b/buildscripts/phing/classes/phing/types/selectors/FileSelector.php
new file mode 100644
index 00000000..05926c86
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/FileSelector.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * $Id: FileSelector.php,v 1.4 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * This is the interface to be used by all selectors.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Bruce Atherton, bruce@callenish.com (Ant)
+ * @package phing.types.selectors
+ */
+interface FileSelector {
+
+ /**
+ * Method that each selector will implement to create their
+ * selection behaviour. If there is a problem with the setup
+ * of a selector, it can throw a BuildException to indicate
+ * the problem.
+ *
+ * @param basedir A PhingFile object for the base directory
+ * @param filename The name of the file to check
+ * @param file A PhingFile object for this filename
+ * @return whether the file should be selected or not
+ * @throws BuildException if the selector was not configured correctly
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file);
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/FilenameSelector.php b/buildscripts/phing/classes/phing/types/selectors/FilenameSelector.php
new file mode 100644
index 00000000..2315c888
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/FilenameSelector.php
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ * $Id: FilenameSelector.php,v 1.8 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+include_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that filters files based on the filename.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Bruce Atherton, bruce@callenish.com (Ant)
+ * @package phing.types.selectors
+ */
+class FilenameSelector extends BaseExtendSelector {
+
+ private $pattern = null;
+ private $casesensitive = true;
+ private $negated = false;
+ const NAME_KEY = "name";
+ const CASE_KEY = "casesensitive";
+ const NEGATE_KEY = "negate";
+
+ public function toString() {
+ $buf = "{filenameselector name: ";
+ $buf .= $this->pattern;
+ $buf .= " negate: ";
+ if ($this->negated) {
+ $buf .= "true";
+ } else {
+ $buf .= "false";
+ }
+ $buf .= " casesensitive: ";
+ if ($this->casesensitive) {
+ $buf .= "true";
+ } else {
+ $buf .= "false";
+ }
+ $buf .= "}";
+ return $buf;
+ }
+
+ /**
+ * The name of the file, or the pattern for the name, that
+ * should be used for selection.
+ *
+ * @param pattern the file pattern that any filename must match
+ * against in order to be selected.
+ */
+ public function setName($pattern) {
+ $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $pattern);
+ $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
+
+ if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) {
+ $pattern .= "**";
+ }
+ $this->pattern = $pattern;
+ }
+
+ /**
+ * Whether to ignore case when checking filenames.
+ *
+ * @param casesensitive whether to pay attention to case sensitivity
+ */
+ public function setCasesensitive($casesensitive) {
+ $this->casesensitive = $casesensitive;
+ }
+
+ /**
+ * You can optionally reverse the selection of this selector,
+ * thereby emulating an &lt;exclude&gt; tag, by setting the attribute
+ * negate to true. This is identical to surrounding the selector
+ * with &lt;not&gt;&lt;/not&gt;.
+ *
+ * @param negated whether to negate this selection
+ */
+ public function setNegate($negated) {
+ $this->negated = $negated;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param array $parameters the complete set of parameters for this selector
+ */
+ public function setParameters($parameters) {
+ parent::setParameters($parameters);
+ if ($parameters !== null) {
+ for ($i=0, $len=count($parameters); $i < $len; $i++) {
+ $paramname = $parameters[$i]->getName();
+ switch(strtolower($paramname)) {
+ case self::NAME_KEY:
+ $this->setName($parameters[$i]->getValue());
+ break;
+ case self::CASE_KEY:
+ $this->setCasesensitive($parameters[$i]->getValue());
+ break;
+ case self::NEGATE_KEY:
+ $this->setNegate($parameters[$i]->getValue());
+ break;
+ default:
+ $this->setError("Invalid parameter " . $paramname);
+ }
+ } // for each param
+ } // if params
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the name attribute has been set.
+ *
+ */
+ public function verifySettings() {
+ if ($this->pattern === null) {
+ $this->setError("The name attribute is required");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset. Most of the work
+ * for this selector is offloaded into SelectorUtils, a static class
+ * that provides the same services for both FilenameSelector and
+ * DirectoryScanner.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a PhingFile object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+ $this->validate();
+ return (SelectorUtils::matchPath($this->pattern, $filename, $this->casesensitive)
+ === !($this->negated));
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/MajoritySelector.php b/buildscripts/phing/classes/phing/types/selectors/MajoritySelector.php
new file mode 100644
index 00000000..19e0fb76
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/MajoritySelector.php
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * $Id: MajoritySelector.php,v 1.6 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * This selector is here just to shake up your thinking a bit. Don't get
+ * too caught up in boolean, there are other ways you can evaluate a
+ * collection of selectors. This one takes a vote of the selectors it
+ * contains, and majority wins. You could also have an "all-but-one"
+ * selector, a "weighted-average" selector, and so on. These are left
+ * as exercises for the reader (as are the usecases where this would
+ * be necessary).
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class MajoritySelector extends BaseSelectorContainer {
+
+ private $allowtie = true;
+
+ public function toString() {
+ $buf = "";
+ if ($this->hasSelectors()) {
+ $buf .= "{majorityselect: ";
+ $buf .= parent::toString();
+ $buf .= "}";
+ }
+ return $buf;
+ }
+
+ public function setAllowtie($tiebreaker) {
+ $this->allowtie = $tiebreaker;
+ }
+
+ /**
+ * Returns true (the file is selected) if most of the other selectors
+ * agree. In case of a tie, go by the allowtie setting. That defaults
+ * to true, meaning in case of a tie, the file is selected.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a PhingFile object for the filename that the selector
+ * can use
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ $yesvotes = 0;
+ $novotes = 0;
+
+ $selectors = $this->selectorElements();
+ for($i=0,$size=count($selectors); $i < $size; $i++) {
+ $result = $selectors[$i]->isSelected($basedir,$filename,$file);
+ if ($result) {
+ $yesvotes = $yesvotes + 1;
+ } else {
+ $novotes = $novotes + 1;
+ }
+ }
+ if ($yesvotes > $novotes) {
+ return true;
+ }
+ else if ($novotes > $yesvotes) {
+ return false;
+ }
+ // At this point, we know we have a tie.
+ return $this->allowtie;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/NoneSelector.php b/buildscripts/phing/classes/phing/types/selectors/NoneSelector.php
new file mode 100644
index 00000000..844078a5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/NoneSelector.php
@@ -0,0 +1,71 @@
+<?php
+/*
+ * $Id: NoneSelector.php,v 1.6 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseSelectorContainer.php';
+
+/**
+ * This selector has a collection of other selectors. All of those selectors
+ * must refuse to select a file before the file is considered selected by
+ * this selector.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class NoneSelector extends BaseSelectorContainer {
+
+ public function toString() {
+ $buf = "";
+ if ($this->hasSelectors()) {
+ $buf .= "{noneselect: ";
+ $buf .= parent::toString();
+ $buf .= "}";
+ }
+ return $buf;
+ }
+
+ /**
+ * Returns true (the file is selected) only if all other selectors
+ * agree that the file should not be selected.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object for the filename that the selector
+ * can use
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ $selectors = $this->selectorElements();
+
+ for($i=0,$size=count($selectors); $i < $size; $i++) {
+ $result = $selectors[$i]->isSelected($basedir, $filename, $file);
+ if ($result) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/NotSelector.php b/buildscripts/phing/classes/phing/types/selectors/NotSelector.php
new file mode 100644
index 00000000..90237084
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/NotSelector.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * $Id: NotSelector.php,v 1.4 2003/12/24 17:43:26 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/NoneSelector.php';
+
+/**
+ * This selector has one other selectors whose meaning it inverts. It
+ * actually relies on NoneSelector for its implementation of the
+ * isSelected() method, but it adds a check to ensure there is only one
+ * other selector contained within.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class NotSelector extends NoneSelector {
+
+ public function toString() {
+ $buf = "";
+ if ($this->hasSelectors()) {
+ $buf .= "{notselect: ";
+ $buf .= parent::toString();
+ $buf .= "}";
+ }
+ return $buf;
+ }
+
+ /**
+ * Makes sure that there is only one entry, sets an error message if
+ * not.
+ */
+ public function verifySettings() {
+ if ($this->selectorCount() != 1) {
+ $this->setError("One and only one selector is allowed within the " .
+ "<not> tag");
+ }
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/OrSelector.php b/buildscripts/phing/classes/phing/types/selectors/OrSelector.php
new file mode 100644
index 00000000..6a8778fa
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/OrSelector.php
@@ -0,0 +1,72 @@
+<?php
+/*
+ * $Id: OrSelector.php,v 1.7 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseSelectorContainer.php';
+
+/**
+ * This selector has a collection of other selectors, any of which have to
+ * select a file in order for this selector to select it.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class OrSelector extends BaseSelectorContainer {
+
+ public function toString() {
+ $buf = "";
+ if ($this->hasSelectors()) {
+ $buf .= "{orselect: ";
+ $buf .= parent::toString();
+ $buf .= "}";
+ }
+ return $buf;
+ }
+
+ /**
+ * Returns true (the file is selected) if any of the other selectors
+ * agree that the file should be selected.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename the name of the file to check
+ * @param file a PhingFile object for the filename that the selector
+ * can use
+ * @return boolean Whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ $selectors = $this->selectorElements();
+
+ // First, check that all elements are correctly configured
+
+ for($i=0,$size=count($selectors); $i < $size; $i++) {
+ $result = $selectors[$i]->isSelected($basedir, $filename, $file);
+ if ($result) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/PresentSelector.php b/buildscripts/phing/classes/phing/types/selectors/PresentSelector.php
new file mode 100644
index 00000000..f5f4c880
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/PresentSelector.php
@@ -0,0 +1,154 @@
+<?php
+
+/*
+ * $Id: PresentSelector.php,v 1.9 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Selector that filters files based on whether they appear in another
+ * directory tree. It can contain a mapper element, so isn't available
+ * as an ExtendSelector (since those parameters can't hold other
+ * elements).
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class PresentSelector extends BaseSelector {
+
+ private $targetdir = null;
+ private $mapperElement = null;
+ private $map = null;
+ private $destmustexist = true;
+ private static $filePresence = array("srconly", "both");
+
+ public function toString() {
+ $buf = "{presentselector targetdir: ";
+ if ($this->targetdir === null) {
+ $buf .= "NOT YET SET";
+ } else {
+ $buf .= $this->targetdir->getName();
+ }
+ $buf .= " present: ";
+ if ($this->destmustexist) {
+ $buf .= "both";
+ } else {
+ $buf .= "srconly";
+ }
+ if ($this->map !== null) {
+ $buf .= $this->map->toString();
+ } elseif ($this->mapperElement !== null) {
+ $buf .= $this->mapperElement->toString();
+ }
+ $buf .= "}";
+ return $buf;
+ }
+
+ /**
+ * The name of the file or directory which is checked for matching
+ * files.
+ *
+ * @param targetdir the directory to scan looking for matching files.
+ */
+ public function setTargetdir(PhingFile $targetdir) {
+ $this->targetdir = $targetdir;
+ }
+
+ /**
+ * Defines the FileNameMapper to use (nested mapper element).
+ * @throws BuildException
+ */
+ public function createMapper() {
+ if ($this->mapperElement !== null) {
+ throw new BuildException("Cannot define more than one mapper");
+ }
+ $this->mapperElement = new Mapper($this->getProject());
+ return $this->mapperElement;
+ }
+
+
+ /**
+ * This sets whether to select a file if its dest file is present.
+ * It could be a <code>negate</code> boolean, but by doing things
+ * this way, we get some documentation on how the system works.
+ * A user looking at the documentation should clearly understand
+ * that the ONLY files whose presence is being tested are those
+ * that already exist in the source directory, hence the lack of
+ * a <code>destonly</code> option.
+ *
+ * @param string $fp An attribute set to either <code>srconly</code or
+ * ><code>both</code>.
+ */
+ public function setPresent($fp) {
+ $idx = array_search($fp, self::$filePresence, true);
+ if ( $idx === 0 ) {
+ $this->destmustexist = false;
+ }
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the targetdir attribute has been set and we have a mapper.
+ */
+ public function verifySettings() {
+ if ($this->targetdir === null) {
+ $this->setError("The targetdir attribute is required.");
+ }
+ if ($this->mapperElement === null) {
+ $this->map = new IdentityMapper();
+ } else {
+ $this->map = $this->mapperElement->getImplementation();
+ }
+ if ($this->map === null) {
+ $this->setError("Could not set <mapper> element.");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a PhingFile object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ // Determine file whose existence is to be checked
+ $destfiles = $this->map->main($filename);
+ // If filename does not match the To attribute of the mapper
+ // then filter it out of the files we are considering
+ if ($destfiles === null) {
+ return false;
+ }
+ // Sanity check
+ if (count($destfiles) !== 1 || $destfiles[0] === null) {
+ throw new BuildException("Invalid destination file results for "
+ . $this->targetdir . " with filename " . $filename);
+ }
+ $destname = $destfiles[0];
+ $destfile = new PhingFile($this->targetdir, $destname);
+ return $destfile->exists() === $this->destmustexist;
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/SelectSelector.php b/buildscripts/phing/classes/phing/types/selectors/SelectSelector.php
new file mode 100644
index 00000000..a7644447
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SelectSelector.php
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * $Id: SelectSelector.php,v 1.6 2003/12/24 17:43:26 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/AndSelector.php';
+
+/**
+ * This selector just holds one other selector and forwards all
+ * requests to it. It exists so that there is a single selector
+ * type that can exist outside of any targets, as an element of
+ * project. It overrides all of the reference stuff so that it
+ * works as expected. Note that this is the only selector you
+ * can reference.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version $Revision: 1.6 $
+ * @package phing.types.selectors
+ */
+class SelectSelector extends AndSelector {
+
+ public function toString() {
+ $buf = "";
+ if ($this->hasSelectors()) {
+ $buf .= "{select: ";
+ $buf .= parent::toString();
+ $buf .= "}";
+ }
+ return $buf;
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced Selector.
+ */
+ private function getRef() {
+ $o = $this->getCheckedRef(get_class($this), "SelectSelector");
+ return $o;
+ }
+
+ /**
+ * Indicates whether there are any selectors here.
+ */
+ public function hasSelectors() {
+ if ($this->isReference()) {
+ return $this->getRef()->hasSelectors();
+ }
+ return parent::hasSelectors();
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container
+ */
+ public function selectorCount() {
+ if ($this->isReference()) {
+ return $this->getRef()->selectorCount();
+ }
+ return parent::selectorCount();
+ }
+
+ /**
+ * Returns the set of selectors as an array.
+ */
+ public function getSelectors(Project $p) {
+ if ($this->isReference()) {
+ return $this->getRef()->getSelectors($p);
+ }
+ return parent::getSelectors($p);
+ }
+
+ /**
+ * Returns an enumerator for accessing the set of selectors.
+ */
+ public function selectorElements() {
+ if ($this->isReference()) {
+ return $this->getRef()->selectorElements();
+ }
+ return parent::selectorElements();
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new selector to add
+ * @return the selector that was added
+ */
+ public function appendSelector(FileSelector $selector) {
+ if ($this->isReference()) {
+ throw $this->noChildrenAllowed();
+ }
+ parent::appendSelector($selector);
+ }
+
+ /**
+ * Makes sure that there is only one entry, sets an error message if
+ * not.
+ */
+ public function verifySettings() {
+ if ($this->selectorCount() != 1) {
+ $this->setError("One and only one selector is allowed within the "
+ . "<selector> tag");
+ }
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/SelectorContainer.php b/buildscripts/phing/classes/phing/types/selectors/SelectorContainer.php
new file mode 100644
index 00000000..4a73b113
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SelectorContainer.php
@@ -0,0 +1,141 @@
+<?php
+
+/*
+ * $Id: SelectorContainer.php,v 1.3 2003/11/19 05:48:30 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * This is the interface for selectors that can contain other selectors.
+ *
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
+ * @package phing.types.selectors
+ */
+interface SelectorContainer {
+
+ /**
+ * Indicates whether there are any selectors here.
+ *
+ * @return whether any selectors are in this container
+ */
+ public function hasSelectors();
+
+ /**
+ * Gives the count of the number of selectors in this container
+ *
+ * @return the number of selectors in this container
+ */
+ public function selectorCount();
+
+ /**
+ * Returns a *copy* of the set of selectors as an array.
+ *
+ * @return an array of selectors in this container
+ */
+ public function getSelectors(Project $p);
+
+ /**
+ * Returns an array for accessing the set of selectors.
+ *
+ * @return an enumerator that goes through each of the selectors
+ */
+ public function selectorElements();
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new selector to add
+ * @return the selector that was added
+ */
+ public function appendSelector(FileSelector $selector);
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * add a "Select" selector entry on the selector list
+ */
+ public function createSelector();
+
+ /**
+ * add an "And" selector entry on the selector list
+ */
+ public function createAnd();
+
+ /**
+ * add an "Or" selector entry on the selector list
+ */
+ public function createOr();
+
+ /**
+ * add a "Not" selector entry on the selector list
+ */
+ public function createNot();
+
+ /**
+ * add a "None" selector entry on the selector list
+ */
+ public function createNone();
+
+ /**
+ * add a majority selector entry on the selector list
+ */
+ public function createMajority();
+
+ /**
+ * add a selector date entry on the selector list
+ */
+ public function createDate();
+
+ /**
+ * add a selector size entry on the selector list
+ */
+ public function createSize();
+
+ /**
+ * add a selector filename entry on the selector list
+ */
+ public function createFilename();
+
+ /**
+ * add an extended selector entry on the selector list
+ */
+ public function createCustom();
+
+ /**
+ * add a contains selector entry on the selector list
+ */
+ public function createContains();
+
+ /**
+ * add a present selector entry on the selector list
+ */
+ public function createPresent();
+
+ /**
+ * add a depth selector entry on the selector list
+ */
+ public function createDepth();
+
+ /**
+ * add a depends selector entry on the selector list
+ */
+ public function createDepend();
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/SelectorScanner.php b/buildscripts/phing/classes/phing/types/selectors/SelectorScanner.php
new file mode 100644
index 00000000..f5bb898a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SelectorScanner.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * $Id: SelectorScanner.php,v 1.3 2003/11/19 05:48:30 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * An interface used to describe the actions required by any type of
+ * directory scanner that supports Selecters.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+interface SelectorScanner {
+
+ /**
+ * Sets the selectors the scanner should use.
+ *
+ * @param selectors the list of selectors
+ */
+ public function setSelectors($selectors);
+
+ /**
+ * Directories which were selected out of a scan.
+ *
+ * @param selectors list selector objects
+ */
+ public function getDeselectedDirectories();
+
+ /**
+ * Files which were selected out of a scan.
+ *
+ * @param selectors list selector objects
+ */
+ public function getDeselectedFiles();
+
+}
diff --git a/buildscripts/phing/classes/phing/types/selectors/SelectorUtils.php b/buildscripts/phing/classes/phing/types/selectors/SelectorUtils.php
new file mode 100644
index 00000000..87247e97
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SelectorUtils.php
@@ -0,0 +1,440 @@
+<?php
+
+/*
+ * $Id: SelectorUtils.php,v 1.5 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * <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>
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Arnout J. Kuiper, ajkuiper@wxs.nl (Ant)
+ * @author Magesh Umasankar
+ * @author Bruce Atherton, bruce@callenish.com (Ant)
+ * @package phing.types.selectors
+ */
+class SelectorUtils {
+
+ private static $instance;
+
+ /**
+ * Retrieves the instance of the Singleton.
+ */
+ public function getInstance() {
+ if (!isset(self::$instance)) {
+ self::$instance = new SelectorUtils();
+ }
+ return self::$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 function matchPatternStart($pattern, $str, $isCaseSensitive = true) {
+
+ // When str starts with a DIRECTORY_SEPARATOR, pattern has to start with a
+ // DIRECTORY_SEPARATOR.
+ // When pattern starts with a DIRECTORY_SEPARATOR, str has to start with a
+ // DIRECTORY_SEPARATOR.
+ if (StringHelper::startsWith(DIRECTORY_SEPARATOR, $str) !==
+ StringHelper::startsWith(DIRECTORY_SEPARATOR, $pattern)) {
+ return false;
+ }
+
+ $patDirs = explode(DIRECTORY_SEPARATOR, $pattern);
+ $strDirs = explode(DIRECTORY_SEPARATOR, $str);
+
+ $patIdxStart = 0;
+ $patIdxEnd = count($patDirs)-1;
+ $strIdxStart = 0;
+ $strIdxEnd = count($strDirs)-1;
+
+ // up to first '**'
+ while ($patIdxStart <= $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+ $patDir = $patDirs[$patIdxStart];
+ if ($patDir == "**") {
+ break;
+ }
+ if (!self::match($patDir, $strDirs[$strIdxStart], $isCaseSensitive)) {
+ return false;
+ }
+ $patIdxStart++;
+ $strIdxStart++;
+ }
+
+ if ($strIdxStart > $strIdxEnd) {
+ // String is exhausted
+ return true;
+ } elseif ($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.
+ *
+ * @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 function matchPath($pattern, $str, $isCaseSensitive = true) {
+
+ // When str starts with a DIRECTORY_SEPARATOR, pattern has to start with a
+ // DIRECTORY_SEPARATOR.
+ // When pattern starts with a DIRECTORY_SEPARATOR, str has to start with a
+ // DIRECTORY_SEPARATOR.
+ if (StringHelper::startsWith(DIRECTORY_SEPARATOR, $str) !==
+ StringHelper::startsWith(DIRECTORY_SEPARATOR, $pattern)) {
+ return false;
+ }
+
+ $patDirs = explode(DIRECTORY_SEPARATOR, $pattern);
+ $strDirs = explode(DIRECTORY_SEPARATOR, $str);
+
+ $patIdxStart = 0;
+ $patIdxEnd = count($patDirs)-1;
+ $strIdxStart = 0;
+ $strIdxEnd = count($strDirs)-1;
+
+ // up to first '**'
+ while ($patIdxStart <= $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+ $patDir = $patDirs[$patIdxStart];
+ if ($patDir == "**") {
+ break;
+ }
+ if (!self::match($patDir, $strDirs[$strIdxStart], $isCaseSensitive)) {
+ return false;
+ }
+ $patIdxStart++;
+ $strIdxStart++;
+ }
+ if ($strIdxStart > $strIdxEnd) {
+ // String is exhausted
+ for ($i=$patIdxStart; $i <= $patIdxEnd; $i++) {
+ if ($patDirs[$i] != "**") {
+ return false;
+ }
+ }
+ return true;
+ } elseif ($patIdxStart > $patIdxEnd) {
+ // String not exhausted, but pattern is. Failure.
+ return false;
+ }
+
+ // up to last '**'
+ while ($patIdxStart <= $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+ $patDir = $patDirs[$patIdxEnd];
+ if ($patDir == "**") {
+ break;
+ }
+ if (!self::match($patDir, $strDirs[$strIdxEnd], $isCaseSensitive)) {
+ return false;
+ }
+ $patIdxEnd--;
+ $strIdxEnd--;
+ }
+
+ if ($strIdxStart > $strIdxEnd) {
+ // String is exhausted
+ for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+ if ($patDirs[$i] != "**") {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ while ($patIdxStart != $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+ $patIdxTmp = -1;
+ for ($i = $patIdxStart+1; $i <= $patIdxEnd; $i++) {
+ if ($patDirs[$i] == "**") {
+ $patIdxTmp = $i;
+ break;
+ }
+ }
+ if ($patIdxTmp == $patIdxStart+1) {
+ // '**/**' situation, so skip one
+ $patIdxStart++;
+ continue;
+ }
+ // Find the pattern between padIdxStart & padIdxTmp in str between
+ // strIdxStart & strIdxEnd
+ $patLength = ($patIdxTmp-$patIdxStart-1);
+ $strLength = ($strIdxEnd-$strIdxStart+1);
+ $foundIdx = -1;
+
+ //strLoop: (start of outer loop)
+ for ($i=0; $i <= $strLength - $patLength; $i++) {
+ for ($j = 0; $j < $patLength; $j++) {
+ $subPat = $patDirs[$patIdxStart+$j+1];
+ $subStr = $strDirs[$strIdxStart+$i+$j];
+ if (!self::match($subPat, $subStr, $isCaseSensitive)) {
+ continue 2; // continue up two levels (to strLoop:)
+ }
+ }
+ $foundIdx = $strIdxStart+$i; // only reached if all sub patterns matched
+ break;
+ }
+
+ if ($foundIdx == -1) {
+ return false;
+ }
+
+ $patIdxStart = $patIdxTmp;
+ $strIdxStart = $foundIdx + $patLength;
+ }
+
+ for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+ if ($patDirs[$i] != "**") {
+ 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 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.
+ */
+ public function match($pattern, $str, $isCaseSensitive = true) {
+
+ $patArr = StringHelper::toCharArray($pattern);
+ $strArr = StringHelper::toCharArray($str);
+ $patIdxStart = 0;
+ $patIdxEnd = count($patArr)-1;
+ $strIdxStart = 0;
+ $strIdxEnd = count($strArr)-1;
+
+ $containsStar = false;
+ for ($i = 0, $size=count($patArr); $i < $size; $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 ($isCaseSensitive && $ch !== $strArr[$i]) {
+ return false;// Character mismatch
+ }
+ if (!$isCaseSensitive && strtoupper($ch) !==
+ strtoupper($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(($ch = $patArr[$patIdxStart]) != '*' && $strIdxStart <= $strIdxEnd) {
+ if ($ch != '?') {
+ if ($isCaseSensitive && $ch !== $strArr[$strIdxStart]) {
+ return false;// Character mismatch
+ }
+ if (!$isCaseSensitive && strtoupper($ch) !==
+ strtoupper($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.
+ for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+ if ($patArr[$i] != '*') {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // Process characters after last star
+ while(($ch = $patArr[$patIdxEnd]) != '*' && $strIdxStart <= $strIdxEnd) {
+ if ($ch != '?') {
+ if ($isCaseSensitive && $ch !== $strArr[$strIdxEnd]) {
+ return false;// Character mismatch
+ }
+ if (!$isCaseSensitive && strtoupper($ch) !==
+ strtoupper($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.
+ for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+ if ($patArr[$i] != '*') {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // process pattern between stars. padIdxStart and patIdxEnd point
+ // always to a '*'.
+ while ($patIdxStart !== $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+ $patIdxTmp = -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
+ $patLength = ($patIdxTmp - $patIdxStart - 1);
+ $strLength = ($strIdxEnd - $strIdxStart + 1);
+ $foundIdx = -1;
+
+ //strLoop:
+ for ($i = 0; $i <= $strLength - $patLength; $i++) {
+ for ($j = 0; $j < $patLength; $j++) {
+ $ch = $patArr[$patIdxStart+$j+1];
+ if ($ch != '?') {
+ if ($isCaseSensitive && $ch !== $strArr[$strIdxStart+$i+$j]) {
+ continue 2; //continue to strLoop:
+ }
+ if (!$isCaseSensitive && strtoupper($ch) !==
+ strtoupper($strArr[$strIdxStart+$i+$j])) {
+ continue 2; //continue to strLoop:
+ }
+ }
+ }
+ // only reached if sub loop completed w/o invoking continue 2
+ $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.
+ for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+ if ($patArr[$i] != '*') {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 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 PhingFile $src the original file
+ * @param PhingFile $target the file being compared against
+ * @param int $granularity the amount in seconds of slack we will give in
+ * determining out of dateness
+ * @return whether the target is out of date
+ */
+ public function isOutOfDate(PhingFile $src, PhingFile $target, $granularity) {
+ if (!$src->exists()) {
+ return false;
+ }
+ if (!$target->exists()) {
+ return true;
+ }
+ if (($src->lastModified() - $granularity) > $target->lastModified()) {
+ return true;
+ }
+ return false;
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/SizeSelector.php b/buildscripts/phing/classes/phing/types/selectors/SizeSelector.php
new file mode 100644
index 00000000..bbc26423
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SizeSelector.php
@@ -0,0 +1,228 @@
+<?php
+
+/*
+ * $Id: SizeSelector.php,v 1.8 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * Selector that filters files based on their size.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class SizeSelector extends BaseExtendSelector {
+
+ private $size = -1;
+ private $multiplier = 1;
+ private $sizelimit = -1;
+ private $cmp = 2;
+ const SIZE_KEY = "value";
+ const UNITS_KEY = "units";
+ const WHEN_KEY = "when";
+
+ private static $sizeComparisons = array("less", "more", "equal");
+ private static $byteUnits = array("K", "k", "kilo", "KILO",
+ "Ki", "KI", "ki", "kibi", "KIBI",
+ "M", "m", "mega", "MEGA",
+ "Mi", "MI", "mi", "mebi", "MEBI",
+ "G", "g", "giga", "GIGA",
+ "Gi", "GI", "gi", "gibi", "GIBI",
+ "T", "t", "tera", "TERA",
+ /* You wish! */ "Ti", "TI", "ti", "tebi", "TEBI"
+ );
+
+ public function toString() {
+ $buf = "{sizeselector value: ";
+ $buf .= $this->sizelimit;
+ $buf .= "compare: ";
+ if ($this->cmp === 0) {
+ $buf .= "less";
+ } elseif ($this->cmp === 1) {
+ $buf .= "more";
+ } else {
+ $buf .= "equal";
+ }
+ $buf .= "}";
+ return $buf;
+ }
+
+ /**
+ * A size selector needs to know what size to base its selecting on.
+ * This will be further modified by the multiplier to get an
+ * actual size limit.
+ *
+ * @param size the size to select against expressed in units
+ */
+ public function setValue($size) {
+ $this->size = $size;
+ if (($this->multiplier !== 0) && ($this->size > -1)) {
+ $this->sizelimit = $size * $this->multiplier;
+ }
+ }
+
+ /**
+ * Sets the units to use for the comparison. This is a little
+ * complicated because common usage has created standards that
+ * play havoc with capitalization rules. Thus, some people will
+ * use "K" for indicating 1000's, when the SI standard calls for
+ * "k". Others have tried to introduce "K" as a multiple of 1024,
+ * but that falls down when you reach "M", since "m" is already
+ * defined as 0.001.
+ * <p>
+ * To get around this complexity, a number of standards bodies
+ * have proposed the 2^10 standard, and at least one has adopted
+ * it. But we are still left with a populace that isn't clear on
+ * how capitalization should work.
+ * <p>
+ * We therefore ignore capitalization as much as possible.
+ * Completely mixed case is not possible, but all upper and lower
+ * forms are accepted for all long and short forms. Since we have
+ * no need to work with the 0.001 case, this practice works here.
+ * <p>
+ * This function translates all the long and short forms that a
+ * unit prefix can occur in and translates them into a single
+ * multiplier.
+ *
+ * @param $units The units to compare the size to.
+ * @return void
+ */
+ public function setUnits($units) {
+ $i = array_search($units, self::$byteUnits, true);
+ if ($i === false) $i = -1; // make it java-like
+
+ $this->multiplier = 0;
+ if (($i > -1) && ($i < 4)) {
+ $this->multiplier = 1000;
+ } elseif (($i > 3) && ($i < 9)) {
+ $this->multiplier = 1024;
+ } elseif (($i > 8) && ($i < 13)) {
+ $this->multiplier = 1000000;
+ } elseif (($i > 12) && ($i < 18)) {
+ $this->multiplier = 1048576;
+ } elseif (($i > 17) && ($i < 22)) {
+ $this->multiplier = 1000000000;
+ } elseif (($i > 21) && ($i < 27)) {
+ $this->multiplier = 1073741824;
+ } elseif (($i > 26) && ($i < 31)) {
+ $this->multiplier = 1000000000000;
+ } elseif (($i > 30) && ($i < 36)) {
+ $this->multiplier = 1099511627776;
+ }
+ if (($this->multiplier > 0) && ($this->size > -1)) {
+ $this->sizelimit = $this->size * $this->multiplier;
+ }
+ }
+
+ /**
+ * This specifies when the file should be selected, whether it be
+ * when the file matches a particular size, when it is smaller,
+ * or whether it is larger.
+ *
+ * @param cmp The comparison to perform, an EnumeratedAttribute
+ */
+ public function setWhen($cmp) {
+ $c = array_search($cmp, self::$sizeComparisons, true);
+ if ($c !== false) {
+ $this->cmp = $c;
+ }
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public function setParameters($parameters) {
+ parent::setParameters($parameters);
+ if ($parameters !== null) {
+ for ($i = 0, $size=count($parameters); $i < $size; $i++) {
+ $paramname = $parameters[$i]->getName();
+ switch(strtolower($paramname)) {
+ case self::SIZE_KEY:
+ try {
+ $this->setValue($parameters[$i]->getValue());
+ } catch (Exception $nfe) {
+ $this->setError("Invalid size setting "
+ . $parameters[$i]->getValue());
+ }
+ break;
+ case self::UNITS_KEY:
+ $this->setUnits($parameters[$i]->getValue());
+ break;
+ case self::WHEN_KEY:
+ $this->setWhen($parameters[$i]->getValue());
+ break;
+ default:
+ $this->setError("Invalid parameter " . $paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * <p>Checks to make sure all settings are kosher. In this case, it
+ * means that the size attribute has been set (to a positive value),
+ * that the multiplier has a valid setting, and that the size limit
+ * is valid. Since the latter is a calculated value, this can only
+ * fail due to a programming error.
+ * </p>
+ * <p>If a problem is detected, the setError() method is called.
+ * </p>
+ */
+ public function verifySettings() {
+ if ($this->size < 0) {
+ $this->setError("The value attribute is required, and must be positive");
+ } elseif ($this->multiplier < 1) {
+ $this->setError("Invalid Units supplied, must be K,Ki,M,Mi,G,Gi,T,or Ti");
+ } elseif ($this->sizelimit < 0) {
+ $this->setError("Internal error: Code is not setting sizelimit correctly");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir A PhingFile object for the base directory
+ * @param filename The name of the file to check
+ * @param file A PhingFile object for this filename
+ * @return whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ $this->validate();
+
+ // Directory size never selected for
+ if ($file->isDirectory()) {
+ return true;
+ }
+ if ($this->cmp === 0) {
+ return ($file->length() < $this->sizelimit);
+ } elseif ($this->cmp === 1) {
+ return ($file->length() > $this->sizelimit);
+ } else {
+ return ($file->length() === $this->sizelimit);
+ }
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/types/selectors/TypeSelector.php b/buildscripts/phing/classes/phing/types/selectors/TypeSelector.php
new file mode 100644
index 00000000..f1532308
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/TypeSelector.php
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * $Id: TypeSelector.php,v 1.3 2005/05/26 13:10:53 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that selects a certain kind of file: directory or regular file.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Jeff Turner <jefft@apache.org> (Ant)
+ * @version $Revision: 1.3 $
+ * @package phing.types.selectors
+ */
+class TypeSelector extends BaseExtendSelector {
+
+ private $type;
+
+ /** Key to used for parameterized custom selector */
+ const TYPE_KEY = "type";
+
+ /** Valid types */
+ private static $types = array('file', 'dir');
+
+ /**
+ * @return string A string describing this object
+ */
+ public function toString() {
+ $buf = "{typeselector type: " . $this->type . "}";
+ return $buf;
+ }
+
+ /**
+ * Set the type of file to require.
+ * @param string $type The type of file - 'file' or 'dir'
+ */
+ public function setType($type) {
+ $this->type = $type;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param array $parameters the complete set of parameters for this selector
+ */
+ public function setParameters($parameters) {
+ parent::setParameters($parameters);
+ if ($parameters !== null) {
+ for ($i = 0, $size=count($parameters); $i < $size; $i++) {
+ $paramname = $parameters[$i]->getName();
+ if (self::TYPE_KEY == strtolower($paramname)) {
+ $this->setType($parameters[$i]->getValue());
+ } else {
+ $this->setError("Invalid parameter " . $paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the pattern attribute has been set.
+ *
+ */
+ public function verifySettings() {
+ if ($this->type === null) {
+ $this->setError("The type attribute is required");
+ } elseif (!in_array($this->type, self::$types, true)) {
+ $this->setError("Invalid type specified; must be one of (" . implode(self::$types) . ")");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param PhingFile $basedir the base directory the scan is being done from
+ * @param string $filename is the name of the file to check
+ * @param PhingFile $file is a PhingFile object the selector can use
+ * @return boolean Whether the file should be selected or not
+ */
+ public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+ // throw BuildException on error
+ $this->validate();
+
+ if ($file->isDirectory()) {
+ return $this->type === 'dir';
+ } else {
+ return $this->type === 'file';
+ }
+ }
+
+}