summaryrefslogtreecommitdiff
path: root/buildscripts/phing/classes/phing/tasks/system
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts/phing/classes/phing/tasks/system')
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/AdhocTask.php88
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/AdhocTaskdefTask.php90
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/AdhocTypedefTask.php71
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/AppendTask.php240
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/AvailableTask.php132
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/ChmodTask.php177
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/ConditionTask.php74
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/CopyTask.php401
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/CvsPassTask.php173
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/CvsTask.php540
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/DeleteTask.php277
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/EchoTask.php107
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/ExecTask.php248
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/ExitTask.php118
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/ForeachTask.php138
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/IfTask.php224
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/IncludePathTask.php115
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/InputTask.php146
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/MatchingTask.php361
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/MkdirTask.php64
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/MoveTask.php197
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/PhingCallTask.php139
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/PhingTask.php596
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/PhpEvalTask.php169
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/PropertyPromptTask.php201
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/PropertyTask.php438
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/ReflexiveTask.php155
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/ResolvePathTask.php122
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/SequentialTask.php57
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/TaskdefTask.php127
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/TouchTask.php170
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/TstampTask.php168
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/TypedefTask.php125
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/UpToDateTask.php217
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/WarnTask.php35
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/XsltTask.php81
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/AndCondition.php46
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/Condition.php39
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/ConditionBase.php195
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/ContainsCondition.php76
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/EqualsCondition.php78
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/IsFalseCondition.php60
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/IsSetCondition.php53
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/IsTrueCondition.php59
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/NotCondition.php48
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/OrCondition.php46
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/OsCondition.php63
-rw-r--r--buildscripts/phing/classes/phing/tasks/system/condition/ReferenceExistsCondition.php52
48 files changed, 7596 insertions, 0 deletions
diff --git a/buildscripts/phing/classes/phing/tasks/system/AdhocTask.php b/buildscripts/phing/classes/phing/tasks/system/AdhocTask.php
new file mode 100644
index 00000000..e4c291a1
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/AdhocTask.php
@@ -0,0 +1,88 @@
+<?php
+/*
+ * $Id: AdhocTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Abstract class for creating adhoc Phing components in buildfile.
+ *
+ * By itself this class can be used to declare a single class within your buildfile.
+ * You can then reference this class in any task that takes custom classes (selectors,
+ * mappers, filters, etc.)
+ *
+ * Subclasses exist for conveniently declaring and registering tasks and types.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.6 $
+ * @package phing.tasks.system
+ */
+class AdhocTask extends Task {
+
+ /**
+ * The PHP script
+ * @var string
+ */
+ protected $script;
+
+ protected $newClasses = array();
+
+ /**
+ * Main entry point
+ */
+ public function main() {
+ $this->execute();
+ if ($this->newClasses) {
+ foreach($this->newClasses as $classname) {
+ $this->log("Added adhoc class " . $classname, PROJECT_MSG_VERBOSE);
+ }
+ } else {
+ $this->log("Adhoc task executed but did not result in any new classes.", PROJECT_MSG_VERBOSE);
+ }
+ }
+
+ /**
+ * Get array of names of newly defined classes.
+ * @return array
+ */
+ protected function getNewClasses() {
+ return $this->newClasses;
+ }
+
+ /**
+ * Load the adhoc class, and perform any core validation.
+ * @return string The classname of the ProjectComponent class.
+ * @throws BuildException - if more than one class is defined.
+ */
+ protected function execute() {
+ $classes = get_declared_classes();
+ eval($this->script);
+ $this->newClasses = array_diff(get_declared_classes(), $classes);
+ }
+
+ /**
+ * Set the script.
+ * @param string $script
+ */
+ public function addText($script) {
+ $this->script = $script;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/AdhocTaskdefTask.php b/buildscripts/phing/classes/phing/tasks/system/AdhocTaskdefTask.php
new file mode 100644
index 00000000..ea336f84
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/AdhocTaskdefTask.php
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * $Id: AdhocTaskdefTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/AdhocTask.php';
+
+/**
+ * A class for creating adhoc tasks in build file.
+ *
+ * <target name="test-adhoc">
+ * <adhoc-task name="foo"><![CDATA[
+ *
+ * class FooTest extends Task {
+ * private $bar;
+ *
+ * function setBar($bar) {
+ * $this->bar = $bar;
+ * }
+ *
+ * function main() {
+ * $this->log("In FooTest: " . $this->bar);
+ * }
+ * }
+ *
+ * ]]></adhoc-task>
+ *
+ * <foo bar="B.L.I.N.G"/>
+ * </target>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.5 $
+ * @package phing.tasks.system
+ */
+class AdhocTaskdefTask extends AdhocTask {
+
+ /**
+ * The tag that refers to this task.
+ */
+ private $name;
+
+ /**
+ * Set the tag that will represent this adhoc task/type.
+ * @param string $name
+ */
+ public function setName($name) {
+ $this->name = $name;
+ }
+
+ /** Main entry point */
+ public function main() {
+ if ($this->name === null) {
+ throw new BuildException("The name attribute is required for adhoc task definition.",$this->location);
+ }
+
+ $this->execute();
+
+ $classes = $this->getNewClasses();
+ if (count($classes) !== 1) {
+ throw new BuildException("You must define one (and only one) class for AdhocTaskdefTask.");
+ }
+ $classname = array_shift($classes);
+
+ // instantiate it to make sure it is an instance of Task
+ $t = new $classname();
+ if (!($t instanceof Task)) {
+ throw new BuildException("The adhoc class you defined must be an instance of phing.Task", $this->location);
+ }
+
+ $this->log("Task " . $this->name . " will be handled by class " . $classname, PROJECT_MSG_VERBOSE);
+ $this->project->addTaskDefinition($this->name, $classname);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/AdhocTypedefTask.php b/buildscripts/phing/classes/phing/tasks/system/AdhocTypedefTask.php
new file mode 100644
index 00000000..b836ad93
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/AdhocTypedefTask.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * $Id: AdhocTypedefTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/AdhocTask.php';
+
+/**
+ * A class for creating adhoc datatypes in build file.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.4 $
+ * @package phing.tasks.system
+ */
+class AdhocTypedefTask extends AdhocTask {
+
+ /**
+ * The tag that refers to this task.
+ */
+ private $name;
+
+ /**
+ * Set the tag that will represent this adhoc task/type.
+ * @param string $name
+ */
+ public function setName($name) {
+ $this->name = $name;
+ }
+
+ /** Main entry point */
+ public function main() {
+
+ if ($this->name === null) {
+ throw new BuildException("The name attribute is required for adhoc task definition.",$this->location);
+ }
+
+ $this->execute();
+
+ $classes = $this->getNewClasses();
+ if (count($classes) !== 1) {
+ throw new BuildException("You must define one (and only one) class for AdhocTypedefTask.");
+ }
+ $classname = array_shift($classes);
+
+ // instantiate it to make sure it is an instance of ProjectComponent
+ $t = new $classname();
+ if (!($t instanceof ProjectComponent)) {
+ throw new BuildException("The adhoc class you defined must be an instance of phing.ProjectComponent", $this->location);
+ }
+
+ $this->log("Datatype " . $this->name . " will be handled by class " . $classname, PROJECT_MSG_VERBOSE);
+ $this->project->addDataTypeDefinition($this->name, $classname);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/AppendTask.php b/buildscripts/phing/classes/phing/tasks/system/AppendTask.php
new file mode 100644
index 00000000..feb797cf
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/AppendTask.php
@@ -0,0 +1,240 @@
+<?php
+/*
+ * $Id: AppendTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/types/FileList.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ * Appends text, contents of a file or set of files defined by a filelist to a destination file.
+ *
+ * <code>
+ * <append text="And another thing\n" destfile="badthings.log"/>
+ * </code>
+ * OR
+ * <code>
+ * <append file="header.html" destfile="fullpage.html"/>
+ * <append file="body.html" destfile="fullpage.html"/>
+ * <append file="footer.html" destfile="fullpage.html"/>
+ * </code>
+ * OR
+ * <code>
+ * <append destfile="${process.outputfile}">
+ * <filterchain>
+ * <xsltfilter style="${process.stylesheet}">
+ * <param name="mode" expression="${process.xslt.mode}"/>
+ * <param name="file_name" expression="%{task.append.current_file.basename}"/> <!-- Example of using a RegisterSlot variable -->
+ * </xsltfilter>
+ * </filterchain>
+ * <filelist dir="book/" listfile="book/PhingGuide.book"/>
+ * </append>
+ * </code>
+ * @package phing.tasks.system
+ * @version $Revision: 1.14 $
+ */
+class AppendTask extends Task {
+
+ /** Append stuff to this file. */
+ private $to;
+
+ /** Explicit file to append. */
+ private $file;
+
+ /** Any filesets of files that should be appended. */
+ private $filesets = array();
+
+ /** Any filelists of files that should be appended. */
+ private $filelists = array();
+
+ /** Any filters to be applied before append happens. */
+ private $filterChains = array();
+
+ /** Text to append. (cannot be used in conjunction w/ files or filesets) */
+ private $text;
+
+ /** Sets specific file to append. */
+ function setFile(PhingFile $f) {
+ $this->file = $f;
+ }
+
+ /**
+ * Set target file to append to.
+ * @deprecated Will be removed with final release.
+ */
+ function setTo(PhingFile $f) {
+ $this->log("The 'to' attribute is deprecated in favor of 'destFile'; please update your code.", PROJECT_MSG_WARN);
+ $this->to = $f;
+ }
+
+ /**
+ * The more conventional naming for method to set destination file.
+ * @param PhingFile $f
+ */
+ function setDestFile(PhingFile $f) {
+ $this->to = $f;
+ }
+
+ /**
+ * Supports embedded <filelist> element.
+ * @return FileList
+ */
+ function createFileList() {
+ $num = array_push($this->filelists, new FileList());
+ return $this->filelists[$num-1];
+ }
+
+ /**
+ * Nested creator, adds a set of files (nested <fileset> attribute).
+ * This is for when you don't care what order files get appended.
+ * @return FileSet
+ */
+ function createFileSet() {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * Creates a filterchain
+ *
+ * @return FilterChain The created filterchain object
+ */
+ function createFilterChain() {
+ $num = array_push($this->filterChains, new FilterChain($this->project));
+ return $this->filterChains[$num-1];
+ }
+
+ /**
+ * Sets text to append. (cannot be used in conjunction w/ files or filesets).
+ * @param string $txt
+ */
+ function setText($txt) {
+ $this->text = (string) $txt;
+ }
+
+ /**
+ * Sets text to append. Supports CDATA.
+ * @param string $txt
+ */
+ function addText($txt) {
+ $this->text = (string) $txt;
+ }
+
+
+ /** Append the file(s). */
+ function main() {
+
+ if ($this->to === null) {
+ throw new BuildException("You must specify the 'destFile' attribute");
+ }
+
+ if ($this->file === null && empty($this->filelists) && empty($this->filesets) && $this->text === null) {
+ throw new BuildException("You must specify a file, use a filelist, or specify a text value.");
+ }
+
+ if ($this->text !== null && ($this->file !== null || !empty($this->filelists))) {
+ throw new BuildException("Cannot use text attribute in conjunction with file or filelists.");
+ }
+
+ // create a filwriter to append to "to" file.
+ $writer = new FileWriter($this->to, $append=true);
+
+ if ($this->text !== null) {
+
+ // simply append the text
+ $this->log("Appending string to " . $this->to->getPath());
+
+ // for debugging primarily, maybe comment
+ // out for better performance(?)
+ $lines = explode("\n", $this->text);
+ foreach($lines as $line) {
+ $this->log($line, PROJECT_MSG_VERBOSE);
+ }
+
+ $writer->write($this->text);
+
+ } else {
+
+ // append explicitly-specified file
+ if ($this->file !== null) {
+ try {
+ $this->appendFile($writer, $this->file);
+ } catch (Exception $ioe) {
+ $this->log("Unable to append contents of file " . $this->file->getAbsolutePath() . ": " . $ioe->getMessage(), PROJECT_MSG_WARN);
+ }
+ }
+
+ // append the files in the filelists
+ foreach($this->filelists as $fl) {
+ try {
+ $files = $fl->getFiles($this->project);
+ $this->appendFiles($writer, $files, $fl->getDir($this->project));
+ } catch (BuildException $be) {
+ $this->log($be->getMessage(), PROJECT_MSG_WARN);
+ }
+ }
+
+ // append any files in filesets
+ foreach($this->filesets as $fs) {
+ try {
+ $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
+ $this->appendFiles($writer, $files, $fs->getDir($this->project));
+ } catch (BuildException $be) {
+ $this->log($be->getMessage(), PROJECT_MSG_WARN);
+ }
+ }
+
+ } // if ($text ) {} else {}
+
+ $writer->close();
+ }
+
+ /**
+ * Append an array of files in a directory.
+ * @param FileWriter $writer The FileWriter that is appending to target file.
+ * @param array $files array of files to delete; can be of zero length
+ * @param PhingFile $dir directory to work from
+ */
+ private function appendFiles(FileWriter $writer, $files, PhingFile $dir) {
+ if (!empty($files)) {
+ $this->log("Attempting to append " . count($files) . " files" .($dir !== null ? ", using basedir " . $dir->getPath(): ""));
+ $basenameSlot = Register::getSlot("task.append.current_file");
+ $pathSlot = Register::getSlot("task.append.current_file.path");
+ foreach($files as $filename) {
+ try {
+ $f = new PhingFile($dir, $filename);
+ $basenameSlot->setValue($filename);
+ $pathSlot->setValue($f->getPath());
+ $this->appendFile($writer, $f);
+ } catch (Exception $ioe) {
+ $this->log("Unable to append contents of file " . $f->getAbsolutePath() . ": " . $ioe->getMessage(), PROJECT_MSG_WARN);
+ }
+ }
+ } // if !empty
+ }
+
+ private function appendFile(FileWriter $writer, PhingFile $f) {
+ $in = FileUtils::getChainedReader(new FileReader($f), $this->filterChains, $this->project);
+ while(-1 !== ($buffer = $in->read())) { // -1 indicates EOF
+ $writer->write($buffer);
+ }
+ $this->log("Appending contents of " . $f->getPath() . " to " . $this->to->getPath());
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/AvailableTask.php b/buildscripts/phing/classes/phing/tasks/system/AvailableTask.php
new file mode 100644
index 00000000..76de3e40
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/AvailableTask.php
@@ -0,0 +1,132 @@
+<?php
+/*
+ * $Id: AvailableTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/tasks/system/condition/ConditionBase.php';
+
+/**
+ * <available> task.
+ *
+ * Note: implements condition interface (see condition/Condition.php)
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version $Revision: 1.11 $
+ * @package phing.tasks.system
+ */
+class AvailableTask extends Task {
+
+ /** Property to check for. */
+ private $property;
+
+ /** Value property should be set to. */
+ private $value = "true";
+
+ /** Resource to check for */
+ private $resource;
+
+ private $type = null;
+ private $filepath = null;
+
+ function setProperty($property) {
+ $this->property = (string) $property;
+ }
+
+ function setValue($value) {
+ $this->value = (string) $value;
+ }
+
+ function setFile(PhingFile $file) {
+ $this->file = $file;
+ }
+
+ function setResource($resource) {
+ $this->resource = (string) $resource;
+ }
+
+ function setType($type) {
+ $this->type = (string) strtolower($type);
+ }
+
+ function main() {
+ if ($this->property === null) {
+ throw new BuildException("property attribute is required", $this->location);
+ }
+ if ($this->evaluate()) {
+ $this->project->setProperty($this->property, $this->value);
+ }
+ }
+
+ function evaluate() {
+ if ($this->file === null && $this->resource === null) {
+ throw new BuildException("At least one of (file|resource) is required", $this->location);
+ }
+
+ if ($this->type !== null && ($this->type !== "file" && $this->type !== "dir")) {
+ throw new BuildException("Type must be one of either dir or file", $this->location);
+ }
+
+ if (($this->file !== null) && !$this->_checkFile()) {
+ $this->log("Unable to find " . $this->file->__toString() . " to set property " . $this->property, PROJECT_MSG_VERBOSE);
+ return false;
+ }
+
+ if (($this->resource !== null) && !$this->_checkResource($this->resource)) {
+ $this->log("Unable to load resource " . $this->resource . " to set property " . $this->property, PROJECT_MSG_VERBOSE);
+ return false;
+ }
+
+ return true;
+ }
+
+ // this is prepared for the path type
+ function _checkFile() {
+ if ($this->filepath === null) {
+ return $this->_checkFile1($this->file);
+ } else {
+ $paths = $this->filepath->listDir();
+ for($i=0,$pcnt=count($paths); $i < $pcnt; $i++) {
+ $this->log("Searching " . $paths[$i], PROJECT_MSG_VERBOSE);
+ $tmp = new PhingFile($paths[$i], $this->file->getName());
+ if($tmp->isFile()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ function _checkFile1($file) {
+ if ($this->type !== null) {
+ if ($this->type === "dir") {
+ return $file->isDirectory();
+ } else if ($this->type === "file") {
+ return $file->isFile();
+ }
+ }
+ return $file->exists();
+ }
+
+ function _checkResource($resource) {
+ return $this->_checkFile1(new PhingFile(Phing::getResourcePath($resource)));
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/ChmodTask.php b/buildscripts/phing/classes/phing/tasks/system/ChmodTask.php
new file mode 100644
index 00000000..80470dea
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/ChmodTask.php
@@ -0,0 +1,177 @@
+<?php
+/*
+ * $Id: ChmodTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ * Task that changes the permissions on a file/directory.
+ *
+ * @author Manuel Holtgrewe <grin@gmx.net>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.12 $
+ * @package phing.tasks.system
+ */
+class ChmodTask extends Task {
+
+ private $file;
+
+ private $mode;
+
+ private $filesets = array();
+
+ private $filesystem;
+
+ private $quiet = false;
+ private $failonerror = true;
+
+ /**
+ * This flag means 'note errors to the output, but keep going'
+ * @see setQuiet()
+ */
+ function setFailonerror($bool) {
+ $this->failonerror = $bool;
+ }
+
+ /**
+ * Set quiet mode, which suppresses warnings if chmod() fails.
+ * @see setFailonerror()
+ */
+ function setQuiet($bool) {
+ $this->quiet = $bool;
+ if ($this->quiet) {
+ $this->failonerror = false;
+ }
+ }
+
+ /**
+ * Sets a single source file to touch. If the file does not exist
+ * an empty file will be created.
+ */
+ function setFile(PhingFile $file) {
+ $this->file = $file;
+ }
+
+ function setMode($str) {
+ $this->mode = $str;
+ }
+
+ /**
+ * Nested creator, adds a set of files (nested fileset attribute).
+ */
+ function createFileSet() {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * Execute the touch operation.
+ * @return void
+ */
+ function main() {
+ // Check Parameters
+ $this->checkParams();
+ $this->chmod();
+ }
+
+ /**
+ * Ensure that correct parameters were passed in.
+ * @return void
+ */
+ private function checkParams() {
+
+ if ($this->file === null && empty($this->filesets)) {
+ throw new BuildException("Specify at least one source - a file or a fileset.");
+ }
+
+ if ($this->mode === null) {
+ throw new BuildException("You have to specify an octal mode for chmod.");
+ }
+
+ // check for mode to be in the correct format
+ if (!preg_match('/^([0-7]){3,4}$/', $this->mode)) {
+ throw new BuildException("You have specified an invalid mode.");
+ }
+
+ }
+
+ /**
+ * Does the actual work.
+ * @return void
+ */
+ private function chmod() {
+
+ if (strlen($this->mode) === 4) {
+ $mode = octdec($this->mode);
+ } else {
+ // we need to prepend the 0 before converting
+ $mode = octdec("0". $this->mode);
+ }
+
+ // one file
+ if ($this->file !== null) {
+ $this->chmodFile($this->file, $mode);
+ }
+
+ // filesets
+ foreach($this->filesets as $fs) {
+
+ $ds = $fs->getDirectoryScanner($this->project);
+ $fromDir = $fs->getDir($this->project);
+
+ $srcFiles = $ds->getIncludedFiles();
+ $srcDirs = $ds->getIncludedDirectories();
+
+ for ($j = 0, $filecount = count($srcFiles); $j < $filecount; $j++) {
+ $this->chmodFile(new PhingFile($fromDir, $srcFiles[$j]), $mode);
+ }
+
+ for ($j = 0, $dircount = count($srcDirs); $j < $dircount; $j++) {
+ $this->chmodFile(new PhingFile($fromDir, $srcDirs[$j]), $mode);
+ }
+ }
+
+ }
+
+ /**
+ * Actually change the mode for the file.
+ * @param PhingFile $file
+ * @param int $mode
+ */
+ private function chmodFile(PhingFile $file, $mode) {
+ if ( !$file->exists() ) {
+ throw new BuildException("The file " . $file->__toString() . " does not exist");
+ }
+
+ try {
+ $file->setMode($mode);
+ $this->log("Changed file mode on '" . $file->__toString() ."' to " . vsprintf("%o", $mode));
+ } catch (Exception $e) {
+ if($this->failonerror) {
+ throw $e;
+ } else {
+ $this->log($e->getMessage(), $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN);
+ }
+ }
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/system/ConditionTask.php b/buildscripts/phing/classes/phing/tasks/system/ConditionTask.php
new file mode 100644
index 00000000..fe6ee60b
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/ConditionTask.php
@@ -0,0 +1,74 @@
+<?php
+/*
+ * $Id: ConditionTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/condition/ConditionBase.php';
+
+/**
+ * <condition> task as a generalization of <available>
+ *
+ * <p>This task supports boolean logic as well as pluggable conditions
+ * to decide, whether a property should be set.</p>
+ *
+ * <p>This task does not extend Task to take advantage of
+ * ConditionBase.</p>
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version $Revision: 1.7 $ $Date: 2006-04-28 10:49:47 -0400 (Fri, 28 Apr 2006) $
+ * @access public
+ * @package phing.tasks.system
+ */
+class ConditionTask extends ConditionBase {
+
+ private $property;
+ private $value = "true";
+
+ /**
+ * The name of the property to set. Required.
+ */
+ function setProperty($p) {
+ $this->property = $p;
+ }
+
+ /**
+ * The value for the property to set. Defaults to "true".
+ */
+ function setValue($v) {
+ $this->value = $v;
+ }
+
+ /**
+ * See whether our nested condition holds and set the property.
+ */
+ function main() {
+
+ if ($this->countConditions() > 1) {
+ throw new BuildException("You must not nest more than one condition into <condition>");
+ }
+ if ($this->countConditions() < 1) {
+ throw new BuildException("You must nest a condition into <condition>");
+ }
+ $cs = $this->getIterator();
+ if ($cs->current()->evaluate()) {
+ $this->project->setProperty($this->property, $this->value);
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/CopyTask.php b/buildscripts/phing/classes/phing/tasks/system/CopyTask.php
new file mode 100644
index 00000000..c5e4c2a5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/CopyTask.php
@@ -0,0 +1,401 @@
+<?php
+/*
+ * $Id: CopyTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/util/FileUtils.php';
+include_once 'phing/util/SourceFileScanner.php';
+include_once 'phing/mappers/IdentityMapper.php';
+include_once 'phing/mappers/FlattenMapper.php';
+
+/**
+ * A phing copy task. Copies a file or directory to a new file
+ * or directory. Files are only copied if the source file is newer
+ * than the destination file, or when the destination file does not
+ * exist. It is possible to explictly overwrite existing files.
+ *
+ * @author Andreas Aderhold, andi@binarycloud.com
+ * @version $Revision: 1.16 $ $Date: 2006-04-28 10:49:47 -0400 (Fri, 28 Apr 2006) $
+ * @package phing.tasks.system
+ */
+class CopyTask extends Task {
+
+ protected $file = null; // the source file (from xml attribute)
+ protected $destFile = null; // the destiantion file (from xml attribute)
+ protected $destDir = null; // the destination dir (from xml attribute)
+ protected $overwrite = false; // overwrite destination (from xml attribute)
+ protected $preserveLMT = true; // sync timestamps (from xml attribute)
+ protected $includeEmpty = true; // include empty dirs? (from XML)
+ protected $flatten = false; // apply the FlattenMapper right way (from XML)
+ protected $mapperElement = null;
+
+ protected $fileCopyMap = array(); // asoc array containing mapped file names
+ protected $dirCopyMap = array(); // asoc array containing mapped file names
+ protected $fileUtils = null; // a instance of fileutils
+ protected $filesets = array(); // all fileset objects assigned to this task
+ protected $filterChains = array(); // all filterchains objects assigned to this task
+
+ protected $verbosity = PROJECT_MSG_VERBOSE;
+
+ /**
+ * Sets up this object internal stuff. i.e. the Fileutils instance
+ *
+ * @return object The CopyTask instnace
+ * @access public
+ */
+ function __construct() {
+ $this->fileUtils = new FileUtils();
+ }
+
+ /**
+ * Set the overwrite flag. IntrospectionHelper takes care of
+ * booleans in set* methods so we can assume that the right
+ * value (boolean primitive) is coming in here.
+ *
+ * @param boolean Overwrite the destination file(s) if it/they already exist
+ * @return void
+ * @access public
+ */
+ function setOverwrite($bool) {
+ $this->overwrite = (boolean) $bool;
+ }
+
+ /**
+ * Used to force listing of all names of copied files.
+ * @param boolean $verbosity
+ */
+ function setVerbose($verbosity) {
+ if ($verbosity) {
+ $this->verbosity = PROJECT_MSG_INFO;
+ } else {
+ $this->verbosity = PROJECT_MSG_VERBOSE;
+ }
+ }
+
+ /**
+ * Set the preserve timestmap flag. IntrospectionHelper takes care of
+ * booleans in set* methods so we can assume that the right
+ * value (boolean primitive) is coming in here.
+ *
+ * @param boolean Preserve the timestamp on the destination file
+ * @return void
+ * @access public
+ */
+ function setTstamp($bool) {
+ $this->preserveLMT = (boolean) $bool;
+ }
+
+
+ /**
+ * Set the include empty dirs flag. IntrospectionHelper takes care of
+ * booleans in set* methods so we can assume that the right
+ * value (boolean primitive) is coming in here.
+ *
+ * @param boolean Flag if empty dirs should be cpoied too
+ * @return void
+ * @access public
+ */
+ function setIncludeEmptyDirs($bool) {
+ $this->includeEmpty = (boolean) $bool;
+ }
+
+
+ /**
+ * Set the file. We have to manually take care of the
+ * type that is coming due to limited type support in php
+ * in and convert it manually if neccessary.
+ *
+ * @param string/object The source file. Either a string or an PhingFile object
+ * @return void
+ * @access public
+ */
+ function setFile(PhingFile $file) {
+ $this->file = $file;
+ }
+
+
+ /**
+ * Set the toFile. We have to manually take care of the
+ * type that is coming due to limited type support in php
+ * in and convert it manually if neccessary.
+ *
+ * @param string/object The dest file. Either a string or an PhingFile object
+ * @return void
+ * @access public
+ */
+ function setTofile(PhingFile $file) {
+ $this->destFile = $file;
+ }
+
+
+ /**
+ * Set the toDir. We have to manually take care of the
+ * type that is coming due to limited type support in php
+ * in and convert it manually if neccessary.
+ *
+ * @param string/object The directory, either a string or an PhingFile object
+ * @return void
+ * @access public
+ */
+ function setTodir(PhingFile $dir) {
+ $this->destDir = $dir;
+ }
+
+ /**
+ * Nested creator, creates a FileSet for this task
+ *
+ * @access public
+ * @return object The created fileset object
+ */
+ function createFileSet() {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * Creates a filterchain
+ *
+ * @access public
+ * @return object The created filterchain object
+ */
+ function createFilterChain() {
+ $num = array_push($this->filterChains, new FilterChain($this->project));
+ return $this->filterChains[$num-1];
+ }
+
+ /**
+ * Nested creator, creates one Mapper for this task
+ *
+ * @access public
+ * @return object The created Mapper type object
+ * @throws BuildException
+ */
+ function createMapper() {
+ if ($this->mapperElement !== null) {
+ throw new BuildException("Cannot define more than one mapper", $this->location);
+ }
+ $this->mapperElement = new Mapper($this->project);
+ return $this->mapperElement;
+ }
+
+ /**
+ * The main entry point where everything gets in motion.
+ *
+ * @access public
+ * @return true on success
+ * @throws BuildException
+ */
+ function main() {
+
+ $this->validateAttributes();
+
+ if ($this->file !== null) {
+ if ($this->file->exists()) {
+ if ($this->destFile === null) {
+ $this->destFile = new PhingFile($this->destDir, (string) $this->file->getName());
+ }
+ if ($this->overwrite === true || ($this->file->lastModified() > $this->destFile->lastModified())) {
+ $this->fileCopyMap[$this->file->getAbsolutePath()] = $this->destFile->getAbsolutePath();
+ } else {
+ $this->log($this->file->getName()." omitted, is up to date");
+ }
+ } else {
+ // terminate build
+ throw new BuildException("Could not find file " . $this->file->__toString() . " to copy.");
+ }
+ }
+
+ $project = $this->getProject();
+
+ // process filesets
+ foreach($this->filesets as $fs) {
+ $ds = $fs->getDirectoryScanner($project);
+ $fromDir = $fs->getDir($project);
+ $srcFiles = $ds->getIncludedFiles();
+ $srcDirs = $ds->getIncludedDirectories();
+ $this->_scan($fromDir, $this->destDir, $srcFiles, $srcDirs);
+ }
+
+ // go and copy the stuff
+ $this->doWork();
+
+ if ($this->destFile !== null) {
+ $this->destDir = null;
+ }
+ }
+
+ /**
+ * Validates attributes coming in from XML
+ *
+ * @access private
+ * @return void
+ * @throws BuildException
+ */
+ private function validateAttributes() {
+
+ if ($this->file === null && count($this->filesets) === 0) {
+ throw new BuildException("CopyTask. Specify at least one source - a file or a fileset.");
+ }
+
+ if ($this->destFile !== null && $this->destDir !== null) {
+ throw new BuildException("Only one of destfile and destdir may be set.");
+ }
+
+ if ($this->destFile === null && $this->destDir === null) {
+ throw new BuildException("One of destfile or destdir must be set.");
+ }
+
+ if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) {
+ throw new BuildException("Use a fileset to copy directories.");
+ }
+
+ if ($this->destFile !== null && count($this->filesets) > 0) {
+ throw new BuildException("Cannot concatenate multple files into a single file.");
+ }
+
+ if ($this->destFile !== null) {
+ $this->destDir = new PhingFile($this->destFile->getParent());
+ }
+ }
+
+ /**
+ * Compares source files to destination files to see if they
+ * should be copied.
+ *
+ * @access private
+ * @return void
+ */
+ private function _scan(&$fromDir, &$toDir, &$files, &$dirs) {
+ /* mappers should be generic, so we get the mappers here and
+ pass them on to builMap. This method is not redundan like it seems */
+ $mapper = null;
+ if ($this->mapperElement !== null) {
+ $mapper = $this->mapperElement->getImplementation();
+ } else if ($this->flatten) {
+ $mapper = new FlattenMapper();
+ } else {
+ $mapper = new IdentityMapper();
+ }
+ $this->buildMap($fromDir, $toDir, $files, $mapper, $this->fileCopyMap);
+ $this->buildMap($fromDir, $toDir, $dirs, $mapper, $this->dirCopyMap);
+ }
+
+ /**
+ * Builds a map of filenames (from->to) that should be copied
+ *
+ * @access private
+ * @return void
+ */
+ private function buildMap(&$fromDir, &$toDir, &$names, &$mapper, &$map) {
+ $toCopy = null;
+ if ($this->overwrite) {
+ $v = array();
+ foreach($names as $name) {
+ $result = $mapper->main($name);
+ if ($result !== null) {
+ $v[] = $name;
+ }
+ }
+ $toCopy = $v;
+ } else {
+ $ds = new SourceFileScanner($this);
+ $toCopy = $ds->restrict($names, $fromDir, $toDir, $mapper);
+ }
+
+ for ($i=0,$_i=count($toCopy); $i < $_i; $i++) {
+ $src = new PhingFile($fromDir, $toCopy[$i]);
+ $mapped = $mapper->main($toCopy[$i]);
+ $dest = new PhingFile($toDir, $mapped[0]);
+ $map[$src->getAbsolutePath()] = $dest->getAbsolutePath();
+ }
+ }
+
+
+ /**
+ * Actually copies the files
+ *
+ * @access private
+ * @return void
+ * @throws BuildException
+ */
+ private function doWork() {
+
+ // These "slots" allow filters to retrieve information about the currently-being-process files
+ $fromSlot = $this->getRegisterSlot("currentFromFile");
+ $fromBasenameSlot = $this->getRegisterSlot("currentFromFile.basename");
+
+ $toSlot = $this->getRegisterSlot("currentToFile");
+ $toBasenameSlot = $this->getRegisterSlot("currentToFile.basename");
+
+ $mapSize = count($this->fileCopyMap);
+ $total = $mapSize;
+ if ($mapSize > 0) {
+ $this->log("Copying ".$mapSize." file".(($mapSize) === 1 ? '' : 's')." to ". $this->destDir->getAbsolutePath());
+ // walks the map and actually copies the files
+ $count=0;
+ foreach($this->fileCopyMap as $from => $to) {
+ if ($from === $to) {
+ $this->log("Skipping self-copy of " . $from, $this->verbosity);
+ $total--;
+ continue;
+ }
+ $this->log("From ".$from." to ".$to, $this->verbosity);
+ try { // try to copy file
+
+ $fromFile = new PhingFile($from);
+ $toFile = new PhingFile($to);
+
+ $fromSlot->setValue($fromFile->getPath());
+ $fromBasenameSlot->setValue($fromFile->getName());
+
+ $toSlot->setValue($toFile->getPath());
+ $toBasenameSlot->setValue($toFile->getName());
+
+ $this->fileUtils->copyFile($fromFile, $toFile, $this->overwrite, $this->preserveLMT, $this->filterChains, $this->getProject());
+
+ $count++;
+ } catch (IOException $ioe) {
+ $this->log("Failed to copy " . $from . " to " . $to . ": " . $ioe->getMessage(), PROJECT_MSG_ERR);
+ }
+ }
+ }
+
+ // handle empty dirs if appropriate
+ if ($this->includeEmpty) {
+ $e = array_values($this->dirCopyMap);
+ $count = 0;
+ foreach ($e as $dir) {
+ $d = new PhingFile((string) $dir);
+ if (!$d->exists()) {
+ if (!$d->mkdirs()) {
+ $this->log("Unable to create directory " . $d->__toString(), PROJECT_MSG_ERR);
+ } else {
+ $count++;
+ }
+ }
+ }
+ if ($count > 0) {
+ $this->log("Copied ".$count." empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath());
+ }
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/CvsPassTask.php b/buildscripts/phing/classes/phing/tasks/system/CvsPassTask.php
new file mode 100644
index 00000000..0003c50f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/CvsPassTask.php
@@ -0,0 +1,173 @@
+<?php
+/*
+ * $Id: CvsPassTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/system/io/BufferedReader.php';
+include_once 'phing/system/io/BufferedWriter.php';
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * Adds an new entry to a CVS password file.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Jeff Martin <jeff@custommonkey.org> (Ant)
+ * @version $Revision: 1.7 $
+ * @package phing.tasks.system
+ */
+class CVSPassTask extends Task {
+
+ /** CVS Root */
+ private $cvsRoot;
+ /** Password file to add password to */
+ private $passFile;
+ /** Password to add to file */
+ private $password;
+
+ /** Array contain char conversion data */
+ private static $shifts = array(
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 114, 120, 53, 79, 96, 109, 72, 108, 70, 64, 76, 67, 116, 74, 68, 87,
+ 111, 52, 75, 119, 49, 34, 82, 81, 95, 65, 112, 86, 118, 110, 122, 105,
+ 41, 57, 83, 43, 46, 102, 40, 89, 38, 103, 45, 50, 42, 123, 91, 35,
+ 125, 55, 54, 66, 124, 126, 59, 47, 92, 71, 115, 78, 88, 107, 106, 56,
+ 36, 121, 117, 104, 101, 100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,
+ 58, 113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85, 223,
+ 225, 216, 187, 166, 229, 189, 222, 188, 141, 249, 148, 200, 184, 136, 248, 190,
+ 199, 170, 181, 204, 138, 232, 218, 183, 255, 234, 220, 247, 213, 203, 226, 193,
+ 174, 172, 228, 252, 217, 201, 131, 230, 197, 211, 145, 238, 161, 179, 160, 212,
+ 207, 221, 254, 173, 202, 146, 224, 151, 140, 196, 205, 130, 135, 133, 143, 246,
+ 192, 159, 244, 239, 185, 168, 215, 144, 139, 165, 180, 157, 147, 186, 214, 176,
+ 227, 231, 219, 169, 175, 156, 206, 198, 129, 164, 150, 210, 154, 177, 134, 127,
+ 182, 128, 158, 208, 162, 132, 167, 209, 149, 241, 153, 251, 237, 236, 171, 195,
+ 243, 233, 253, 240, 194, 250, 191, 155, 142, 137, 245, 235, 163, 242, 178, 152
+ );
+
+ /**
+ * Create a CVS task using the default cvspass file location.
+ */
+ public function __construct() {
+ $this->passFile = new PhingFile(
+ Phing::getProperty("cygwin.user.home",
+ Phing::getProperty("user.home"))
+ . DIRECTORY_SEPARATOR . ".cvspass");
+ }
+
+ /**
+ * Does the work.
+ *
+ * @throws BuildException if someting goes wrong with the build
+ */
+ public final function main() {
+ if ($this->cvsRoot === null) {
+ throw new BuildException("cvsroot is required");
+ }
+ if ($this->password === null) {
+ throw new BuildException("password is required");
+ }
+
+ $this->log("cvsRoot: " . $this->cvsRoot, PROJECT_MSG_DEBUG);
+ $this->log("password: " . $this->password, PROJECT_MSG_DEBUG);
+ $this->log("passFile: " . $this->passFile->__toString(), PROJECT_MSG_DEBUG);
+
+ $reader = null;
+ $writer = null;
+
+ try {
+ $buf = "";
+
+ if ($this->passFile->exists()) {
+ $reader = new BufferedReader(new FileReader($this->passFile));
+
+ $line = null;
+ while (($line = $reader->readLine()) !== null) {
+ if (!StringHelper::startsWith($this->cvsRoot, $line)) {
+ $buf .= $line . Phing::getProperty("line.separator");
+ }
+ }
+ }
+
+ $pwdfile = $buf . $this->cvsRoot . " A" . $this->mangle($this->password);
+
+ $this->log("Writing -> " . $pwdfile , PROJECT_MSG_DEBUG);
+
+ $writer = new BufferedWriter(new FileWriter($this->passFile));
+ $writer->write($pwdfile);
+ $writer->newLine();
+
+ $writer->close();
+ if ($reader) {
+ $reader->close();
+ }
+
+ } catch (IOException $e) {
+ if ($reader) {
+ try {
+ $reader->close();
+ } catch (Exception $e) {}
+ }
+
+ if ($writer) {
+ try {
+ $writer->close();
+ } catch (Exception $e) {}
+ }
+
+ throw new BuildException($e);
+ }
+ }
+
+ /**
+ * "Encode" the password.
+ */
+ private final function mangle($password){
+ $buf = "";
+ for ($i = 0, $plen = strlen($password); $i < $plen; $i++) {
+ $buf .= chr(self::$shifts[ord($password{$i})]);
+ }
+ return $buf;
+ }
+
+ /**
+ * The CVS repository to add an entry for.
+ * @param string $cvsRoot
+ */
+ public function setCvsroot($cvsRoot) {
+ $this->cvsRoot = $cvsRoot;
+ }
+
+ /**
+ * Password file to add the entry to.
+ * @param PhingFile $passFile
+ */
+ public function setPassfile(PhingFile $passFile) {
+ $this->passFile = $passFile;
+ }
+
+ /**
+ * Password to be added to the password file.
+ * @param string $password
+ */
+ public function setPassword($password) {
+ $this->password = $password;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/CvsTask.php b/buildscripts/phing/classes/phing/tasks/system/CvsTask.php
new file mode 100644
index 00000000..de2950ec
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/CvsTask.php
@@ -0,0 +1,540 @@
+<?php
+/*
+ * $Id: CvsTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/tasks/system/ExecTask.php';
+include_once 'phing/types/Commandline.php';
+
+/**
+ * Task for performing CVS operations.
+ *
+ * NOTE: This implementation has been moved here from Cvs.java with
+ * the addition of some accessors for extensibility. Another task
+ * can extend this with some customized output processing.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author costin@dnt.ro (Ant)
+ * @author stefano@apache.org (Ant)
+ * @author Wolfgang Werner <wwerner@picturesafe.de> (Ant)
+ * @author Kevin Ross <kevin.ross@bredex.com> (Ant)
+ * @version $Revision: 1.14 $
+ * @package phing.tasks.system
+ */
+class CvsTask extends Task {
+
+ /**
+ * Default compression level to use, if compression is enabled via
+ * setCompression( true ).
+ */
+ const DEFAULT_COMPRESSION_LEVEL = 3;
+
+ private $cmd;
+
+ /**
+ * List of Commandline children
+ * @var array Commandline[]
+ */
+ private $commandlines = array();
+
+ /**
+ * the CVSROOT variable.
+ */
+ private $cvsRoot;
+
+ /**
+ * the CVS_RSH variable.
+ */
+ private $cvsRsh;
+
+ /**
+ * the package/module to check out.
+ */
+ private $cvsModule;
+
+ /**
+ * the default command.
+ */
+ private static $default_command = "checkout";
+
+ /**
+ * the CVS command to execute.
+ */
+ private $command = null;
+
+ /**
+ * suppress information messages.
+ */
+ private $quiet = false;
+
+ /**
+ * compression level to use.
+ */
+ private $compression = 0;
+
+ /**
+ * report only, don't change any files.
+ */
+ private $noexec = false;
+
+ /**
+ * CVS port
+ */
+ private $port = 0;
+
+ /**
+ * CVS password file
+ * @var File
+ */
+ private $passFile = null;
+
+ /**
+ * the directory where the checked out files should be placed.
+ * @var File
+ */
+ private $dest;
+
+ private $error;
+
+ private $output;
+
+ /**
+ * If true it will stop the build if cvs exits with error.
+ * Default is false. (Iulian)
+ * @var boolean
+ */
+ private $failOnError = false;
+
+ public function init() {
+ $this->cmd = new Commandline();
+ }
+
+ /**
+ * Sets up the environment for toExecute and then runs it.
+ * @param Commandline $toExecute
+ * @throws BuildException
+ */
+ protected function runCommand(Commandline $toExecute) {
+
+ // We are putting variables into the script's environment
+ // and not removing them (!) This should be fine, but is
+ // worth remembering and testing.
+
+ if ($this->port > 0) {
+ putenv("CVS_CLIENT_PORT=".$this->port);
+ }
+
+ // Need a better cross platform integration with <cvspass>, so
+ // use the same filename.
+
+ if ($this->passFile === null) {
+ $defaultPassFile = new PhingFile(Phing::getProperty("cygwin.user.home", Phing::getProperty("user.home"))
+ . DIRECTORY_SEPARATOR . ".cvspass");
+ if($defaultPassFile->exists()) {
+ $this->setPassfile($defaultPassFile);
+ }
+ }
+
+ if ($this->passFile !== null) {
+ if ($this->passFile->isFile() && $this->passFile->canRead()) {
+ putenv("CVS_PASSFILE=" . $this->passFile->__toString());
+ $this->log("Using cvs passfile: " . $this->passFile->__toString(), PROJECT_MSG_INFO);
+ } elseif (!$this->passFile->canRead()) {
+ $this->log("cvs passfile: " . $this->passFile->__toString()
+ . " ignored as it is not readable", PROJECT_MSG_WARN);
+ } else {
+ $this->log("cvs passfile: " . $this->passFile->__toString()
+ . " ignored as it is not a file",
+ PROJECT_MSG_WARN);
+ }
+ }
+
+ if ($this->cvsRsh !== null) {
+ putenv("CVS_RSH=".$this->cvsRsh);
+ }
+
+ // Use the ExecTask to handle execution of the command
+ $exe = new ExecTask($this->project);
+ $exe->setProject($this->project);
+
+ //exe.setAntRun(project);
+ if ($this->dest === null) {
+ $this->dest = $this->project->getBaseDir();
+ }
+
+ if (!$this->dest->exists()) {
+ $this->dest->mkdirs();
+ }
+
+ if ($this->output !== null) {
+ $exe->setOutput($this->output);
+ }
+
+ if ($this->error !== null) {
+ $exe->setError($this->error);
+ }
+
+ $exe->setDir($this->dest);
+
+ if (is_object($toExecute)) {
+ $toExecuteStr = $toExecute->__toString(); // unfortunately no more automagic for initial 5.0.0 release :(
+ }
+
+ $exe->setCommand($toExecuteStr);
+
+ try {
+ $actualCommandLine = $toExecuteStr; // we converted to string above
+ $this->log($actualCommandLine, PROJECT_MSG_INFO);
+ $retCode = $exe->execute();
+ $this->log("retCode=" . $retCode, PROJECT_MSG_DEBUG);
+ /*Throw an exception if cvs exited with error. (Iulian)*/
+ if ($this->failOnError && $retCode !== 0) {
+ throw new BuildException("cvs exited with error code "
+ . $retCode
+ . Phing::getProperty("line.separator")
+ . "Command line was ["
+ . $toExecute->describeCommand() . "]", $this->getLocation());
+ }
+ } catch (IOException $e) {
+ if ($this->failOnError) {
+ throw new BuildException($e, $this->getLocation());
+ } else {
+ $this->log("Caught exception: " . $e, PROJECT_MSG_WARN);
+ }
+ } catch (BuildException $e) {
+ if ($this->failOnError) {
+ throw $e;
+ } else {
+ $t = $e->getCause();
+ if ($t === null) {
+ $t = $e;
+ }
+ $this->log("Caught exception: " . $t, PROJECT_MSG_WARN);
+ }
+ } catch (Exception $e) {
+ if ($this->failOnError) {
+ throw new BuildException($e, $this->getLocation());
+ } else {
+ $this->log("Caught exception: " . $e, PROJECT_MSG_WARN);
+ }
+ }
+ }
+
+ /**
+ *
+ * @return void
+ * @throws BuildException
+ */
+ public function main() {
+
+ $savedCommand = $this->getCommand();
+
+ if ($this->getCommand() === null && empty($this->commandlines)) {
+ // re-implement legacy behaviour:
+ $this->setCommand(self::$default_command);
+ }
+
+ $c = $this->getCommand();
+ $cloned = null;
+ if ($c !== null) {
+ $cloned = $this->cmd->__copy();
+ $cloned->createArgument(true)->setLine($c);
+ $this->addConfiguredCommandline($cloned, true);
+ }
+
+ try {
+ for ($i = 0, $vecsize=count($this->commandlines); $i < $vecsize; $i++) {
+ $this->runCommand($this->commandlines[$i]);
+ }
+
+ // finally {
+ if ($cloned !== null) {
+ $this->removeCommandline($cloned);
+ }
+ $this->setCommand($savedCommand);
+
+ } catch (Exception $e) {
+ // finally {
+ if ($cloned !== null) {
+ $this->removeCommandline($cloned);
+ }
+ $this->setCommand($savedCommand);
+ throw $e;
+ }
+ }
+
+ /**
+ * The CVSROOT variable.
+ *
+ * @param string $root
+ */
+ public function setCvsRoot($root) {
+
+ // Check if not real cvsroot => set it to null
+ if ($root !== null) {
+ if (trim($root) == "") {
+ $root = null;
+ }
+ }
+
+ $this->cvsRoot = $root;
+ }
+
+ public function getCvsRoot() {
+ return $this->cvsRoot;
+ }
+
+ /**
+ * The CVS_RSH variable.
+ *
+ * @param rsh
+ */
+ public function setCvsRsh($rsh) {
+ // Check if not real cvsrsh => set it to null
+ if ($rsh !== null) {
+ if (trim($rsh) == "") {
+ $rsh = null;
+ }
+ }
+
+ $this->cvsRsh = $rsh;
+ }
+
+ public function getCvsRsh() {
+ return $this->cvsRsh;
+ }
+
+ /**
+ * Port used by CVS to communicate with the server.
+ *
+ * @param int $port
+ */
+ public function setPort($port){
+ $this->port = $port;
+ }
+
+ /**
+ * @return int
+ */
+ public function getPort() {
+ return $this->port;
+ }
+
+ /**
+ * Password file to read passwords from.
+ *
+ * @param passFile
+ */
+ public function setPassfile(PhingFile $passFile) {
+ $this->passFile = $passFile;
+ }
+
+ /**
+ * @return File
+ */
+ public function getPassFile() {
+ return $this->passFile;
+ }
+
+ /**
+ * The directory where the checked out files should be placed.
+ *
+ * @param PhingFile $dest
+ */
+ public function setDest(PhingFile $dest) {
+ $this->dest = $dest;
+ }
+
+ public function getDest() {
+ return $this->dest;
+ }
+
+ /**
+ * The package/module to operate upon.
+ *
+ * @param string $p
+ */
+ public function setModule($m) {
+ $this->cvsModule = $m;
+ }
+
+ public function getModule(){
+ return $this->cvsModule;
+ }
+
+ /**
+ * The tag of the package/module to operate upon.
+ * @param string $p
+ */
+ public function setTag($p) {
+ // Check if not real tag => set it to null
+ if ($p !== null && trim($p) !== "") {
+ $this->appendCommandArgument("-r");
+ $this->appendCommandArgument($p);
+ }
+ }
+
+ /**
+ * This needs to be public to allow configuration
+ * of commands externally.
+ */
+ public function appendCommandArgument($arg) {
+ $this->cmd->createArgument()->setValue($arg);
+ }
+
+ /**
+ * Use the most recent revision no later than the given date.
+ * @param p
+ */
+ public function setDate($p) {
+ if ($p !== null && trim($p) !== "") {
+ $this->appendCommandArgument("-D");
+ $this->appendCommandArgument($p);
+ }
+ }
+
+ /**
+ * The CVS command to execute.
+ * @param string $c
+ */
+ public function setCommand($c) {
+ $this->command = $c;
+ }
+
+ public function getCommand() {
+ return $this->command;
+ }
+
+ /**
+ * If true, suppress informational messages.
+ * @param boolean $q
+ */
+ public function setQuiet($q) {
+ $this->quiet = $q;
+ }
+
+ /**
+ * If true, report only and don't change any files.
+ *
+ * @param boolean $ne
+ */
+ public function setNoexec($ne) {
+ $this->noexec = (boolean) $ne;
+ }
+
+ /**
+ * Stop the build process if the command exits with
+ * a return code other than 0.
+ * Defaults to false.
+ * @param boolean $failOnError
+ */
+ public function setFailOnError($failOnError) {
+ $this->failOnError = (boolean) $failOnError;
+ }
+
+ /**
+ * Configure a commandline element for things like cvsRoot, quiet, etc.
+ * @return string
+ */
+ protected function configureCommandline($c) {
+ if ($c === null) {
+ return;
+ }
+ $c->setExecutable("cvs");
+
+ if ($this->cvsModule !== null) {
+ $c->createArgument()->setLine($this->cvsModule);
+ }
+ if ($this->compression > 0 && $this->compression < 10) {
+ $c->createArgument(true)->setValue("-z" . $this->compression);
+ }
+ if ($this->quiet) {
+ $c->createArgument(true)->setValue("-q");
+ }
+ if ($this->noexec) {
+ $c->createArgument(true)->setValue("-n");
+ }
+ if ($this->cvsRoot !== null) {
+ $c->createArgument(true)->setLine("-d" . $this->cvsRoot);
+ }
+ }
+
+ protected function removeCommandline(Commandline $c) {
+ $idx = array_search($c, $this->commandlines, true);
+ if ($idx === false) {
+ return false;
+ }
+ $this->commandlines = array_splice($this->commandlines, $idx, 1);
+ return true;
+ }
+
+ /**
+ * Configures and adds the given Commandline.
+ * @param insertAtStart If true, c is
+ */
+ public function addConfiguredCommandline(Commandline $c, $insertAtStart = false) {
+ if ($c === null) {
+ return;
+ }
+ $this->configureCommandline($c);
+ if ($insertAtStart) {
+ array_unshift($this->commandlines, $c);
+ } else {
+ array_push($this->commandlines, $c);
+ }
+ }
+
+ /**
+ * If set to a value 1-9 it adds -zN to the cvs command line, else
+ * it disables compression.
+ * @param int $level
+ */
+ public function setCompressionLevel($level) {
+ $this->compression = $level;
+ }
+
+ /**
+ * If true, this is the same as compressionlevel="3".
+ *
+ * @param boolean $usecomp If true, turns on compression using default
+ * level, AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL.
+ */
+ public function setCompression($usecomp) {
+ $this->setCompressionLevel($usecomp ?
+ self::DEFAULT_COMPRESSION_LEVEL : 0);
+ }
+
+ /**
+ * File to which output should be written.
+ * @param PhingFile $output
+ */
+ function setOutput(PhingFile $f) {
+ $this->output = $f;
+ }
+
+ /**
+ * File to which error output should be written.
+ * @param PhingFile $output
+ */
+ function setError(PhingFile $f) {
+ $this->error = $f;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/DeleteTask.php b/buildscripts/phing/classes/phing/tasks/system/DeleteTask.php
new file mode 100644
index 00000000..00e1e7a7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/DeleteTask.php
@@ -0,0 +1,277 @@
+<?php
+/*
+ * $Id: DeleteTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Deletes a file or directory, or set of files defined by a fileset.
+ *
+ * @version $Revision: 1.13 $
+ * @package phing.tasks.system
+ */
+class DeleteTask extends Task {
+
+ protected $file;
+ protected $dir;
+ protected $filesets = array();
+ protected $includeEmpty = false;
+
+ protected $quiet = false;
+ protected $failonerror = true;
+ protected $verbosity = PROJECT_MSG_VERBOSE;
+
+ /** Any filelists of files that should be deleted. */
+ private $filelists = array();
+
+ /**
+ * Set the name of a single file to be removed.
+ * @param PhingFile $file
+ */
+ function setFile(PhingFile $file) {
+ $this->file = $file;
+ }
+
+ /**
+ * Set the directory from which files are to be deleted.
+ * @param PhingFile $dir
+ */
+ function setDir(PhingFile $dir) {
+ $this->dir = $dir;
+ }
+
+ /**
+ * Used to force listing of all names of deleted files.
+ * @param boolean $verbosity
+ */
+ function setVerbose($verbosity) {
+ if ($verbosity) {
+ $this->verbosity = PROJECT_MSG_INFO;
+ } else {
+ $this->verbosity = PROJECT_MSG_VERBOSE;
+ }
+ }
+
+ /**
+ * If the file does not exist, do not display a diagnostic
+ * message or modify the exit status to reflect an error.
+ * This means that if a file or directory cannot be deleted,
+ * then no error is reported. This setting emulates the
+ * -f option to the Unix rm command. Default is false
+ * meaning things are verbose
+ */
+ function setQuiet($bool) {
+ $this->quiet = $bool;
+ if ($this->quiet) {
+ $this->failonerror = false;
+ }
+ }
+
+ /** this flag means 'note errors to the output, but keep going' */
+ function setFailOnError($bool) {
+ $this->failonerror = $bool;
+ }
+
+
+ /** Used to delete empty directories.*/
+ function setIncludeEmptyDirs($includeEmpty) {
+ $this->includeEmpty = (boolean) $includeEmpty;
+ }
+
+ /** Nested creator, adds a set of files (nested fileset attribute). */
+ function createFileSet() {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /** Nested creator, adds a set of files (nested fileset attribute). */
+ function createFileList() {
+ $num = array_push($this->filelists, new FileList());
+ return $this->filelists[$num-1];
+ }
+
+ /** Delete the file(s). */
+ function main() {
+ if ($this->file === null && $this->dir === null && count($this->filesets) === 0 && count($this->filelists) === 0) {
+ throw new BuildException("At least one of the file or dir attributes, or a fileset element, or a filelist element must be set.");
+ }
+
+ if ($this->quiet && $this->failonerror) {
+ throw new BuildException("quiet and failonerror cannot both be set to true", $this->location);
+ }
+
+ // delete a single file
+ if ($this->file !== null) {
+ if ($this->file->exists()) {
+ if ($this->file->isDirectory()) {
+ $this->log("Directory " . $this->file->__toString() . " cannot be removed using the file attribute. Use dir instead.");
+ } else {
+ $this->log("Deleting: " . $this->file->__toString());
+ try {
+ $this->file->delete();
+ } catch(Exception $e) {
+ $message = "Unable to delete file " . $this->file->__toString() .": " .$e->getMessage();
+ if($this->failonerror) {
+ throw new BuildException($message);
+ } else {
+ $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN);
+ }
+ }
+ }
+ } else {
+ $this->log("Could not find file " . $this->file->getAbsolutePath() . " to delete.",PROJECT_MSG_VERBOSE);
+ }
+ }
+
+ // delete the directory
+ if ($this->dir !== null && $this->dir->exists() && $this->dir->isDirectory()) {
+ if ($this->verbosity === PROJECT_MSG_VERBOSE) {
+ $this->log("Deleting directory " . $this->dir->__toString());
+ }
+ $this->removeDir($this->dir);
+ }
+
+ // delete the files in the filelists
+ foreach($this->filelists as $fl) {
+ try {
+ $files = $fl->getFiles($this->project);
+ $this->removeFiles($fl->getDir($this->project), $files, $empty=array());
+ } catch (BuildException $be) {
+ // directory doesn't exist or is not readable
+ if ($this->failonerror) {
+ throw $be;
+ } else {
+ $this->log($be->getMessage(), $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN);
+ }
+ }
+ }
+
+ // delete the files in the filesets
+ foreach($this->filesets as $fs) {
+ try {
+ $ds = $fs->getDirectoryScanner($this->project);
+ $files = $ds->getIncludedFiles();
+ $dirs = $ds->getIncludedDirectories();
+ $this->removeFiles($fs->getDir($this->project), $files, $dirs);
+ } catch (BuildException $be) {
+ // directory doesn't exist or is not readable
+ if ($this->failonerror) {
+ throw $be;
+ } else {
+ $this->log($be->getMessage(), $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN);
+ }
+ }
+ }
+ }
+
+ /**
+ * Recursively removes a directory.
+ * @param PhingFile $d The directory to remove.
+ */
+ private function removeDir($d) {
+ $list = $d->listDir();
+ if ($list === null) {
+ $list = array();
+ }
+
+ foreach($list as $s) {
+ $f = new PhingFile($d, $s);
+ if ($f->isDirectory()) {
+ $this->removeDir($f);
+ } else {
+ $this->log("Deleting " . $f->__toString(), $this->verbosity);
+ try {
+ $f->delete();
+ } catch (Exception $e) {
+ $message = "Unable to delete file " . $f->__toString() . ": " . $e->getMessage();
+ if($this->failonerror) {
+ throw new BuildException($message);
+ } else {
+ $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN);
+ }
+ }
+ }
+ }
+ $this->log("Deleting directory " . $d->getAbsolutePath(), $this->verbosity);
+ try {
+ $d->delete();
+ } catch (Exception $e) {
+ $message = "Unable to delete directory " . $d->__toString() . ": " . $e->getMessage();
+ if($this->failonerror) {
+ throw new BuildException($message);
+ } else {
+ $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN);
+ }
+ }
+ }
+
+ /**
+ * remove an array of files in a directory, and a list of subdirectories
+ * which will only be deleted if 'includeEmpty' is true
+ * @param PhingFile $d directory to work from
+ * @param array &$files array of files to delete; can be of zero length
+ * @param array &$dirs array of directories to delete; can of zero length
+ */
+ private function removeFiles(PhingFile $d, &$files, &$dirs) {
+ if (count($files) > 0) {
+ $this->log("Deleting " . count($files) . " files from " . $d->__toString());
+ for ($j=0,$_j=count($files); $j < $_j; $j++) {
+ $f = new PhingFile($d, $files[$j]);
+ $this->log("Deleting " . $f->getAbsolutePath(), $this->verbosity);
+ try {
+ $f->delete();
+ } catch (Exception $e) {
+ $message = "Unable to delete file " . $f->__toString() . ": " . $e->getMessage();
+ if($this->failonerror) {
+ throw new BuildException($message);
+ } else {
+ $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN);
+ }
+ }
+
+ }
+ }
+
+ if (count($dirs) > 0 && $this->includeEmpty) {
+ $dirCount = 0;
+ for ($j=count($dirs)-1; $j>=0; --$j) {
+ $dir = new PhingFile($d, $dirs[$j]);
+ $dirFiles = $dir->listDir();
+ if ($dirFiles === null || count($dirFiles) === 0) {
+ $this->log("Deleting " . $dir->__toString(), $this->verbosity);
+ try {
+ $dir->delete();
+ $dirCount++;
+ } catch (Exception $e) {
+ $message="Unable to delete directory " + $dir;
+ if($this->failonerror) {
+ throw new BuildException($message);
+ } else {
+ $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN);
+ }
+ }
+ }
+ }
+ if ($dirCount > 0) {
+ $this->log("Deleted $dirCount director" . ($dirCount==1 ? "y" : "ies") . " from " . $d->__toString());
+ }
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/EchoTask.php b/buildscripts/phing/classes/phing/tasks/system/EchoTask.php
new file mode 100644
index 00000000..229f5130
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/EchoTask.php
@@ -0,0 +1,107 @@
+<?php
+/*
+ * $Id: EchoTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Echos a message to the logging system or to a file
+ *
+ * @author Michiel Rook <michiel@trendserver.nl>
+ * @author Andreas Aderhold, andi@binarycloud.com
+ * @version $Revision: 1.5 $ $Date: 2006-04-28 10:49:47 -0400 (Fri, 28 Apr 2006) $
+ * @package phing.tasks.system
+ */
+
+class EchoTask extends Task {
+
+ protected $msg = "";
+
+ protected $file = "";
+
+ protected $append = false;
+
+ protected $level = "info";
+
+ function main() {
+ switch ($this->level)
+ {
+ case "error": $loglevel = PROJECT_MSG_ERR; break;
+ case "warning": $loglevel = PROJECT_MSG_WARN; break;
+ case "info": $loglevel = PROJECT_MSG_INFO; break;
+ case "verbose": $loglevel = PROJECT_MSG_VERBOSE; break;
+ case "debug": $loglevel = PROJECT_MSG_DEBUG; break;
+ }
+
+ if (empty($this->file))
+ {
+ $this->log($this->msg, $loglevel);
+ }
+ else
+ {
+ if ($this->append)
+ {
+ $handle = fopen($this->file, "a");
+ }
+ else
+ {
+ $handle = fopen($this->file, "w");
+ }
+
+ fwrite($handle, $this->msg);
+
+ fclose($handle);
+ }
+ }
+
+ /** setter for file */
+ function setFile($file)
+ {
+ $this->file = (string) $file;
+ }
+
+ /** setter for level */
+ function setLevel($level)
+ {
+ $this->level = (string) $level;
+ }
+
+ /** setter for append */
+ function setAppend($append)
+ {
+ $this->append = $append;
+ }
+
+ /** setter for message */
+ function setMsg($msg) {
+ $this->setMessage($msg);
+ }
+
+ /** alias setter */
+ function setMessage($msg) {
+ $this->msg = (string) $msg;
+ }
+
+ /** Supporting the <echo>Message</echo> syntax. */
+ function addText($msg)
+ {
+ $this->msg = (string) $msg;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/ExecTask.php b/buildscripts/phing/classes/phing/tasks/system/ExecTask.php
new file mode 100644
index 00000000..104f7697
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/ExecTask.php
@@ -0,0 +1,248 @@
+<?php
+
+/*
+ * $Id: ExecTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Executes a command on the shell.
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.17 $
+ * @package phing.tasks.system
+ */
+class ExecTask extends Task {
+
+ /**
+ * Command to execute.
+ * @var string
+ */
+ protected $command;
+
+ /**
+ * Working directory.
+ * @var File
+ */
+ protected $dir;
+
+ /**
+ * Operating system.
+ * @var string
+ */
+ protected $os;
+
+ /**
+ * Whether to escape shell command using escapeshellcmd().
+ * @var boolean
+ */
+ protected $escape = false;
+
+ /**
+ * Where to direct output.
+ * @var File
+ */
+ protected $output;
+
+ /**
+ * Whether to passthru the output
+ * @var boolean
+ */
+ protected $passthru = false;
+
+ /**
+ * Where to direct error output.
+ * @var File
+ */
+ protected $error;
+
+ /**
+ * If spawn is set then [unix] programs will redirect stdout and add '&'.
+ * @var boolean
+ */
+ protected $spawn = false;
+
+ /**
+ * Whether to check the return code.
+ * @var boolean
+ */
+ protected $checkreturn = false;
+
+ /**
+ * Main method: wraps execute() command.
+ * @return void
+ */
+ public function main() {
+ $this->execute();
+ }
+
+ /**
+ * Executes a program and returns the return code.
+ * Output from command is logged at INFO level.
+ * @return int Return code from execution.
+ */
+ public function execute() {
+
+ // test if os match
+ $myos = Phing::getProperty("os.name");
+ $this->log("Myos = " . $myos, PROJECT_MSG_VERBOSE);
+ if (($this->os !== null) && (strpos($os, $myos) === false)) {
+ // this command will be executed only on the specified OS
+ $this->log("Not found in " . $os, PROJECT_MSG_VERBOSE);
+ return 0;
+ }
+
+ if ($this->dir !== null) {
+ if ($this->dir->isDirectory()) {
+ $currdir = getcwd();
+ @chdir($this->dir->getPath());
+ } else {
+ throw new BuildException("Can't chdir to:" . $this->dir->__toString());
+ }
+ }
+
+
+ if ($this->escape == true) {
+ // FIXME - figure out whether this is correct behavior
+ $this->command = escapeshellcmd($this->command);
+ }
+
+ if ($this->error !== null) {
+ $this->command .= ' 2> ' . $this->error->getPath();
+ $this->log("Writing error output to: " . $this->error->getPath());
+ }
+
+ if ($this->output !== null) {
+ $this->command .= ' 1> ' . $this->output->getPath();
+ $this->log("Writing standard output to: " . $this->output->getPath());
+ } elseif ($this->spawn) {
+ $this->command .= ' 1>/dev/null';
+ $this->log("Sending ouptut to /dev/null");
+ }
+
+ // If neither output nor error are being written to file
+ // then we'll redirect error to stdout so that we can dump
+ // it to screen below.
+
+ if ($this->output === null && $this->error === null) {
+ $this->command .= ' 2>&1';
+ }
+
+ // we ignore the spawn boolean for windows
+ if ($this->spawn) {
+ $this->command .= ' &';
+ }
+
+ $this->log("Executing command: " . $this->command);
+
+ $output = array();
+ $return = null;
+ exec($this->command, $output, $return);
+
+ if ($this->dir !== null) {
+ @chdir($currdir);
+ }
+
+ foreach($output as $line) {
+ $this->log($line, ($this->passthru ? PROJECT_MSG_INFO : PROJECT_MSG_VERBOSE));
+ }
+
+ if($return != 0 && $this->checkreturn)
+ {
+ throw new BuildException("Task exited with code $return");
+ }
+
+ return $return;
+ }
+
+ /**
+ * The command to use.
+ * @param mixed $command String or string-compatible (e.g. w/ __toString()).
+ */
+ function setCommand($command) {
+ $this->command = "" . $command;
+ }
+
+ /**
+ * Whether to use escapeshellcmd() to escape command.
+ * @param boolean $escape
+ */
+ function setEscape($escape) {
+ $this->escape = (bool) $escape;
+ }
+
+ /**
+ * Specify the workign directory for executing this command.
+ * @param PhingFile $dir
+ */
+ function setDir(PhingFile $dir) {
+ $this->dir = $dir;
+ }
+
+ /**
+ * Specify OS (or muliple OS) that must match in order to execute this command.
+ * @param string $os
+ */
+ function setOs($os) {
+ $this->os = (string) $os;
+ }
+
+ /**
+ * File to which output should be written.
+ * @param PhingFile $output
+ */
+ function setOutput(PhingFile $f) {
+ $this->output = $f;
+ }
+
+ /**
+ * File to which error output should be written.
+ * @param PhingFile $output
+ */
+ function setError(PhingFile $f) {
+ $this->error = $f;
+ }
+
+ /**
+ * Whether to use passthru the output.
+ * @param boolean $passthru
+ */
+ function setPassthru($passthru) {
+ $this->passthru = (bool) $passthru;
+ }
+
+ /**
+ * Whether to suppress all output and run in the background.
+ * @param boolean $spawn
+ */
+ function setSpawn($spawn) {
+ $this->spawn = (bool) $spawn;
+ }
+
+ /**
+ * Whether to check the return code.
+ * @param boolean $checkreturn
+ */
+ function setCheckreturn($checkreturn) {
+ $this->checkreturn = (bool) $checkreturn;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/system/ExitTask.php b/buildscripts/phing/classes/phing/tasks/system/ExitTask.php
new file mode 100644
index 00000000..7e08d369
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/ExitTask.php
@@ -0,0 +1,118 @@
+<?php
+/*
+ * $Id: ExitTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Exits the active build, giving an additional message
+ * if available.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Nico Seessle <nico@seessle.de> (Ant)
+ * @version $Revision: 1.7 $
+ * @package phing.tasks.system
+ */
+class ExitTask extends Task {
+
+ private $message;
+ private $ifCondition;
+ private $unlessCondition;
+
+ /**
+ * A message giving further information on why the build exited.
+ *
+ * @param string $value message to output
+ */
+ public function setMsg($value) {
+ $this->setMessage($value);
+ }
+
+ /**
+ * A message giving further information on why the build exited.
+ *
+ * @param value message to output
+ */
+ public function setMessage($value) {
+ $this->message = $value;
+ }
+
+ /**
+ * Only fail if a property of the given name exists in the current project.
+ * @param c property name
+ */
+ public function setIf($c) {
+ $this->ifCondition = $c;
+ }
+
+ /**
+ * Only fail if a property of the given name does not
+ * exist in the current project.
+ * @param c property name
+ */
+ public function setUnless($c) {
+ $this->unlessCondition = $c;
+ }
+
+ /**
+ * @throws BuildException
+ */
+ public function main() {
+ if ($this->testIfCondition() && $this->testUnlessCondition()) {
+ if ($this->message !== null) {
+ throw new BuildException($this->message);
+ } else {
+ throw new BuildException("No message");
+ }
+ }
+ }
+
+ /**
+ * Set a multiline message.
+ */
+ public function addText($msg) {
+ if ($this->message === null) {
+ $this->message = "";
+ }
+ $this->message .= $this->project->replaceProperties($msg);
+ }
+
+ /**
+ * @return boolean
+ */
+ private function testIfCondition() {
+ if ($this->ifCondition === null || $this->ifCondition === "") {
+ return true;
+ }
+
+ return $this->project->getProperty($this->ifCondition) !== null;
+ }
+
+ /**
+ * @return boolean
+ */
+ private function testUnlessCondition() {
+ if ($this->unlessCondition === null || $this->unlessCondition === "") {
+ return true;
+ }
+ return $this->project->getProperty($this->unlessCondition) === null;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/ForeachTask.php b/buildscripts/phing/classes/phing/tasks/system/ForeachTask.php
new file mode 100644
index 00000000..a2a42665
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/ForeachTask.php
@@ -0,0 +1,138 @@
+<?php
+/*
+ * $Id: ForeachTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/tasks/system/PhingTask.php';
+
+/**
+ * <foreach> task
+ *
+ * Task definition for the foreach task. This task takes a list with
+ * delimited values, and executes a target with set param.
+ *
+ * Usage:
+ * <foreach list="values" target="targ" param="name" delimiter="|" />
+ *
+ * Attributes:
+ * list --> The list of values to process, with the delimiter character,
+ * indicated by the "delimiter" attribute, separating each value.
+ * target --> The target to call for each token, passing the token as the
+ * parameter with the name indicated by the "param" attribute.
+ * param --> The name of the parameter to pass the tokens in as to the
+ * target.
+ * delimiter --> The delimiter string that separates the values in the "list"
+ * parameter. The default is ",".
+ *
+ * @author Jason Hines <jason@greenhell.com>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.9 $
+ * @package phing.tasks.system
+ */
+class ForeachTask extends Task {
+
+ /** Delimter-separated list of values to process. */
+ private $list;
+
+ /** Name of parameter to pass to callee */
+ private $param;
+
+ /** Delimter that separates items in $list */
+ private $delimiter = ',';
+
+ /**
+ * PhingCallTask that will be invoked w/ calleeTarget.
+ * @var PhingCallTask
+ */
+ private $callee;
+
+ /**
+ * Target to execute.
+ * @var string
+ */
+ private $calleeTarget;
+
+ function init() {
+ $this->callee = $this->project->createTask("phingcall");
+ $this->callee->setOwningTarget($this->getOwningTarget());
+ $this->callee->setTaskName($this->getTaskName());
+ $this->callee->setLocation($this->getLocation());
+ $this->callee->init();
+ }
+
+ /**
+ * This method does the work.
+ * @return void
+ */
+ function main() {
+ if ($this->list === null) {
+ throw new BuildException("Missing list to iterate through");
+ }
+ if (trim($this->list) === '') {
+ return;
+ }
+ if ($this->param === null) {
+ throw new BuildException("You must supply a property name to set on each iteration in param");
+ }
+ if ($this->calleeTarget === null) {
+ throw new BuildException("You must supply a target to perform");
+ }
+
+ $callee = $this->callee;
+ $callee->setTarget($this->calleeTarget);
+ $callee->setInheritAll(true);
+ $callee->setInheritRefs(true);
+
+ $arr = explode($this->delimiter, $this->list);
+
+ foreach ($arr as $value) {
+ $this->log("Setting param '$this->param' to value '$value'", PROJECT_MSG_VERBOSE);
+ $prop = $callee->createProperty();
+ $prop->setOverride(true);
+ $prop->setName($this->param);
+ $prop->setValue($value);
+ $callee->main();
+ }
+ }
+
+ function setList($list) {
+ $this->list = (string) $list;
+ }
+
+ function setTarget($target) {
+ $this->calleeTarget = (string) $target;
+ }
+
+ function setParam($param) {
+ $this->param = (string) $param;
+ }
+
+ function setDelimiter($delimiter) {
+ $this->delimiter = (string) $delimiter;
+ }
+
+ /**
+ * @return Property
+ */
+ function createProperty() {
+ return $this->callee->createProperty();
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/IfTask.php b/buildscripts/phing/classes/phing/tasks/system/IfTask.php
new file mode 100644
index 00000000..ab773355
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/IfTask.php
@@ -0,0 +1,224 @@
+<?php
+
+/*
+ * $Id: IfTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/condition/ConditionBase.php';
+require_once 'phing/tasks/system/SequentialTask.php';
+
+/**
+ * Perform some tasks based on whether a given condition holds true or
+ * not.
+ *
+ * <p>This task is heavily based on the Condition framework that can
+ * be found in Ant 1.4 and later, therefore it cannot be used in
+ * conjunction with versions of Ant prior to 1.4.</p>
+ *
+ * <p>This task doesn't have any attributes, the condition to test is
+ * specified by a nested element - see the documentation of your
+ * <code><condition&gt;</code> task (see
+ * <a href="http://jakarta.apache.org/ant/manual/CoreTasks/condition.html">the
+ * online documentation</a> for example) for a complete list of nested
+ * elements.</p>
+ *
+ * <p>Just like the <code><condition&gt;</code> task, only a single
+ * condition can be specified - you combine them using
+ * <code><and&gt;</code> or <code><or&gt;</code> conditions.</p>
+ *
+ * <p>In addition to the condition, you can specify three different
+ * child elements, <code><elseif&gt;</code>, <code><then&gt;</code> and
+ * <code><else&gt;</code>. All three subelements are optional.
+ *
+ * Both <code><then&gt;</code> and <code><else&gt;</code> must not be
+ * used more than once inside the if task. Both are
+ * containers for Ant tasks, just like Ant's
+ * <code><parallel&gt;</code> and <code><sequential&gt;</code>
+ * tasks - in fact they are implemented using the same class as Ant's
+ * <code><sequential&gt;</code> task.</p>
+ *
+ * The <code><elseif&gt;</code> behaves exactly like an <code><if&gt;</code>
+ * except that it cannot contain the <code><else&gt;</code> element
+ * inside of it. You may specify as may of these as you like, and the
+ * order they are specified is the order they are evaluated in. If the
+ * condition on the <code><if&gt;</code> is false, then the first
+ * <code><elseif&gt;</code> who's conditional evaluates to true
+ * will be executed. The <code><else&gt;</code> will be executed
+ * only if the <code><if&gt;</code> and all <code><elseif&gt;</code>
+ * conditions are false.
+ *
+ * <p>Use the following task to define the <code><if&gt;</code>
+ * task before you use it the first time:</p>
+ *
+ * <pre><code>
+ * <taskdef name="if" classname="net.sf.antcontrib.logic.IfTask" /&gt;
+ * </code></pre>
+ *
+ * <h3>Crude Example</h3>
+ *
+ * <code>
+ * <if>
+ * <equals arg1="${foo}" arg2="bar" />
+ * <then>
+ * <echo message="The value of property foo is bar" />
+ * </then>
+ * <else>
+ * <echo message="The value of property foo is not bar" />
+ * </else>
+ * </if>
+ * </code>
+ *
+ * <code>
+ * <if>
+ * <equals arg1="${foo}" arg2="bar" /&gt;
+ * <then>
+ * <echo message="The value of property foo is 'bar'" />
+ * </then>
+ *
+ * <elseif>
+ * <equals arg1="${foo}" arg2="foo" />
+ * <then>
+ * <echo message="The value of property foo is 'foo'" />
+ * </then>
+ * </elseif>
+ *
+ * <else>
+ * <echo message="The value of property foo is not 'foo' or 'bar'" />
+ * </else>
+ * </if>
+ * </code>
+ *
+ * @author <a href="mailto:stefan.bodewig@freenet.de">Stefan Bodewig</a>
+ */
+class IfTask extends ConditionBase {
+
+
+ private $thenTasks = null;
+ private $elseIfTasks = array();
+ private $elseTasks = null;
+
+ /***
+ * A nested Else if task
+ */
+ public function addElseIf(ElseIfTask $ei)
+ {
+ $this->elseIfTasks[] = $ei;
+ }
+
+ /**
+ * A nested <then> element - a container of tasks that will
+ * be run if the condition holds true.
+ *
+ * <p>Not required.</p>
+ */
+ public function addThen(SequentialTask $t) {
+ if ($this->thenTasks != null) {
+ throw new BuildException("You must not nest more than one <then> into <if>");
+ }
+ $this->thenTasks = $t;
+ }
+
+ /**
+ * A nested <else> element - a container of tasks that will
+ * be run if the condition doesn't hold true.
+ *
+ * <p>Not required.</p>
+ */
+ public function addElse(SequentialTask $e) {
+ if ($this->elseTasks != null) {
+ throw new BuildException("You must not nest more than one <else> into <if>");
+ }
+ $this->elseTasks = $e;
+ }
+
+ public function main() {
+
+ if ($this->countConditions() > 1) {
+ throw new BuildException("You must not nest more than one condition into <if>");
+ }
+ if ($this->countConditions() < 1) {
+ throw new BuildException("You must nest a condition into <if>");
+ }
+ $conditions = $this->getConditions();
+ $c = $conditions[0];
+
+ if ($c->evaluate()) {
+ if ($this->thenTasks != null) {
+ $this->thenTasks->main();
+ }
+ } else {
+ $done = false;
+ $sz = count($this->elseIfTasks);
+ for($i=0; $i < $sz && !$done; $i++) {
+ $ei = $this->elseIfTasks[$i];
+ if ($ei->evaluate()) {
+ $done = true;
+ $ei->main();
+ }
+ }
+
+ if (!$done && $this->elseTasks != null) {
+ $this->elseTasks->main();
+ }
+ }
+ }
+}
+
+/**
+ * "Inner" class for IfTask.
+ * This class has same basic structure as the IfTask, although of course it doesn't support <else> tags.
+ */
+class ElseIfTask extends ConditionBase {
+
+ private $thenTasks = null;
+
+ public function addThen(SequentialTask $t) {
+ if ($this->thenTasks != null) {
+ throw new BuildException("You must not nest more than one <then> into <elseif>");
+ }
+ $this->thenTasks = $t;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function evaluate() {
+
+ if ($this->countConditions() > 1) {
+ throw new BuildException("You must not nest more than one condition into <elseif>");
+ }
+ if ($this->countConditions() < 1) {
+ throw new BuildException("You must nest a condition into <elseif>");
+ }
+
+ $conditions = $this->getConditions();
+ $c = $conditions[0];
+
+ return $c->evaluate();
+ }
+
+ /**
+ *
+ */
+ public function main() {
+ if ($this->thenTasks != null) {
+ $this->thenTasks->main();
+ }
+ }
+ } \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/system/IncludePathTask.php b/buildscripts/phing/classes/phing/tasks/system/IncludePathTask.php
new file mode 100644
index 00000000..ce9beee5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/IncludePathTask.php
@@ -0,0 +1,115 @@
+<?php
+
+/*
+ * $Id: IncludePathTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/types/Path.php';
+
+/**
+ * Adds a normalized path to the PHP include_path.
+ *
+ * This provides a way to alter the include_path without editing any global php.ini settings
+ * or PHP_CLASSPATH environment variable.
+ *
+ * <code>
+ * <includepath classpath="new/path/here"/>
+ * </code>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.1 $
+ * @package phing.tasks.system
+ */
+class IncludePathTask extends Task {
+
+ /**
+ * Classname of task to register.
+ * This can be a dot-path -- relative to a location on PHP include_path.
+ * E.g. path.to.MyClass -> path/to/MyClass.php
+ * @var string
+ */
+ private $classname;
+
+ /**
+ * Path to add to PHP include_path to aid in finding specified class.
+ * @var Path
+ */
+ private $classpath;
+
+ /**
+ * Refid to already defined classpath
+ */
+ private $classpathId;
+
+ /**
+ * 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->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->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) {
+ $this->classpathId = $r->getRefId();
+ $this->createClasspath()->setRefid($r);
+ }
+
+
+ /** Main entry point */
+ public function main() {
+
+ // Apparently casting to (string) no longer invokes __toString() automatically.
+ if (is_object($this->classpath)) {
+ $this->classpath = $this->classpath->__toString();
+ }
+
+ if (empty($this->classpath)) {
+ throw new BuildException("Provided classpath was empty.");
+ }
+
+ $curr_parts = explode(PATH_SEPARATOR, get_include_path());
+ $add_parts = explode(PATH_SEPARATOR, $this->classpath);
+ $new_parts = array_diff($add_parts, $curr_parts);
+
+ if ($new_parts) {
+ $this->log("Prepending new include_path components: " . implode(PATH_SEPARATOR, $new_parts), PROJECT_MSG_VERBOSE);
+ set_include_path(implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts)));
+ }
+
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/InputTask.php b/buildscripts/phing/classes/phing/tasks/system/InputTask.php
new file mode 100644
index 00000000..a5e1fdb9
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/InputTask.php
@@ -0,0 +1,146 @@
+<?php
+/*
+ * $Id: InputTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/input/InputRequest.php';
+include_once 'phing/input/YesNoInputRequest.php';
+include_once 'phing/input/MultipleChoiceInputRequest.php';
+
+/**
+ * Reads input from the InputHandler.
+ *
+ * @see Project::getInputHandler()
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Ulrich Schmidt <usch@usch.net> (Ant)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.6 $
+ * @package phing.tasks.system
+ */
+class InputTask extends Task {
+
+ private $validargs;
+ private $message = ""; // required
+ private $propertyName; // required
+ private $defaultValue;
+ private $promptChar;
+
+ /**
+ * Defines valid input parameters as comma separated strings. If set, input
+ * task will reject any input not defined as accepted and requires the user
+ * to reenter it. Validargs are case sensitive. If you want 'a' and 'A' to
+ * be accepted you need to define both values as accepted arguments.
+ *
+ * @param validargs A comma separated String defining valid input args.
+ */
+ public function setValidargs ($validargs) {
+ $this->validargs = $validargs;
+ }
+
+ /**
+ * Defines the name of a property to be set from input.
+ *
+ * @param string $name Name for the property to be set from input
+ */
+ public function setPropertyName($name) {
+ $this->propertyName = $name;
+ }
+
+ /**
+ * Sets the Message which gets displayed to the user during the build run.
+ * @param message The message to be displayed.
+ */
+ public function setMessage ($message) {
+ $this->message = $message;
+ }
+
+ /**
+ * Set a multiline message.
+ */
+ public function addText($msg) {
+ $this->message .= $this->project->replaceProperties($msg);
+ }
+
+ /**
+ * Add a default value.
+ * @param string $v
+ */
+ public function setDefaultValue($v) {
+ $this->defaultValue = $v;
+ }
+
+ /**
+ * Set the character/string to use for the prompt.
+ * @param string $c
+ */
+ public function setPromptChar($c) {
+ $this->promptChar = $c;
+ }
+
+ /**
+ * Actual method executed by phing.
+ * @throws BuildException
+ */
+ public function main() {
+
+ if ($this->propertyName === null) {
+ throw new BuildException("You must specify a value for propertyName attribute.");
+ }
+
+ if ($this->validargs !== null) {
+ $accept = preg_split('/[\s,]+/', $this->validargs);
+
+ // is it a boolean (yes/no) inputrequest?
+ $yesno = false;
+ if (count($accept) == 2) {
+ $yesno = true;
+ foreach($accept as $ans) {
+ if(!StringHelper::isBoolean($ans)) {
+ $yesno = false;
+ break;
+ }
+ }
+ }
+ if ($yesno) $request = new YesNoInputRequest($this->message, $accept);
+ else $request = new MultipleChoiceInputRequest($this->message, $accept);
+ } else {
+ $request = new InputRequest($this->message);
+ }
+
+ // default default is curr prop value
+ $request->setDefaultValue($this->project->getProperty($this->propertyName));
+
+ $request->setPromptChar($this->promptChar);
+
+ // unless overridden...
+ if ($this->defaultValue !== null) {
+ $request->setDefaultValue($this->defaultValue);
+ }
+
+ $this->project->getInputHandler()->handleInput($request);
+
+ $value = $request->getInput();
+
+ if ($value !== null) {
+ $this->project->setUserProperty($this->propertyName, $value);
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/MatchingTask.php b/buildscripts/phing/classes/phing/tasks/system/MatchingTask.php
new file mode 100644
index 00000000..c5497fbd
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/MatchingTask.php
@@ -0,0 +1,361 @@
+<?php
+/*
+ * $Id: MatchingTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+require_once 'phing/types/selectors/SelectorContainer.php';
+include_once 'phing/types/FileSet.php';
+include_once 'phing/types/PatternSet.php';
+include_once 'phing/util/DirectoryScanner.php';
+
+/**
+ * This is an abstract task that should be used by all those tasks that
+ * require to include or exclude files based on pattern matching.
+ *
+ * This is very closely based on the ANT class of the same name.
+ *
+ * @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 Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version $Revision: 1.4 $
+ * @package phing.tasks.system
+ */
+abstract class MatchingTask extends Task implements SelectorContainer {
+
+ /** @var boolean */
+ protected $useDefaultExcludes = true;
+
+ /** @var FileSet */
+ protected $fileset;
+
+ /**
+ * Create instance; set fileset to new FileSet.
+ */
+ public function __construct() {
+ $this->fileset = new FileSet();
+ }
+
+ /**
+ * @see ProjectComponent::setProject()
+ */
+ public function setProject(Project $project) {
+ parent::setProject($project);
+ $this->fileset->setProject($project);
+ }
+
+ /**
+ * add a name entry on the include list
+ * @return PatternSetNameEntry
+ */
+ public function createInclude() {
+ return $this->fileset->createInclude();
+ }
+
+ /**
+ * add a name entry on the include files list
+ * @return PatternSetNameEntry
+ */
+ public function createIncludesFile() {
+ return $this->fileset->createIncludesFile();
+ }
+
+ /**
+ * add a name entry on the exclude list
+ * @return PatternSetNameEntry
+ */
+ public function createExclude() {
+ return $this->fileset->createExclude();
+ }
+
+ /**
+ * add a name entry on the include files list
+ * @return PatternSetNameEntry
+ */
+ public function createExcludesFile() {
+ return $this->fileset->createExcludesFile();
+ }
+
+ /**
+ * add a set of patterns
+ * @return PatternSet
+ */
+ public function createPatternSet() {
+ return $this->fileset->createPatternSet();
+ }
+
+ /**
+ * Sets the set of include patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param string $includes the string containing the include patterns
+ * @return void
+ */
+ public function setIncludes($includes) {
+ $this->fileset->setIncludes($includes);
+ }
+
+ /**
+ * Sets the set of exclude patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param string $excludes the string containing the exclude patterns
+ */
+ public function setExcludes($excludes) {
+ $this->fileset->setExcludes($excludes);
+ }
+
+
+ /**
+ * Sets whether default exclusions should be used or not.
+ *
+ * @param boolean $useDefaultExcludes "true"|"on"|"yes" when default exclusions
+ * should be used, "false"|"off"|"no" when they
+ * shouldn't be used.
+ */
+ public function setDefaultexcludes($useDefaultExcludes) {
+ $this->useDefaultExcludes = (boolean) $useDefaultExcludes;
+ }
+
+ /**
+ * Returns the directory scanner needed to access the files to process.
+ * @return DirectoryScanner
+ */
+ protected function getDirectoryScanner(PhingFile $baseDir) {
+ $this->fileset->setDir($baseDir);
+ $this->fileset->setDefaultexcludes($this->useDefaultExcludes);
+ return $this->fileset->getDirectoryScanner($this->project);
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param PhingFile $includesfile A string containing the filename to fetch
+ * the include patterns from.
+ * @return void
+ */
+ public function setIncludesfile(PhingFile $includesfile) {
+ $this->fileset->setIncludesfile(includesfile);
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param PhingFile $excludesfile A string containing the filename to fetch
+ * the include patterns from.
+ * @return void
+ */
+ public function setExcludesfile(PhingFile $excludesfile) {
+ $this->fileset->setExcludesfile($excludesfile);
+ }
+
+ /**
+ * Sets case sensitivity of the file system
+ *
+ * @param boolean $isCaseSensitive "true"|"on"|"yes" if file system is case
+ * sensitive, "false"|"off"|"no" when not.
+ * @return void
+ */
+ public function setCaseSensitive($isCaseSensitive) {
+ $this->fileset->setCaseSensitive($isCaseSensitive);
+ }
+
+ /**
+ * Sets whether or not symbolic links should be followed.
+ *
+ * @param boolean $followSymlinks whether or not symbolic links should be followed
+ * @return void
+ */
+ public function setFollowSymlinks($followSymlinks) {
+ $this->fileset->setFollowSymlinks($followSymlinks);
+ }
+
+ /**
+ * Indicates whether there are any selectors here.
+ *
+ * @return boolean Whether any selectors are in this container
+ */
+ public function hasSelectors() {
+ return $this->fileset->hasSelectors();
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container
+ *
+ * @return int The number of selectors in this container
+ */
+ public function selectorCount() {
+ return $this->fileset->selectorCount();
+ }
+
+ /**
+ * Returns the set of selectors as an array.
+ *
+ * @return array FileSelector[] An array of selectors in this container
+ */
+ public function getSelectors(Project $p) {
+ return $this->fileset->getSelectors($p);
+ }
+
+ /**
+ * Returns an enumerator for accessing the set of selectors.
+ *
+ * @return an enumerator that goes through each of the selectors
+ */
+ public function selectorElements() {
+ return $this->fileset->selectorElements();
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param FileSelector $selector the new selector to add
+ * @return void
+ */
+ public function appendSelector(FileSelector $selector) {
+ $this->fileset->appendSelector($selector);
+ }
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * add a "Select" selector entry on the selector list
+ * @return SelectSelector
+ */
+ public function createSelector() {
+ return $this->fileset->createSelector();
+ }
+
+ /**
+ * add an "And" selector entry on the selector list
+ * @return AndSelector
+ */
+ public function createAnd() {
+ return $this->fileset->createAnd();
+ }
+
+ /**
+ * add an "Or" selector entry on the selector list
+ * @return void
+ */
+ public function createOr() {
+ return $this->fileset->createOr();
+ }
+
+ /**
+ * add a "Not" selector entry on the selector list
+ * @return NotSelector
+ */
+ public function createNot() {
+ return $this->fileset->createNot();
+ }
+
+ /**
+ * add a "None" selector entry on the selector list
+ * @return NoneSelector
+ */
+ public function createNone() {
+ return $this->fileset->createNone();
+ }
+
+ /**
+ * add a majority selector entry on the selector list
+ * @return MajoritySelector
+ */
+ public function createMajority() {
+ return $this->fileset->createMajority();
+ }
+
+ /**
+ * add a selector date entry on the selector list
+ * @return DateSelector
+ */
+ public function createDate() {
+ return $this->fileset->addDate();
+ }
+
+ /**
+ * add a selector size entry on the selector list
+ * @return SizeSelector
+ */
+ public function createSize() {
+ return $this->fileset->createSize();
+ }
+
+ /**
+ * add a selector filename entry on the selector list
+ * @return FilenameSelector
+ */
+ public function createFilename() {
+ return $this->fileset->createFilename();
+ }
+
+ /**
+ * add an extended selector entry on the selector list
+ * @return ExtendSelector
+ */
+ public function createCustom() {
+ return $this->fileset->createCustom();
+ }
+
+ /**
+ * add a contains selector entry on the selector list
+ * @return ContainsSelector
+ */
+ public function createContains() {
+ return $this->fileset->createContains();
+ }
+
+ /**
+ * add a present selector entry on the selector list
+ * @return PresentSelector
+ */
+ public function createPresent() {
+ return $this->fileset->createPresent();
+ }
+
+ /**
+ * add a depth selector entry on the selector list
+ * @return DepthSelector
+ */
+ public function createDepth() {
+ return $this->fileset->createDepth();
+ }
+
+ /**
+ * add a depends selector entry on the selector list
+ * @return DependSelector
+ */
+ public function createDepend() {
+ return $this->fileset->createDepend();
+ }
+
+ /**
+ * Accessor for the implict fileset.
+ *
+ * @return FileSet
+ */
+ protected final function getImplicitFileSet() {
+ return $this->fileset;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/MkdirTask.php b/buildscripts/phing/classes/phing/tasks/system/MkdirTask.php
new file mode 100644
index 00000000..9d5c1f31
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/MkdirTask.php
@@ -0,0 +1,64 @@
+<?php
+/*
+ * $Id: MkdirTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Task to create a directory.
+ *
+ * @author Andreas Aderhold, andi@binarycloud.com
+ * @version $Revision: 1.8 $
+ * @package phing.tasks.system
+ */
+class MkdirTask extends Task {
+
+ /** directory to create*/
+ private $dir;
+
+ /**
+ * create the directory and all parents
+ *
+ * @throws BuildException if dir is somehow invalid, or creation failed.
+ */
+ function main() {
+ if ($this->dir === null) {
+ throw new BuildException("dir attribute is required", $this->location);
+ }
+ if ($this->dir->isFile()) {
+ throw new BuildException("Unable to create directory as a file already exists with that name: " . $this->dir->getAbsolutePath());
+ }
+ if (!$this->dir->exists()) {
+ $result = $this->dir->mkdirs();
+ if (!$result) {
+ $msg = "Directory " . $this->dir->getAbsolutePath() . " creation was not successful for an unknown reason";
+ throw new BuildException($msg, $this->location);
+ }
+ $this->log("Created dir: " . $this->dir->getAbsolutePath());
+ }
+ }
+
+ /** the directory to create; required. */
+ function setDir(PhingFile $dir) {
+ $this->dir = $dir;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/MoveTask.php b/buildscripts/phing/classes/phing/tasks/system/MoveTask.php
new file mode 100644
index 00000000..a3e94536
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/MoveTask.php
@@ -0,0 +1,197 @@
+<?php
+/*
+ * $Id: MoveTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/CopyTask.php';
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/system/io/IOException.php';
+
+/**
+ * Moves a file or directory to a new file or directory.
+ *
+ * By default, the destination file is overwritten if it
+ * already exists. When overwrite is turned off, then files
+ * are only moved if the source file is newer than the
+ * destination file, or when the destination file does not
+ * exist.
+ *
+ * Source files and directories are only deleted when the file or
+ * directory has been copied to the destination successfully.
+ *
+ * @version $Revision: 1.8 $
+ * @package phing.tasks.system
+ */
+class MoveTask extends CopyTask {
+
+ function __construct() {
+ parent::__construct();
+ $this->forceOverwrite = true;
+ }
+
+ protected function doWork() {
+
+ $copyMapSize = count($this->fileCopyMap);
+ if ($copyMapSize > 0) {
+ // files to move
+ $this->log("Moving $copyMapSize files to " . $this->destDir->getAbsolutePath());
+
+ foreach($this->fileCopyMap as $from => $to) {
+ if ($from == $to) {
+ $this->log("Skipping self-move of $from", $this->verbosity);
+ continue;
+ }
+
+ $moved = false;
+ $f = new PhingFile($from);
+ $d = new PhingFile($to);
+
+ $moved = false;
+ try { // try to rename
+ $this->log("Attempting to rename $from to $to", $this->verbosity);
+ $this->renameFile($f, $d, $this->forceOverwrite);
+ $moved = true;
+ } catch (IOException $ioe) {
+ $moved = false;
+ $this->log("Failed to rename $from to $to: " . $ioe->getMessage(), $this->verbosity);
+ }
+
+ if (!$moved) {
+ try { // try to move
+ $this->log("Moving $from to $to", $this->verbosity);
+
+ $this->fileUtils->copyFile($f, $d, $this->forceOverwrite, $this->preserveLMT, $this->filterChains, $this->getProject());
+
+ $f = new PhingFile($fromFile);
+ $f->delete();
+ } catch (IOException $ioe) {
+ $msg = "Failed to move $from to $to: " . $ioe->getMessage();
+ throw new BuildException($msg, $this->location);
+ }
+ } // if !moved
+ } // foreach fileCopyMap
+ } // if copyMapSize
+
+ // handle empty dirs if appropriate
+ if ($this->includeEmpty) {
+ $e = array_keys($this->dirCopyMap);
+ $count = 0;
+ foreach ($e as $dir) {
+ $d = new PhingFile((string) $dir);
+ if (!$d->exists()) {
+ if (!$d->mkdirs()) {
+ $this->log("Unable to create directory " . $d->getAbsolutePath(), PROJECT_MSG_ERR);
+ } else {
+ $count++;
+ }
+ }
+ }
+ if ($count > 0) {
+ $this->log("moved $count empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath());
+ }
+ }
+
+ if (count($this->filesets) > 0) {
+ // process filesets
+ foreach($this->filesets as $fs) {
+ $dir = $fs->getDir($this->project);
+ if ($this->okToDelete($dir)) {
+ $this->deleteDir($dir);
+ }
+ }
+ }
+ }
+
+ /** Its only ok to delete a dir tree if there are no files in it. */
+ private function okToDelete($d) {
+ $list = $d->listDir();
+ if ($list === null) {
+ return false; // maybe io error?
+ }
+
+ foreach($list as $s) {
+ $f = new PhingFile($d, $s);
+ if ($f->isDirectory()) {
+ if (!$this->okToDelete($f)) {
+ return false;
+ }
+ } else {
+ // found a file
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Go and delete the directory tree. */
+ private function deleteDir($d) {
+
+ $list = $d->listDir();
+ if ($list === null) {
+ return; // on an io error list() can return null
+ }
+
+ foreach($list as $fname) {
+ $f = new PhingFile($d, $fname);
+ if ($f->isDirectory()) {
+ $this->deleteDir($f);
+ } else {
+ throw new BuildException("UNEXPECTED ERROR - The file " . $f->getAbsolutePath() . " should not exist!");
+ }
+ }
+
+ $this->log("Deleting directory " . $d->getPath(), $this->verbosity);
+ try {
+ $d->delete();
+ } catch (Exception $e) {
+ throw new BuildException("Unable to delete directory " . $d->__toString() . ": " . $e->getMessage());
+ }
+ }
+
+ /**
+ * Attempts to rename a file from a source to a destination.
+ * If overwrite is set to true, this method overwrites existing file
+ * even if the destination file is newer.
+ * Otherwise, the source f
+ * ile is renamed only if the destination file #
+ * is older than it.
+ */
+ private function renameFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite) {
+ $renamed = true;
+
+ // ensure that parent dir of dest file exists!
+ $parent = $destFile->getParentFile();
+ if ($parent !== null) {
+ if (!$parent->exists()) {
+ $parent->mkdirs();
+ }
+ }
+ if ($destFile->exists()) {
+ try {
+ $destFile->delete();
+ } catch (Exception $e) {
+ throw new BuildException("Unable to remove existing file " . $destFile->__toString() . ": " . $e->getMessage());
+ }
+ }
+ $renamed = $sourceFile->renameTo($destFile);
+
+ return $renamed;
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/tasks/system/PhingCallTask.php b/buildscripts/phing/classes/phing/tasks/system/PhingCallTask.php
new file mode 100644
index 00000000..34d4336d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/PhingCallTask.php
@@ -0,0 +1,139 @@
+<?php
+/*
+ * $Id: PhingCallTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Call another target in the same project.
+ *
+ * <pre>
+ * <target name="foo">
+ * <phingcall target="bar">
+ * <property name="property1" value="aaaaa" />
+ * <property name="foo" value="baz" />
+ * </phingcall>
+ * </target>
+ *
+ * <target name="bar" depends="init">
+ * <echo message="prop is ${property1} ${foo}" />
+ * </target>
+ * </pre>
+ *
+ * <p>This only works as expected if neither property1 nor foo are
+ * defined in the project itself.
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @copyright 2001,2002 THYRELL. All rights reserved
+ * @version $Revision: 1.9 $
+ * @access public
+ * @package phing.tasks.system
+ */
+class PhingCallTask extends Task {
+
+ private $callee;
+ private $subTarget;
+ // must match the default value of PhingTask#inheritAll
+ private $inheritAll = true;
+ // must match the default value of PhingTask#inheritRefs
+ private $inheritRefs = false;
+
+ /**
+ * If true, pass all properties to the new Phing project.
+ * Defaults to true. Future use.
+ * @param boolean new value
+ */
+ function setInheritAll($inherit) {
+ $this->inheritAll = (boolean) $inherit;
+ }
+
+ /**
+ * If true, pass all references to the new Phing project.
+ * Defaults to false. Future use.
+ *
+ * @param boolean new value
+ */
+ function setInheritRefs($inheritRefs) {
+ $this->inheritRefs = (boolean) $inheritRefs;
+ }
+
+ /**
+ * init this task by creating new instance of the phing task and
+ * configuring it's by calling its own init method.
+ */
+ function init() {
+ $this->callee = $this->project->createTask("phing");
+ $this->callee->setOwningTarget($this->getOwningTarget());
+ $this->callee->setTaskName($this->getTaskName());
+ $this->callee->setLocation($this->getLocation());
+ $this->callee->init();
+ }
+
+ /**
+ * hand off the work to the phing task of ours, after setting it up
+ * @throws BuildException on validation failure or if the target didn't
+ * execute
+ */
+ function main() {
+
+ $this->log("Running PhingCallTask for target '" . $this->subTarget . "'", PROJECT_MSG_DEBUG);
+ if ($this->callee === null) {
+ $this->init();
+ }
+
+ if ($this->subTarget === null) {
+ throw new BuildException("Attribute target is required.", $this->location);
+ }
+
+ $this->callee->setPhingfile($this->project->getProperty("phing.file"));
+ $this->callee->setTarget($this->subTarget);
+ $this->callee->setInheritAll($this->inheritAll);
+ $this->callee->setInheritRefs($this->inheritRefs);
+ $this->callee->main();
+ }
+
+ /**
+ * Alias for createProperty
+ * @see createProperty()
+ */
+ function createParam() {
+ if ($this->callee === null) {
+ $this->init();
+ }
+ return $this->callee->createProperty();
+ }
+
+ /**
+ * Property to pass to the invoked target.
+ */
+ function createProperty() {
+ if ($this->callee === null) {
+ $this->init();
+ }
+ return $this->callee->createProperty();
+ }
+
+ /**
+ * Target to execute, required.
+ */
+ function setTarget($target) {
+ $this->subTarget = (string) $target;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/PhingTask.php b/buildscripts/phing/classes/phing/tasks/system/PhingTask.php
new file mode 100644
index 00000000..e9883dd7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/PhingTask.php
@@ -0,0 +1,596 @@
+<?php
+
+/*
+ * $Id: PhingTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/util/FileUtils.php';
+include_once 'phing/types/Reference.php';
+include_once 'phing/tasks/system/PropertyTask.php';
+
+/**
+ * Task that invokes phing on another build file.
+ *
+ * Use this task, for example, if you have nested buildfiles in your project. Unlike
+ * AntTask, PhingTask can even support filesets:
+ *
+ * <pre>
+ * <phing>
+ * <fileset dir="${srcdir}">
+ * <include name="** /build.xml" /> <!-- space added after ** is there because of PHP comment syntax -->
+ * <exclude name="build.xml" />
+ * </fileset>
+ * </phing>
+ * </pre>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.20 $
+ * @package phing.tasks.system
+ */
+class PhingTask extends Task {
+
+ /** the basedir where is executed the build file */
+ private $dir;
+
+ /** build.xml (can be absolute) in this case dir will be ignored */
+ private $phingFile;
+
+ /** the target to call if any */
+ protected $newTarget;
+
+ /** should we inherit properties from the parent ? */
+ private $inheritAll = true;
+
+ /** should we inherit references from the parent ? */
+ private $inheritRefs = false;
+
+ /** the properties to pass to the new project */
+ private $properties = array();
+
+ /** the references to pass to the new project */
+ private $references = array();
+
+ /** The filesets that contain the files PhingTask is to be run on. */
+ private $filesets = array();
+
+ /** the temporary project created to run the build file */
+ private $newProject;
+
+ /** Fail the build process when the called build fails? */
+ private $haltOnFailure = false;
+
+ /**
+ * If true, abort the build process if there is a problem with or in the target build file.
+ * Defaults to false.
+ *
+ * @param boolean new value
+ */
+ public function setHaltOnFailure($hof) {
+ $this->haltOnFailure = (boolean) $hof;
+ }
+
+ /**
+ * Creates a Project instance for the project to call.
+ * @return void
+ */
+ public function init() {
+ $this->newProject = new Project();
+ $tdf = $this->project->getTaskDefinitions();
+ $this->newProject->addTaskDefinition("property", $tdf["property"]);
+ }
+
+ /**
+ * Called in execute or createProperty if newProject is null.
+ *
+ * <p>This can happen if the same instance of this task is run
+ * twice as newProject is set to null at the end of execute (to
+ * save memory and help the GC).</p>
+ *
+ * <p>Sets all properties that have been defined as nested
+ * property elements.</p>
+ */
+ private function reinit() {
+ $this->init();
+ $count = count($this->properties);
+ for ($i = 0; $i < $count; $i++) {
+ $p = $this->properties[$i];
+ $newP = $this->newProject->createTask("property");
+ $newP->setName($p->getName());
+ if ($p->getValue() !== null) {
+ $newP->setValue($p->getValue());
+ }
+ if ($p->getFile() !== null) {
+ $newP->setFile($p->getFile());
+ }
+ if ($p->getPrefix() !== null) {
+ $newP->setPrefix($p->getPrefix());
+ }
+ if ($p->getRefid() !== null) {
+ $newP->setRefid($p->getRefid());
+ }
+ if ($p->getEnvironment() !== null) {
+ $newP->setEnvironment($p->getEnvironment());
+ }
+ if ($p->getUserProperty() !== null) {
+ $newP->setUserProperty($p->getUserProperty());
+ }
+ if ($p->getOverride() !== null) {
+ $newP->setOverride($p->getOverride());
+ }
+ $this->properties[$i] = $newP;
+ }
+ }
+
+ /**
+ * Main entry point for the task.
+ *
+ * @return void
+ */
+ public function main() {
+
+ // Call Phing on the file set with the attribute "phingfile"
+ if ($this->phingFile !== null or $this->dir !== null) {
+ $this->processFile();
+ }
+
+ // if no filesets are given stop here; else process filesets
+ if (empty($this->filesets)) {
+ return;
+ }
+
+ // preserve old settings
+ $savedDir = $this->dir;
+ $savedPhingFile = $this->phingFile;
+ $savedTarget = $this->newTarget;
+ $buildFailed = false;
+
+ // set no specific target for files in filesets
+ // [HL] I'm commenting this out; I don't know why this should not be supported!
+ // $this->newTarget = null;
+
+ foreach($this->filesets as $fs) {
+
+ $ds = $fs->getDirectoryScanner($this->project);
+
+ $fromDir = $fs->getDir($this->project);
+ $srcFiles = $ds->getIncludedFiles();
+
+ foreach($srcFiles as $fname) {
+ $f = new PhingFile($ds->getbasedir(), $fname);
+ $f = $f->getAbsoluteFile();
+ $this->phingFile = $f->getAbsolutePath();
+ $this->dir = $f->getParentFile();
+ $this->processFile(); // run Phing!
+ }
+ }
+
+ // side effect free programming ;-)
+ $this->dir = $savedDir;
+ $this->phingFile = $savedPhingFile;
+ $this->newTarget = $savedTarget;
+
+ // [HL] change back to correct dir
+ if ($this->dir !== null) {
+ chdir($this->dir->getAbsolutePath());
+ }
+
+ }
+
+ /**
+ * Execute phing file.
+ *
+ * @return void
+ */
+ private function processFile() {
+
+ $savedDir = $this->dir;
+ $savedPhingFile = $this->phingFile;
+ $savedTarget = $this->newTarget;
+
+ try {
+ if ($this->newProject === null) {
+ $this->reinit();
+ }
+
+ if (($this->dir === null) && ($this->inheritAll)) {
+ $this->dir = $this->getProject()->getBaseDir();
+ }
+ $this->initializeProject();
+ if ($this->dir !== null) {
+ $this->newProject->setBaseDir($this->dir);
+ if ($savedDir !== null) { // has been set explicitly
+ $this->newProject->setInheritedProperty("project.basedir", $this->dir->getAbsolutePath());
+ }
+ } else {
+ $this->dir = $this->getProject()->getBaseDir();
+ }
+
+ $this->overrideProperties();
+ if ($this->phingFile === null) {
+ $this->phingFile = "build.xml";
+ }
+
+ $fu = new FileUtils();
+ $file = $fu->resolveFile($this->dir, $this->phingFile);
+ $this->phingFile = $file->getAbsolutePath();
+
+ $this->log("Calling Buildfile '" . $this->phingFile . "' with target '" . $this->newTarget . "'");
+
+ $this->newProject->setUserProperty("phing.file", $this->phingFile);
+
+ ProjectConfigurator::configureProject($this->newProject, new PhingFile($this->phingFile));
+
+ if ($this->newTarget === null) {
+ $this->newTarget = $this->newProject->getDefaultTarget();
+ }
+
+ // Are we trying to call the target in which we are defined?
+ if ($this->newProject->getBaseDir() == $this->project->getBaseDir() &&
+ $this->newProject->getProperty("phing.file") == $this->project->getProperty("phing.file") &&
+ $this->getOwningTarget() !== null &&
+ $this->newTarget == $this->getOwningTarget()->getName()) {
+
+ throw new BuildException("phing task calling its own parent target");
+ }
+
+ $this->addReferences();
+ $this->newProject->executeTarget($this->newTarget);
+
+ } catch (Exception $e) {
+ $buildFailed = true;
+ $this->log($e->getMessage(), PROJECT_MSG_ERR);
+
+ // important!!! continue on to perform cleanup
+ // tasks.
+ }
+
+ // } finally {
+ // restore values (prevent side-effects)
+ // !this must match code in catch () {} block!
+ $this->newProject = null;
+ $pkeys = array_keys($this->properties);
+ foreach($pkeys as $k) {
+ $this->properties[$k]->setProject(null);
+ }
+ $this->dir = $savedDir;
+ $this->phingFile = $savedPhingFile;
+ $this->newTarget = $savedTarget;
+
+ // [HL] change back to correct dir
+ if ($this->dir !== null) {
+ chdir($this->dir->getAbsolutePath());
+ }
+
+ if ($this->haltOnFailure == true && $buildFailed == true)
+ throw new BuildException("Execution of the target buildfile failed. Aborting.");
+ }
+
+ /**
+ * Configure the Project, i.e. make intance, attach build listeners
+ * (copy from father project), add Task and Datatype definitions,
+ * copy properties and references from old project if these options
+ * are set via the attributes of the XML tag.
+ *
+ * Developer note:
+ * This function replaces the old methods "init", "_reinit" and
+ * "_initializeProject".
+ *
+ * @access protected
+ */
+ private function initializeProject() {
+
+ $this->newProject->setInputHandler($this->project->getInputHandler());
+
+ foreach($this->project->getBuildListeners() as $listener) {
+ $this->newProject->addBuildListener($listener);
+ }
+
+ /* Copy things from old project. Datatypes and Tasks are always
+ * copied, properties and references only if specified so/not
+ * specified otherwise in the XML definition.
+ */
+ // Add Datatype definitions
+ foreach ($this->project->getDataTypeDefinitions() as $typeName => $typeClass) {
+ $this->newProject->addDataTypeDefinition($typeName, $typeClass);
+ }
+
+ // Add Task definitions
+ foreach ($this->project->getTaskDefinitions() as $taskName => $taskClass) {
+ if ($taskClass == "propertytask") {
+ // we have already added this taskdef in init()
+ continue;
+ }
+ $this->newProject->addTaskDefinition($taskName, $taskClass);
+ }
+
+ // set user-defined properties
+ $this->project->copyUserProperties($this->newProject);
+
+ if (!$this->inheritAll) {
+ // set System built-in properties separately,
+ // b/c we won't inherit them.
+ $this->newProject->setSystemProperties();
+
+ } else {
+ // set all properties from calling project
+ $properties = $this->project->getProperties();
+ foreach ($properties as $name => $value) {
+ if ($name == "basedir" || $name == "phing.file" || $name == "phing.version") {
+ // basedir and phing.file get special treatment in main()
+ continue;
+ }
+ // don't re-set user properties, avoid the warning message
+ if ($this->newProject->getProperty($name) === null){
+ // no user property
+ $this->newProject->setNewProperty($name, $value);
+ }
+ }
+
+ }
+
+ }
+
+ /**
+ * Override the properties in the new project with the one
+ * explicitly defined as nested elements here.
+ * @return void
+ * @throws BuildException
+ */
+ private function overrideProperties() {
+ foreach(array_keys($this->properties) as $i) {
+ $p = $this->properties[$i];
+ $p->setProject($this->newProject);
+ $p->main();
+ }
+ $this->project->copyInheritedProperties($this->newProject);
+ }
+
+ /**
+ * Add the references explicitly defined as nested elements to the
+ * new project. Also copy over all references that don't override
+ * existing references in the new project if inheritrefs has been
+ * requested.
+ *
+ * @return void
+ * @throws BuildException
+ */
+ private function addReferences() {
+
+ // parent project references
+ $projReferences = $this->project->getReferences();
+
+ $newReferences = $this->newProject->getReferences();
+
+ $subprojRefKeys = array();
+
+ if (count($this->references) > 0) {
+ for ($i=0, $count=count($this->references); $i < $count; $i++) {
+ $ref = $this->references[$i];
+ $refid = $ref->getRefId();
+
+ if ($refid === null) {
+ throw new BuildException("the refid attribute is required"
+ . " for reference elements");
+ }
+ if (!isset($projReferences[$refid])) {
+ $this->log("Parent project doesn't contain any reference '"
+ . $refid . "'",
+ PROJECT_MSG_WARN);
+ continue;
+ }
+
+ $subprojRefKeys[] = $refid;
+ //thisReferences.remove(refid);
+ $toRefid = $ref->getToRefid();
+ if ($toRefid === null) {
+ $toRefid = $refid;
+ }
+ $this->copyReference($refid, $toRefid);
+ }
+ }
+
+ // Now add all references that are not defined in the
+ // subproject, if inheritRefs is true
+ if ($this->inheritRefs) {
+
+ // get the keys that are were not used by the subproject
+ $unusedRefKeys = array_diff(array_keys($projReferences), $subprojRefKeys);
+
+ foreach($unusedRefKeys as $key) {
+ if (isset($newReferences[$key])) {
+ continue;
+ }
+ $this->copyReference($key, $key);
+ }
+ }
+ }
+
+ /**
+ * Try to clone and reconfigure the object referenced by oldkey in
+ * the parent project and add it to the new project with the key
+ * newkey.
+ *
+ * <p>If we cannot clone it, copy the referenced object itself and
+ * keep our fingers crossed.</p>
+ *
+ * @param string $oldKey
+ * @param string $newKey
+ * @return void
+ */
+ private function copyReference($oldKey, $newKey) {
+ $orig = $this->project->getReference($oldKey);
+ if ($orig === null) {
+ $this->log("No object referenced by " . $oldKey . ". Can't copy to "
+ .$newKey,
+ PROJECT_SG_WARN);
+ return;
+ }
+
+ $copy = clone $orig;
+
+ if ($copy instanceof ProjectComponent) {
+ $copy->setProject($this->newProject);
+ } elseif (in_array('setProject', get_class_methods(get_class($copy)))) {
+ $copy->setProject($this->newProject);
+ } elseif ($copy instanceof Project) {
+ // don't copy the old "Project" itself
+ } else {
+ $msg = "Error setting new project instance for "
+ . "reference with id " . $oldKey;
+ throw new BuildException($msg);
+ }
+
+ $this->newProject->addReference($newKey, $copy);
+ }
+
+ /**
+ * If true, pass all properties to the new phing project.
+ * Defaults to true.
+ *
+ * @access public
+ */
+ function setInheritAll($value) {
+ $this->inheritAll = (boolean) $value;
+ }
+
+ /**
+ * If true, pass all references to the new phing project.
+ * Defaults to false.
+ *
+ * @access public
+ */
+ function setInheritRefs($value) {
+ $this->inheritRefs = (boolean)$value;
+ }
+
+ /**
+ * The directory to use as a base directory for the new phing project.
+ * Defaults to the current project's basedir, unless inheritall
+ * has been set to false, in which case it doesn't have a default
+ * value. This will override the basedir setting of the called project.
+ *
+ * @access public
+ */
+ function setDir($d) {
+ if ( is_string($d) )
+ $this->dir = new PhingFile($d);
+ else
+ $this->dir = $d;
+ }
+
+ /**
+ * The build file to use.
+ * Defaults to "build.xml". This file is expected to be a filename relative
+ * to the dir attribute given.
+ *
+ * @access public
+ */
+ function setPhingfile($s) {
+ // it is a string and not a file to handle relative/absolute
+ // otherwise a relative file will be resolved based on the current
+ // basedir.
+ $this->phingFile = $s;
+ }
+
+ /**
+ * Alias function for setPhingfile
+ *
+ * @access public
+ */
+ function setBuildfile($s) {
+ $this->setPhingFile($s);
+ }
+
+ /**
+ * The target of the new Phing project to execute.
+ * Defaults to the new project's default target.
+ *
+ * @access public
+ */
+ function setTarget($s) {
+ $this->newTarget = $s;
+ }
+
+ /**
+ * Support for filesets; This method returns a reference to an instance
+ * of a FileSet object.
+ *
+ * @return FileSet
+ */
+ function createFileSet() {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * Property to pass to the new project.
+ * The property is passed as a 'user property'
+ *
+ * @access public
+ */
+ function createProperty() {
+ $p = new PropertyTask();
+ $p->setFallback($this->newProject);
+ $p->setUserProperty(true);
+ $this->properties[] = $p;
+ return $p;
+ }
+
+ /**
+ * Reference element identifying a data type to carry
+ * over to the new project.
+ *
+ * @access public
+ */
+ function createReference() {
+ $num = array_push($this->references, new PhingReference());
+ return $this->references[$num-1];
+ }
+
+}
+
+/**
+ * Helper class that implements the nested <reference>
+ * element of <phing> and <phingcall>.
+ */
+class PhingReference extends Reference {
+
+ private $targetid = null;
+
+ /**
+ * Set the id that this reference to be stored under in the
+ * new project.
+ *
+ * @param targetid the id under which this reference will be passed to
+ * the new project */
+ public function setToRefid($targetid) {
+ $this->targetid = $targetid;
+ }
+
+ /**
+ * Get the id under which this reference will be stored in the new
+ * project
+ *
+ * @return the id of the reference in the new project.
+ */
+ public function getToRefid() {
+ return $this->targetid;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/PhpEvalTask.php b/buildscripts/phing/classes/phing/tasks/system/PhpEvalTask.php
new file mode 100644
index 00000000..f1b72815
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/PhpEvalTask.php
@@ -0,0 +1,169 @@
+<?php
+/*
+ * $Id: PhpEvalTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Executes PHP function or evaluates expression and sets return value to a property.
+ *
+ * WARNING:
+ * This task can, of course, be abused with devastating effects. E.g. do not
+ * modify internal Phing classes unless you know what you are doing.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.7 $
+ * @package phing.tasks.system
+ *
+ * @todo Add support for evaluating expressions
+ */
+class PhpEvalTask extends Task {
+
+ protected $expression; // Expression to evaluate
+ protected $function; // Function to execute
+ protected $class; // Class containing function to execute
+ protected $returnProperty; // name of property to set to return value
+ protected $params = array(); // parameters for function calls
+
+ /** Main entry point. */
+ function main() {
+
+ if ($this->function === null && $this->expression === null) {
+ throw new BuildException("You must specify a function to execute or PHP expression to evalute.", $this->location);
+ }
+
+ if ($this->function !== null && $this->expression !== null) {
+ throw new BuildException("You can specify function or expression, but not both.", $this->location);
+ }
+
+ if ($this->expression !== null && !empty($this->params)) {
+ throw new BuildException("You cannot use nested <param> tags when evaluationg a PHP expression.", $this->location);
+ }
+
+ $retval = null;
+ if ($this->function !== null) {
+ $retval = $this->callFunction();
+ } elseif ($this->expression !== null) {
+ $retval = $this->evalExpression();
+ }
+
+ if ($this->returnProperty !== null) {
+ $this->project->setProperty($this->returnProperty, $retval);
+ }
+ }
+
+ /**
+ * Calls function and returns results.
+ * @return mixed
+ */
+ protected function callFunction() {
+
+ if ($this->class !== null) {
+ // import the classname & unqualify it, if necessary
+ $this->class = Phing::import($this->class);
+
+ $user_func = array($this->class, $this->function);
+ $h_func = $this->class . '::' . $this->function; // human-readable (for log)
+ } else {
+ $user_func = $this->function;
+ $h_func = $user_func; // human-readable (for log)
+ }
+
+ // put parameters into simple array
+ $params = array();
+ foreach($this->params as $p) {
+ $params[] = $p->getValue();
+ }
+
+ $this->log("Calling PHP function: " . $h_func . "()");
+ foreach($params as $p) {
+ $this->log(" param: " . $p, PROJECT_MSG_VERBOSE);
+ }
+
+ $return = call_user_func_array($user_func, $params);
+ return $return;
+ }
+
+ /**
+ * Evaluates expression and returns resulting value.
+ * @return mixed
+ */
+ protected function evalExpression() {
+ $this->log("Evaluating PHP expression: " . $this->expression);
+ if (!StringHelper::endsWith(';', trim($this->expression))) {
+ $this->expression .= ';';
+ }
+ $retval = null;
+ eval('$retval = ' . $this->expression);
+ return $retval;
+ }
+
+ /** Set function to execute */
+ public function setFunction($f) {
+ $this->function = $f;
+ }
+
+ /** Set [static] class which contains function to execute */
+ public function setClass($c) {
+ $this->class = $c;
+ }
+
+ /** Sets property name to set with return value of function or expression.*/
+ public function setReturnProperty($r) {
+ $this->returnProperty = $r;
+ }
+
+ /** Set PHP expression to evaluate. */
+ public function addText($expression) {
+ $this->expression = $expression;
+ }
+
+ /** Set PHP expression to evaluate. */
+ public function setExpression($expression) {
+ $this->expression = $expression;
+ }
+
+ /** Add a nested <param> tag. */
+ public function createParam() {
+ $p = new FunctionParam();
+ $this->params[] = $p;
+ return $p;
+ }
+}
+
+/**
+ * Supports the <param> nested tag for PhpTask.
+ */
+class FunctionParam {
+
+ private $val;
+
+ public function setValue($v) {
+ $this->val = $v;
+ }
+
+ public function addText($v) {
+ $this->val = $v;
+ }
+
+ public function getValue() {
+ return $this->val;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/system/PropertyPromptTask.php b/buildscripts/phing/classes/phing/tasks/system/PropertyPromptTask.php
new file mode 100644
index 00000000..e7e12f33
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/PropertyPromptTask.php
@@ -0,0 +1,201 @@
+<?php
+/*
+ * $Id: PropertyPromptTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/system/io/ConsoleReader.php';
+
+/**
+ * Deprecated task that uses console to prompt user for property values.
+ *
+ * This class is very slightly simpler than the InputTask, but lacks the ability
+ * to use a non-console input handler. You should, therefore, use InputTask. This
+ * class can serve as a reference, but will be removed in the future.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Anthony J. Young-Garner <ajyoung@alum.mit.edu> (Ant)
+ * @version $Revision: 1.4 $
+ * @package phing.tasks.system
+ * @deprecated - in favor of the more capable InputTask
+ */
+class PropertyPromptTask extends Task {
+
+ private $propertyName; // required
+ private $defaultValue;
+ private $proposedValue; // required
+ private $promptText; // required
+ private $promptCharacter;
+ private $useExistingValue;
+
+ /**
+ * Sets the prompt text that will be presented to the user.
+ * @param string $prompt
+ * @return void
+ */
+ public function addText($prompt) {
+ $this->setPromptText($prompt);
+ }
+
+ /**
+ * Run the PropertyPrompt task.
+ * @throws BuildException
+ */
+ public function main() {
+ $this->proposedValue = $this->project->getProperty($this->propertyName);
+ $currentValue = $this->defaultValue;
+ if ($currentValue == "" && $this->proposedValue !== null) { $currentValue = $this->proposedValue; }
+ if (! (($this->useExistingValue === true) && ($this->proposedValue !== null))) {
+
+ $this->log("Prompting user for " . $this->propertyName . ". " . $this->getDefaultMessage(), PROJECT_MSG_VERBOSE);
+
+ print "\n" . $this->promptText . " [" . $currentValue . "] " . $this->promptCharacter . " ";
+
+ /** future version should probably have hooks for validation of user input.*/
+ $reader = new ConsoleReader();
+
+ try {
+ $this->proposedValue = $reader->readLine();
+ } catch (IOException $e) {
+ $this->log("Prompt failed. Using default. (Failure reason: " . $e->getMessage().")");
+ $this->proposedValue = $this->defaultValue;
+ }
+
+ if (empty($this->proposedValue)) {
+ $this->log("No value specified, using default.", PROJECT_MSG_VERBOSE);
+ $this->proposedValue = $this->defaultValue;
+ }
+
+ if (!empty($this->proposedValue)) {
+ $this->project->setProperty($this->propertyName, $this->proposedValue);
+ }
+
+ }
+ }
+
+ /**
+ * Returns a string to be inserted in the log message
+ * indicating whether a default response was specified
+ * in the build file.
+ */
+ private function getDefaultMessage() {
+ if ($this->defaultValue == "") {
+ return "No default response specified.";
+ } else return "Default response is " . $this->defaultValue . ".";
+ }
+
+ /**
+ * Returns defaultValue specified
+ * in this task for the Property
+ * being set.
+ * @return string
+ */
+ public function getDefaultValue() {
+ return $this->defaultValue;
+ }
+
+ /**
+ * Returns the terminating character used to
+ * punctuate the prompt text.
+ * @return string
+ */
+ public function getPromptCharacter() {
+ return $this->promptCharacter;
+ }
+
+ /**
+ * Returns text of the prompt.
+ * @return java.lang.String
+ */
+ public function getPromptText() {
+ return $this->promptText;
+ }
+
+ /**
+ * Returns name of the Ant Project Property
+ * being set by this task.
+ * @return string
+ */
+ public function getPropertyName() {
+ return $this->propertyName;
+ }
+ /**
+ * Initializes this task.
+ */
+ public function init() {
+ parent::init();
+ $this->defaultValue = "";
+ $this->promptCharacter = "?";
+ $this->useExistingValue = false;
+ }
+
+ /**
+ * Insert the method's description here.
+ * Creation date: (12/10/2001 8:16:16 AM)
+ * @return boolean
+ */
+ public function isUseExistingValue() {
+ return $this->useExistingValue;
+ }
+
+ /**
+ * Sets defaultValue for the Property
+ * being set by this task.
+ * @param string $newDefaultvalue
+ */
+ public function setDefaultvalue($newDefaultvalue) {
+ $this->defaultValue = $newDefaultvalue;
+ }
+
+ /**
+ * Sets the terminating character used to
+ * punctuate the prompt text (default is "?").
+ * @param newPromptcharacter java.lang.String
+ */
+ public function setPromptCharacter($newPromptcharacter) {
+ $this->promptCharacter = $newPromptcharacter;
+ }
+
+ /**
+ * Sets text of the prompt.
+ * @param newPrompttext java.lang.String
+ */
+ public function setPromptText($newPrompttext) {
+ $this->promptText = $newPrompttext;
+ }
+
+ /**
+ * Specifies the Phing Project Property
+ * being set by this task.
+ * @param newPropertyname java.lang.String
+ */
+ public function setPropertyName($newPropertyname) {
+ $this->propertyName = $newPropertyname;
+ }
+
+ /**
+ *
+ *
+ * @param boolean newUseExistingValue
+ */
+ public function setUseExistingValue($newUseExistingValue) {
+ $this->useExistingValue = $newUseExistingValue;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/PropertyTask.php b/buildscripts/phing/classes/phing/tasks/system/PropertyTask.php
new file mode 100644
index 00000000..d6168e44
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/PropertyTask.php
@@ -0,0 +1,438 @@
+<?php
+
+/*
+ * $Id: PropertyTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/system/util/Properties.php';
+
+/**
+ * Task for setting properties in buildfiles.
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision$
+ * @package phing.tasks.system
+ */
+class PropertyTask extends Task {
+
+ /** name of the property */
+ protected $name;
+
+ /** value of the property */
+ protected $value;
+
+ protected $reference;
+ protected $env; // Environment
+ protected $file;
+ protected $ref;
+ protected $prefix;
+ protected $fallback;
+
+ /** Whether to force overwrite of existing property. */
+ protected $override = false;
+
+ /** Whether property should be treated as "user" property. */
+ protected $userProperty = false;
+
+ /**
+ * Sets a the name of current property component
+ */
+ function setName($name) {
+ $this->name = (string) $name;
+ }
+
+ /** Get property component name. */
+ function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Sets a the value of current property component.
+ * @param mixed Value of name, all scalars allowed
+ */
+ function setValue($value) {
+ $this->value = (string) $value;
+ }
+
+ /**
+ * Sets value of property to CDATA tag contents.
+ * @param string $values
+ * @since 2.2.0
+ */
+ public function addText($value) {
+ $this->setValue($value);
+ }
+
+ /** Get the value of current property component. */
+ function getValue() {
+ return $this->value;
+ }
+
+ /** Set a file to use as the source for properties. */
+ function setFile($file) {
+ if (is_string($file)) {
+ $file = new PhingFile($file);
+ }
+ $this->file = $file;
+ }
+
+ /** Get the PhingFile that is being used as property source. */
+ function getFile() {
+ return $this->file;
+ }
+
+ function setRefid(Reference $ref) {
+ $this->reference = $ref;
+ }
+
+ function getRefid() {
+ return $this->reference;
+ }
+
+ /**
+ * Prefix to apply to properties loaded using <code>file</code>.
+ * A "." is appended to the prefix if not specified.
+ * @param string $prefix prefix string
+ * @return void
+ * @since 2.0
+ */
+ public function setPrefix($prefix) {
+ $this->prefix = $prefix;
+ if (!StringHelper::endsWith(".", $prefix)) {
+ $this->prefix .= ".";
+ }
+ }
+
+ /**
+ * @return string
+ * @since 2.0
+ */
+ public function getPrefix() {
+ return $this->prefix;
+ }
+
+ /**
+ * the prefix to use when retrieving environment variables.
+ * Thus if you specify environment="myenv"
+ * you will be able to access OS-specific
+ * environment variables via property names "myenv.PATH" or
+ * "myenv.TERM".
+ * <p>
+ * Note that if you supply a property name with a final
+ * "." it will not be doubled. ie environment="myenv." will still
+ * allow access of environment variables through "myenv.PATH" and
+ * "myenv.TERM". This functionality is currently only implemented
+ * on select platforms. Feel free to send patches to increase the number of platforms
+ * this functionality is supported on ;).<br>
+ * Note also that properties are case sensitive, even if the
+ * environment variables on your operating system are not, e.g. it
+ * will be ${env.Path} not ${env.PATH} on Windows 2000.
+ * @param env prefix
+ */
+ function setEnvironment($env) {
+ $this->env = (string) $env;
+ }
+
+ function getEnvironment() {
+ return $this->env;
+ }
+
+ /**
+ * Set whether this is a user property (ro).
+ * This is deprecated in Ant 1.5, but the userProperty attribute
+ * of the class is still being set via constructor, so Phing will
+ * allow this method to function.
+ * @param boolean $v
+ */
+ function setUserProperty($v) {
+ $this->userProperty = (boolean) $v;
+ }
+
+ function getUserProperty() {
+ return $this->userProperty;
+ }
+
+ function setOverride($v) {
+ $this->override = (boolean) $v;
+ }
+
+ function getOverride() {
+ return $this->override;
+ }
+
+ function toString() {
+ return (string) $this->value;
+ }
+
+ /**
+ * @param Project $p
+ */
+ function setFallback($p) {
+ $this->fallback = $p;
+ }
+
+ function getFallback() {
+ return $this->fallback;
+ }
+ /**
+ * set the property in the project to the value.
+ * if the task was give a file or env attribute
+ * here is where it is loaded
+ */
+ function main() {
+ if ($this->name !== null) {
+ if ($this->value === null && $this->ref === null) {
+ throw new BuildException("You must specify value or refid with the name attribute", $this->getLocation());
+ }
+ } else {
+ if ($this->file === null && $this->env === null ) {
+ throw new BuildException("You must specify file or environment when not using the name attribute", $this->getLocation());
+ }
+ }
+
+ if ($this->file === null && $this->prefix !== null) {
+ throw new BuildException("Prefix is only valid when loading from a file.", $this->getLocation());
+ }
+
+ if (($this->name !== null) && ($this->value !== null)) {
+ $this->addProperty($this->name, $this->value);
+ }
+
+ if ($this->file !== null) {
+ $this->loadFile($this->file);
+ }
+
+ if ( $this->env !== null ) {
+ $this->loadEnvironment($this->env);
+ }
+
+ if (($this->name !== null) && ($this->ref !== null)) {
+ // get the refereced property
+ try {
+ $this->addProperty($this->name, $this->reference->getReferencedObject($this->project)->toString());
+ } catch (BuildException $be) {
+ if ($this->fallback !== null) {
+ $this->addProperty($this->name, $this->reference->getReferencedObject($this->fallback)->toString());
+ } else {
+ throw $be;
+ }
+ }
+ }
+ }
+
+ /**
+ * load the environment values
+ * @param string $prefix prefix to place before them
+ */
+ protected function loadEnvironment($prefix) {
+
+ $props = new Properties();
+ if ( substr($prefix, strlen($prefix)-1) == '.' ) {
+ $prefix .= ".";
+ }
+ $this->log("Loading Environment $prefix", PROJECT_MSG_VERBOSE);
+ foreach($_ENV as $key => $value) {
+ $props->setProperty($prefix . '.' . $key, $value);
+ }
+ $this->addProperties($props);
+ }
+
+ /**
+ * iterate through a set of properties,
+ * resolve them then assign them
+ */
+ protected function addProperties($props) {
+ $this->resolveAllProperties($props);
+ foreach($props->keys() as $name) {
+ $value = $props->getProperty($name);
+ $v = $this->project->replaceProperties($value);
+ if ($this->prefix !== null) {
+ $name = $this->prefix . $name;
+ }
+ $this->addProperty($name, $v);
+ }
+ }
+
+ /**
+ * add a name value pair to the project property set
+ * @param string $name name of property
+ * @param string $value value to set
+ */
+ protected function addProperty($name, $value) {
+ if ($this->userProperty) {
+ if ($this->project->getUserProperty($name) === null || $this->override) {
+ $this->project->setInheritedProperty($name, $value);
+ } else {
+ $this->log("Override ignored for " . $name, PROJECT_MSG_VERBOSE);
+ }
+ } else {
+ if ($this->override) {
+ $this->project->setProperty($name, $value);
+ } else {
+ $this->project->setNewProperty($name, $value);
+ }
+ }
+ }
+
+ /**
+ * load properties from a file.
+ * @param PhingFile $file
+ */
+ protected function loadFile(PhingFile $file) {
+ $props = new Properties();
+ $this->log("Loading ". $file->getAbsolutePath(), PROJECT_MSG_INFO);
+ try { // try to load file
+ if ($file->exists()) {
+ $props->load($file);
+ $this->addProperties($props);
+ } else {
+ $this->log("Unable to find property file: ". $file->getAbsolutePath() ."... skipped", PROJECT_MSG_WARN);
+ }
+ } catch (IOException $ioe) {
+ throw new BuildException("Could not load properties from file.", $ioe);
+ }
+ }
+
+ /**
+ * Given a Properties object, this method goes through and resolves
+ * any references to properties within the object.
+ *
+ * @param Properties $props The collection of Properties that need to be resolved.
+ * @return void
+ */
+ protected function resolveAllProperties(Properties $props) {
+
+ $keys = $props->keys();
+
+ while(count($keys)) {
+
+ // There may be a nice regex/callback way to handle this
+ // replacement, but at the moment it is pretty complex, and
+ // would probably be a lot uglier to work into a preg_replace_callback()
+ // system. The biggest problem is the fact that a resolution may require
+ // multiple passes.
+
+ $name = array_shift($keys);
+ $value = $props->getProperty($name);
+ $resolved = false;
+
+ while(!$resolved) {
+
+ $fragments = array();
+ $propertyRefs = array();
+
+ // [HL] this was ::parsePropertyString($this->value ...) ... this seems wrong
+ self::parsePropertyString($value, $fragments, $propertyRefs);
+
+ $resolved = true;
+ if (count($propertyRefs) !== 0) {
+
+ $sb = "";
+
+ $i = $fragments;
+ $j = $propertyRefs;
+ while(count($i)) {
+ $fragment = array_shift($i);
+ if ($fragment === null) {
+ $propertyName = array_shift($j);
+
+ if ($propertyName === $name) {
+ // Should we maybe just log this as an error & move on?
+ // $this->log("Property ".$name." was circularly defined.", PROJECT_MSG_ERR);
+ throw new BuildException("Property ".$name." was circularly defined.");
+ }
+
+ $fragment = $this->getProject()->getProperty($propertyName);
+ if ($fragment === null) {
+ if ($props->containsKey($propertyName)) {
+ $fragment = $props->getProperty($propertyName);
+ $resolved = false; // parse again (could have been replaced w/ another var)
+ } else {
+ $fragment = "\${".$propertyName."}";
+ }
+ }
+ }
+ $sb .= $fragment;
+ }
+
+ $this->log("Resolved Property \"$value\" to \"$sb\"", PROJECT_MSG_DEBUG);
+ $value = $sb;
+ $props->setProperty($name, $value);
+
+ } // if (count($propertyRefs))
+
+ } // while (!$resolved)
+
+ } // while (count($keys)
+ }
+
+
+ /**
+ * This method will parse a string containing ${value} style
+ * property values into two lists. The first list is a collection
+ * of text fragments, while the other is a set of string property names
+ * null entries in the first list indicate a property reference from the
+ * second list.
+ *
+ * This is slower than regex, but useful for this class, which has to handle
+ * multiple parsing passes for properties.
+ *
+ * @param string $value The string to be scanned for property references
+ * @param array &$fragments The found fragments
+ * @param array &$propertyRefs The found refs
+ */
+ protected function parsePropertyString($value, &$fragments, &$propertyRefs) {
+
+ $prev = 0;
+ $pos = 0;
+
+ while (($pos = strpos($value, '$', $prev)) !== false) {
+
+ if ($pos > $prev) {
+ array_push($fragments, StringHelper::substring($value, $prev, $pos-1));
+ }
+ if ($pos === (strlen($value) - 1)) {
+ array_push($fragments, '$');
+ $prev = $pos + 1;
+ } elseif ($value{$pos+1} !== '{' ) {
+
+ // the string positions were changed to value-1 to correct
+ // a fatal error coming from function substring()
+ array_push($fragments, StringHelper::substring($value, $pos, $pos + 1));
+ $prev = $pos + 2;
+ } else {
+ $endName = strpos($value, '}', $pos);
+ if ($endName === false) {
+ throw new BuildException("Syntax error in property: $value");
+ }
+ $propertyName = StringHelper::substring($value, $pos + 2, $endName-1);
+ array_push($fragments, null);
+ array_push($propertyRefs, $propertyName);
+ $prev = $endName + 1;
+ }
+ }
+
+ if ($prev < strlen($value)) {
+ array_push($fragments, StringHelper::substring($value, $prev));
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/ReflexiveTask.php b/buildscripts/phing/classes/phing/tasks/system/ReflexiveTask.php
new file mode 100644
index 00000000..dc7cfeb7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/ReflexiveTask.php
@@ -0,0 +1,155 @@
+<?php
+/*
+ * $Id: ReflexiveTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * This task is for using filter chains to make changes to files and overwrite the original files.
+ *
+ * This task was created to serve the need for "cleanup" tasks -- e.g. a ReplaceRegexp task or strip task
+ * being used to modify files and then overwrite the modified files. In many (most?) cases you probably
+ * should just use a copy task to preserve the original source files, but this task supports situations
+ * where there is no src vs. build directory, and modifying source files is actually desired.
+ *
+ * <code>
+ * <reflexive>
+ * <fileset dir=".">
+ * <include pattern="*.html">
+ * </fileset>
+ * <filterchain>
+ * <replaceregexp>
+ * <regexp pattern="\n\r" replace="\n"/>
+ * </replaceregexp>
+ * </filterchain>
+ * </reflexive>
+ * </code>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.11 $
+ * @package phing.tasks.system
+ */
+class ReflexiveTask extends Task {
+
+ /** Single file to process. */
+ private $file;
+
+ /** Any filesets that should be processed. */
+ private $filesets = array();
+
+ /** Any filters to be applied before append happens. */
+ private $filterChains = array();
+
+ /** Alias for setFrom() */
+ function setFile(PhingFile $f) {
+ $this->file = $f;
+ }
+
+ /** Nested creator, adds a set of files (nested fileset attribute). */
+ function createFileSet() {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * Creates a filterchain
+ *
+ * @return object The created filterchain object
+ */
+ function createFilterChain() {
+ $num = array_push($this->filterChains, new FilterChain($this->project));
+ return $this->filterChains[$num-1];
+ }
+
+ /** Append the file(s). */
+ function main() {
+
+ if ($this->file === null && empty($this->filesets)) {
+ throw new BuildException("You must specify a file or fileset(s) for the <reflexive> task.");
+ }
+
+ // compile a list of all files to modify, both file attrib and fileset elements
+ // can be used.
+
+ $files = array();
+
+ if ($this->file !== null) {
+ $files[] = $this->file;
+ }
+
+ if (!empty($this->filesets)) {
+ $filenames = array();
+ foreach($this->filesets as $fs) {
+ try {
+ $ds = $fs->getDirectoryScanner($this->project);
+ $filenames = $ds->getIncludedFiles(); // get included filenames
+ $dir = $fs->getDir($this->project);
+ foreach ($filenames as $fname) {
+ $files[] = new PhingFile($dir, $fname);
+ }
+ } catch (BuildException $be) {
+ $this->log($be->getMessage(), PROJECT_MSG_WARN);
+ }
+ }
+ }
+
+ $this->log("Applying reflexive processing to " . count($files) . " files.");
+
+ // These "slots" allow filters to retrieve information about the currently-being-process files
+ $slot = $this->getRegisterSlot("currentFile");
+ $basenameSlot = $this->getRegisterSlot("currentFile.basename");
+
+
+ foreach($files as $file) {
+ // set the register slots
+
+ $slot->setValue($file->getPath());
+ $basenameSlot->setValue($file->getName());
+
+ // 1) read contents of file, pulling through any filters
+ $in = null;
+ try {
+ $contents = "";
+ $in = FileUtils::getChainedReader(new FileReader($file), $this->filterChains, $this->project);
+ while(-1 !== ($buffer = $in->read())) {
+ $contents .= $buffer;
+ }
+ $in->close();
+ } catch (Exception $e) {
+ if ($in) $in->close();
+ $this->log("Erorr reading file: " . $e->getMessage(), PROJECT_MSG_WARN);
+ }
+
+ try {
+ // now create a FileWriter w/ the same file, and write to the file
+ $out = new FileWriter($file);
+ $out->write($contents);
+ $out->close();
+ $this->log("Applying reflexive processing to " . $file->getPath(), PROJECT_MSG_VERBOSE);
+ } catch (Exception $e) {
+ if ($out) $out->close();
+ $this->log("Error writing file back: " . $e->getMessage(), PROJECT_MSG_WARN);
+ }
+
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/system/ResolvePathTask.php b/buildscripts/phing/classes/phing/tasks/system/ResolvePathTask.php
new file mode 100644
index 00000000..b468afb5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/ResolvePathTask.php
@@ -0,0 +1,122 @@
+<?php
+/*
+ * $Id: ResolvePathTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Task for resolving relative paths and setting absolute path in property value.
+ *
+ * This task was created to address a need for resolving absolute paths of files / directories.
+ * In many cases a relative directory (e.g. "./build") is specified, but it needs to be treated
+ * as an absolute path since other build files (e.g. in subdirs) should all be using the same
+ * path -- and not treating it as a relative path to their own directory.
+ *
+ * <code>
+ * <property name="relative_path" value="./dirname"/>
+ * <resolvepath propertyName="absolute_path" file="${relative_path}"/>
+ * <echo>Resolved [absolute] path: ${absolute_path}</echo>
+ * </code>
+ *
+ * TODO:
+ * - Possibly integrate this with PackageAsPath, for handling/resolving dot-path paths.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.6 $
+ * @package phing.tasks.system
+ */
+class ResolvePathTask extends Task {
+
+ /** Name of property to set. */
+ private $propertyName;
+
+ /** The [possibly] relative file/path that needs to be resolved. */
+ private $file;
+
+ /** Base directory used for resolution. */
+ private $dir;
+
+ /**
+ * Set the name of the property to set.
+ * @param string $v Property name
+ * @return void
+ */
+ public function setPropertyName($v) {
+ $this->propertyName = $v;
+ }
+
+ /**
+ * Sets a base dir to use for resolution.
+ * @param PhingFile $d
+ */
+ function setDir(PhingFile $d) {
+ $this->dir = $d;
+ }
+
+ /**
+ * Sets a path (file or directory) that we want to resolve.
+ * This is the same as setFile() -- just more generic name so that it's
+ * clear that you can also use it to set directory.
+ * @param string $f
+ * @see setFile()
+ */
+ function setPath($f) {
+ $this->file = $f;
+ }
+
+ /**
+ * Sets a file that we want to resolve.
+ * @param string $f
+ */
+ function setFile($f) {
+ $this->file = $f;
+ }
+
+ /**
+ * Perform the resolution & set property.
+ */
+ public function main() {
+
+ if (!$this->propertyName) {
+ throw new BuildException("You must specify the propertyName attribute", $this->getLocation());
+ }
+
+ // Currently only files are supported
+ if ($this->file === null) {
+ throw new BuildException("You must specify a path to resolve", $this->getLocation());
+ }
+
+ $fs = FileSystem::getFileSystem();
+
+ // if dir attribute was specified then we should
+ // use that as basedir to which file was relative.
+ // -- unless the file specified is an absolute path
+ if ($this->dir !== null && !$fs->isAbsolute(new PhingFile($this->file))) {
+ $resolved = new PhingFile($this->dir->getPath(), $this->file);
+ } else {
+ // otherwise just resolve it relative to project basedir
+ $resolved = $this->project->resolveFile($this->file);
+ }
+
+ $this->log("Resolved " . $this->file . " to " . $resolved->getAbsolutePath(), PROJECT_MSG_INFO);
+ $this->project->setProperty($this->propertyName, $resolved->getAbsolutePath());
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/SequentialTask.php b/buildscripts/phing/classes/phing/tasks/system/SequentialTask.php
new file mode 100644
index 00000000..50327e3f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/SequentialTask.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * $Id: SequentialTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+require_once 'phing/TaskContainer.php';
+
+/**
+ * Sequential is a container task that contains other Phing Task objects.
+ *
+ * The sequential task has no attributes and does not support any nested
+ * elements apart from Ant tasks. Any valid Ant task may be embedded within the
+ * sequential task.
+ *
+ * @since 2.1.2
+ */
+class SequentialTask extends Task implements TaskContainer {
+
+ /** Optional Vector holding the nested tasks */
+ private $nestedTasks = array();
+
+ /**
+ * Add a nested task to Sequential.
+ * @param Task $nestedTask Nested task to execute Sequential
+ */
+ public function addTask(Task $nestedTask) {
+ $this->nestedTasks[] = $nestedTask;
+ }
+
+ /**
+ * Execute all nestedTasks.
+ * @throws BuildException if one of the nested tasks fails.
+ */
+ public function main() {
+ foreach($this->nestedTasks as $task) {
+ $task->perform();
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/TaskdefTask.php b/buildscripts/phing/classes/phing/tasks/system/TaskdefTask.php
new file mode 100644
index 00000000..4a90e106
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/TaskdefTask.php
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ * $Id: TaskdefTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Register a task for use within a buildfile.
+ *
+ * This is for registering your own tasks -- or any non-core Task -- for use within a buildfile.
+ * If you find that you are using a particular class frequently, you may want to edit the
+ * phing/tasks/defaults.properties file so that it is included by default. You may also
+ * want to submit it (if LGPL or compatible license) to be included in Phing distribution.
+ *
+ * <pre>
+ * <taskdef name="mytag" classname="path.to.MyHandlingClass"/>
+ * .
+ * .
+ * <mytag param1="val1" param2="val2"/>
+ * </pre>
+ *
+ * TODO:
+ * -- possibly refactor since this is almost the same as TypeDefTask
+ * (right now these are just too simple to really justify creating an abstract class)
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.11 $
+ * @package phing.tasks.system
+ */
+class TaskdefTask extends Task {
+
+ /** Tag name for task that will be used in XML */
+ private $name;
+
+ /**
+ * Classname of task to register.
+ * This can be a dot-path -- relative to a location on PHP include_path.
+ * E.g. path.to.MyClass -> path/to/MyClass.php
+ * @var string
+ */
+ private $classname;
+
+ /**
+ * Path to add to PHP include_path to aid in finding specified class.
+ * @var Path
+ */
+ private $classpath;
+
+ /**
+ * Refid to already defined classpath
+ */
+ private $classpathId;
+
+ /**
+ * 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->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->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) {
+ $this->classpathId = $r->getRefId();
+ $this->createClasspath()->setRefid($r);
+ }
+
+ /**
+ * Sets the name that will be used in XML buildfile.
+ * @param string $name
+ */
+ public function setName($name) {
+ $this->name = $name;
+ }
+
+ /**
+ * Sets the class name / dotpath to use.
+ * @param string $class
+ */
+ public function setClassname($class) {
+ $this->classname = $class;
+ }
+
+ /** Main entry point */
+ public function main() {
+ if ($this->name === null || $this->classname === null) {
+ throw new BuildException("You must specify name and class attributes for <taskdef>.");
+ }
+ $this->log("Task " . $this->name . " will be handled by class " . $this->classname, PROJECT_MSG_VERBOSE);
+ $this->project->addTaskDefinition($this->name, $this->classname, $this->classpath);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/TouchTask.php b/buildscripts/phing/classes/phing/tasks/system/TouchTask.php
new file mode 100644
index 00000000..6c6c4080
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/TouchTask.php
@@ -0,0 +1,170 @@
+<?php
+/*
+ * $Id: TouchTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/util/DirectoryScanner.php';
+include_once 'phing/types/FileSet.php';
+include_once 'phing/util/FileUtils.php';
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/system/io/IOException.php';
+
+/**
+ * Touch a file and/or fileset(s); corresponds to the Unix touch command.
+ *
+ * If the file to touch doesn't exist, an empty one is created.
+ *
+ * @version $Revision: 1.12 $
+ * @package phing.tasks.system
+ */
+class TouchTask extends Task {
+
+ private $file;
+ private $millis = -1;
+ private $dateTime;
+ private $filesets = array();
+ private $fileUtils;
+
+ function __construct() {
+ $this->fileUtils = new FileUtils();
+ }
+
+ /**
+ * Sets a single source file to touch. If the file does not exist
+ * an empty file will be created.
+ */
+ function setFile(PhingFile $file) {
+ $this->file = $file;
+ }
+
+ /**
+ * the new modification time of the file
+ * in milliseconds since midnight Jan 1 1970.
+ * Optional, default=now
+ */
+ function setMillis($millis) {
+ $this->millis = (int) $millis;
+ }
+
+ /**
+ * the new modification time of the file
+ * in the format MM/DD/YYYY HH:MM AM or PM;
+ * Optional, default=now
+ */
+ function setDatetime($dateTime) {
+ $this->dateTime = (string) $dateTime;
+ }
+
+ /**
+ * Nested creator, adds a set of files (nested fileset attribute).
+ * @return FileSet
+ */
+ function createFileSet() {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * Execute the touch operation.
+ */
+ function main() {
+ $savedMillis = $this->millis;
+
+ if ($this->file === null && count($this->filesets) === 0) {
+ throw new BuildException("Specify at least one source - a file or a fileset.");
+ }
+
+ if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) {
+ throw new BuildException("Use a fileset to touch directories.");
+ }
+
+ try { // try to touch file
+ if ($this->dateTime !== null) {
+ $this->setMillis(strtotime($this->dateTime));
+ if ($this->millis < 0) {
+ throw new BuildException("Date of {$this->dateTime} results in negative milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT).");
+ }
+ }
+ $this->_touch();
+ } catch (Exception $ex) {
+ throw new BuildException("Error touch()ing file", $ex, $this->location);
+ }
+
+ $this->millis = $savedMillis;
+
+ }
+
+ /**
+ * Does the actual work.
+ */
+ function _touch() {
+ if ($this->file !== null) {
+ if (!$this->file->exists()) {
+ $this->log("Creating " . $this->file->__toString(), PROJECT_MSG_INFO);
+ try { // try to create file
+ $this->file->createNewFile();
+ } catch(IOException $ioe) {
+ throw new BuildException("Error creating new file " . $this->file->__toString(), $ioe, $this->location);
+ }
+ }
+ }
+
+ $resetMillis = false;
+ if ($this->millis < 0) {
+ $resetMillis = true;
+ $this->millis = Phing::currentTimeMillis();
+ }
+
+ if ($this->file !== null) {
+ $this->touchFile($this->file);
+ }
+
+ // deal with the filesets
+ foreach($this->filesets as $fs) {
+
+ $ds = $fs->getDirectoryScanner($this->getProject());
+ $fromDir = $fs->getDir($this->getProject());
+
+ $srcFiles = $ds->getIncludedFiles();
+ $srcDirs = $ds->getIncludedDirectories();
+
+ for ($j=0,$_j=count($srcFiles); $j < $_j; $j++) {
+ $this->touchFile(new PhingFile($fromDir, (string) $srcFiles[$j]));
+ }
+
+ for ($j=0,$_j=count($srcDirs); $j < $_j ; $j++) {
+ $this->touchFile(new PhingFile($fromDir, (string) $srcDirs[$j]));
+ }
+ }
+
+ if ($resetMillis) {
+ $this->millis = -1;
+ }
+ }
+
+ private function touchFile($file) {
+ if ( !$file->canWrite() ) {
+ throw new BuildException("Can not change modification date of read-only file " . $file->__toString());
+ }
+ $file->setLastModified($this->millis);
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/system/TstampTask.php b/buildscripts/phing/classes/phing/tasks/system/TstampTask.php
new file mode 100644
index 00000000..9341c3dd
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/TstampTask.php
@@ -0,0 +1,168 @@
+<?php
+/*
+ * $Id: TstampTask.php 58 2006-04-28 14:41:04Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Sets properties to the current time, or offsets from the current time.
+ * The default properties are TSTAMP, DSTAMP and TODAY;
+ *
+ * Based on Ant's Tstamp task.
+ *
+ * @author Michiel Rook <michiel@trendserver.nl>
+ * @version $Revision: 1.6 $
+ * @package phing.tasks.system
+ * @since 2.2.0
+ */
+class TstampTask extends Task
+{
+ private $customFormats = array();
+
+ private $prefix = "";
+
+ /**
+ * Set a prefix for the properties. If the prefix does not end with a "."
+ * one is automatically added.
+ * @param prefix the prefix to use.
+ */
+ public function setPrefix($prefix)
+ {
+ $this->prefix = $prefix;
+
+ if (!empty($this->prefix))
+ {
+ $this->prefix.= ".";
+ }
+ }
+
+ /**
+ * Adds a custom format
+ *
+ * @param TstampCustomFormat custom format
+ */
+ public function addFormat(TstampCustomFormat $cf)
+ {
+ $this->customFormats[] = $cf;
+ }
+
+ /**
+ * Create the timestamps. Custom ones are done before
+ * the standard ones.
+ *
+ * @throws BuildException
+ */
+ public function main()
+ {
+ foreach ($this->customFormats as $cf)
+ {
+ $cf->execute($this);
+ }
+
+ $dstamp = strftime('%Y%m%d');
+ $this->prefixProperty('DSTAMP', $dstamp);
+
+ $tstamp = strftime('%H%M');
+ $this->prefixProperty('TSTAMP', $tstamp);
+
+ $today = strftime('%B %d %Y');
+ $this->prefixProperty('TODAY', $today);
+ }
+
+ /**
+ * helper that encapsulates prefix logic and property setting
+ * policy (i.e. we use setNewProperty instead of setProperty).
+ */
+ public function prefixProperty($name, $value)
+ {
+ $this->getProject()->setNewProperty($this->prefix . $name, $value);
+ }
+}
+
+class TstampCustomFormat
+{
+ private $propertyName = "";
+ private $pattern = "";
+ private $locale = "";
+
+ /**
+ * The property to receive the date/time string in the given pattern
+ *
+ * @param propertyName the name of the property.
+ */
+ public function setProperty($propertyName)
+ {
+ $this->propertyName = $propertyName;
+ }
+
+ /**
+ * The date/time pattern to be used. The values are as
+ * defined by the PHP strftime() function.
+ *
+ * @param pattern
+ */
+ public function setPattern($pattern)
+ {
+ $this->pattern = $pattern;
+ }
+
+ /**
+ * The locale used to create date/time string.
+ *
+ * @param locale
+ */
+ public function setLocale($locale)
+ {
+ $this->locale = $locale;
+ }
+
+ /**
+ * validate parameter and execute the format.
+ *
+ * @param TstampTask reference to task
+ */
+ public function execute(TstampTask $tstamp)
+ {
+ if (empty($this->propertyName))
+ {
+ throw new BuildException("property attribute must be provided");
+ }
+
+ if (empty($this->pattern))
+ {
+ throw new BuildException("pattern attribute must be provided");
+ }
+
+ if (!empty($this->locale))
+ {
+ setlocale(LC_ALL, $this->locale);
+ }
+
+ $value = strftime($this->pattern);
+ $tstamp->prefixProperty($this->propertyName, $value);
+
+ if (!empty($this->locale))
+ {
+ // reset locale
+ setlocale(LC_ALL, NULL);
+ }
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/tasks/system/TypedefTask.php b/buildscripts/phing/classes/phing/tasks/system/TypedefTask.php
new file mode 100644
index 00000000..de058c90
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/TypedefTask.php
@@ -0,0 +1,125 @@
+<?php
+/*
+ * $Id: TypedefTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+
+/**
+ * Register a datatype for use within a buildfile.
+ *
+ * This is for registering your own datatypes for use within a buildfile.
+ *
+ * If you find that you are using a particular class frequently, you may want to edit the
+ * phing/types/defaults.properties file so that it is included by default. You may also
+ * want to submit it (if LGPL or compatible license) to be included in Phing distribution.
+ *
+ * <pre>
+ * <typedef name="mytype" classname="path.to.MyHandlingClass"/>
+ * .
+ * <sometask ...>
+ * <mytype param1="val1" param2="val2"/>
+ * </sometask>
+ * </pre>
+ *
+ * TODO:
+ * -- possibly refactor since this is almost the same as TaskDefTask
+ * (right now these are just too simple to really justify creating an abstract class)
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.7 $
+ * @package phing.tasks.system
+ */
+class TypedefTask extends Task {
+
+ /** Tag name for datatype that will be used in XML */
+ private $name;
+
+ /**
+ * Classname of task to register.
+ * This can be a dot-path -- relative to a location on PHP include_path.
+ * E.g. path.to.MyClass -> path/to/MyClass.php
+ * @var string
+ */
+ private $classname;
+
+ /**
+ * Path to add to PHP include_path to aid in finding specified class.
+ * @var Path
+ */
+ private $classpath;
+
+ /** Refid to already defined classpath */
+ private $classpathId;
+
+ /**
+ * 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->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->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) {
+ $this->classpathId = $r->getRefId();
+ $this->createClasspath()->setRefid($r);
+ }
+
+ /** Main entry point */
+ public function main() {
+ if ($this->name === null || $this->classname === null) {
+ throw new BuildException("You must specify name and class attributes for <typedef>.");
+ }
+ $this->project->addDataTypeDefinition($this->name, $this->classname, $this->classpath);
+ }
+
+ /**
+ * Sets the name that will be used in XML buildfile.
+ * @param string $name
+ */
+ public function setName($name) {
+ $this->name = $name;
+ }
+
+ /**
+ * Sets the class name / dotpath to use.
+ * @param string $class
+ */
+ public function setClassname($class) {
+ $this->classname = $class;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/UpToDateTask.php b/buildscripts/phing/classes/phing/tasks/system/UpToDateTask.php
new file mode 100644
index 00000000..720fae12
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/UpToDateTask.php
@@ -0,0 +1,217 @@
+<?php
+/*
+ * $Id: UpToDateTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Task.php';
+include_once 'phing/tasks/system/condition/Condition.php';
+include_once 'phing/util/DirectoryScanner.php';
+include_once 'phing/util/SourceFileScanner.php';
+include_once 'phing/mappers/MergeMapper.php';
+
+/**
+ * Sets the given property if the specified target has a timestamp
+ * greater than all of the source files.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author William Ferguson <williamf@mincom.com> (Ant)
+ * @author Hiroaki Nakamura <hnakamur@mc.neweb.ne.jp> (Ant)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.6 $
+ * @package phing.tasks.system
+ */
+class UpToDateTask extends Task implements Condition {
+
+ private $_property;
+ private $_value;
+ private $_sourceFile;
+ private $_targetFile;
+ private $sourceFileSets = array();
+
+ protected $mapperElement = null;
+
+ /**
+ * The property to set if the target file is more up-to-date than
+ * (each of) the source file(s).
+ *
+ * @param property the name of the property to set if Target is up-to-date.
+ */
+ public function setProperty($property) {
+ $this->_property = $property;
+ }
+
+ /**
+ * The value to set the named property to if the target file is more
+ * up-to-date than (each of) the source file(s). Defaults to 'true'.
+ *
+ * @param value the value to set the property to if Target is up-to-date
+ */
+ public function setValue($value) {
+ $this->_value = $value;
+ }
+
+ /**
+ * Returns the value, or "true" if a specific value wasn't provided.
+ */
+ private function getValue() {
+ return ($this->_value !== null) ? $this->_value : "true";
+ }
+
+ /**
+ * The file which must be more up-to-date than (each of) the source file(s)
+ * if the property is to be set.
+ *
+ * @param file the file we are checking against.
+ */
+ public function setTargetFile($file) {
+ if (is_string($file)) {
+ $file = new PhingFile($file);
+ }
+ $this->_targetFile = $file;
+ }
+
+ /**
+ * The file that must be older than the target file
+ * if the property is to be set.
+ *
+ * @param file the file we are checking against the target file.
+ */
+ public function setSrcfile($file) {
+ if (is_string($file)) {
+ $file = new PhingFile($file);
+ }
+ $this->_sourceFile = $file;
+ }
+
+ /**
+ * Nested <srcfiles> element.
+ */
+ public function createSrcfiles() {
+ $fs = new FileSet();
+ $this->sourceFileSets[] = $fs;
+ return $fs;
+ }
+
+ /**
+ * Defines the FileNameMapper to use (nested mapper element).
+ */
+ public function createMapper() {
+ if ($this->mapperElement !== null) {
+ throw new BuildException("Cannot define more than one mapper",
+ $this->location);
+ }
+ $this->mapperElement = new Mapper($this->getProject());
+ return $this->mapperElement;
+ }
+
+ /**
+ * Evaluate (all) target and source file(s) to
+ * see if the target(s) is/are up-to-date.
+ * @return boolean
+ */
+ public function evaluate() {
+ if (count($this->sourceFileSets) === 0 && $this->_sourceFile === null) {
+ throw new BuildException("At least one srcfile or a nested "
+ . "<srcfiles> element must be set.");
+ }
+
+ if (count($this->sourceFileSets) > 0 && $this->_sourceFile !== null) {
+ throw new BuildException("Cannot specify both the srcfile "
+ . "attribute and a nested <srcfiles> "
+ . "element.");
+ }
+
+ if ($this->_targetFile === null && $this->mapperElement === null) {
+ throw new BuildException("The targetfile attribute or a nested "
+ . "mapper element must be set.");
+ }
+
+ // if the target file is not there, then it can't be up-to-date
+ if ($this->_targetFile !== null && !$this->_targetFile->exists()) {
+ return false;
+ }
+
+ // if the source file isn't there, throw an exception
+ if ($this->_sourceFile !== null && !$this->_sourceFile->exists()) {
+ throw new BuildException($this->_sourceFile->getAbsolutePath()
+ . " not found.");
+ }
+
+ $upToDate = true;
+ for($i=0,$size=count($this->sourceFileSets); $i < $size && $upToDate; $i++) {
+ $fs = $this->sourceFileSets[$i];
+ $ds = $fs->getDirectoryScanner($this->project);
+ $upToDate = $upToDate && $this->scanDir($fs->getDir($this->project),
+ $ds->getIncludedFiles());
+ }
+
+ if ($this->_sourceFile !== null) {
+ if ($this->mapperElement === null) {
+ $upToDate = $upToDate &&
+ ($this->_targetFile->lastModified() >= $this->_sourceFile->lastModified());
+ } else {
+ $sfs = new SourceFileScanner($this);
+ $upToDate = $upToDate &&
+ count($sfs->restrict($this->_sourceFile->getAbsolutePath(),
+ null, null,
+ $this->mapperElement->getImplementation())) === 0;
+ }
+ }
+ return $upToDate;
+ }
+
+
+ /**
+ * Sets property to true if target file(s) have a more recent timestamp
+ * than (each of) the corresponding source file(s).
+ * @throws BuildException
+ */
+ public function main() {
+ if ($this->_property === null) {
+ throw new BuildException("property attribute is required.",
+ $this->location);
+ }
+ $upToDate = $this->evaluate();
+ if ($upToDate) {
+ $this->project->setNewProperty($this->_property, $this->getValue());
+ if ($this->mapperElement === null) {
+ $this->log("File \"" . $this->_targetFile->getAbsolutePath()
+ . "\" is up-to-date.", PROJECT_MSG_VERBOSE);
+ } else {
+ $this->log("All target files are up-to-date.",
+ PROJECT_MSG_VERBOSE);
+ }
+ }
+ }
+
+ protected function scanDir(PhingFile $srcDir, $files) {
+ $sfs = new SourceFileScanner($this);
+ $mapper = null;
+ $dir = $srcDir;
+ if ($this->mapperElement === null) {
+ $mm = new MergeMapper();
+ $mm->setTo($this->_targetFile->getAbsolutePath());
+ $mapper = $mm;
+ $dir = null;
+ } else {
+ $mapper = $this->mapperElement->getImplementation();
+ }
+ return (count($sfs->restrict($files, $srcDir, $dir, $mapper)) === 0);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/WarnTask.php b/buildscripts/phing/classes/phing/tasks/system/WarnTask.php
new file mode 100644
index 00000000..50318e71
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/WarnTask.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * $Id: WarnTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/EchoTask.php';
+
+/**
+ * Simple task to echo a warning message (PROJECT_MSG_WARN) to all output devices.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.1 $ $Date: 2006-04-28 10:49:47 -0400 (Fri, 28 Apr 2006) $
+ * @package phing.tasks.system
+ */
+class WarnTask extends EchoTask {
+ function main() {
+ $this->log($this->msg, PROJECT_MSG_WARN);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/XsltTask.php b/buildscripts/phing/classes/phing/tasks/system/XsltTask.php
new file mode 100644
index 00000000..0374aa59
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/XsltTask.php
@@ -0,0 +1,81 @@
+<?php
+/*
+ * $Id: XsltTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/CopyTask.php';
+include_once 'phing/system/io/FileReader.php';
+include_once 'phing/system/io/FileWriter.php';
+include_once 'phing/filters/XsltFilter.php';
+
+/**
+ * Implements an XSLT processing filter while copying files.
+ *
+ * This is a shortcut for calling the <copy> task with the XSLTFilter used
+ * in the <filterchains> section.
+ *
+ * @author Andreas Aderhold, andi@binarycloud.com
+ * @version $Revision: 1.8 $
+ * @package phing.tasks.system
+ */
+class XsltTask extends CopyTask {
+
+ /** XSLTFilter object that we use to handle transformation. */
+ private $xsltFilter;
+
+ /** Parameters to pass to XSLT procesor. */
+ private $parameters = array();
+
+ /**
+ * Setup the filterchains w/ XSLTFilter that we will use while copying the files.
+ */
+ function init() {
+ $xf = new XsltFilter();
+ $chain = $this->createFilterChain($this->getProject());
+ $chain->addXsltFilter($xf);
+ $this->xsltFilter = $xf;
+ }
+
+ /**
+ * Set any XSLT Param and invoke CopyTask::main()
+ * @see CopyTask::main()
+ */
+ function main() {
+ $this->log("Doing XSLT transformation using stylesheet " . $this->xsltFilter->getStyle(), PROJECT_MSG_VERBOSE);
+ $this->xsltFilter->setParams($this->parameters);
+ parent::main();
+ }
+
+ /**
+ * Set the stylesheet to use.
+ * @param PhingFile $style
+ */
+ function setStyle(PhingFile $style) {
+ $this->xsltFilter->setStyle($style);
+ }
+
+ /**
+ * Support nested <param> tags useing XSLTParam class.
+ * @return XSLTParam
+ */
+ function createParam() {
+ $num = array_push($this->parameters, new XSLTParam());
+ return $this->parameters[$num-1];
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/AndCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/AndCondition.php
new file mode 100644
index 00000000..c16ce499
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/AndCondition.php
@@ -0,0 +1,46 @@
+<?php
+/*
+ * $Id: AndCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/condition/ConditionBase.php';
+
+/**
+ * <and> condition container.
+ *
+ * Iterates over all conditions and returns false as soon as one
+ * evaluates to false.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version $Revision: 1.7 $
+ * @package phing.tasks.system.condition
+ */
+class AndCondition extends ConditionBase implements Condition {
+
+ public function evaluate() {
+ foreach($this as $c) { // ConditionBase implements IteratorAggregator
+ if (!$c->evaluate()) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/Condition.php b/buildscripts/phing/classes/phing/tasks/system/condition/Condition.php
new file mode 100644
index 00000000..73e0c232
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/Condition.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * $Id: Condition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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>.
+ */
+
+/**
+ * Condition interface specification:
+ *
+ * Each condition must implement a method applying to this prototye:
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.4 $
+ * @package phing.tasks.system.condition
+ */
+interface Condition {
+ /**
+ * @return boolean
+ * @throws BuildException
+ */
+ public function evaluate();
+}
+?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/ConditionBase.php b/buildscripts/phing/classes/phing/tasks/system/condition/ConditionBase.php
new file mode 100644
index 00000000..1c09fe49
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/ConditionBase.php
@@ -0,0 +1,195 @@
+<?php
+/*
+ * $Id: ConditionBase.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/Project.php';
+include_once 'phing/tasks/system/AvailableTask.php';
+include_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Abstract baseclass for the <condition> task as well as several
+ * conditions - ensures that the types of conditions inside the task
+ * and the "container" conditions are in sync.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version $Revision: 1.16 $
+ * @package phing.tasks.system.condition
+ */
+abstract class ConditionBase extends ProjectComponent implements IteratorAggregate {
+
+ public $conditions = array(); // needs to be public for "inner" class access
+
+ function countConditions() {
+ return count($this->conditions);
+ }
+
+ /**
+ * Required for IteratorAggregate
+ */
+ function getIterator() {
+ return new ConditionEnumeration($this);
+ }
+
+ function getConditions() {
+ return $this->conditions;
+ }
+
+ /**
+ * @return void
+ */
+ function addAvailable(AvailableTask $a) {
+ $this->conditions[] = $a;
+ }
+
+ /**
+ * @return NotCondition
+ */
+ function createNot() {
+ include_once 'phing/tasks/system/condition/NotCondition.php';
+ $num = array_push($this->conditions, new NotCondition());
+ return $this->conditions[$num-1];
+ }
+
+ /**
+ * @return AndCondition
+ */
+ function createAnd() {
+ include_once 'phing/tasks/system/condition/AndCondition.php';
+ $num = array_push($this->conditions, new AndCondition());
+ return $this->conditions[$num-1];
+ }
+
+ /**
+ * @return OrCondition
+ */
+ function createOr() {
+ include_once 'phing/tasks/system/condition/OrCondition.php';
+ $num = array_push($this->conditions, new OrCondition());
+ return $this->conditions[$num-1];
+ }
+
+ /**
+ * @return EqualsCondition
+ */
+ function createEquals() {
+ include_once 'phing/tasks/system/condition/EqualsCondition.php';
+ $num = array_push($this->conditions, new EqualsCondition());
+ return $this->conditions[$num-1];
+ }
+
+ /**
+ * @return OsCondition
+ */
+ function createOs() {
+ include_once 'phing/tasks/system/condition/OsCondition.php';
+ $num = array_push($this->conditions, new OsCondition());
+ return $this->conditions[$num-1];
+ }
+
+ /**
+ * @return IsFalseCondition
+ */
+ function createIsFalse() {
+ include_once 'phing/tasks/system/condition/IsFalseCondition.php';
+ $num = array_push($this->conditions, new IsFalseCondition());
+ return $this->conditions[$num-1];
+ }
+
+ /**
+ * @return IsTrueCondition
+ */
+ function createIsTrue() {
+ include_once 'phing/tasks/system/condition/IsTrueCondition.php';
+ $num = array_push($this->conditions, new IsTrueCondition());
+ return $this->conditions[$num-1];
+ }
+
+ /**
+ * @return ContainsCondition
+ */
+ function createContains() {
+ include_once 'phing/tasks/system/condition/ContainsCondition.php';
+ $num = array_push($this->conditions, new ContainsCondition());
+ return $this->conditions[$num-1];
+ }
+
+ /**
+ * @return IsSetCondition
+ */
+ function createIsSet() {
+ include_once 'phing/tasks/system/condition/IsSetCondition.php';
+ $num = array_push($this->conditions, new IsSetCondition());
+ return $this->conditions[$num-1];
+ }
+
+ /**
+ * @return ReferenceExistsCondition
+ */
+ function createReferenceExists() {
+ include_once 'phing/tasks/system/condition/ReferenceExistsCondition.php';
+ $num = array_push($this->conditions, new ReferenceExistsCondition());
+ return $this->conditions[$num-1];
+ }
+
+}
+
+/**
+ * "Inner" class for handling enumerations.
+ * Uses build-in PHP5 iterator support.
+ */
+class ConditionEnumeration implements Iterator {
+
+ /** Current element number */
+ private $num = 0;
+
+ /** "Outer" ConditionBase class. */
+ private $outer;
+
+ function __construct(ConditionBase $outer) {
+ $this->outer = $outer;
+ }
+
+ public function valid() {
+ return $this->outer->countConditions() > $this->num;
+ }
+
+ function current() {
+ $o = $this->outer->conditions[$this->num];
+ if ($o instanceof ProjectComponent) {
+ $o->setProject($this->outer->getProject());
+ }
+ return $o;
+ }
+
+ function next() {
+ $this->num++;
+ }
+
+ function key() {
+ return $this->num;
+ }
+
+ function rewind() {
+ $this->num = 0;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/ContainsCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/ContainsCondition.php
new file mode 100644
index 00000000..95849cd8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/ContainsCondition.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * $Id: ContainsCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/condition/Condition.php';
+
+/**
+ * Is one string part of another string?
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.3 $
+ * @package phing.tasks.system.condition
+ */
+class ContainsCondition implements Condition {
+
+ private $string;
+ private $subString;
+ private $caseSensitive = true;
+
+ /**
+ * The string to search in.
+ * @param string $a1
+ */
+ public function setString($a1) {
+ $this->string = $a1;
+ }
+
+ /**
+ * The string to search for.
+ * @param string $a2
+ */
+ public function setSubstring($a2) {
+ $this->subString = $a2;
+ }
+
+ /**
+ * Whether to search ignoring case or not.
+ */
+ public function setCaseSensitive($b) {
+ $this->caseSensitive = (boolean) $b;
+ }
+
+ /**
+ * Check whether string contains substring.
+ * @throws BuildException
+ */
+ public function evaluate() {
+ if ($this->string === null || $this->subString === null) {
+ throw new BuildException("both string and substring are required "
+ . "in contains");
+ }
+
+ return $this->caseSensitive
+ ? strpos($this->string, $this->subString) !== false
+ : substr(strtolower($this->string), strtolower($this->subString)) !== false;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/EqualsCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/EqualsCondition.php
new file mode 100644
index 00000000..32d51380
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/EqualsCondition.php
@@ -0,0 +1,78 @@
+<?php
+/*
+ * $Id: EqualsCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/condition/Condition.php';
+
+/**
+ * A simple string comparator. Compares two strings for eqiality in a
+ * binary safe manner. Implements the condition interface specification.
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version $Revision: 1.7 $ $Date: 2006-04-28 10:49:47 -0400 (Fri, 28 Apr 2006) $
+ * @access public
+ * @package phing.tasks.system.condition
+ */
+class EqualsCondition implements Condition {
+
+ private $arg1;
+ private $arg2;
+ private $trim = false;
+ private $caseSensitive = true;
+
+ public function setArg1($a1) {
+ $this->arg1 = $a1;
+ }
+
+ public function setArg2($a2) {
+ $this->arg2 = $a2;
+ }
+
+ /**
+ * Should we want to trim the arguments before comparing them?
+ * @param boolean $b
+ */
+ public function setTrim($b) {
+ $this->trim = (boolean) $b;
+ }
+
+ /**
+ * Should the comparison be case sensitive?
+ * @param boolean $b
+ */
+ public function setCaseSensitive($b) {
+ $this->caseSensitive = (boolean) $b;
+ }
+
+ public function evaluate() {
+ if ($this->arg1 === null || $this->arg2 === null) {
+ throw new BuildException("Both arg1 and arg2 are required in equals.");
+ }
+
+ if ($this->trim) {
+ $this->arg1 = trim($this->arg1);
+ $this->arg2 = trim($this->arg2);
+ }
+
+ //print("[comparison] Comparing '".$this->arg1."' and '".$this->arg2."'\n");
+ return $this->caseSensitive ? $this->arg1 === $this->arg2 : strtolower($this->arg1) === strtolower($this->arg2);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/IsFalseCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/IsFalseCondition.php
new file mode 100644
index 00000000..ebbd1a3d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/IsFalseCondition.php
@@ -0,0 +1,60 @@
+<?php
+/*
+ * $Id: IsFalseCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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';
+require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Condition that tests whether a given string evals to false.
+ *
+ * @author Hans Lellelid (Phing)
+ * @author Steve Loughran (Ant)
+ * @version $Revision: 1.4 $
+ * @package phing.tasks.system.condition
+ */
+class IsFalseCondition extends ProjectComponent implements Condition {
+
+ /**
+ * what we eval
+ */
+ private $value;
+
+ /**
+ * Set the value to be tested.
+ * @param boolean $value
+ */
+ public function setValue($value) {
+ $this->value = $value;
+ }
+
+ /**
+ * return the inverted value;
+ * @throws BuildException if someone forgot to spec a value
+ */
+ public function evaluate() {
+ if ($this->value === null) {
+ throw new BuildException("Nothing to test for falsehood");
+ }
+ return !$this->value;
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/IsSetCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/IsSetCondition.php
new file mode 100644
index 00000000..4f81c50f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/IsSetCondition.php
@@ -0,0 +1,53 @@
+<?php
+/*
+ * $Id: IsSetCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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';
+require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Condition that tests whether a given property has been set.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.4 $
+ * @package phing.tasks.system.condition
+ */
+class IsSetCondition extends ProjectComponent implements Condition {
+
+ private $property;
+
+ public function setProperty($p) {
+ $this->property = $p;
+ }
+
+ /**
+ * Check whether property is set.
+ * @throws BuildException
+ */
+ public function evaluate() {
+ if ($this->property === null) {
+ throw new BuildException("No property specified for isset "
+ . "condition");
+ }
+ return $this->project->getProperty($this->property) !== null;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/IsTrueCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/IsTrueCondition.php
new file mode 100644
index 00000000..4affefc5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/IsTrueCondition.php
@@ -0,0 +1,59 @@
+<?php
+/*
+ * $Id: IsTrueCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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';
+require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Condition that tests whether a given string evals to true.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Steve Loughran (Ant)
+ * @package phing.tasks.system.condition
+ */
+class IsTrueCondition extends ProjectComponent implements Condition {
+
+ /**
+ * what we eval
+ */
+ private $value;
+
+ /**
+ * Set the value to be tested.
+ * @param boolean $value
+ */
+ public function setValue($value) {
+ $this->value = $value;
+ }
+
+ /**
+ * return the inverted value;
+ * @throws BuildException if someone forgot to spec a value
+ */
+ public function evaluate() {
+ if ($this->value === null) {
+ throw new BuildException("Nothing to test for falsehood");
+ }
+ return $this->value;
+ }
+
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/NotCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/NotCondition.php
new file mode 100644
index 00000000..c76ef2b8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/NotCondition.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * $Id: NotCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/condition/ConditionBase.php';
+
+/**
+ * <not> condition.
+ *
+ * Evaluates to true if the single condition nested into it is false
+ * and vice versa.
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version $Revision: 1.6 $ $Date: 2006-04-28 10:49:47 -0400 (Fri, 28 Apr 2006) $
+ * @access public
+ * @package phing.tasks.system.condition
+ */
+class NotCondition extends ConditionBase implements Condition {
+
+ function evaluate() {
+ if ($this->countConditions() > 1) {
+ throw new BuildException("You must not nest more than one condition into <not>");
+ }
+ if ($this->countConditions() < 1) {
+ throw new BuildException("You must nest a condition into <not>");
+ }
+ $conds = $this->getIterator();
+ return !$conds->current()->evaluate();
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/OrCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/OrCondition.php
new file mode 100644
index 00000000..778abfd0
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/OrCondition.php
@@ -0,0 +1,46 @@
+<?php
+/*
+ * $Id: OrCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/condition/ConditionBase.php';
+
+/**
+ * <or> condition container.
+ *
+ * Iterates over all conditions and returns true as soon as one
+ * evaluates to true.
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @copyright 2001,2002 THYRELL. All rights reserved
+ * @version $Revision: 1.8 $ $Date: 2006-04-28 10:49:47 -0400 (Fri, 28 Apr 2006) $
+ * @access public
+ * @package phing.tasks.system.condition
+ */
+class OrCondition extends ConditionBase implements Condition {
+
+ function evaluate() {
+ foreach($this as $c) { // ConditionBase implements IteratorAggregator
+ if ($c->evaluate()) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/OsCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/OsCondition.php
new file mode 100644
index 00000000..d80729e7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/OsCondition.php
@@ -0,0 +1,63 @@
+<?php
+/*
+ * $Id: OsCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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/tasks/system/condition/ConditionBase.php';
+
+/**
+ * Condition that tests the OS type.
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version $Revision: 1.8 $ $Date: 2006-04-28 10:49:47 -0400 (Fri, 28 Apr 2006) $
+ * @access public
+ * @package phing.tasks.system.condition
+ */
+class OsCondition implements Condition {
+
+ private $family;
+
+ function setFamily($f) {
+ $this->family = strtolower($f);
+ }
+
+ function evaluate() {
+ $osName = strtolower(Phing::getProperty("os.name"));
+
+ if ($this->family !== null) {
+ if ($this->family === "windows") {
+ return StringHelper::startsWith("win", $osName);
+ } elseif ($this->family === "mac") {
+ return (strpos($osName, "mac") !== false || strpos($osName, "darwin") !== false);
+ } elseif ($this->family === ("unix")) {
+ return (
+ StringHelper::endsWith("ix", $osName) ||
+ StringHelper::endsWith("ux", $osName) ||
+ StringHelper::endsWith("bsd", $osName) ||
+ StringHelper::startsWith("sunos", $osName) ||
+ StringHelper::startsWith("darwin", $osName)
+ );
+ }
+ throw new BuildException("Don't know how to detect os family '" . $this->family . "'");
+ }
+ return false;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/system/condition/ReferenceExistsCondition.php b/buildscripts/phing/classes/phing/tasks/system/condition/ReferenceExistsCondition.php
new file mode 100644
index 00000000..04c1cbbd
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/system/condition/ReferenceExistsCondition.php
@@ -0,0 +1,52 @@
+<?php
+/*
+ * $Id: ReferenceExistsCondition.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * 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'; require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Condition that tests whether a given reference exists.
+ *
+ * @author Matthias Pigulla <mp@webfactory.de> (Phing)
+ * @version $Revision: 1.1 $
+ * @package phing.tasks.system.condition */
+class ReferenceExistsCondition extends ProjectComponent implements Condition {
+
+ private $refid;
+
+ public function setRef($id) {
+ $this->refid = (string) $id;
+ }
+
+ /**
+ * Check whether the reference exists.
+ * @throws BuildException
+ */
+ public function evaluate() {
+ if ($this->refid === null) {
+ throw new BuildException("No ref attribute specified for reference-exists "
+ . "condition");
+ }
+ $refs = $this->project->getReferences();
+ return isset($refs[$this->refid]);
+ }
+
+}
+