summaryrefslogtreecommitdiff
path: root/buildscripts/phing/classes/phing/filters
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts/phing/classes/phing/filters')
-rw-r--r--buildscripts/phing/classes/phing/filters/BaseFilterReader.php157
-rw-r--r--buildscripts/phing/classes/phing/filters/BaseParamFilterReader.php69
-rw-r--r--buildscripts/phing/classes/phing/filters/ChainableReader.php42
-rw-r--r--buildscripts/phing/classes/phing/filters/ExpandProperties.php82
-rw-r--r--buildscripts/phing/classes/phing/filters/HeadFilter.php161
-rw-r--r--buildscripts/phing/classes/phing/filters/LineContains.php258
-rw-r--r--buildscripts/phing/classes/phing/filters/LineContainsRegexp.php179
-rw-r--r--buildscripts/phing/classes/phing/filters/PrefixLines.php142
-rw-r--r--buildscripts/phing/classes/phing/filters/ReplaceRegexp.php129
-rw-r--r--buildscripts/phing/classes/phing/filters/ReplaceTokens.php415
-rw-r--r--buildscripts/phing/classes/phing/filters/StripLineBreaks.php148
-rw-r--r--buildscripts/phing/classes/phing/filters/StripLineComments.php205
-rw-r--r--buildscripts/phing/classes/phing/filters/StripPhpComments.php190
-rw-r--r--buildscripts/phing/classes/phing/filters/TabToSpaces.php144
-rw-r--r--buildscripts/phing/classes/phing/filters/TailFilter.php157
-rw-r--r--buildscripts/phing/classes/phing/filters/TidyFilter.php162
-rw-r--r--buildscripts/phing/classes/phing/filters/TranslateGettext.php285
-rw-r--r--buildscripts/phing/classes/phing/filters/XsltFilter.php317
-rw-r--r--buildscripts/phing/classes/phing/filters/util/ChainReaderHelper.php184
-rw-r--r--buildscripts/phing/classes/phing/filters/util/IniFileTokenReader.php96
20 files changed, 3522 insertions, 0 deletions
diff --git a/buildscripts/phing/classes/phing/filters/BaseFilterReader.php b/buildscripts/phing/classes/phing/filters/BaseFilterReader.php
new file mode 100644
index 00000000..c9f8c619
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/BaseFilterReader.php
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ * $Id: BaseFilterReader.php,v 1.8 2004/05/20 02:24:10 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/system/io/FilterReader.php';
+include_once 'phing/system/io/StringReader.php';
+
+
+/**
+ * Base class for core filter readers.
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @version $Revision: 1.8 $ $Date: 2004/05/20 02:24:10 $
+ * @access public
+ * @see FilterReader
+ * @package phing.filters
+ */
+class BaseFilterReader extends FilterReader {
+
+ /** Have the parameters passed been interpreted? */
+ protected $initialized = false;
+
+ /** The Phing project this filter is part of. */
+ protected $project = null;
+
+ /**
+ * Constructor used by Phing's introspection mechanism.
+ * The original filter reader is only used for chaining
+ * purposes, never for filtering purposes (and indeed
+ * it would be useless for filtering purposes, as it has
+ * no real data to filter). ChainedReaderHelper uses
+ * this placeholder instance to create a chain of real filters.
+ *
+ * @param Reader $in
+ */
+ function __construct($in = null) {
+ if ($in === null) {
+ $dummy = "";
+ $in = new StringReader($dummy);
+ }
+ parent::__construct($in);
+ }
+
+ /**
+ * Returns the initialized status.
+ *
+ * @return boolean whether or not the filter is initialized
+ */
+ function getInitialized() {
+ return $this->initialized;
+ }
+
+ /**
+ * Sets the initialized status.
+ *
+ * @param boolean $initialized Whether or not the filter is initialized.
+ */
+ function setInitialized($initialized) {
+ $this->initialized = (boolean) $initialized;
+ }
+
+ /**
+ * Sets the project to work with.
+ *
+ * @param object $project The project this filter is part of.
+ * Should not be <code>null</code>.
+ */
+ function setProject(Project $project) {
+ // type check, error must never occur, bad code of it does
+ $this->project = $project;
+ }
+
+ /**
+ * Returns the project this filter is part of.
+ *
+ * @return object The project this filter is part of
+ */
+ function getProject() {
+ return $this->project;
+ }
+
+ /**
+ * Reads characters.
+ *
+ * @param off Offset at which to start storing characters.
+ * @param len Maximum number of characters to read.
+ *
+ * @return Characters read, or -1 if the end of the stream
+ * has been reached
+ *
+ * @throws IOException If an I/O error occurs
+ */
+ function read($len = null) {
+ return $this->in->read($len);
+ }
+
+ /**
+ * Reads a line of text ending with '\n' (or until the end of the stream).
+ * The returned String retains the '\n'.
+ *
+ * @return the line read, or <code>null</code> if the end of the
+ stream has already been reached
+ *
+ * @throws IOException if the underlying reader throws one during
+ * reading
+ */
+ function readLine() {
+ $line = null;
+
+ while ( ($ch = $this->in->read(1)) !== -1 ) {
+ $line .= $ch;
+ if ( $ch === "\n" )
+ break;
+ }
+
+ return $line;
+ }
+
+ /**
+ * Returns whether the end of file has been reached with input stream.
+ * @return boolean
+ */
+ function eof() {
+ return $this->in->eof();
+ }
+
+ /**
+ * Convenience method to support logging in filters.
+ * @param string $msg Message to log.
+ * @param int $level Priority level.
+ */
+ function log($msg, $level = PROJECT_MSG_INFO) {
+ if ($this->project !== null) {
+ $this->project->log("[filter:".get_class($this)."] ".$msg, $level);
+ }
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/BaseParamFilterReader.php b/buildscripts/phing/classes/phing/filters/BaseParamFilterReader.php
new file mode 100644
index 00000000..3d767b40
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/BaseParamFilterReader.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * $Id: BaseParamFilterReader.php,v 1.5 2005/02/27 20:52:08 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/types/Parameterizable.php';
+include_once 'phing/types/Parameter.php';
+
+/**
+ * Base class for core filter readers.
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @copyright © 2003 seasonfive. All rights reserved
+ * @version $Revision: 1.5 $ $Date: 2005/02/27 20:52:08 $
+ * @access public
+ * @see FilterReader
+ * @package phing.filters
+ */
+class BaseParamFilterReader extends BaseFilterReader implements Parameterizable {
+
+ /** The passed in parameter array. */
+ protected $_parameters = array();
+
+ /*
+ * Sets the parameters used by this filter, and sets
+ * the filter to an uninitialized status.
+ *
+ * @param array Array of parameters to be used by this filter.
+ * Should not be <code>null</code>.
+ */
+ function setParameters($parameters) {
+ // type check, error must never occur, bad code of it does
+ if ( !is_array($parameters) ) {
+ throw new Exception("Expected parameters array got something else");
+ }
+
+ $this->_parameters = $parameters;
+ $this->setInitialized(false);
+ }
+
+ /*
+ * Returns the parameters to be used by this filter.
+ *
+ * @return the parameters to be used by this filter
+ */
+ function &getParameters() {
+ return $this->_parameters;
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/ChainableReader.php b/buildscripts/phing/classes/phing/filters/ChainableReader.php
new file mode 100644
index 00000000..c7de07c4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/ChainableReader.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * $Id: ChainableReader.php,v 1.2 2003/11/19 05:48:27 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+/**
+ * Interface indicating that a reader may be chained to another one.
+ *
+ * @author Magesh Umasankar
+ */
+interface ChainableReader {
+
+ /**
+ * Returns a reader with the same configuration as this one,
+ * but filtering input from the specified reader.
+ *
+ * @param Reader $rdr the reader which the returned reader should be filtering
+ *
+ * @return Reader A reader with the same configuration as this one, but
+ * filtering input from the specified reader
+ */
+ public function chain(Reader $rdr);
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/ExpandProperties.php b/buildscripts/phing/classes/phing/filters/ExpandProperties.php
new file mode 100644
index 00000000..dfd98cc8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/ExpandProperties.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * $Id: ExpandProperties.php,v 1.6 2004/07/14 17:14:15 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Expands Phing Properties, if any, in the data.
+ * <p>
+ * Example:<br>
+ * <pre><expandproperties/></pre>
+ * Or:
+ * <pre><filterreader classname="phing.filters.ExpandProperties'/></pre>
+ *
+ * @author Yannick Lecaillez <yl@seasonfive.com>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.6 $
+ * @see BaseFilterReader
+ * @package phing.filters
+ */
+class ExpandProperties extends BaseFilterReader implements ChainableReader {
+
+ /**
+ * Returns the filtered stream.
+ * The original stream is first read in fully, and the Phing properties are expanded.
+ *
+ * @return mixed the filtered stream, or -1 if the end of the resulting stream has been reached.
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ function read($len = null) {
+
+ $buffer = $this->in->read($len);
+
+ if($buffer === -1) {
+ return -1;
+ }
+
+ $project = $this->getProject();
+ $buffer = ProjectConfigurator::replaceProperties($project, $buffer, $project->getProperties());
+
+ return $buffer;
+ }
+
+ /**
+ * Creates a new ExpandProperties filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param object A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return object A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new ExpandProperties($reader);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/HeadFilter.php b/buildscripts/phing/classes/phing/filters/HeadFilter.php
new file mode 100644
index 00000000..84673b4a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/HeadFilter.php
@@ -0,0 +1,161 @@
+<?php
+
+/*
+ * $Id: HeadFilter.php,v 1.6 2004/03/15 14:45:06 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Reads the first <code>n</code> lines of a stream.
+ * (Default is first 10 lines.)
+ * <p>
+ * Example:
+ * <pre><headfilter lines="3"/></pre>
+ * Or:
+ * <pre><filterreader classname="phing.filters.HeadFilter">
+ * <param name="lines" value="3"/>
+ * </filterreader></pre>
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author hans lellelid, hans@velum.net
+ * @version $Revision: 1.6 $ $Date: 2004/03/15 14:45:06 $
+ * @access public
+ * @see FilterReader
+ * @package phing.filters
+ */
+class HeadFilter extends BaseParamFilterReader implements ChainableReader {
+
+ /**
+ * Parameter name for the number of lines to be returned.
+ */
+ const LINES_KEY = "lines";
+
+ /**
+ * Number of lines currently read in.
+ * @var integer
+ */
+ private $_linesRead = 0;
+
+ /**
+ * Number of lines to be returned in the filtered stream.
+ * @var integer
+ */
+ private $_lines = 10;
+
+ /**
+ * Returns first n lines of stream.
+ * @return the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ function read($len = null) {
+
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ // note, if buffer contains fewer lines than
+ // $this->_lines this code will not work.
+
+ if($this->_linesRead < $this->_lines) {
+
+ $buffer = $this->in->read($len);
+
+ if($buffer === -1) {
+ return -1;
+ }
+
+ // now grab first X lines from buffer
+
+ $lines = explode("\n", $buffer);
+
+ $linesCount = count($lines);
+
+ // must account for possibility that the num lines requested could
+ // involve more than one buffer read.
+ $len = ($linesCount > $this->_lines ? $this->_lines - $this->_linesRead : $linesCount);
+ $filtered_buffer = implode("\n", array_slice($lines, 0, $len) );
+ $this->_linesRead += $len;
+
+ return $filtered_buffer;
+
+ }
+
+ return -1; // EOF, since the file is "finished" as far as subsequent filters are concerned.
+ }
+
+ /**
+ * Sets the number of lines to be returned in the filtered stream.
+ *
+ * @param integer $lines the number of lines to be returned in the filtered stream.
+ */
+ function setLines($lines) {
+ $this->_lines = (int) $lines;
+ }
+
+ /**
+ * Returns the number of lines to be returned in the filtered stream.
+ *
+ * @return integer The number of lines to be returned in the filtered stream.
+ */
+ function getLines() {
+ return $this->_lines;
+ }
+
+ /**
+ * Creates a new HeadFilter using the passed in
+ * Reader for instantiation.
+ *
+ * @param object A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return object A new filter based on this configuration, but filtering
+ * the specified reader.
+ */
+ function chain(Reader $reader) {
+ $newFilter = new HeadFilter($reader);
+ $newFilter->setLines($this->getLines());
+ $newFilter->setInitialized(true);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+
+ /**
+ * Scans the parameters list for the "lines" parameter and uses
+ * it to set the number of lines to be returned in the filtered stream.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ for($i = 0, $_i=count($params) ; $i < $_i; $i++) {
+ if ( self::LINES_KEY == $params[$i]->getName() ) {
+ $this->_lines = (int) $params[$i]->getValue();
+ break;
+ }
+ }
+ }
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/LineContains.php b/buildscripts/phing/classes/phing/filters/LineContains.php
new file mode 100644
index 00000000..8f3136b7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/LineContains.php
@@ -0,0 +1,258 @@
+<?php
+
+/*
+ * $Id: LineContains.php,v 1.11 2005/02/27 20:52:08 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Filter which includes only those lines that contain all the user-specified
+ * strings.
+ *
+ * Example:
+ *
+ * <pre><linecontains>
+ * <contains value="foo">
+ * <contains value="bar">
+ * </linecontains></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.LineContains">
+ * <param type="contains" value="foo"/>
+ * <param type="contains" value="bar"/>
+ * </filterreader></pre>
+ *
+ * This will include only those lines that contain <code>foo</code> and
+ * <code>bar</code>.
+ *
+ * @author Yannick Lecaillez <yl@seasonfive.com>
+ * @author Hans Lellelid <hans@velum.net>
+ * @version $Revision: 1.11 $
+ * @see PhingFilterReader
+ * @package phing.filters
+*/
+class LineContains extends BaseParamFilterReader implements ChainableReader {
+
+ /**
+ * The parameter name for the string to match on.
+ * @var string
+ */
+ const CONTAINS_KEY = "contains";
+
+ /**
+ * Array of Contains objects.
+ * @var array
+ */
+ private $_contains = array();
+
+ /**
+ * [Deprecated]
+ * @var string
+ */
+ private $_line = null;
+
+ /**
+ * Returns all lines in a buffer that contain specified strings.
+ * @return mixed buffer, -1 on EOF
+ */
+ function read($len = null) {
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ $buffer = $this->in->read($len);
+
+ if ($buffer === -1) {
+ return -1;
+ }
+
+ $lines = explode("\n", $buffer);
+ $matched = array();
+ $containsSize = count($this->_contains);
+
+ foreach($lines as $line) {
+ for($i = 0 ; $i < $containsSize ; $i++) {
+ $containsStr = $this->_contains[$i]->getValue();
+ if ( strstr($line, $containsStr) === false ) {
+ $line = null;
+ break;
+ }
+ }
+ if($line !== null) {
+ $matched[] = $line;
+ }
+ }
+ $filtered_buffer = implode("\n", $matched);
+ return $filtered_buffer;
+ }
+
+ /**
+ * [Deprecated. For reference only, used to be read() method.]
+ * Returns the next character in the filtered stream, only including
+ * lines from the original stream which contain all of the specified words.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ function readChar() {
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ $ch = -1;
+
+ if ( $this->_line !== null ) {
+ $ch = substr($this->_line, 0, 1);
+ if ( strlen($this->_line) === 1 )
+ $this->_line = null;
+ else
+ $this->_line = substr($this->_line, 1);
+ } else {
+ $this->_line = $this->readLine();
+ if ( $this->_line === null ) {
+ $ch = -1;
+ } else {
+ $containsSize = count($this->_contains);
+ for($i = 0 ; $i < $containsSize ; $i++) {
+ $containsStr = $this->_contains[$i]->getValue();
+ if ( strstr($this->_line, $containsStr) === false ) {
+ $this->_line = null;
+ break;
+ }
+ }
+ return $this->readChar();
+ }
+ }
+
+ return $ch;
+ }
+
+ /**
+ * Adds a <code><contains></code> nested element.
+ *
+ * @return Contains The <code>contains</code> element added.
+ * Must not be <code>null</code>.
+ */
+ function createContains() {
+ $num = array_push($this->_contains, new Contains());
+ return $this->_contains[$num-1];
+ }
+
+ /**
+ * Sets the array of words which must be contained within a line read
+ * from the original stream in order for it to match this filter.
+ *
+ * @param array $contains An array of words which must be contained
+ * within a line in order for it to match in this filter.
+ * Must not be <code>null<code>.
+ */
+ function setContains($contains) {
+ // type check, error must never occur, bad code of it does
+ if ( !is_array($contains) ) {
+ throw new Exception("Excpected array got something else");
+ }
+
+ $this->_contains = $contains;
+ }
+
+ /**
+ * Returns the vector of words which must be contained within a line read
+ * from the original stream in order for it to match this filter.
+ *
+ * @return array The array of words which must be contained within a line read
+ * from the original stream in order for it to match this filter. The
+ * returned object is "live" - in other words, changes made to the
+ * returned object are mirrored in the filter.
+ */
+ function getContains() {
+ return $this->_contains;
+ }
+
+ /**
+ * Creates a new LineContains using the passed in
+ * Reader for instantiation.
+ *
+ * @param object A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return object A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new LineContains($reader);
+ $newFilter->setContains($this->getContains());
+ $newFilter->setInitialized(true);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+
+ /**
+ * Parses the parameters to add user-defined contains strings.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ foreach($params as $param) {
+ if ( self::CONTAINS_KEY == $param->getType() ) {
+ $cont = new Contains();
+ $cont->setValue($param->getValue());
+ array_push($this->_contains, $cont);
+ break; // because we only support a single contains
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Holds a contains element.
+ */
+class Contains {
+
+ /**
+ * @var string
+ */
+ private $_value;
+
+ /**
+ * Set 'contains' value.
+ * @param string $contains
+ */
+ function setValue($contains) {
+ $this->_value = (string) $contains;
+ }
+
+ /**
+ * Returns 'contains' value.
+ * @return string
+ */
+ function getValue() {
+ return $this->_value;
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/filters/LineContainsRegexp.php b/buildscripts/phing/classes/phing/filters/LineContainsRegexp.php
new file mode 100644
index 00000000..dcbb532c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/LineContainsRegexp.php
@@ -0,0 +1,179 @@
+<?php
+/*
+ * $Id: LineContainsRegexp.php,v 1.8 2005/02/27 20:52:08 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/types/RegularExpression.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Filter which includes only those lines that contain the user-specified
+ * regular expression matching strings.
+ *
+ * Example:
+ * <pre><linecontainsregexp>
+ * <regexp pattern="foo*">
+ * </linecontainsregexp></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.LineContainsRegExp">
+ * <param type="regexp" value="foo*"/>
+ * </filterreader></pre>
+ *
+ * This will fetch all those lines that contain the pattern <code>foo</code>
+ *
+ * @author Yannick Lecaillez <yl@seasonfive.com>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.8 $
+ * @see FilterReader
+ * @package phing.filters
+ */
+class LineContainsRegexp extends BaseParamFilterReader implements ChainableReader {
+
+ /**
+ * Parameter name for regular expression.
+ * @var string
+ */
+ const REGEXP_KEY = "regexp";
+
+ /**
+ * Regular expressions that are applied against lines.
+ * @var array
+ */
+ private $_regexps = array();
+
+ /**
+ * Returns all lines in a buffer that contain specified strings.
+ * @return mixed buffer, -1 on EOF
+ */
+ function read($len = null) {
+
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ $buffer = $this->in->read($len);
+
+ if ($buffer === -1) {
+ return -1;
+ }
+
+ $lines = explode("\n", $buffer);
+ $matched = array();
+
+ $regexpsSize = count($this->_regexps);
+ foreach($lines as $line) {
+ for($i = 0 ; $i<$regexpsSize ; $i++) {
+ $regexp = $this->_regexps[$i];
+ $re = $regexp->getRegexp($this->getProject());
+ $matches = $re->matches($line);
+ if ( !$matches ) {
+ $line = null;
+ break;
+ }
+ }
+ if($line !== null) {
+ $matched[] = $line;
+ }
+ }
+ $filtered_buffer = implode("\n", $matched);
+ return $filtered_buffer;
+ }
+
+ /**
+ * Adds a <code>regexp</code> element.
+ *
+ * @return object regExp The <code>regexp</code> element added.
+ */
+ function createRegexp() {
+ $num = array_push($this->_regexps, new RegularExpression());
+ return $this->_regexps[$num-1];
+ }
+
+ /**
+ * Sets the vector of regular expressions which must be contained within
+ * a line read from the original stream in order for it to match this
+ * filter.
+ *
+ * @param regexps An array of regular expressions which must be contained
+ * within a line in order for it to match in this filter. Must not be
+ * <code>null</code>.
+ */
+ function setRegexps($regexps) {
+ // type check, error must never occur, bad code of it does
+ if ( !is_array($regexps) ) {
+ throw new Exception("Excpected an 'array', got something else");
+ }
+ $this->_regexps = $regexps;
+ }
+
+ /**
+ * Returns the array of regular expressions which must be contained within
+ * a line read from the original stream in order for it to match this
+ * filter.
+ *
+ * @return array The array of regular expressions which must be contained within
+ * a line read from the original stream in order for it to match this
+ * filter. The returned object is "live" - in other words, changes made to
+ * the returned object are mirrored in the filter.
+ */
+ function getRegexps() {
+ return $this->_regexps;
+ }
+
+ /**
+ * Creates a new LineContainsRegExp using the passed in
+ * Reader for instantiation.
+ *
+ * @param object A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return object A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new LineContainsRegExp($reader);
+ $newFilter->setRegexps($this->getRegexps());
+ $newFilter->setInitialized(true);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+
+ /**
+ * Parses parameters to add user defined regular expressions.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ for($i = 0 ; $i<count($params) ; $i++) {
+ if ( self::REGEXP_KEY === $params[$i]->getType() ) {
+ $pattern = $params[$i]->getValue();
+ $regexp = new RegularExpression();
+ $regexp->setPattern($pattern);
+ array_push($this->_regexps, $regexp);
+ }
+ }
+ }
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/PrefixLines.php b/buildscripts/phing/classes/phing/filters/PrefixLines.php
new file mode 100644
index 00000000..a5580f87
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/PrefixLines.php
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * $Id: PrefixLines.php,v 1.6 2004/03/15 14:45:06 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Attaches a prefix to every line.
+ *
+ * Example:
+ * <pre><prefixlines prefix="Foo"/></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.PrefixLines">
+ * <param name="prefix" value="Foo"/>
+ * </filterreader></pre>
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author hans lellelid, hans@velum.net
+ * @version $Revision: 1.6 $ $Date: 2004/03/15 14:45:06 $
+ * @access public
+ * @see FilterReader
+ * @package phing.filters
+*/
+class PrefixLines extends BaseParamFilterReader implements ChainableReader {
+
+ /**
+ * Parameter name for the prefix.
+ * @var string
+ */
+ const PREFIX_KEY = "lines";
+
+ /**
+ * The prefix to be used.
+ * @var string
+ */
+ private $_prefix = null;
+
+ /**
+ * Adds a prefix to each line of input stream and returns resulting stream.
+ *
+ * @return mixed buffer, -1 on EOF
+ */
+ function read($len = null) {
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ $buffer = $this->in->read($len);
+
+ if ($buffer === -1) {
+ return -1;
+ }
+
+ $lines = explode("\n", $buffer);
+ $filtered = array();
+
+ foreach($lines as $line) {
+ $line = $this->_prefix . $line;
+ $filtered[] = $line;
+ }
+
+ $filtered_buffer = implode("\n", $filtered);
+ return $filtered_buffer;
+ }
+
+ /**
+ * Sets the prefix to add at the start of each input line.
+ *
+ * @param string $prefix The prefix to add at the start of each input line.
+ * May be <code>null</code>, in which case no prefix
+ * is added.
+ */
+ function setPrefix($prefix) {
+ $this->_prefix = (string) $prefix;
+ }
+
+ /**
+ * Returns the prefix which will be added at the start of each input line.
+ *
+ * @return string The prefix which will be added at the start of each input line
+ */
+ function getPrefix() {
+ return $this->_prefix;
+ }
+
+ /**
+ * Creates a new PrefixLines filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param object A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return object A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new PrefixLines($reader);
+ $newFilter->setPrefix($this->getPrefix());
+ $newFilter->setInitialized(true);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+
+ /**
+ * Initializes the prefix if it is available from the parameters.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ for($i = 0, $_i=count($params) ; $i < $_i ; $i++) {
+ if ( self::PREFIX_KEY == $params[$i]->getName() ) {
+ $this->_prefix = (string) $params[$i]->getValue();
+ break;
+ }
+ }
+ }
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/ReplaceRegexp.php b/buildscripts/phing/classes/phing/filters/ReplaceRegexp.php
new file mode 100644
index 00000000..3c5592e8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/ReplaceRegexp.php
@@ -0,0 +1,129 @@
+<?php
+
+/*
+ * $Id: ReplaceRegexp.php,v 1.5 2003/12/24 12:38:39 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+include_once 'phing/types/RegularExpression.php';
+
+/**
+ * Performs a regexp find/replace on stream.
+ * <p>
+ * Example:<br>
+ * <pre>
+ * <replaceregexp>
+ * <regexp pattern="\r\n" replace="\n"/>
+ * <regexp pattern="(\w+)\.xml" replace="\1.php" ignoreCase="true"/>
+ * </replaceregexp>
+ * </pre>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.5 $
+ * @package phing.filters
+ */
+class ReplaceRegexp extends BaseFilterReader implements ChainableReader {
+
+ /**
+ * @var array RegularExpression[]
+ */
+ private $regexps = array();
+
+ /**
+ * Creator method handles nested <regexp> tags.
+ * @return RegularExpression
+ */
+ function createRegexp() {
+ $num = array_push($this->regexps, new RegularExpression());
+ return $this->regexps[$num-1];
+ }
+
+ /**
+ * Sets the current regexps.
+ * (Used when, e.g., cloning/chaining the method.)
+ * @param array RegularExpression[]
+ */
+ function setRegexps($regexps) {
+ $this->regexps = $regexps;
+ }
+
+ /**
+ * Gets the current regexps.
+ * (Used when, e.g., cloning/chaining the method.)
+ * @return array RegularExpression[]
+ */
+ function getRegexps() {
+ return $this->regexps;
+ }
+
+ /**
+ * Returns the filtered stream.
+ * The original stream is first read in fully, and the regex replace is performed.
+ *
+ * @param int $len Required $len for Reader compliance.
+ *
+ * @return mixed The filtered stream, or -1 if the end of the resulting stream has been reached.
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ function read($len = null) {
+
+ $buffer = $this->in->read($len);
+
+ if($buffer === -1) {
+ return -1;
+ }
+
+ // perform regex replace here ...
+ foreach($this->regexps as $exptype) {
+ $regexp = $exptype->getRegexp($this->project);
+ try {
+ $buffer = $regexp->replace($buffer);
+ $this->log("Performing regexp replace: /".$regexp->getPattern()."/".$regexp->getReplace()."/g".($regexp->getIgnoreCase() ? 'i' : ''), PROJECT_MSG_VERBOSE);
+ } catch (Exception $e) {
+ // perhaps mismatch in params (e.g. no replace or pattern specified)
+ $this->log("Error performing regexp replace: " . $e->getMessage(), PROJECT_MSG_WARN);
+ }
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Creates a new ReplaceRegExp filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param Reader $reader A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return ReplaceRegExp A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new ReplaceRegExp($reader);
+ $newFilter->setProject($this->getProject());
+ $newFilter->setRegexps($this->getRegexps());
+ return $newFilter;
+ }
+
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/ReplaceTokens.php b/buildscripts/phing/classes/phing/filters/ReplaceTokens.php
new file mode 100644
index 00000000..999f734f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/ReplaceTokens.php
@@ -0,0 +1,415 @@
+<?php
+
+/*
+ * $Id: ReplaceTokens.php,v 1.14 2005/06/16 15:09:10 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/types/TokenSource.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/*
+ * Replaces tokens in the original input with user-supplied values.
+ *
+ * Example:
+ *
+ * <pre><replacetokens begintoken="#" endtoken="#">;
+ * <token key="DATE" value="${TODAY}"/>
+ * </replacetokens></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.ReplaceTokens">
+ * <param type="tokenchar" name="begintoken" value="#"/>
+ * <param type="tokenchar" name="endtoken" value="#"/>
+ * <param type="token" name="DATE" value="${TODAY}"/>
+ * </filterreader></pre>
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author hans lellelid, hans@velum.net
+ * @version $Revision: 1.14 $ $Date: 2005/06/16 15:09:10 $
+ * @access public
+ * @see BaseParamFilterReader
+ * @package phing.filters
+ */
+class ReplaceTokens extends BaseParamFilterReader implements ChainableReader {
+
+ /**
+ * Default "begin token" character.
+ * @var string
+ */
+ const DEFAULT_BEGIN_TOKEN = "@";
+
+ /**
+ * Default "end token" character.
+ * @var string
+ */
+ const DEFAULT_END_TOKEN = "@";
+
+ /**
+ * [Deprecated] Data that must be read from, if not null.
+ * @var string
+ */
+ private $_queuedData = null;
+
+ /**
+ * Array to hold the replacee-replacer pairs (String to String).
+ * @var array
+ */
+ private $_tokens = array();
+
+ /**
+ * Array to hold the token sources that make tokens from
+ * different sources available
+ * @var array
+ */
+ private $_tokensources = array();
+
+ /**
+ * Array holding all tokens given directly to the Filter and
+ * those passed via a TokenSource.
+ * @var array
+ */
+ private $_alltokens = null;
+
+ /**
+ * Character marking the beginning of a token.
+ * @var string
+ */
+ private $_beginToken = "@"; // self::DEFAULT_BEGIN_TOKEN;
+
+ /**
+ * Character marking the end of a token.
+ * @var string
+ */
+ private $_endToken = "@"; //self::DEFAULT_END_TOKEN;
+
+ /**
+ * Performs lookup on key and returns appropriate replacement string.
+ * @param array $matches Array of 1 el containing key to search for.
+ * @return string Text with which to replace key or value of key if none is found.
+ * @access private
+ */
+ private function replaceTokenCallback($matches) {
+
+ $key = $matches[1];
+
+ /* Get tokens from tokensource and merge them with the
+ * tokens given directly via build file. This should be
+ * done a bit more elegantly
+ */
+ if ($this->_alltokens === null) {
+ $this->_alltokens = array();
+
+ $count = count($this->_tokensources);
+ for ($i = 0; $i < $count; $i++) {
+ $source = $this->_tokensources[$i];
+ $this->_alltokens = array_merge($this->_alltokens, $source->getTokens());
+ }
+
+
+ $this->_alltokens = array_merge($this->_tokens, $this->_alltokens);
+ }
+
+ $tokens = $this->_alltokens;
+
+ $replaceWith = null;
+ $count = count($tokens);
+
+ for ($i = 0; $i < $count; $i++) {
+ if ($tokens[$i]->getKey() === $key) {
+ $replaceWith = $tokens[$i]->getValue();
+ }
+ }
+
+ if ($replaceWith === null) {
+ $replaceWith = $this->_beginToken . $key . $this->_endToken;
+ $this->log("No token defined for key \"".$this->_beginToken . $key . $this->_endToken."\"");
+ } else {
+ $this->log("Replaced \"".$this->_beginToken . $key . $this->_endToken ."\" with \"".$replaceWith."\"");
+ }
+
+ return $replaceWith;
+ }
+
+ /**
+ * Returns stream with tokens having been replaced with appropriate values.
+ * If a replacement value is not found for a token, the token is left in the stream.
+ *
+ * @return mixed filtered stream, -1 on EOF.
+ */
+ function read($len = null) {
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ // read from next filter up the chain
+ $buffer = $this->in->read($len);
+
+ if($buffer === -1) {
+ return -1;
+ }
+
+ // filter buffer
+ $buffer = preg_replace_callback(
+ "/".preg_quote($this->_beginToken)."([\w\.\-:]+?)".preg_quote($this->_endToken)."/",
+ array($this, 'replaceTokenCallback'), $buffer);
+
+ return $buffer;
+ }
+
+ /**
+ * Sets the "begin token" character.
+ *
+ * @param string $beginToken the character used to denote the beginning of a token.
+ */
+ function setBeginToken($beginToken) {
+ $this->_beginToken = (string) $beginToken;
+ }
+
+ /**
+ * Returns the "begin token" character.
+ *
+ * @return string The character used to denote the beginning of a token.
+ */
+ function getBeginToken() {
+ return $this->_beginToken;
+ }
+
+ /**
+ * Sets the "end token" character.
+ *
+ * @param string $endToken the character used to denote the end of a token
+ */
+ function setEndToken($endToken) {
+ $this->_endToken = (string) $endToken;
+ }
+
+ /**
+ * Returns the "end token" character.
+ *
+ * @return the character used to denote the beginning of a token
+ */
+ function getEndToken() {
+ return $this->_endToken;
+ }
+
+ /**
+ * Adds a token element to the map of tokens to replace.
+ *
+ * @return object The token added to the map of replacements.
+ * Must not be <code>null</code>.
+ */
+ function createToken() {
+ $num = array_push($this->_tokens, new Token());
+ return $this->_tokens[$num-1];
+ }
+
+ /**
+ * Adds a token source to the sources of this filter.
+ *
+ * @return object A Reference to the source just added.
+ */
+ function createTokensource() {
+ $num = array_push($this->_tokensources, new TokenSource());
+ return $this->_tokensources[$num-1];
+ }
+
+ /**
+ * Sets the map of tokens to replace.
+ * ; used by ReplaceTokens::chain()
+ *
+ * @param array A map (String->String) of token keys to replacement
+ * values. Must not be <code>null</code>.
+ */
+ function setTokens($tokens) {
+ // type check, error must never occur, bad code of it does
+ if ( !is_array($tokens) ) {
+ throw new Exception("Excpected 'array', got something else");
+ }
+
+ $this->_tokens = $tokens;
+ }
+
+ /**
+ * Returns the map of tokens which will be replaced.
+ * ; used by ReplaceTokens::chain()
+ *
+ * @return array A map (String->String) of token keys to replacement values.
+ */
+ function getTokens() {
+ return $this->_tokens;
+ }
+
+ /**
+ * Sets the tokensources to use; used by ReplaceTokens::chain()
+ *
+ * @param array An array of token sources.
+ */
+ function setTokensources($sources) {
+ // type check
+ if ( !is_array($sources)) {
+ throw new Exception("Exspected 'array', got something else");
+ }
+ $this->_tokensources = $sources;
+ }
+
+ /**
+ * Returns the token sources used by this filter; used by ReplaceTokens::chain()
+ *
+ * @return array
+ */
+ function getTokensources() {
+ return $this->_tokensources;
+ }
+
+ /**
+ * Creates a new ReplaceTokens using the passed in
+ * Reader for instantiation.
+ *
+ * @param object A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return object A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new ReplaceTokens($reader);
+ $newFilter->setProject($this->getProject());
+ $newFilter->setBeginToken($this->getBeginToken());
+ $newFilter->setEndToken($this->getEndToken());
+ $newFilter->setTokens($this->getTokens());
+ $newFilter->setTokensources($this->getTokensources());
+ $newFilter->setInitialized(true);
+ return $newFilter;
+ }
+
+ /**
+ * Initializes tokens and loads the replacee-replacer hashtable.
+ * This method is only called when this filter is used through
+ * a <filterreader> tag in build file.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ for($i = 0 ; $i<count($params) ; $i++) {
+ if ( $params[$i] !== null ) {
+ $type = $params[$i]->getType();
+ if ( $type === "tokenchar" ) {
+ $name = $params[$i]->getName();
+ if ( $name === "begintoken" ) {
+ $this->_beginToken = substr($params[$i]->getValue(), 0, 1);
+ } else if ( $name === "endtoken" ) {
+ $this->_endToken = substr($params[$i]->getValue(), 0, 1);
+ }
+ } else if ( $type === "token" ) {
+ $name = $params[$i]->getName();
+ $value = $params[$i]->getValue();
+
+ $tok = new Token();
+ $tok->setKey($name);
+ $tok->setValue($value);
+
+ array_push($this->_tokens, $tok);
+ } else if ( $type === "tokensource" ) {
+ // Store data from nested tags in local array
+ $arr = array(); $subparams = $params[$i]->getParams();
+ $count = count($subparams);
+ for ($i = 0; $i < $count; $i++) {
+ $arr[$subparams[$i]->getName()] = $subparams[$i]->getValue();
+ }
+
+ // Create TokenSource
+ $tokensource = new TokenSource();
+ if (isset($arr["classname"]))
+ $tokensource->setClassname($arr["classname"]);
+
+ // Copy other parameters 1:1 to freshly created TokenSource
+ foreach ($arr as $key => $value) {
+ if (strtolower($key) === "classname")
+ continue;
+ $param = $tokensource->createParam();
+ $param->setName($key);
+ $param->setValue($value);
+ }
+
+ $this->_tokensources[] = $tokensource;
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Holds a token.
+ */
+class Token {
+
+ /**
+ * Token key.
+ * @var string
+ */
+ private $_key;
+
+ /**
+ * Token value.
+ * @var string
+ */
+ private $_value;
+
+ /**
+ * Sets the token key.
+ *
+ * @param string $key The key for this token. Must not be <code>null</code>.
+ */
+ function setKey($key) {
+ $this->_key = (string) $key;
+ }
+
+ /**
+ * Sets the token value.
+ *
+ * @param string $value The value for this token. Must not be <code>null</code>.
+ */
+ function setValue($value) {
+ $this->_value = (string) $value;
+ }
+
+ /**
+ * Returns the key for this token.
+ *
+ * @return string The key for this token.
+ */
+ function getKey() {
+ return $this->_key;
+ }
+
+ /**
+ * Returns the value for this token.
+ *
+ * @return string The value for this token.
+ */
+ function getValue() {
+ return $this->_value;
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/StripLineBreaks.php b/buildscripts/phing/classes/phing/filters/StripLineBreaks.php
new file mode 100644
index 00000000..c5a06129
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/StripLineBreaks.php
@@ -0,0 +1,148 @@
+<?php
+
+/*
+ * $Id: StripLineBreaks.php,v 1.8 2004/03/15 14:45:06 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Filter to flatten the stream to a single line.
+ *
+ * Example:
+ *
+ * <pre><striplinebreaks/></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.StripLineBreaks"/></pre>
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author hans lellelid, hans@velum.net
+ * @version $Revision: 1.8 $ $Date: 2004/03/15 14:45:06 $
+ * @access public
+ * @see BaseParamFilterReader
+ * @package phing.filters
+ */
+class StripLineBreaks extends BaseParamFilterReader implements ChainableReader {
+
+ /**
+ * Default line-breaking characters.
+ * @var string
+ */
+ const DEFAULT_LINE_BREAKS = "\r\n";
+
+ /**
+ * Parameter name for the line-breaking characters parameter.
+ * @var string
+ */
+ const LINES_BREAKS_KEY = "linebreaks";
+
+ /**
+ * The characters that are recognized as line breaks.
+ * @var string
+ */
+ private $_lineBreaks = "\r\n"; // self::DEFAULT_LINE_BREAKS;
+
+ /**
+ * Returns the filtered stream, only including
+ * characters not in the set of line-breaking characters.
+ *
+ * @return mixed the resulting stream, or -1
+ * if the end of the resulting stream has been reached.
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ function read($len = null) {
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ $buffer = $this->in->read($len);
+ if($buffer === -1) {
+ return -1;
+ }
+
+ $buffer = preg_replace("/[".$this->_lineBreaks."]/", '', $buffer);
+
+ return $buffer;
+ }
+
+ /**
+ * Sets the line-breaking characters.
+ *
+ * @param string $lineBreaks A String containing all the characters to be
+ * considered as line-breaking.
+ */
+ function setLineBreaks($lineBreaks) {
+ $this->_lineBreaks = (string) $lineBreaks;
+ }
+
+ /**
+ * Gets the line-breaking characters.
+ *
+ * @return string A String containing all the characters that are considered as line-breaking.
+ */
+ function getLineBreaks() {
+ return $this->_lineBreaks;
+ }
+
+ /**
+ * Creates a new StripLineBreaks using the passed in
+ * Reader for instantiation.
+ *
+ * @param object A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return object A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new StripLineBreaks($reader);
+ $newFilter->setLineBreaks($this->getLineBreaks());
+ $newFilter->setInitialized(true);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+
+ /**
+ * Parses the parameters to set the line-breaking characters.
+ */
+ private function _initialize() {
+ $userDefinedLineBreaks = null;
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ for($i = 0 ; $i<count($params) ; $i++) {
+ if ( self::LINE_BREAKS_KEY === $params[$i]->getName() ) {
+ $userDefinedLineBreaks = $params[$i]->getValue();
+ break;
+ }
+ }
+ }
+
+ if ( $userDefinedLineBreaks !== null ) {
+ $this->_lineBreaks = $userDefinedLineBreaks;
+ }
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/StripLineComments.php b/buildscripts/phing/classes/phing/filters/StripLineComments.php
new file mode 100644
index 00000000..5d97979a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/StripLineComments.php
@@ -0,0 +1,205 @@
+<?php
+
+/*
+ * $Id: StripLineComments.php,v 1.8 2005/02/27 20:52:08 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/*
+ * This filter strips line comments.
+ *
+ * Example:
+ *
+ * <pre><striplinecomments>
+ * <comment value="#"/>
+ * <comment value="--"/>
+ * <comment value="REM "/>
+ * <comment value="rem "/>
+ * <comment value="//"/>
+ * </striplinecomments></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.StripLineComments">
+ * <param type="comment" value="#"/>
+ * <param type="comment" value="--"/>
+ * <param type="comment" value="REM "/>
+ * <param type="comment" value="rem "/>
+ * <param type="comment" value="//"/>
+ * </filterreader></pre>
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author hans lellelid, hans@velum.net
+ * @version $Revision: 1.8 $ $Date: 2005/02/27 20:52:08 $
+ * @access public
+ * @see BaseParamFilterReader
+ * @package phing.filters
+ */
+class StripLineComments extends BaseParamFilterReader implements ChainableReader {
+
+ /** Parameter name for the comment prefix. */
+ const COMMENTS_KEY = "comment";
+
+ /** Array that holds the comment prefixes. */
+ private $_comments = array();
+
+ /**
+ * Returns stream only including
+ * lines from the original stream which don't start with any of the
+ * specified comment prefixes.
+ *
+ * @return mixed the resulting stream, or -1
+ * if the end of the resulting stream has been reached.
+ *
+ * @throws IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ function read($len = null) {
+
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ $buffer = $this->in->read($len);
+
+ if ($buffer === -1) {
+ return -1;
+ }
+
+ $lines = explode("\n", $buffer);
+ $filtered = array();
+
+ $commentsSize = count($this->_comments);
+
+ foreach($lines as $line) {
+ for($i = 0; $i < $commentsSize; $i++) {
+ $comment = $this->_comments[$i]->getValue();
+ if ( StringHelper::startsWith($comment, ltrim($line)) ) {
+ $line = null;
+ break;
+ }
+ }
+ if ($line !== null) {
+ $filtered[] = $line;
+ }
+ }
+
+ $filtered_buffer = implode("\n", $filtered);
+ return $filtered_buffer;
+ }
+
+ /*
+ * Adds a <code>comment</code> element to the list of prefixes.
+ *
+ * @return comment The <code>comment</code> element added to the
+ * list of comment prefixes to strip.
+ */
+ function createComment() {
+ $num = array_push($this->_comments, new Comment());
+ return $this->_comments[$num-1];
+ }
+
+ /*
+ * Sets the list of comment prefixes to strip.
+ *
+ * @param comments A list of strings, each of which is a prefix
+ * for a comment line. Must not be <code>null</code>.
+ */
+ function setComments($lineBreaks) {
+ if (!is_array($lineBreaks)) {
+ throw new Exception("Excpected 'array', got something else");
+ }
+ $this->_comments = $lineBreaks;
+ }
+
+ /*
+ * Returns the list of comment prefixes to strip.
+ *
+ * @return array The list of comment prefixes to strip.
+ */
+ function getComments() {
+ return $this->_comments;
+ }
+
+ /*
+ * Creates a new StripLineComments using the passed in
+ * Reader for instantiation.
+ *
+ * @param reader A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new StripLineComments($reader);
+ $newFilter->setComments($this->getComments());
+ $newFilter->setInitialized(true);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+
+ /*
+ * Parses the parameters to set the comment prefixes.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ for($i = 0 ; $i<count($params) ; $i++) {
+ if ( self::COMMENTS_KEY === $params[$i]->getType() ) {
+ $comment = new Comment();
+ $comment->setValue($params[$i]->getValue());
+ array_push($this->_comments, $comment);
+ }
+ }
+ }
+ }
+}
+
+/*
+ * The class that holds a comment representation.
+*/
+class Comment {
+
+ /** The prefix for a line comment. */
+ private $_value;
+
+ /*
+ * Sets the prefix for this type of line comment.
+ *
+ * @param string $value The prefix for a line comment of this type.
+ * Must not be <code>null</code>.
+ */
+ function setValue($value) {
+ $this->_value = (string) $value;
+ }
+
+ /*
+ * Returns the prefix for this type of line comment.
+ *
+ * @return string The prefix for this type of line comment.
+ */
+ function getValue() {
+ return $this->_value;
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/filters/StripPhpComments.php b/buildscripts/phing/classes/phing/filters/StripPhpComments.php
new file mode 100644
index 00000000..9e21eed3
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/StripPhpComments.php
@@ -0,0 +1,190 @@
+<?php
+
+/*
+ * $Id: StripPhpComments.php,v 1.6 2004/07/16 01:36:35 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * This is a Php comment and string stripper reader that filters
+ * those lexical tokens out for purposes of simple Php parsing.
+ * (if you have more complex Php parsing needs, use a real lexer).
+ * Since this class heavily relies on the single char read function,
+ * you are reccomended to make it work on top of a buffered reader.
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author hans lellelid, hans@velum.net
+ * @version $Revision: 1.6 $ $Date: 2004/07/16 01:36:35 $
+ * @access public
+ * @see FilterReader
+ * @package phing.filters
+ * @todo -c use new PHP functions to perform this instead of regex.
+ */
+class StripPhpComments extends BaseFilterReader implements ChainableReader {
+ /**
+ * The read-ahead character, used for effectively pushing a single
+ * character back. -1 indicates that no character is in the buffer.
+ */
+ private $_readAheadCh = -1;
+
+ /**
+ * Whether or not the parser is currently in the middle of a string
+ * literal.
+ * @var boolean
+ */
+ private $_inString = false;
+
+ /**
+ * Returns the stream without Php comments.
+ *
+ * @return the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @throws IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ function read($len = null) {
+
+ $buffer = $this->in->read($len);
+ if($buffer === -1) {
+ return -1;
+ }
+
+ // This regex replace /* */ and // style comments
+ $buffer = preg_replace('/\/\*[^*]*\*+([^\/*][^*]*\*+)*\/|\/\/[^\n]*|("(\\\\.|[^"\\\\])*"|\'(\\\\.|[^\'\\\\])*\'|.[^\/"\'\\\\]*)/s', "$2", $buffer);
+
+ // The regex above is not identical to, but is based on the expression below:
+ //
+ // created by Jeffrey Friedl
+ // and later modified by Fred Curtis.
+ // s{
+ // /\* ## Start of /* ... */ comment
+ // [^*]*\*+ ## Non-* followed by 1-or-more *'s
+ // (
+ // [^/*][^*]*\*+
+ // )* ## 0-or-more things which don't start with /
+ // ## but do end with '*'
+ // / ## End of /* ... */ comment
+ //
+ // | ## OR various things which aren't comments:
+ //
+ // (
+ // " ## Start of " ... " string
+ // (
+ // \\. ## Escaped char
+ // | ## OR
+ // [^"\\] ## Non "\
+ // )*
+ // " ## End of " ... " string
+ //
+ // | ## OR
+ //
+ // ' ## Start of ' ... ' string
+ // (
+ // \\. ## Escaped char
+ // | ## OR
+ // [^'\\] ## Non '\
+ // )*
+ // ' ## End of ' ... ' string
+ //
+ // | ## OR
+ //
+ // . ## Anything other char
+ // [^/"'\\]* ## Chars which doesn't start a comment, string or escape
+ // )
+ // }{$2}gxs;
+
+ return $buffer;
+ }
+
+
+ /*
+ * Returns the next character in the filtered stream, not including
+ * Php comments.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @throws IOException if the underlying stream throws an IOException
+ * during reading
+ * @deprecated
+ */
+ function readChar() {
+ $ch = -1;
+
+ if ( $this->_readAheadCh !== -1 ) {
+ $ch = $this->_readAheadCh;
+ $this->_readAheadCh = -1;
+ } else {
+ $ch = $this->in->readChar();
+ if ( $ch === "\"" ) {
+ $this->_inString = !$this->_inString;
+ } else {
+ if ( !$this->_inString ) {
+ if ( $ch === "/" ) {
+ $ch = $this->in->readChar();
+ if ( $ch === "/" ) {
+ while ( $ch !== "\n" && $ch !== -1 ) {
+ $ch = $this->in->readChar();
+ }
+ } else if ( $ch === "*" ) {
+ while ( $ch !== -1 ) {
+ $ch = $this->in->readChar();
+ while ( $ch === "*" && $ch !== -1 ) {
+ $ch = $this->in->readChar();
+ }
+
+ if ( $ch === "/" ) {
+ $ch = $this->readChar();
+ echo "$ch\n";
+ break;
+ }
+ }
+ } else {
+ $this->_readAheadCh = $ch;
+ $ch = "/";
+ }
+ }
+ }
+ }
+ }
+
+ return $ch;
+ }
+
+ /**
+ * Creates a new StripJavaComments using the passed in
+ * Reader for instantiation.
+ *
+ * @param reader A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new StripPhpComments($reader);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/filters/TabToSpaces.php b/buildscripts/phing/classes/phing/filters/TabToSpaces.php
new file mode 100644
index 00000000..7293d3b5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/TabToSpaces.php
@@ -0,0 +1,144 @@
+<?php
+
+/*
+ * $Id: TabToSpaces.php,v 1.9 2004/03/15 14:45:06 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseParamFilterReader.php';
+require_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Converts tabs to spaces.
+ *
+ * Example:
+ *
+ * <pre><tabtospaces tablength="8"></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.TabsToSpaces">
+ * <param name="tablength" value="8">
+ * </filterreader></pre>
+ *
+ * @author Yannick Lecaillez <yl@seasonfive.com>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.9 $
+ * @see BaseParamFilterReader
+ * @package phing.filters
+ */
+class TabToSpaces extends BaseParamFilterReader implements ChainableReader {
+
+ /**
+ * The default tab length.
+ * @var int
+ */
+ const DEFAULT_TAB_LENGTH = 8;
+
+ /**
+ * Parameter name for the length of a tab.
+ * @var string
+ */
+ const TAB_LENGTH_KEY = "tablength";
+
+ /**
+ * Tab length in this filter.
+ * @var int
+ */
+ private $tabLength = 8; //self::DEFAULT_TAB_LENGTH;
+
+ /**
+ * Returns stream after converting tabs to the specified number of spaces.
+ *
+ * @return the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ function read($len = null) {
+
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ $buffer = $this->in->read($len);
+
+ if($buffer === -1) {
+ return -1;
+ }
+
+ $buffer = str_replace("\t", str_repeat(' ', $this->tabLength), $buffer);
+
+ return $buffer;
+ }
+
+ /**
+ * Sets the tab length.
+ *
+ * @param int $tabLength The number of spaces to be used when converting a tab.
+ */
+ function setTablength($tabLength) {
+ $this->tabLength = (int) $tabLength;
+ }
+
+ /**
+ * Returns the tab length.
+ *
+ * @return int The number of spaces used when converting a tab
+ */
+ function getTablength() {
+ return $this->tabLength;
+ }
+
+ /**
+ * Creates a new TabsToSpaces using the passed in
+ * Reader for instantiation.
+ *
+ * @param Reader $reader A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return Reader A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new TabToSpaces($reader);
+ $newFilter->setTablength($this->getTablength());
+ $newFilter->setInitialized(true);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+
+ /**
+ * Parses the parameters to set the tab length.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ for($i = 0 ; $i<count($params) ; $i++) {
+ if (self::TAB_LENGTH_KEY === $params[$i]->getName()) {
+ $this->tabLength = $params[$i]->getValue();
+ break;
+ }
+ }
+ }
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/TailFilter.php b/buildscripts/phing/classes/phing/filters/TailFilter.php
new file mode 100644
index 00000000..a6af6e4b
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/TailFilter.php
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ * $Id: TailFilter.php,v 1.7 2004/03/15 14:45:06 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseParamFilterReader.php';
+
+/**
+ * Reads the last <code>n</code> lines of a stream. (Default is last10 lines.)
+ *
+ * Example:
+ *
+ * <pre><tailfilter lines="3" /></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.TailFilter">
+ * <param name="lines" value="3">
+ * </filterreader></pre>
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author hans lellelid, hans@velum.net
+ * @copyright © 2003 seasonfive. All rights reserved
+ * @version $Revision: 1.7 $
+ * @see BaseParamFilterReader
+ * @package phing.filters
+ */
+class TailFilter extends BaseParamFilterReader implements ChainableReader {
+
+ /**
+ * Parameter name for the number of lines to be returned.
+ * @var string
+ */
+ const LINES_KEY = "lines";
+
+
+ /**
+ * Number of lines to be returned in the filtered stream.
+ * @var integer
+ */
+ private $_lines = 10;
+
+ /**
+ * Array to hold lines.
+ * @var array
+ */
+ private $_lineBuffer = array();
+
+ /**
+ * Returns the last n lines of a file.
+ * @param int $len Num chars to read.
+ * @return mixed The filtered buffer or -1 if EOF.
+ */
+ function read($len = null) {
+
+ while ( ($buffer = $this->in->read($len)) !== -1 ) {
+ // Remove the last "\n" from buffer for
+ // prevent explode to add an empty cell at
+ // the end of array
+ $buffer= trim($buffer, "\n");
+
+ $lines = explode("\n", $buffer);
+
+ if ( count($lines) >= $this->_lines ) {
+ // Buffer have more (or same) number of lines than needed.
+ // Fill lineBuffer with the last "$this->_lines" lasts ones.
+ $off = count($lines)-$this->_lines;
+ $this->_lineBuffer = array_slice($lines, $off);
+ } else {
+ // Some new lines ...
+ // Prepare space for insert these new ones
+ $this->_lineBuffer = array_slice($this->_lineBuffer, count($lines)-1);
+ $this->_lineBuffer = array_merge($this->_lineBuffer, $lines);
+ }
+ }
+
+ if ( empty($this->_lineBuffer) )
+ $ret = -1;
+ else {
+ $ret = implode("\n", $this->_lineBuffer);
+ $this->_lineBuffer = array();
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Sets the number of lines to be returned in the filtered stream.
+ *
+ * @param integer $lines the number of lines to be returned in the filtered stream.
+ */
+ function setLines($lines) {
+ $this->_lines = (int) $lines;
+ }
+
+ /**
+ * Returns the number of lines to be returned in the filtered stream.
+ *
+ * @return integer The number of lines to be returned in the filtered stream.
+ */
+ function getLines() {
+ return $this->_lines;
+ }
+
+ /**
+ * Creates a new TailFilter using the passed in
+ * Reader for instantiation.
+ *
+ * @param object A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return object A new filter based on this configuration, but filtering
+ * the specified reader.
+ */
+ function chain(Reader $reader) {
+ $newFilter = new TailFilter($reader);
+ $newFilter->setLines($this->getLines());
+ $newFilter->setInitialized(true);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+
+ /**
+ * Scans the parameters list for the "lines" parameter and uses
+ * it to set the number of lines to be returned in the filtered stream.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ for($i=0, $_i=count($params); $i < $_i; $i++) {
+ if ( self::LINES_KEY == $params[$i]->getName() ) {
+ $this->_lines = (int) $params[$i]->getValue();
+ break;
+ }
+ }
+ }
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/TidyFilter.php b/buildscripts/phing/classes/phing/filters/TidyFilter.php
new file mode 100644
index 00000000..10d75fc4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/TidyFilter.php
@@ -0,0 +1,162 @@
+<?php
+/*
+ * $Id: TidyFilter.php,v 1.2 2005/12/08 19:15:20 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * This filter uses the bundled-with-PHP Tidy extension to filter input.
+ *
+ * <p>
+ * Example:<br/>
+ * <pre>
+ * <tidyfilter encoding="utf8">
+ * <config name="indent" value="true"/>
+ * <config name="output-xhtml" value="true"/>
+ * </tidyfilter>
+ * </pre>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.2 $ $Date: 2005/12/08 19:15:20 $
+ * @package phing.filters
+ */
+class TidyFilter extends BaseParamFilterReader implements ChainableReader {
+
+ /** @var string Encoding of resulting document. */
+ private $encoding = 'utf8';
+
+ /** @var array Parameter[] */
+ private $configParameters = array();
+
+ /**
+ * Set the encoding for resulting (X)HTML document.
+ * @param string $v
+ */
+ public function setEncoding($v) {
+ $this->encoding = $v;
+ }
+
+ /**
+ * Sets the config params.
+ * @param array Parameter[]
+ * @see chain()
+ */
+ public function setConfigParameters($params)
+ {
+ $this->configParameters = $params;
+ }
+
+ /**
+ * Adds a <config> element (which is a Parameter).
+ * @return Parameter
+ */
+ public function createConfig() {
+ $num = array_push($this->configParameters, new Parameter());
+ return $this->configParameters[$num-1];
+ }
+
+ /**
+ * Converts the Parameter objects being used to store configuration into a simle assoc array.
+ * @return array
+ */
+ private function getDistilledConfig() {
+ $config = array();
+ foreach($this->configParameters as $p) {
+ $config[$p->getName()] = $p->getValue();
+ }
+ return $config;
+ }
+
+ /**
+ * Reads input and returns Tidy-filtered output.
+ *
+ * @return the resulting stream, or -1 if the end of the resulting stream has been reached
+ *
+ * @throws IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ function read($len = null) {
+
+ if (!class_exists('Tidy')) {
+ throw new BuildException("You must enable the 'tidy' extension in your PHP configuration in order to use the Tidy filter.");
+ }
+
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ $buffer = $this->in->read($len);
+ if($buffer === -1) {
+ return -1;
+ }
+
+ $config = $this->getDistilledConfig();
+
+ $tidy = new Tidy();
+ $tidy->parseString($buffer, $config, $this->encoding);
+ $tidy->cleanRepair();
+
+ return tidy_get_output($tidy);
+
+ }
+
+
+ /**
+ * Creates a new TidyFilter using the passed in Reader for instantiation.
+ *
+ * @param reader A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public function chain(Reader $reader) {
+ $newFilter = new TidyFilter($reader);
+ $newFilter->setConfigParameters($this->configParameters);
+ $newFilter->setEncoding($this->encoding);
+ $newFilter->setProject($this->getProject());
+ return $newFilter;
+ }
+
+ /**
+ * Initializes any parameters (e.g. config options).
+ * This method is only called when this filter is used through a <filterreader> tag in build file.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ($params) {
+ foreach($params as $param) {
+ if ($param->getType() == "config") {
+ $this->configParameters[] = $param;
+ } else {
+
+ if ($param->getName() == "encoding") {
+ $this->setEncoding($param->getValue());
+ }
+
+ }
+
+ }
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/filters/TranslateGettext.php b/buildscripts/phing/classes/phing/filters/TranslateGettext.php
new file mode 100644
index 00000000..f71823e3
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/TranslateGettext.php
@@ -0,0 +1,285 @@
+<?php
+
+/*
+ * $Id: TranslateGettext.php,v 1.11 2005/12/08 15:59:56 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Replaces gettext("message id") and _("message id") with the translated string.
+ *
+ * Gettext is great for creating multi-lingual sites, but in some cases (e.g. for
+ * performance reasons) you may wish to replace the gettext calls with the translations
+ * of the strings; that's what this task is for. Note that this is similar to
+ * ReplaceTokens, but both the find and the replace aspect is more complicated -- hence
+ * this is a separate, stand-alone filter.
+ *
+ * <p>
+ * Example:<br>
+ * <pre>
+ * <translategettext locale="en_US" domain="messages" dir="${webroot}/local"/>
+ * </pre>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.11 $ $Date: 2005/12/08 15:59:56 $
+ * @access public
+ * @see BaseFilterReader
+ * @package phing.filters
+ */
+class TranslateGettext extends BaseParamFilterReader implements ChainableReader {
+
+ // constants for specifying keys to expect
+ // when this is called using <filterreader ... />
+ const DOMAIN_KEY = "domain";
+ const DIR_KEY = "dir";
+ const LOCALE_KEY = "locale";
+
+ /** The domain to use */
+ private $domain = 'messages';
+
+ /** The dir containing LC_MESSAGES */
+ private $dir;
+
+ /** The locale to use */
+ private $locale;
+
+ /** The system locale before it was changed for this filter. */
+ private $storedLocale;
+
+ /**
+ * Set the text domain to use.
+ * The text domain must correspond to the name of the compiled .mo files.
+ * E.g. "messages" ==> $dir/LC_MESSAGES/messages.mo
+ * "mydomain" ==> $dir/LC_MESSAGES/mydomain.mo
+ * @param string $domain
+ */
+ function setDomain($domain) {
+ $this->domain = $domain;
+ }
+
+ /**
+ * Get the current domain.
+ * @return string
+ */
+ function getDomain() {
+ return $this->domain;
+ }
+
+ /**
+ * Sets the root locale directory.
+ * @param PhingFile $dir
+ */
+ function setDir(PhingFile $dir) {
+ $this->dir = $dir;
+ }
+
+ /**
+ * Gets the root locale directory.
+ * @return PhingFile
+ */
+ function getDir() {
+ return $this->dir;
+ }
+
+ /**
+ * Sets the locale to use for translation.
+ * Note that for gettext() to work, you have to make sure this locale
+ * is specific enough for your system (e.g. some systems may allow an 'en' locale,
+ * but others will require 'en_US', etc.).
+ * @param string $locale
+ */
+ function setLocale($locale) {
+ $this->locale = $locale;
+ }
+
+ /**
+ * Gets the locale to use for translation.
+ * @return string
+ */
+ function getLocale() {
+ return $this->locale;
+ }
+
+ /**
+ * Make sure that required attributes are set.
+ * @throws BuldException - if any required attribs aren't set.
+ */
+ protected function checkAttributes() {
+ if (!$this->domain || !$this->locale || !$this->dir) {
+ throw new BuildException("You must specify values for domain, locale, and dir attributes.");
+ }
+ }
+
+ /**
+ * Initialize the gettext/locale environment.
+ * This method will change some env vars and locale settings; the
+ * restoreEnvironment should put them all back :)
+ *
+ * @return void
+ * @throws BuildException - if locale cannot be set.
+ * @see restoreEnvironment()
+ */
+ protected function initEnvironment() {
+ $this->storedLocale = getenv("LANG");
+
+ $this->log("Setting locale to " . $this->locale, PROJECT_MSG_DEBUG);
+ putenv("LANG=".$this->locale);
+ $ret = setlocale(LC_ALL, $this->locale);
+ if ($ret === false) {
+ $msg = "Could not set locale to " . $this->locale
+ . ". You may need to use fully qualified name"
+ . " (e.g. en_US instead of en).";
+ throw new BuildException($msg);
+ }
+
+ $this->log("Binding domain '".$this->domain."' to " . $this->dir, PROJECT_MSG_DEBUG);
+ bindtextdomain($this->domain, $this->dir->getAbsolutePath());
+ textdomain($this->domain);
+ }
+
+ /**
+ * Restores environment settings and locale.
+ * This does _not_ restore any gettext-specific settings
+ * (e.g. textdomain()).
+ *
+ * @return void
+ */
+ protected function restoreEnvironment() {
+ putenv("LANG=".$this->storedLocale);
+ setlocale(LC_ALL, $this->storedLocale);
+ }
+
+ /**
+ * Performs gettext translation of msgid and returns translated text.
+ *
+ * This function simply wraps gettext() call, but provides ability to log
+ * string replacements. (alternative would be using preg_replace with /e which
+ * would probably be faster, but no ability to debug/log.)
+ *
+ * @param array $matches Array of matches; we're interested in $matches[2].
+ * @return string Translated text
+ */
+ private function xlateStringCallback($matches) {
+ $charbefore = $matches[1];
+ $msgid = $matches[2];
+ $translated = gettext($msgid);
+ $this->log("Translating \"$msgid\" => \"$translated\"", PROJECT_MSG_DEBUG);
+ return $charbefore . '"' . $translated . '"';
+ }
+
+ /**
+ * Returns the filtered stream.
+ * The original stream is first read in fully, and then translation is performed.
+ *
+ * @return mixed the filtered stream, or -1 if the end of the resulting stream has been reached.
+ *
+ * @throws IOException - if the underlying stream throws an IOException during reading
+ * @throws BuildException - if the correct params are not supplied
+ */
+ function read($len = null) {
+
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ // Make sure correct params/attribs have been set
+ $this->checkAttributes();
+
+ $buffer = $this->in->read($len);
+ if($buffer === -1) {
+ return -1;
+ }
+
+ // Setup the locale/gettext environment
+ $this->initEnvironment();
+
+
+ // replace any occurrences of _("") or gettext("") with
+ // the translated value.
+ //
+ // ([^\w]|^)_\("((\\"|[^"])*)"\)
+ // --$1--- -----$2----
+ // ---$3-- [match escaped quotes or any char that's not a quote]
+ //
+ // also match gettext() -- same as above
+
+ $buffer = preg_replace_callback('/([^\w]|^)_\("((\\\"|[^"])*)"\)/', array($this, 'xlateStringCallback'), $buffer);
+ $buffer = preg_replace_callback('/([^\w]|^)gettext\("((\\\"|[^"])*)"\)/', array($this, 'xlateStringCallback'), $buffer);
+
+ // Check to see if there are any _('') calls and flag an error
+
+ // Check to see if there are any unmatched gettext() calls -- and flag an error
+
+ $matches = array();
+ if (preg_match('/([^\w]|^)(gettext\([^\)]+\))/', $buffer, $matches)) {
+ $this->log("Unable to perform translation on: " . $matches[2], PROJECT_MSG_WARN);
+ }
+
+ $this->restoreEnvironment();
+
+ return $buffer;
+ }
+
+ /**
+ * Creates a new TranslateGettext filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param Reader $reader A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return TranslateGettext A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new TranslateGettext($reader);
+ $newFilter->setProject($this->getProject());
+ $newFilter->setDomain($this->getDomain());
+ $newFilter->setLocale($this->getLocale());
+ $newFilter->setDir($this->getDir());
+ return $newFilter;
+ }
+
+ /**
+ * Parses the parameters if this filter is being used in "generic" mode.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ foreach($params as $param) {
+ switch($param->getType()) {
+ case self::DOMAIN_KEY:
+ $this->setDomain($param->getValue());
+ break;
+ case self::DIR_KEY:
+ $this->setDir($this->project->resolveFile($param->getValue()));
+ break;
+
+ case self::LOCALE_KEY:
+ $this->setLocale($param->getValue());
+ break;
+ } // switch
+ }
+ } // if params !== null
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/filters/XsltFilter.php b/buildscripts/phing/classes/phing/filters/XsltFilter.php
new file mode 100644
index 00000000..0b8c4e6f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/XsltFilter.php
@@ -0,0 +1,317 @@
+<?php
+
+/*
+ * $Id: XsltFilter.php,v 1.16 2005/12/07 20:05:01 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Applies XSL stylesheet to incoming text.
+ *
+ * Uses PHP XSLT support (libxslt).
+ *
+ * @author Hans Lellelid <hans@velum.net>
+ * @author Yannick Lecaillez <yl@seasonfive.com>
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @version $Revision: 1.16 $
+ * @see FilterReader
+ * @package phing.filters
+ */
+class XsltFilter extends BaseParamFilterReader implements ChainableReader {
+
+ /**
+ * Path to XSL stylesheet.
+ * @var string
+ */
+ private $xslFile = null;
+
+ /**
+ * Whether XML file has been transformed.
+ * @var boolean
+ */
+ private $processed = false;
+
+ /**
+ * XSLT Params.
+ * @var array
+ */
+ private $xsltParams = array();
+
+ /**
+ * Whether to use loadHTML() to parse the input XML file.
+ */
+ private $html = false;
+
+ /**
+ * Create new XSLT Param object, to handle the <param/> nested element.
+ * @return XSLTParam
+ */
+ function createParam() {
+ $num = array_push($this->xsltParams, new XSLTParam());
+ return $this->xsltParams[$num-1];
+ }
+
+ /**
+ * Sets the XSLT params for this class.
+ * This is used to "clone" this class, in the chain() method.
+ * @param array $params
+ */
+ function setParams($params) {
+ $this->xsltParams = $params;
+ }
+
+ /**
+ * Returns the XSLT params set for this class.
+ * This is used to "clone" this class, in the chain() method.
+ * @return array
+ */
+ function getParams() {
+ return $this->xsltParams;
+ }
+
+ /**
+ * Set the XSLT stylesheet.
+ * @param mixed $file PhingFile object or path.
+ */
+ function setStyle(PhingFile $file) {
+ $this->xslFile = $file;
+ }
+
+ /**
+ * Whether to use HTML parser for the XML.
+ * This is supported in libxml2 -- Yay!
+ * @return boolean
+ */
+ function getHtml() {
+ return $this->html;
+ }
+
+ /**
+ * Whether to use HTML parser for XML.
+ * @param boolean $b
+ */
+ function setHtml($b) {
+ $this->html = (boolean) $b;
+ }
+
+ /**
+ * Get the path to XSLT stylesheet.
+ * @return mixed XSLT stylesheet path.
+ */
+ function getStyle() {
+ return $this->xslFile;
+ }
+
+ /**
+ * Reads stream, applies XSLT and returns resulting stream.
+ * @return string transformed buffer.
+ * @throws BuildException - if XSLT support missing, if error in xslt processing
+ */
+ function read($len = null) {
+
+ if (!class_exists('XSLTProcessor')) {
+ throw new BuildException("Could not find the XSLTProcessor class. Make sure PHP has been compiled/configured to support XSLT.");
+ }
+
+ if ($this->processed === true) {
+ return -1; // EOF
+ }
+
+ if ( !$this->getInitialized() ) {
+ $this->_initialize();
+ $this->setInitialized(true);
+ }
+
+ // Read XML
+ $_xml = null;
+ while ( ($data = $this->in->read($len)) !== -1 )
+ $_xml .= $data;
+
+ if ($_xml === null ) { // EOF?
+ return -1;
+ }
+
+ if(empty($_xml)) {
+ $this->log("XML file is empty!", PROJECT_MSG_WARN);
+ return ''; // return empty string, don't attempt to apply XSLT
+ }
+
+ // Read XSLT
+ $_xsl = null;
+ $xslFr = new FileReader($this->xslFile);
+ $xslFr->readInto($_xsl);
+
+ $this->log("Tranforming XML " . $this->in->getResource() . " using style " . $this->xslFile->getPath(), PROJECT_MSG_VERBOSE);
+
+ $out = '';
+ try {
+ $out = $this->process($_xml, $_xsl);
+ $this->processed = true;
+ } catch (IOException $e) {
+ throw new BuildException($e);
+ }
+
+ return $out;
+ }
+
+ // {{{ method _ProcessXsltTransformation($xml, $xslt) throws BuildException
+ /**
+ * Try to process the XSLT transformation
+ *
+ * @param string XML to process.
+ * @param string XSLT sheet to use for the processing.
+ *
+ * @throws BuildException On XSLT errors
+ */
+ protected function process($xml, $xsl) {
+
+ $processor = new XSLTProcessor();
+
+ $xmlDom = new DOMDocument();
+ $xslDom = new DOMDocument();
+
+ if ($this->html) {
+ $xmlDom->loadHTML($xml);
+ } else {
+ $xmlDom->loadXML($xml);
+ }
+
+ $xslDom->loadxml($xsl);
+
+ $processor->importStylesheet($xslDom);
+
+ // ignoring param "type" attrib, because
+ // we're only supporting direct XSL params right now
+ foreach($this->xsltParams as $param) {
+ $this->log("Setting XSLT param: " . $param->getName() . "=>" . $param->getExpression(), PROJECT_MSG_DEBUG);
+ $processor->setParameter(null, $param->getName(), $param->getExpression());
+ }
+
+ $result = $processor->transformToXML($xmlDom);
+
+ if ( !$result ) {
+ //$errno = xslt_errno($processor);
+ //$err = xslt_error($processor);
+ throw new BuildException("XSLT Error");
+ } else {
+ return $result;
+ }
+ }
+
+ /**
+ * Creates a new XsltFilter using the passed in
+ * Reader for instantiation.
+ *
+ * @param Reader A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return Reader A new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ function chain(Reader $reader) {
+ $newFilter = new XsltFilter($reader);
+ $newFilter->setProject($this->getProject());
+ $newFilter->setStyle($this->getStyle());
+ $newFilter->setInitialized(true);
+ $newFilter->setParams($this->getParams());
+ $newFilter->setHtml($this->getHtml());
+ return $newFilter;
+ }
+
+ /**
+ * Parses the parameters to get stylesheet path.
+ */
+ private function _initialize() {
+ $params = $this->getParameters();
+ if ( $params !== null ) {
+ for($i = 0, $_i=count($params) ; $i < $_i; $i++) {
+ if ( $params[$i]->getType() === null ) {
+ if ($params[$i]->getName() === "style") {
+ $this->setStyle($params[$i]->getValue());
+ }
+ } elseif ($params[$i]->getType() == "param") {
+ $xp = new XSLTParam();
+ $xp->setName($params[$i]->getName());
+ $xp->setExpression($params[$i]->getValue());
+ $this->xsltParams[] = $xp;
+ }
+ }
+ }
+ }
+
+}
+
+
+/**
+ * Class that holds an XSLT parameter.
+ */
+class XSLTParam {
+
+ private $name;
+
+ private $expr;
+
+ /**
+ * Sets param name.
+ * @param string $name
+ */
+ public function setName($name) {
+ $this->name = $name;
+ }
+
+ /**
+ * Get param name.
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Sets expression value.
+ * @param string $expr
+ */
+ public function setExpression($expr) {
+ $this->expr = $expr;
+ }
+
+ /**
+ * Sets expression to dynamic register slot.
+ * @param RegisterSlot $expr
+ */
+ public function setListeningExpression(RegisterSlot $expr) {
+ $this->expr = $expr;
+ }
+
+ /**
+ * Returns expression value -- performs lookup if expr is registerslot.
+ * @return string
+ */
+ public function getExpression() {
+ if ($this->expr instanceof RegisterSlot) {
+ return $this->expr->getValue();
+ } else {
+ return $this->expr;
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/filters/util/ChainReaderHelper.php b/buildscripts/phing/classes/phing/filters/util/ChainReaderHelper.php
new file mode 100644
index 00000000..80508a82
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/util/ChainReaderHelper.php
@@ -0,0 +1,184 @@
+<?php
+/*
+ * $Id: ChainReaderHelper.php,v 1.8 2005/02/27 20:52:09 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/Project.php';
+include_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/types/PhingFilterReader.php';
+include_once 'phing/types/FilterChain.php';
+include_once 'phing/types/Parameter.php';
+include_once 'phing/util/FileUtils.php';
+include_once 'phing/util/StringHelper.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Process a FilterReader chain.
+ *
+ * Here, the interesting method is 'getAssembledReader'.
+ * The purpose of this one is to create a simple Reader object which
+ * apply all filters on another primary Reader object.
+ *
+ * For example : In copyFile (phing.util.FileUtils) the primary Reader
+ * is a FileReader object (more accuratly, a BufferedReader) previously
+ * setted for the source file to copy. So, consider this filterchain :
+ *
+ * <filterchain>
+ * <stripphpcomments />
+ * <linecontains>
+ * <contains value="foo">
+ * </linecontains>
+ * <tabtospaces tablength="8" />
+ * </filterchain>
+ *
+ * getAssembledReader will return a Reader object wich read on each
+ * of these filters. Something like this : ('->' = 'which read data from') :
+ *
+ * [TABTOSPACES] -> [LINECONTAINS] -> [STRIPPHPCOMMENTS] -> [FILEREADER]
+ * (primary reader)
+ *
+ * So, getAssembledReader will return the TABTOSPACES Reader object. Then
+ * each read done with this Reader object will follow this path.
+ *
+ * Hope this explanation is clear :)
+ *
+ * TODO: Implement the classPath feature.
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @version $Revision: 1.8 $ $Date: 2005/02/27 20:52:09 $
+ * @access public
+ * @package phing.filters.util
+*/
+class ChainReaderHelper {
+
+ /** Primary reader to wich the reader chain is to be attached */
+ private $primaryReader = null;
+
+ /** The site of the buffer to be used. */
+ private $bufferSize = 8192;
+
+ /** Chain of filters */
+ private $filterChains = array();
+
+ /** The Phing project */
+ private $project;
+
+ /*
+ * Sets the primary reader
+ */
+ function setPrimaryReader(Reader $reader) {
+ $this->primaryReader = $reader;
+ }
+
+ /*
+ * Set the project to work with
+ */
+ function setProject(Project $project) {
+ $this->project = $project;
+ }
+
+ /*
+ * Get the project
+ */
+ function getProject() {
+ return $this->project;
+ }
+
+ /*
+ * Sets the buffer size to be used. Defaults to 8192,
+ * if this method is not invoked.
+ */
+ function setBufferSize($size) {
+ $this->bufferSize = $size;
+ }
+
+ /*
+ * Sets the collection of filter reader sets
+ */
+ function setFilterChains(&$fchain) {
+ $this->filterChains = &$fchain;
+ }
+
+ /*
+ * Assemble the reader
+ */
+ function getAssembledReader() {
+
+ $instream = $this->primaryReader;
+ $filterReadersCount = count($this->filterChains);
+ $finalFilters = array();
+
+ // Collect all filter readers of all filter chains used ...
+ for($i = 0 ; $i<$filterReadersCount ; $i++) {
+ $filterchain = &$this->filterChains[$i];
+ $filterReaders = $filterchain->getFilterReaders();
+ $readerCount = count($filterReaders);
+ for($j = 0 ; $j<$readerCount ; $j++) {
+ $finalFilters[] = $filterReaders[$j];
+ }
+ }
+
+ // ... then chain the filter readers.
+ $filtersCount = count($finalFilters);
+ if ( $filtersCount > 0 ) {
+ for($i = 0 ; $i<$filtersCount ; $i++) {
+ $filter = $finalFilters[$i];
+
+ if ( $filter instanceof PhingFilterReader ) {
+
+ // This filter reader is an external class.
+ $className = $filter->getClassName();
+ $classpath = $filter->getClasspath();
+ $project = $filter->getProject();
+
+ if ( $className !== null ) {
+ $cls = Phing::import($className, $classpath);
+ $impl = new $cls();
+ }
+
+ if ( !($impl instanceof FilterReader) ) {
+ throw new Exception($className." does not extend phing.system.io.FilterReader");
+ }
+
+ $impl->setReader($instream); // chain
+ $impl->setProject($this->getProject()); // what about $project above ?
+
+ if ( $impl instanceof Parameterizable ) {
+ $impl->setParameters($filter->getParams());
+ }
+
+ $instream = $impl; // now that it's been chained
+
+ } elseif (($filter instanceof ChainableReader) && ($filter instanceof Reader)) {
+ if ( $this->getProject() !== null && ($filter instanceof BaseFilterReader) ) {
+ $filter->setProject($this->getProject());
+ }
+ $instream = $filter->chain($instream);
+ } else {
+ throw new Exception("Cannot chain invalid filter: " . get_class($filter));
+ }
+ }
+ }
+
+ return $instream;
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/filters/util/IniFileTokenReader.php b/buildscripts/phing/classes/phing/filters/util/IniFileTokenReader.php
new file mode 100644
index 00000000..34bc5943
--- /dev/null
+++ b/buildscripts/phing/classes/phing/filters/util/IniFileTokenReader.php
@@ -0,0 +1,96 @@
+<?php
+/*
+ * $Id: IniFileTokenReader.php,v 1.7 2005/05/26 13:10:51 mrook Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/types/TokenReader.php';
+include_once 'phing/system/io/IOException.php';
+include_once 'phing/filters/ReplaceTokens.php'; // For class Token
+
+/**
+ * Class that allows reading tokens from INI files.
+ *
+ * @author Manuel Holtgewe
+ * @version $Revision: 1.7 $
+ * @package phing.filters.util
+ */
+class IniFileTokenReader extends TokenReader {
+
+ /**
+ * Holds the path to the INI file that is to be read.
+ * @var object Reference to a PhingFile Object representing
+ * the path to the INI file.
+ */
+ private $file = null;
+
+ /**
+ * @var string Sets the section to load from the INI file.
+ * if omitted, all sections are loaded.
+ */
+ private $section = null;
+
+ /**
+ * Reads the next token from the INI file
+ *
+ * @throws IOException On error
+ */
+ function readToken() {
+ if ($this->file === null) {
+ throw new BuildException("No File set for IniFileTokenReader");
+ }
+
+ static $tokens = null;
+ if ($tokens === null) {
+ $tokens = array();
+ $arr = parse_ini_file($this->file->getAbsolutePath(), true);
+ if ($this->section === null) {
+ foreach ($arr as $sec_name => $values) {
+ foreach($arr[$sec_name] as $key => $value) {
+ $tok = new Token;
+ $tok->setKey($key);
+ $tok->setValue($value);
+ $tokens[] = $tok;
+ }
+ }
+ } else if (isset($arr[$this->section])) {
+ foreach ($arr[$this->section] as $key => $value) {
+ $tok = new Token;
+ $tok->setKey($key);
+ $tok->setValue($value);
+ $tokens[] = $tok;
+ }
+ }
+ }
+
+ if (count($tokens) > 0) {
+ return array_pop($tokens);
+ } else
+ return null;
+ }
+
+ function setFile(PhingFile $file) {
+ $this->file = $file;
+ }
+
+ function setSection($str) {
+ $this->section = (string) $str;
+ }
+}
+
+?>