summaryrefslogtreecommitdiff
path: root/buildscripts/phing/classes/phing/types
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts/phing/classes/phing/types')
-rwxr-xr-xbuildscripts/phing/classes/phing/types/AbstractFileSet.php587
-rwxr-xr-xbuildscripts/phing/classes/phing/types/Commandline.php475
-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/Excludes.php208
-rw-r--r--buildscripts/phing/classes/phing/types/ExcludesNameEntry.php81
-rwxr-xr-xbuildscripts/phing/classes/phing/types/FileList.php224
-rw-r--r--buildscripts/phing/classes/phing/types/FileSet.php56
-rwxr-xr-xbuildscripts/phing/classes/phing/types/FilterChain.php191
-rw-r--r--buildscripts/phing/classes/phing/types/IterableFileSet.php56
-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.php452
-rwxr-xr-xbuildscripts/phing/classes/phing/types/PatternSet.php493
-rw-r--r--buildscripts/phing/classes/phing/types/PearPackageFileSet.php179
-rwxr-xr-xbuildscripts/phing/classes/phing/types/PhingFilterReader.php136
-rw-r--r--buildscripts/phing/classes/phing/types/Reference.php56
-rwxr-xr-xbuildscripts/phing/classes/phing/types/RegularExpression.php128
-rwxr-xr-xbuildscripts/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
-rwxr-xr-xbuildscripts/phing/classes/phing/types/selectors/ContainsRegexpSelector.php164
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/ContainsSelector.php151
-rwxr-xr-xbuildscripts/phing/classes/phing/types/selectors/DateSelector.php214
-rwxr-xr-xbuildscripts/phing/classes/phing/types/selectors/DependSelector.php151
-rwxr-xr-xbuildscripts/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.php124
-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
-rwxr-xr-xbuildscripts/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.php200
-rw-r--r--buildscripts/phing/classes/phing/types/selectors/SizeSelector.php228
-rwxr-xr-xbuildscripts/phing/classes/phing/types/selectors/TypeSelector.php120
47 files changed, 7188 insertions, 0 deletions
diff --git a/buildscripts/phing/classes/phing/types/AbstractFileSet.php b/buildscripts/phing/classes/phing/types/AbstractFileSet.php
new file mode 100755
index 00000000..60ca4d04
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/AbstractFileSet.php
@@ -0,0 +1,587 @@
+<?php
+/*
+ * $Id: b7d8ccab6ed556e74626d880dcc09be20ea8bd58 $
+ *
+ * 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 $Id$
+ * @see ProjectComponent
+ * @package phing.types
+ */
+class AbstractFileSet extends DataType implements SelectorContainer {
+
+ // These vars are public for cloning purposes
+
+ /**
+ * @var boolean
+ */
+ public $useDefaultExcludes = true;
+
+ /**
+ * Whether to expand/dereference symbolic links, default is false
+ * @var boolean
+ */
+ protected $expandSymbolicLinks = false;
+
+ /**
+ * @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();
+ }
+
+ /**
+ * Sets whether to expand/dereference symbolic links, default is false
+ * @var boolean
+ */
+ function setExpandSymbolicLinks($expandSymbolicLinks)
+ {
+ $this->expandSymbolicLinks = $expandSymbolicLinks;
+ }
+
+ /**
+ * 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->isLink() || !$this->expandSymbolicLinks) {
+ if (!$this->dir->isDirectory()) {
+ throw new BuildException($this->dir->getAbsolutePath()." is not a directory.");
+ }
+ }
+ $ds = new DirectoryScanner();
+ $ds->setExpandSymbolicLinks($this->expandSymbolicLinks);
+ $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 100755
index 00000000..d6b36e14
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Commandline.php
@@ -0,0 +1,475 @@
+<?php
+/*
+ * $Id: 891b349dcd88b825ae99edf53ed4c7ac2c1c2467 $
+ *
+ * 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>
+ * @package phing.types
+ */
+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, $escape = false) {
+ if ($escape) {
+ return escapeshellarg($argument);
+ } elseif (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, $escape = false) {
+ // 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], $escape);
+ }
+ 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 .= ":" . PHP_EOL;
+ for ($i = $offset, $alen=count($args); $i < $alen; $i++) {
+ $buf .= "'" . $args[$i] . "'" . PHP_EOL;
+ }
+ $buf .= self::DISCLAIMER;
+ return $buf;
+ }
+}
+
+
+/**
+ * "Inner" class used for nested xml command line definitions.
+ *
+ * @package phing.types
+ */
+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
+ *
+ * @package phing.types
+ */
+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..8aa3b487
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/DataType.php
@@ -0,0 +1,182 @@
+<?php
+/*
+ * $Id: 3b15630144c62dda1f447d8eed1e5eda7ac8a466 $
+ *
+ * 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..85b2c529
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Description.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * $Id: bb303eb742207be6958c8107e21ec7c964c09dee $
+ *
+ * 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..527127bb
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/DirSet.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * $Id: 1ab2ec4f1b43daee6cf4c247b4b18b78d87052bc $
+ *
+ * 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/Excludes.php b/buildscripts/phing/classes/phing/types/Excludes.php
new file mode 100644
index 00000000..2d45b593
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Excludes.php
@@ -0,0 +1,208 @@
+<?php
+/*
+ * $Id: 0c22f261d1984da235c6cf4993d1275c225a33ba $
+ *
+ * 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/FileSet.php';
+require_once 'phing/types/ExcludesNameEntry.php';
+
+/**
+ * Datatype which handles excluded files, classes and methods.
+ *
+ * @package phing.types
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: 0c22f261d1984da235c6cf4993d1275c225a33ba $
+ * @since 2.4.6
+ */
+class Excludes extends DataType
+{
+ /**
+ * The directory scanner for getting the excluded files
+ *
+ * @var DirectoryScanner
+ */
+ private $_directoryScanner = null;
+
+ /**
+ * Holds the excluded file patterns
+ *
+ * @var array
+ */
+ private $_files = array();
+
+ /**
+ * Holds the excluded classes
+ *
+ * @var array
+ */
+ private $_classes = array();
+
+ /**
+ * Holds the excluded methods
+ *
+ * @var array
+ */
+ private $_methods = array();
+
+ /**
+ * ctor
+ *
+ * @param Project $project
+ */
+ public function __construct(Project $project)
+ {
+ $this->_directoryScanner = new DirectoryScanner();
+ $this->_directoryScanner->setBasedir($project->getBasedir());
+ }
+
+ /**
+ * Add a name entry on the exclude file list
+ *
+ * @return ExcludesNameEntry Reference to object
+ */
+ public function createFile()
+ {
+ return $this->_addFile($this->_files);
+ }
+
+ /**
+ * Add a name entry on the exclude class list
+ *
+ * @return ExcludesNameEntry Reference to object
+ */
+ public function createClass()
+ {
+ return $this->_addClass($this->_classes);
+ }
+
+ /**
+ * Add a name entry on the exclude method list
+ *
+ * @return ExcludesNameEntry Reference to object
+ */
+ public function createMethod()
+ {
+ return $this->_addMethod($this->_methods);
+ }
+
+ /**
+ * Adds a file to the exclusion list
+ *
+ * @param FileSet $fileSet The FileSet into which the nameentry should be added
+ *
+ * @return ExcludesNameEntry Reference to the created ExcludesNameEntry instance
+ */
+ private function _addFile(&$fileList)
+ {
+ $file = new ExcludesNameEntry();
+ $fileList[] = $file;
+
+ return $file;
+ }
+
+ /**
+ * Adds a class to the exclusion list
+ *
+ * @return ExcludesNameEntry Reference to the created ExcludesNameEntry instance
+ */
+ private function _addClass(&$classList)
+ {
+ $excludedClass = new ExcludesNameEntry();
+ $classList[] = $excludedClass;
+
+ return $excludedClass;
+ }
+
+ /**
+ * Adds a method to the exclusion list
+ *
+ * @return ExcludesNameEntry Reference to the created ExcludesNameEntry instance
+ */
+ private function _addMethod(&$methodList)
+ {
+ $excludedMethod = new ExcludesNameEntry();
+ $methodList[] = $excludedMethod;
+
+ return $excludedMethod;
+ }
+
+ /**
+ * Returns the excluded files
+ *
+ * @return array
+ */
+ public function getExcludedFiles()
+ {
+ $includes = array();
+
+ foreach ($this->_files as $file) {
+ $includes[] = $file->getName();
+ }
+
+ $this->_directoryScanner->setIncludes($includes);
+ $this->_directoryScanner->scan();
+
+ $files = $this->_directoryScanner->getIncludedFiles();
+ $dir = $this->_directoryScanner->getBasedir();
+ $fileList = array();
+
+ foreach ($files as $file) {
+ $fileList[] = $dir . DIRECTORY_SEPARATOR . $file;
+ }
+
+ return $fileList;
+ }
+
+ /**
+ * Returns the excluded class names
+ *
+ * @return array
+ */
+ public function getExcludedClasses()
+ {
+ $excludedClasses = array();
+
+ foreach ($this->_classes as $excludedClass) {
+ $excludedClasses[] = $excludedClass->getName();
+ }
+
+ return $excludedClasses;
+ }
+
+ /**
+ * Returns the excluded method names
+ *
+ * @return array
+ */
+ public function getExcludedMethods()
+ {
+ $excludedMethods = array();
+
+ foreach ($this->_methods as $excludedMethod) {
+ $classAndMethod = explode('::', $excludedMethod->getName());
+ $className = $classAndMethod[0];
+ $methodName = $classAndMethod[1];
+
+ $excludedMethods[$className][] = $methodName;
+ }
+
+ return $excludedMethods;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/types/ExcludesNameEntry.php b/buildscripts/phing/classes/phing/types/ExcludesNameEntry.php
new file mode 100644
index 00000000..1aa6aae5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/ExcludesNameEntry.php
@@ -0,0 +1,81 @@
+<?php
+/*
+ * $Id: a1098700b4f205baacfd5adf5434e5a4803a6a3f $
+ *
+ * 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 for holding nested excludes elements (file, class, method).
+ *
+ * @package phing.types
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: a1098700b4f205baacfd5adf5434e5a4803a6a3f $
+ * @since 2.4.6
+ */
+class ExcludesNameEntry
+{
+ /**
+ * Holds the name of a file, class or method or a file pattern
+ *
+ * @var string
+ */
+ private $_name;
+
+ /**
+ * An alias for the setName() method.
+ * Set the name of a file pattern.
+ *
+ * @see setName()
+ *
+ * @param string $pattern The file pattern
+ */
+ public function addText($pattern)
+ {
+ $this->setName($pattern);
+ }
+
+ /**
+ * Set the name of a file, class or method
+ *
+ * @param string $name
+ */
+ public function setName($name)
+ {
+ $this->_name = (string) $name;
+ }
+
+ /**
+ * Get the name of a file, class or method or the file pattern
+ *
+ * @return string The name of a file, class or method or the file pattern
+ */
+ public function getName()
+ {
+ return $this->_name;
+ }
+
+ /**
+ * Gets a string representation of this name or pattern.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return $this->_name;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/types/FileList.php b/buildscripts/phing/classes/phing/types/FileList.php
new file mode 100755
index 00000000..bc7c6b18
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/FileList.php
@@ -0,0 +1,224 @@
+<?php
+/*
+ * $Id: aab0ffb8e2266923f6cdaf165741dc38931a2aed $
+ *
+ * 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 $Id$
+ * @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.
+ * @param Project $p
+ * @return PhingFile
+ */
+ function getListFile(Project $p) {
+ 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..229e4419
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/FileSet.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * $Id: 1fbeb217059bb26788059dd46affde1428d5a52e $
+ *
+ * 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 100755
index 00000000..e6575c33
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/FilterChain.php
@@ -0,0 +1,191 @@
+<?php
+/*
+ * $Id: ec2362b430c0a863a77968e9003b09c4b9a78d7e $
+ *
+ * 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/IconvFilter.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/ReplaceTokensWithFile.php';
+include_once 'phing/filters/StripPhpComments.php';
+include_once 'phing/filters/StripLineBreaks.php';
+include_once 'phing/filters/StripLineComments.php';
+include_once 'phing/filters/StripWhitespace.php';
+include_once 'phing/filters/TabToSpaces.php';
+include_once 'phing/filters/TidyFilter.php';
+include_once 'phing/filters/TranslateGettext.php';
+include_once 'phing/filters/XincludeFilter.php';
+include_once 'phing/filters/XsltFilter.php';
+
+/**
+ * FilterChain may contain a chained set of filter readers.
+ *
+ * @author Yannick Lecaillez <yl@seasonfive.com>
+ * @version $Id$
+ * @package phing.types
+ */
+class FilterChain extends DataType {
+
+ private $filterReaders = array();
+
+ function __construct($project = null) {
+ if ($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 addIconvFilter(IconvFilter $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 addReplaceTokensWithFile(ReplaceTokensWithFile $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 addStripWhitespace(StripWhitespace $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 addXincludeFilter(XincludeFilter $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
+ * @throws 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/IterableFileSet.php b/buildscripts/phing/classes/phing/types/IterableFileSet.php
new file mode 100644
index 00000000..bc800bbe
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/IterableFileSet.php
@@ -0,0 +1,56 @@
+<?php
+/*
+ * $Id: a607a54aa4e434c01a1f36600274fb31041549e2 $
+ *
+ * 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>.
+ */
+
+/**
+ * FileSet adapter to SPL's Iterator.
+ *
+ * @package phing.types
+ * @author Alexey Shockov <alexey@shockov.com>
+ * @since 2.4.0
+ * @internal
+ */
+class IterableFileSet
+ extends FileSet
+ implements IteratorAggregate
+{
+ /**
+ * @return Iterator
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->getFiles());
+ }
+ /**
+ * @return array
+ */
+ private function getFiles()
+ {
+ $directoryScanner = $this->getDirectoryScanner($this->getProject());
+ $files = $directoryScanner->getIncludedFiles();
+
+ $baseDirectory = $directoryScanner->getBasedir();
+ foreach ($files as $index => $file) {
+ $files[$index] = realpath($baseDirectory.'/'.$file);
+ }
+
+ return $files;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/types/Mapper.php b/buildscripts/phing/classes/phing/types/Mapper.php
new file mode 100644
index 00000000..03042c64
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Mapper.php
@@ -0,0 +1,207 @@
+<?php
+/*
+ * $Id: bab760877500c0bb1ed4d6879c7e31c60c3fd307 $
+ *
+ * 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(Reference $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..cbba153c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Parameter.php
@@ -0,0 +1,99 @@
+<?php
+/*
+ * $Id: 725ec7b7d585219471bb8793da0210c7ab1452c0 $
+ *
+ * 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..7efe790a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Parameterizable.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * $Id: e0d41388dad173e2dd61527524d6c3958683171b $
+ *
+ * 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..b8525628
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Path.php
@@ -0,0 +1,452 @@
+<?php
+/*
+ * $Id: 762715ec83a12704f4ab528e507c28396c159083 $
+ *
+ * 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);
+ 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);
+ while ($tok->hasMoreTokens()) {
+ $pathElement = $tok->nextToken();
+ try {
+ $element = self::resolveFile($project, $pathElement);
+ for ($i = 0, $_i=strlen($element); $i < $_i; $i++) {
+ self::translateFileSep($element, $i);
+ }
+ $result[] = $element;
+ } catch (BuildException $e) {
+ $this->project->log("Dropping path element " . $pathElement
+ . " as it is not valid relative to the project",
+ Project::MSG_VERBOSE);
+ }
+ }
+
+ 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.
+ *
+ * @package phing.types
+ */
+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;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/types/PatternSet.php b/buildscripts/phing/classes/phing/types/PatternSet.php
new file mode 100755
index 00000000..32967d62
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/PatternSet.php
@@ -0,0 +1,493 @@
+<?php
+/*
+ * $Id: af3bd3709d79ad0299bf6ec0130a8a244ee325ab $
+ *
+ * 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 $Id: af3bd3709d79ad0299bf6ec0130a8a244ee325ab $
+ * @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
+ *
+ * @return 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
+ *
+ * @return 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
+ *
+ * @return 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
+ *
+ * @return 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
+ * @return 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
+ * @return 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
+ * @return 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 }";
+ }
+}
+
+
+/**
+ * "Internal" class for holding an include/exclude pattern.
+ *
+ * @package phing.types
+ */
+class PatternSetNameEntry {
+
+ /**
+ * The pattern.
+ * @var string
+ */
+ private $name;
+
+ /**
+ * The if-condition property for this pattern to be applied.
+ * @var string
+ */
+ private $ifCond;
+
+ /**
+ * The unless-condition property for this pattern to be applied.
+ * @var string
+ */
+ private $unlessCond;
+
+ /**
+ * An alias for the setName() method.
+ * @see setName()
+ * @param string $pattern
+ */
+ public function setPattern($pattern) {
+ $this->setName($pattern);
+ }
+
+ /**
+ * Set the pattern text.
+ * @param string $name The pattern
+ */
+ public function setName($name) {
+ $this->name = (string) $name;
+ }
+
+ /**
+ * Sets an if-condition property for this pattern to match.
+ * @param string $cond
+ */
+ public function setIf($cond) {
+ $this->ifCond = (string) $cond;
+ }
+
+
+ /**
+ * Sets an unless-condition property for this pattern to match.
+ * @param string $cond
+ */
+ public function setUnless($cond) {
+ $this->unlessCond = (string) $cond;
+ }
+
+ /**
+ * Get the pattern text.
+ * @return string The pattern.
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Evaluates the pattern.
+ * @return string The pattern or null if it is ruled out by a condition.
+ */
+ public function evalName(Project $project) {
+ return $this->valid($project) ? $this->name : null;
+ }
+
+
+ /**
+ * Checks whether pattern should be applied based on whether the if and unless
+ * properties are set in project.
+ * @param Project $project
+ * @return boolean
+ */
+ public function valid(Project $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;
+ }
+
+ /**
+ * Gets a string representation of this pattern.
+ * @return string
+ */
+ public 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/PearPackageFileSet.php b/buildscripts/phing/classes/phing/types/PearPackageFileSet.php
new file mode 100644
index 00000000..8cf99b28
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/PearPackageFileSet.php
@@ -0,0 +1,179 @@
+<?php
+/**
+ * Part of phing, the PHP build tool
+ *
+ * PHP version 5
+ *
+ * @category Types
+ * @package phing.types
+ * @author Christian Weiske <cweiske@cweiske.de>
+ * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html
+ * @version SVN: $Id: 5ba010b83645d0ea709761a3d8260fc013239458 $
+ * @link http://www.phing.info/
+ */
+require_once 'phing/types/FileSet.php';
+require_once 'PEAR/Config.php';
+require_once 'phing/util/PearPackageScanner.php';
+
+/**
+ * Fileset that contains files of an installed PEAR package.
+ * It can be used to package up PEAR package dependencies in own
+ * release files (zip, tgz, phar).
+ *
+ * @internal
+ * A normal fileset is used that way in CopyTask, rSTTask:
+ * <code>
+ * $ds = $fs->getDirectoryScanner($project);
+ * $fromDir = $fs->getDir($project);
+ * $srcFiles = $ds->getIncludedFiles();
+ * $srcDirs = $ds->getIncludedDirectories();
+ * </code>
+ * The scanner is used as follows:
+ * <code>
+ * $ds->getBaseDir()
+ * $ds->scan()
+ * </code>
+ *
+ * @category Types
+ * @package phing.types
+ * @author Christian Weiske <cweiske@cweiske.de>
+ * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html
+ * @link http://www.phing.info/
+ */
+class PearPackageFileSet extends FileSet
+{
+ /**
+ * Name of channel the package is from, e.g. "pear.php.net".
+ *
+ * @var string
+ */
+ protected $channel;
+
+ /**
+ * Package name to get files from, e.g. "Console_CommandLine"
+ *
+ * @var string
+ */
+ protected $package;
+
+ /**
+ * Use files of that role only.
+ * Multiple roles are not supported, and you always have to specify one.
+ *
+ * @var string
+ */
+ protected $role = 'php';
+
+ /**
+ * Prefix to prepend to the file paths in the zip
+ */
+ protected $prefix;
+
+ /**
+ * Full path to a PEAR config file.
+ * If none provided, default one is used.
+ */
+ protected $config;
+
+ /**
+ * @var PearPackageScanner instance
+ */
+ protected $pps;
+
+
+ /**
+ * Creates and returns the pear package scanner.
+ * Scanner already has scan() called.
+ *
+ * @param Project $project Current phing project
+ *
+ * @return PearPackageScanner
+ */
+ public function getDirectoryScanner(Project $project)
+ {
+ if ($this->isReference()) {
+ $obj = $this->getRef($project);
+ return $obj->getDirectoryScanner($project);
+ }
+
+ $this->loadPearPackageScanner();
+ return $this->pps;
+ }
+
+ /**
+ * Returns the base directory all package files are relative to
+ *
+ * @return PhingFile Base directory
+ */
+ public function getDir()
+ {
+ if ($this->pps === null) {
+ $this->loadPearPackageScanner();
+ }
+ return new PhingFile((string) $this->pps->getBaseDir());
+ }
+
+ /**
+ * Loads the package scanner instance into $this->pps
+ *
+ * @return void
+ */
+ protected function loadPearPackageScanner()
+ {
+ $this->pps = new PearPackageScanner();
+ $this->pps->setPackage($this->package);
+ $this->pps->setChannel($this->channel);
+ $this->pps->setRole($this->role);
+ $this->pps->setConfig($this->config);
+ $this->pps->scan();
+ }
+
+ /**
+ * Sets the package name.
+ * If no channel is given, "pear.php.net" is used.
+ *
+ * @param string $package Single package name, or "channel/name" combination
+ *
+ * @return void
+ */
+ public function setPackage($package)
+ {
+ $parts = explode('/', $package);
+ if (count($parts) > 2) {
+ throw new BuildException('Invalid package name: ' . $package);
+ }
+
+ if (count($parts) == 1) {
+ $this->channel = 'pear.php.net';
+ $this->package = $parts[0];
+ } else {
+ $this->channel = $parts[0];
+ $this->package = $parts[1];
+ }
+ }
+
+ /**
+ * Sets the role of files that should be included.
+ * Examples are php,doc,script
+ *
+ * @param string $role PEAR file role
+ *
+ * @return void
+ */
+ public function setRole($role)
+ {
+ $this->role = $role;
+ }
+
+ /**
+ * Sets the full path to the PEAR configuration file
+ *
+ * @param string $config Configuration file
+ *
+ * @return void
+ */
+ public function setConfig($config)
+ {
+ $this->config = $config;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/types/PhingFilterReader.php b/buildscripts/phing/classes/phing/types/PhingFilterReader.php
new file mode 100755
index 00000000..2337977a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/PhingFilterReader.php
@@ -0,0 +1,136 @@
+<?php
+/*
+ * $Id: fee06c9abce6700d773004bd83a5312d94c5aa29 $
+ *
+ * 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 $Id$
+ * @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..5f490b3f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/Reference.php
@@ -0,0 +1,56 @@
+<?php
+/*
+ * $Id: 48c142f41717a31654d5cbfdb37f339e84adf391 $
+ *
+ * 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 100755
index 00000000..84a25591
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/RegularExpression.php
@@ -0,0 +1,128 @@
+<?php
+/*
+ * $Id: 257bd788b6185a3561f10a8de40502473076b6dd $
+ *
+ * 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 $Id$
+ * @access public
+ * @see phing.util.regex.RegexMatcher
+ * @package phing.types
+*/
+class RegularExpression extends DataType {
+
+ private $regexp = null;
+ /**
+ * @todo Probably both $ignoreCase and $multiline should be removed
+ * from attribute list of RegularExpression class:
+ * actual values are preserved on regexp *engine* level, not expression
+ * object itself.
+ */
+ private $ignoreCase = false;
+ private $multiline = 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 setModifiers($modifiers) {
+ $this->regexp->setModifiers($modifiers);
+ }
+
+ function getModifiers() {
+ return $this->regexp->getModifiers();
+ }
+
+ function setIgnoreCase($bit) {
+ $this->regexp->setIgnoreCase($bit);
+ }
+
+ function getIgnoreCase() {
+ return $this->regexp->getIgnoreCase();
+ }
+
+ function setMultiline($multiline) {
+ $this->regexp->setMultiline($multiline);
+ }
+
+ function getMultiline() {
+ return $this->regexp->getMultiline();
+ }
+
+ 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 100755
index 00000000..98ed3083
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/TokenReader.php
@@ -0,0 +1,66 @@
+<?php
+/*
+ * $Id: c267e1935c57a372e5b8fc07eef73bd084195e82 $
+ *
+ * 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 $Id$
+ * @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..0ca0367a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/TokenSource.php
@@ -0,0 +1,157 @@
+<?php
+/*
+ * $Id: 1bc91e925ce194c2e7a615e8f8c950d2057a9cb5 $
+ *
+ * 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..1a27829d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/AndSelector.php
@@ -0,0 +1,67 @@
+<?php
+/*
+ * $Id: f36556afb9487cce2e56d5c174e3ce4c43ef968f $
+ *
+ * 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..d8ae0444
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/BaseExtendSelector.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * $Id: 0c36c2b00f8ab8d20025b9ad38043c762b6fc7f9 $
+ *
+ * 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..c463fa33
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/BaseSelector.php
@@ -0,0 +1,84 @@
+<?php
+/*
+ * $Id: e1f8e20eb87ea465d29ba3add6fada790642bcf8 $
+ *
+ * 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..3b2a10b1
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/BaseSelectorContainer.php
@@ -0,0 +1,270 @@
+<?php
+
+/*
+ * $Id: 9dd90d3e78d751562859bbe5179db148ee5b025c $
+ *
+ * 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 100755
index 00000000..5b45bac8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/ContainsRegexpSelector.php
@@ -0,0 +1,164 @@
+<?php
+
+/*
+ * $Id: 2a891d7cc3fb1b710b72d51e6a8cf2d0b553f91a $
+ *
+ * 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 $Id$
+ * @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..5e270583
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/ContainsSelector.php
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * $Id: ab2c641c048573b0a9976b7cb92138b8ceda511f $
+ *
+ * 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 100755
index 00000000..0f8c28a8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/DateSelector.php
@@ -0,0 +1,214 @@
+<?php
+
+/*
+ * $Id: f05cee91082616c66b2e109157b1d2f2298a66f8 $
+ *
+ * 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 $Id: f05cee91082616c66b2e109157b1d2f2298a66f8 $
+ * @package phing.types.selectors
+ */
+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 100755
index 00000000..3b869199
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/DependSelector.php
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * $Id: eac9e808c89c2a8f414f86afc589eda4f218dd6e $
+ *
+ * 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 $Id$
+ * @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 100755
index 00000000..0ad6c8eb
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/DepthSelector.php
@@ -0,0 +1,158 @@
+<?php
+/*
+ * $Id: 9c244177a7f95995cd30c67c9fee47c1e977e4e2 $
+ *
+ * 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 $Id$
+ * @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..8394387c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/ExtendFileSelector.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * $Id: dc3c5cb2a3043b7a3f7600591ce825b6563ec0ce $
+ *
+ * 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..1204ef12
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/ExtendSelector.php
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * $Id: 1683a0a93b4bb5486f3cffbe40e8260f886c6258 $
+ *
+ * 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 (phing.types.Path) support to this class
+ * and to the Mappers class. See Ant versions for implimentation details.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @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.
+ *
+ * @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..3c014d61
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/FileSelector.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * $Id: 26b8712469a798faf79d1c877aad89d64880f061 $
+ *
+ * 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..04abbe2e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/FilenameSelector.php
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ * $Id: d0a6af11eeda50b911bad3717528a9ea72291185 $
+ *
+ * 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..5ad2629e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/MajoritySelector.php
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * $Id: 9071d88eb880abe5a299f7c5db707d4439ccaa6c $
+ *
+ * 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..f8941208
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/NoneSelector.php
@@ -0,0 +1,71 @@
+<?php
+/*
+ * $Id: a085187a008c4d8e8ba25fd6f1315b3dee92ec27 $
+ *
+ * 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..08e70a5a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/NotSelector.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * $Id: 8dcce9d2d304b7a8d4be0ef5b5111b582846840d $
+ *
+ * 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..56e6df1e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/OrSelector.php
@@ -0,0 +1,72 @@
+<?php
+/*
+ * $Id: bfed3cc534a3e1ab8789f0ed4a6e64419979e21a $
+ *
+ * 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..462d3927
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/PresentSelector.php
@@ -0,0 +1,154 @@
+<?php
+
+/*
+ * $Id: db4c8bc8217483d4150b2d9e62d2ef5129038b4e $
+ *
+ * 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 100755
index 00000000..0db73e5d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SelectSelector.php
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * $Id: aa3a5cceea362713959333bda113e0ca5428a530 $
+ *
+ * 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 $Id$
+ * @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..0ee42237
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SelectorContainer.php
@@ -0,0 +1,141 @@
+<?php
+
+/*
+ * $Id: 6fedde4695e4838f435f336b7936190b16429706 $
+ *
+ * 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..91fc3f4c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SelectorScanner.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * $Id: 3c28c4c2e4c41cf4507870e472ed9f278e2d9c9f $
+ *
+ * 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..2d7e5068
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SelectorUtils.php
@@ -0,0 +1,200 @@
+<?php
+
+/*
+ * $Id: 4a682bbe8751f6e09a725af7cfdf2bd17ab00645 $
+ *
+ * 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 static 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 static 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 static function matchPath($pattern, $str, $isCaseSensitive = true) {
+
+ $rePattern = preg_quote($pattern, '/');
+ $dirSep = preg_quote(DIRECTORY_SEPARATOR, '/');
+ $trailingDirSep = '(('.$dirSep.')?|('.$dirSep.').+)';
+ $patternReplacements = array(
+ $dirSep.'\*\*'.$dirSep => $dirSep.'.*'.$trailingDirSep,
+ $dirSep.'\*\*' => $trailingDirSep,
+ '\*\*'.$dirSep => '.*'.$trailingDirSep,
+ '\*\*' => '.*',
+ '\*' => '[^'.$dirSep.']*',
+ '\?' => '[^'.$dirSep.']'
+ );
+ $rePattern = str_replace(array_keys($patternReplacements), array_values($patternReplacements), $rePattern);
+ $rePattern = '/^'.$rePattern.'$/'.($isCaseSensitive ? '' : 'i');
+ return (bool) preg_match($rePattern, $str);
+ }
+
+ /**
+ * 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 static function match($pattern, $str, $isCaseSensitive = true) {
+
+ $rePattern = preg_quote($pattern, '/');
+ $rePattern = str_replace(array("\*", "\?"), array('.*', '.'), $rePattern);
+ $rePattern = '/^'.$rePattern.'$/'.($isCaseSensitive ? '' : 'i');
+ return (bool) preg_match($rePattern, $str);
+ }
+
+ /**
+ * 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 static 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..3aaf8a92
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/SizeSelector.php
@@ -0,0 +1,228 @@
+<?php
+
+/*
+ * $Id: 4969c98a4e03305a23770e2afd5da641999f6174 $
+ *
+ * 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 100755
index 00000000..6ff024e8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/types/selectors/TypeSelector.php
@@ -0,0 +1,120 @@
+<?php
+
+/*
+ * $Id: 95c34bb6a364dc0131e9e9c5c124d5074b4a2a21 $
+ *
+ * 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 $Id: 95c34bb6a364dc0131e9e9c5c124d5074b4a2a21 $
+ * @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', 'link');
+
+ /**
+ * @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->isLink()) {
+ if ($this->type == 'link')
+ return true;
+
+ $this->log($file->getAbsolutePath() . " is a link, proceeding with " . $file->getCanonicalPath() . " instead.", Project::MSG_DEBUG);
+ $file = new PhingFile($file->getCanonicalPath());
+ }
+
+ if ($file->isDirectory()) {
+ return $this->type === 'dir';
+ } else {
+ return $this->type === 'file';
+ }
+ }
+
+}