Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/*
3
 *  $Id: AppendTask.php 144 2007-02-05 15:19:00Z hans $
4
 *
5
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
 *
17
 * This software consists of voluntary contributions made by many individuals
18
 * and is licensed under the LGPL. For more information please see
19
 * <http://phing.info>.
20
 */
21
 
22
require_once 'phing/Task.php';
23
include_once 'phing/types/FileList.php';
24
include_once 'phing/types/FileSet.php';
25
 
26
/**
27
 *  Appends text, contents of a file or set of files defined by a filelist to a destination file.
28
 *
29
 * <code>
30
 * <append text="And another thing\n" destfile="badthings.log"/>
31
 * </code>
32
 * OR
33
 * <code>
34
 * <append file="header.html" destfile="fullpage.html"/>
35
 * <append file="body.html" destfile="fullpage.html"/>
36
 * <append file="footer.html" destfile="fullpage.html"/>
37
 * </code>
38
 * OR
39
 * <code>
40
 * <append destfile="${process.outputfile}">
41
 *    <filterchain>
42
 *        <xsltfilter style="${process.stylesheet}">
43
 *            <param name="mode" expression="${process.xslt.mode}"/>
44
 *            <param name="file_name" expression="%{task.append.current_file.basename}"/> <!-- Example of using a RegisterSlot variable -->
45
 *        </xsltfilter>
46
 *    </filterchain>
47
 *     <filelist dir="book/" listfile="book/PhingGuide.book"/>
48
 * </append>
49
 * </code>
50
 * @package phing.tasks.system
51
 * @version $Revision: 1.14 $
52
 */
