1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 */
19

20
/**
21
 * The Target component. Carries all required target data. Implements the
22
 * abstract class {@link TaskContainer}
23
 *
24
 * @author    Andreas Aderhold <andi@binarycloud.com>
25
 * @copyright 2001,2002 THYRELL. All rights reserved
26
 * @see       TaskContainer
27
 * @package   phing
28
 */
29
class Target implements TaskContainer
30
{
31

32
    /**
33
     * Name of target
34
     *
35
     * @var string
36
     */
37
    private $name;
38

39
    /**
40
     * Dependencies
41
     *
42
     * @var array
43
     */
44
    private $dependencies = [];
45

46
    /**
47
     * Holds objects of children of this target
48
     *
49
     * @var array
50
     */
51
    private $children = [];
52

53
    /**
54
     * The if condition from xml
55
     *
56
     * @var string
57
     */
58
    private $ifCondition = "";
59

60
    /**
61
     * The unless condition from xml
62
     *
63
     * @var string
64
     */
65
    private $unlessCondition = "";
66

67
    /**
68
     * Description of this target
69
     *
70
     * @var string
71
     */
72
    private $description;
73

74
    /**
75
     * Whether to hide target in targets list (-list -p switches)
76
     *
77
     * @var boolean
78
     */
79
    private $hidden = false;
80

81
    /**
82
     * Whether to log message as INFO or VERBOSE if target skipped
83
     *
84
     * @var boolean
85
     */
86
    private $logSkipped = false;
87

88
    /**
89
     * Rreference to project
90
     *
91
     * @var Project
92
     */
93
    private $project;
94
    private $location;
95

96 1
    public function __construct(Target $other = null)
97
    {
98 1
        if ($other !== null) {
99 0
            $this->name = $other->name;
100 0
            $this->ifCondition = $other->ifCondition;
101 0
            $this->unlessCondition = $other->unlessCondition;
102 0
            $this->dependencies = $other->dependencies;
103 0
            $this->location = $other->location;
104 0
            $this->project = $other->project;
105 0
            $this->description = $other->description;
106
            // The children are added to after this cloning
107 0
            $this->children = $other->children;
108
        }
109
    }
110

111
    /**
112
     * References the project to the current component.
113
     *
114
     * @param Project $project The reference to the current project
115
     */
116 1
    public function setProject(Project $project)
117
    {
118 1
        $this->project = $project;
119
    }
120

121
    /**
122
     * Returns reference to current project
123
     *
124
     * @return Project Reference to current porject object
125
     */
126 1
    public function getProject()
127
    {
128 1
        return $this->project;
129
    }
130

131
    /**
132
     * Sets the location of this target's definition.
133
     *
134
     * @param location location
135
     */
136 1
    public function setLocation(Location $location): void
137
    {
138 1
        $this->location = $location;
139
    }
140

141
    /**
142
     * Get the location of this target's definition.
143
     *
144
     * @return Location
145
     */
146 1
    public function getLocation(): Location
147
    {
148 1
        return $this->location;
149
    }
150

151
    /**
152
     * Sets the target dependencies from xml
153
     *
154
     * @param  string $depends Comma separated list of targetnames that depend on
155
     *                         this target
156
     * @throws BuildException
157
     */
158 1
    public function setDepends($depends)
159
    {
160
        // explode should be faster than strtok
161 1
        $deps = explode(',', $depends);
162 1
        for ($i = 0, $size = count($deps); $i < $size; $i++) {
163 1
            $trimmed = trim($deps[$i]);
164 1
            if ($trimmed === "") {
165 1
                throw new BuildException(
166 1
                    "Syntax Error: Depend attribute for target " . $this->getName() . " is malformed."
167
                );
168
            }
169 1
            $this->addDependency($trimmed);
170
        }
171
    }
172

173
    /**
174
     * Adds a singular dependent target name to the list
175
     *
176
     * @param string $dependency The dependency target to add
177
     */
178 1
    public function addDependency($dependency)
179
    {
180 1
        $this->dependencies[] = (string) $dependency;
181
    }
182

183
    /**
184
     * Returns reference to indexed array of the dependencies this target has.
185
     *
186
     * @return array Reference to target dependencoes
187
     */
188 1
    public function getDependencies()
189
    {
190 1
        return $this->dependencies;
191
    }
192

193
    /**
194
     * @param string $targetName Name of the target to search for
195
     * @return false|int|string
196
     */
197 1
    public function dependsOn($targetName)
198
    {
199 1
        return \array_search($targetName, $this->dependencies);
200
    }
201

202
    /**
203
     * Sets the name of the target
204
     *
205
     * @param string $name Name of this target
206
     */
207 1
    public function setName($name)
208
    {
209 1
        $this->name = (string) $name;
210
    }
211

212
    /**
213
     * Returns name of this target.
214
     *
215
     * @return string The name of the target
216
     */
217 1
    public function getName()
218
    {
219 1
        return (string) $this->name;
220
    }
221

222
    /**
223
     * Set target status. If true, target does not come in phing -list
224
     *
225
     * @param  boolean $flag
226
     * @return Target
227
     */
228 1
    public function setHidden($flag)
229
    {
230 1
        $this->hidden = (bool) $flag;
231

232 1
        return $this;
233
    }
234

235
    /**
236
     * Get target status. If true, target does not come in phing -list
237
     *
238
     * @return boolean
239
     */
240 0
    public function getHidden()
241
    {
242 0
        return $this->hidden;
243
    }
244

245
    /**
246
     * Alias for getHidden()
247
     *
248
     * @return boolean
249
     */
250 0
    public function isHidden()
251
    {
252 0
        return $this->getHidden();
253
    }
254

255
    /**
256
     * Adds a task element to the list of this targets child elements
257
     *
258
     * @param Task $task The task object to add
259
     */
260 1
    public function addTask(Task $task)
261
    {
262 1
        $this->children[] = $task;
263
    }
264

265
    /**
266
     * Adds a runtime configurable element to the list of this targets child
267
     * elements.
268
     *
269
     * @param RuntimeConfigurable $rtc The RuntimeConfigurable object
270
     */
271 1
    public function addDataType($rtc)
272
    {
273 1
        $this->children[] = $rtc;
274
    }
275

276
    /**
277
     * Returns an array of all tasks this target has as childrens.
278
     *
279
     * The task objects are copied here. Don't use this method to modify
280
     * task objects.
281
     *
282
     * @return array Task[]
283
     */
284 1
    public function getTasks()
285
    {
286 1
        $tasks = [];
287 1
        for ($i = 0, $size = count($this->children); $i < $size; $i++) {
288 1
            $tsk = $this->children[$i];
289 1
            if ($tsk instanceof Task) {
290
                // note: we're copying objects here!
291 1
                $tasks[] = clone $tsk;
292
            }
293
        }
294

295 1
        return $tasks;
296
    }
297

298
    /**
299
     * Set the if-condition from the XML tag, if any. The property name given
300
     * as parameter must be present so the if condition evaluates to true
301
     *
302
     * @param string $property The property name that has to be present
303
     */
304 1
    public function setIf($property)
305
    {
306 1
        $this->ifCondition = $property ?? "";
307
    }
308

309
    /**
310
     * Set the unless-condition from the XML tag, if any. The property name
311
     * given as parameter must be present so the unless condition evaluates
312
     * to true
313
     *
314
     * @param string $property The property name that has to be present
315
     */
316 1
    public function setUnless($property)
317
    {
318 1
        $this->unlessCondition = $property ?? "";
319
    }
320

321
    /**
322
     * Sets a textual description of this target.
323
     *
324
     * @param string $description The description text
325
     */
326 1
    public function setDescription($description)
327
    {
328 1
        $this->description = $description;
329
    }
330

331
    /**
332
     * Returns the description of this target.
333
     *
334
     * @return string The description text of this target
335
     */
336 0
    public function getDescription()
337
    {
338 0
        return $this->description;
339
    }
340

341 1
    public function setLogSkipped(bool $log)
342
    {
343 1
        $this->logSkipped = $log;
344
    }
345

346
    /**
347
     * @return bool|null
348
     */
349 1
    public function getLogSkipped()
350
    {
351 1
        if ($this->logSkipped === null) {
352 0
            $this->setLogSkipped(false);
353
        }
354

355 1
        return $this->logSkipped;
356
    }
357

358
    /**
359
     * Returns a string representation of this target. In our case it
360
     * simply returns the target name field
361
     *
362
     * @return string The string representation of this target
363
     */
364 1
    public function __toString()
365
    {
366 1
        return (string) $this->name;
367
    }
368

369
    /**
370
     * The entry point for this class. Does some checking, then processes and
371
     * performs the tasks for this target.
372
     */
373 1
    public function main()
374
    {
375 1
        if ($this->testIfCondition() && $this->testUnlessCondition()) {
376 1
            foreach ($this->children as $o) {
377 1
                if ($o instanceof Task) {
378
                    // child is a task
379 1
                    $o->perform();
380 1
                } elseif ($o instanceof RuntimeConfigurable) {
381
                    // child is a RuntimeConfigurable
382 1
                    $o->maybeConfigure($this->project);
383
                }
384
            }
385 1
        } elseif (!$this->testIfCondition()) {
386 1
            $this->project->log(
387 1
                "Skipped target '" . $this->name . "' because property '" . $this->ifCondition . "' not set.",
388 1
                $this->getLogSkipped() ? Project::MSG_INFO : Project::MSG_VERBOSE
389
            );
390
        } else {
391 1
            $this->project->log(
392 1
                "Skipped target '" . $this->name . "' because property '" . $this->unlessCondition . "' set.",
393 1
                $this->getLogSkipped() ? Project::MSG_INFO : Project::MSG_VERBOSE
394
            );
395
        }
396
    }
397

398
    /**
399
     * Performs the tasks by calling the main method of this target that
400
     * actually executes the tasks.
401
     *
402
     * This method is for ZE2 and used for proper exception handling of
403
     * task exceptions.
404
     */
405 1
    public function performTasks()
406
    {
407
        try { // try to execute this target
408 1
            $this->project->fireTargetStarted($this);
409 1
            $this->main();
410 1
            $this->project->fireTargetFinished($this, $null = null);
411 1
        } catch (BuildException $exc) {
412
            // log here and rethrow
413 1
            $this->project->fireTargetFinished($this, $exc);
414 1
            throw $exc;
415
        }
416
    }
417

418
    /**
419
     * Tests if the property set in ifConfiditon exists.
420
     *
421
     * @return boolean <code>true</code> if the property specified
422
     *                 in <code>$this->ifCondition</code> exists;
423
     *                 <code>false</code> otherwise
424
     */
425 1
    private function testIfCondition()
426
    {
427 1
        if ($this->ifCondition === "") {
428 1
            return true;
429
        }
430

431 1
        $properties = explode(",", $this->ifCondition);
432

433 1
        $result = true;
434 1
        foreach ($properties as $property) {
435 1
            $test = $this->getProject()->replaceProperties($property);
436 1
            $result = $result && ($this->project->getProperty($test) !== null);
437
        }
438

439 1
        return $result;
440
    }
441

442
    /**
443
     * Tests if the property set in unlessCondition exists.
444
     *
445
     * @return boolean <code>true</code> if the property specified
446
     *                 in <code>$this->unlessCondition</code> exists;
447
     *                 <code>false</code> otherwise
448
     */
449 1
    private function testUnlessCondition()
450
    {
451 1
        if ($this->unlessCondition === "") {
452 1
            return true;
453
        }
454

455 1
        $properties = explode(",", $this->unlessCondition);
456

457 1
        $result = true;
458 1
        foreach ($properties as $property) {
459 1
            $test = $this->getProject()->replaceProperties($property);
460 1
            $result = $result && ($this->project->getProperty($test) === null);
461
        }
462

463 1
        return $result;
464
    }
465

466
    /**
467
     * Replaces all occurrences of the given task in the list
468
     * of children with the replacement data type wrapper.
469
     * @param Task $task
470
     * @param RuntimeConfigurable|Task $o
471
     */
472 1
    public function replaceChild(Task $task, $o)
473
    {
474 1
        $keys = array_keys($this->children, $task);
475 1
        foreach ($keys as $index) {
476 1
            $this->children[$index] = $o;
477
        }
478
    }
479

480
    /**
481
     * @param string $depends
482
     * @param string $targetName
483
     * @param string $attributeName
484
     * @return string[]
485
     * @throws \BuildException
486
     */
487 1
    public static function parseDepends($depends, $targetName, $attributeName)
488
    {
489 1
        $list = [];
490 1
        if ($depends !== '') {
491 1
            $list = explode(',', $depends);
492 1
            array_walk($list, 'trim');
493 1
            if (count($list) === 0) {
494 0
                throw new BuildException("Syntax Error: "
495 0
                    . $attributeName
496 0
                    . " attribute of target \""
497 0
                    . $targetName
498 0
                    . "\" contains an empty string.");
499
            }
500
        }
501 1
        return $list;
502
    }
503
}

Read our documentation on viewing source code .

Loading