53
class AppendTask extends Task {
54
 
55
    /** Append stuff to this file. */
56
    private $to;
57
 
58
    /** Explicit file to append. */
59
    private $file;
60
 
61
    /** Any filesets of files that should be appended. */
62
    private $filesets = array();
63
 
64
    /** Any filelists of files that should be appended. */
65
    private $filelists = array();
66
 
67
    /** Any filters to be applied before append happens. */
68
    private $filterChains = array();
69
 
70
    /** Text to append. (cannot be used in conjunction w/ files or filesets) */
71
    private $text;
72
 
73
    /** Sets specific file to append. */
74
    function setFile(PhingFile $f) {
75
        $this->file = $f;
76
    }
77
 
78
    /**
79
     * Set target file to append to.
80
     * @deprecated Will be removed with final release.
81
     */
82
    function setTo(PhingFile $f) {
83
        $this->log("The 'to' attribute is deprecated in favor of 'destFile'; please update your code.", Project::MSG_WARN);
84
        $this->to = $f;
85
    }
86
 
87
    /**
88
     * The more conventional naming for method to set destination file.
89
     * @param PhingFile $f
90
     */
91
    function setDestFile(PhingFile $f) {
92
        $this->to = $f;
93
    }
94
 
95
    /**
96
     * Supports embedded <filelist> element.
97
     * @return FileList
98
     */
99
    function createFileList() {
100
        $num = array_push($this->filelists, new FileList());
101
        return $this->filelists[$num-1];
102
    }
103
 
104
    /**
105
     * Nested creator, adds a set of files (nested <fileset> attribute).
106
     * This is for when you don't care what order files get appended.
107
     * @return FileSet
108
     */
109
    function createFileSet() {
110
        $num = array_push($this->filesets, new FileSet());
111
        return $this->filesets[$num-1];
112
    }
113
 
114
    /**
115
     * Creates a filterchain
116
     *
117
     * @return FilterChain The created filterchain object
118
     */
119
    function createFilterChain() {
120
        $num = array_push($this->filterChains, new FilterChain($this->project));
121
        return $this->filterChains[$num-1];
122
    }
123
 
124
    /**
125
     * Sets text to append.  (cannot be used in conjunction w/ files or filesets).
126
     * @param string $txt
127
     */
128
    function setText($txt) {
129
        $this->text = (string) $txt;
130
    }
131
 
132
    /**
133
     * Sets text to append. Supports CDATA.
134
     * @param string $txt
135
     */
136
    function addText($txt) {
137
        $this->text = (string) $txt;
138
    }
139
 
140
 
141
    /** Append the file(s). */
142
    function main() {
143
 
144
        if ($this->to === null) {
145
            throw new BuildException("You must specify the 'destFile' attribute");
146
        }
147
 
148
        if ($this->file === null && empty($this->filelists) && empty($this->filesets) && $this->text === null) {
149
            throw new BuildException("You must specify a file, use a filelist, or specify a text value.");
150
        }
151
 
152
        if ($this->text !== null && ($this->file !== null || !empty($this->filelists))) {
153
            throw new BuildException("Cannot use text attribute in conjunction with file or filelists.");
154
        }
155
 
156
        // create a filwriter to append to "to" file.
157
        $writer = new FileWriter($this->to, $append=true);
158
 
159
        if ($this->text !== null) {
160
 
161
            // simply append the text
162
            $this->log("Appending string to " . $this->to->getPath());
163
 
164
            // for debugging primarily, maybe comment
165
            // out for better performance(?)
166
            $lines = explode("\n", $this->text);
167
            foreach($lines as $line) {
168
                $this->log($line, Project::MSG_VERBOSE);
169
            }
170
 
171
            $writer->write($this->text);
172
 
173
        } else {
174
 
175
            // append explicitly-specified file
176
            if ($this->file !== null) {
177
                try {
178
                    $this->appendFile($writer, $this->file);
179
                } catch (Exception $ioe) {
180
                    $this->log("Unable to append contents of file " . $this->file->getAbsolutePath() . ": " . $ioe->getMessage(), Project::MSG_WARN);
181
                }
182
            }
183
 
184
            // append the files in the filelists
185
            foreach($this->filelists as $fl) {
186
                try {
187
                    $files = $fl->getFiles($this->project);
188
                    $this->appendFiles($writer, $files, $fl->getDir($this->project));
189
                } catch (BuildException $be) {
190
                    $this->log($be->getMessage(), Project::MSG_WARN);
191
                }
192
            }
193
 
194
            // append any files in filesets
195
            foreach($this->filesets as $fs) {
196
                try {
197
                    $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
198
                    $this->appendFiles($writer, $files, $fs->getDir($this->project));
199
                } catch (BuildException $be) {
200
                    $this->log($be->getMessage(), Project::MSG_WARN);
201
                }
202
            }
203
 
204
        } // if ($text ) {} else {}
205
 
206
        $writer->close();
207
    }
208
 
209
    /**
210
     * Append an array of files in a directory.
211
     * @param FileWriter $writer The FileWriter that is appending to target file.
212
     * @param array $files array of files to delete; can be of zero length
213
     * @param PhingFile $dir directory to work from
214
     */
215
    private function appendFiles(FileWriter $writer, $files, PhingFile $dir) {
216
        if (!empty($files)) {
217
            $this->log("Attempting to append " . count($files) . " files" .($dir !== null ? ", using basedir " . $dir->getPath(): ""));
218
            $basenameSlot = Register::getSlot("task.append.current_file");
219
            $pathSlot = Register::getSlot("task.append.current_file.path");
220
            foreach($files as $filename) {
221
                try {
222
                    $f = new PhingFile($dir, $filename);
223
                    $basenameSlot->setValue($filename);
224
                    $pathSlot->setValue($f->getPath());
225
                    $this->appendFile($writer, $f);
226
                } catch (Exception $ioe) {
227
                    $this->log("Unable to append contents of file " . $f->getAbsolutePath() . ": " . $ioe->getMessage(), Project::MSG_WARN);
228
                }
229
            }
230
        } // if !empty
231
    }
232
 
233
    private function appendFile(FileWriter $writer, PhingFile $f) {
234
        $in = FileUtils::getChainedReader(new FileReader($f), $this->filterChains, $this->project);
235
        while(-1 !== ($buffer = $in->read())) { // -1 indicates EOF
236
            $writer->write($buffer);
237
        }
238
        $this->log("Appending contents of " . $f->getPath() . " to " . $this->to->getPath());
239
    }
240
}