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 handler class.
22
 *
23
 * This class handles the occurrence of a <target> tag and it's possible
24
 * nested tags (datatypes and tasks).
25
 *
26
 * @author    Andreas Aderhold <andi@binarycloud.com>
27
 * @copyright 2001,2002 THYRELL. All rights reserved
28
 * @package   phing.parser
29
 */
30
class TargetHandler extends AbstractHandler
31
{
32

33
    /**
34
     * Reference to the target object that represents the currently parsed
35
     * target.
36
     *
37
     * @var Target the target instance
38
     */
39
    private $target;
40

41
    /**
42
     * The phing project configurator object
43
     *
44
     * @var ProjectConfigurator
45
     */
46
    private $configurator;
47

48
    /**
49
     * @var PhingXMLContext
50
     */
51
    private $context;
52

53
    /**
54
     * Constructs a new TargetHandler
55
     *
56
     * @param    AbstractSAXParser $parser
57
     * @param    AbstractHandler $parentHandler
58
     * @param    ProjectConfigurator $configurator
59
     * @param    PhingXMLContext $context
60
     * @internal param the $object ExpatParser object
61
     * @internal param the $object parent handler that invoked this handler
62
     * @internal param the $object ProjectConfigurator object
63
     */
64 1
    public function __construct(
65
        AbstractSAXParser $parser,
66
        AbstractHandler $parentHandler,
67
        ProjectConfigurator $configurator,
68
        PhingXMLContext $context
69
    ) {
70 1
        parent::__construct($parser, $parentHandler);
71 1
        $this->configurator = $configurator;
72 1
        $this->context = $context;
73
    }
74

75
    /**
76
     * Executes initialization actions required to setup the data structures
77
     * related to the tag.
78
     * <p>
79
     * This includes:
80
     * <ul>
81
     * <li>creation of the target object</li>
82
     * <li>calling the setters for attributes</li>
83
     * <li>adding the target to the project</li>
84
     * <li>adding a reference to the target (if id attribute is given)</li>
85
     * </ul>
86
     *
87
     * @param    $tag
88
     * @param    $attrs
89
     * @throws   BuildException
90
     * @throws   ExpatParseException
91
     * @internal param the $string tag that comes in
92
     * @internal param attributes $array the tag carries
93
     */
94 1
    public function init($tag, $attrs)
95
    {
96 1
        $name = null;
97 1
        $depends = "";
98 1
        $extensionPoint = null;//'fail';
99 1
        $extensionPointMissing = null;
100 1
        $ifCond = null;
101 1
        $unlessCond = null;
102 1
        $id = null;
103 1
        $description = null;
104 1
        $isHidden = false;
105 1
        $logskipped = false;
106

107 1
        foreach ($attrs as $key => $value) {
108 1
            switch ($key) {
109 1
                case "name":
110 1
                    $name = (string) $value;
111 1
                    break;
112 1
                case "depends":
113 1
                    $depends = (string) $value;
114 1
                    break;
115 1
                case "if":
116 1
                    $ifCond = (string) $value;
117 1
                    break;
118 1
                case "unless":
119 1
                    $unlessCond = (string) $value;
120 1
                    break;
121 1
                case "id":
122 0
                    $id = (string) $value;
123 0
                    break;
124 1
                case "hidden":
125 0
                    $isHidden = ($value === 'true' || $value === '1');
126 0
                    break;
127 1
                case "description":
128 1
                    $description = (string) $value;
129 1
                    break;
130 1
                case "logskipped":
131 0
                    $logskipped = $value;
132 0
                    break;
133 1
                case "extensionof":
134 1
                    $extensionPoint = $value;
135 1
                    break;
136 1
                case "onmissingextensionpoint":
137 1
                    if (!in_array($value, ['fail', 'warn', 'ignore'], true)) {
138 0
                        throw new BuildException('Invalid onMissingExtensionPoint ' . $value);
139
                    }
140 1
                    $extensionPointMissing = $value;
141 1
                    break;
142
                default:
143 0
                    throw new ExpatParseException("Unexpected attribute '$key'", $this->parser->getLocation());
144
            }
145
        }
146

147 1
        if ($name === null) {
148 0
            throw new ExpatParseException(
149 0
                "target element appears without a name attribute",
150 0
                $this->parser->getLocation()
151
            );
152
        }
153

154
        // shorthand
155 1
        $project = $this->configurator->project;
156

157
        // check to see if this target is a dup within the same file
158 1
        if (isset($this->context->getCurrentTargets()[$name])) {
159 0
            throw new BuildException(
160 0
                "Duplicate target: $name",
161 0
                $this->parser->getLocation()
162
            );
163
        }
164

165 1
        $this->target = $tag === 'target' ? new Target() : new ExtensionPoint();
166 1
        $this->target->setProject($project);
167 1
        $this->target->setLocation($this->parser->getLocation());
168 1
        $this->target->setHidden($isHidden);
169 1
        $this->target->setIf($ifCond);
170 1
        $this->target->setUnless($unlessCond);
171 1
        $this->target->setDescription($description);
172 1
        $this->target->setLogSkipped(StringHelper::booleanValue($logskipped));
173
        // take care of dependencies
174 1
        if ($depends !== '') {
175 1
            $this->target->setDepends($depends);
176
        }
177

178
        // check to see if target with same name is already defined
179 1
        $projectTargets = $project->getTargets();
180 1
        if (isset($projectTargets[$name])) {
181
            if (
182 1
                $this->configurator->isIgnoringProjectTag()
183 1
                && $this->configurator->getCurrentProjectName() != null
184 1
                && strlen($this->configurator->getCurrentProjectName()) != 0
185
            ) {
186
                // In an impored file (and not completely
187
                // ignoring the project tag)
188 1
                $newName = $this->configurator->getCurrentProjectName() . "." . $name;
189 1
                $project->log(
190
                    "Already defined in main or a previous import, " .
191 1
                    "define {$name} as {$newName}",
192 1
                    Project::MSG_VERBOSE
193
                );
194 1
                $name = $newName;
195
            } else {
196 0
                $project->log(
197
                    "Already defined in main or a previous import, " .
198 0
                    "ignore {$name}",
199 0
                    Project::MSG_VERBOSE
200
                );
201 0
                $name = null;
202
            }
203
        }
204

205 1
        if ($name !== null) {
206 1
            $this->target->setName($name);
207 1
            $project->addOrReplaceTarget($name, $this->target);
208 1
            if ($id !== null && $id !== "") {
209 0
                $project->addReference($id, $this->target);
210
            }
211
        }
212

213 1
        if ($extensionPointMissing !== null && $extensionPoint === null) {
214 1
            throw new BuildException(
215
                "onMissingExtensionPoint attribute cannot " .
216 1
                "be specified unless extensionOf is specified",
217 1
                $this->target->getLocation()
218
            );
219
        }
220 1
        if ($extensionPoint !== null) {
221 1
            foreach (Target::parseDepends($extensionPoint, $name, 'extensionof') as $extPointName) {
222 1
                if ($extensionPointMissing === null) {
223 1
                    $extensionPointMissing = 'fail';
224
                }
225 1
                $this->context->addExtensionPoint([
226 1
                    $extPointName,
227 1
                    $this->target->getName(),
228 1
                    $extensionPointMissing,
229
                    null
230
                ]);
231
            }
232
        }
233
    }
234

235
    /**
236
     * Checks for nested tags within the current one. Creates and calls
237
     * handlers respectively.
238
     *
239
     * @param string $name the tag that comes in
240
     * @param array $attrs attributes the tag carries
241
     */
242 1
    public function startElement($name, $attrs)
243
    {
244 1
        $tmp = new ElementHandler($this->parser, $this, $this->configurator, null, null, $this->target);
245 1
        $tmp->init($name, $attrs);
246
    }
247

248
    /**
249
     * Checks if this target has dependencies and/or nested tasks.
250
     * If the target has neither, show a warning.
251
     */
252 1
    protected function finished()
253
    {
254 1
        if (!$this->target instanceof ExtensionPoint && !count($this->target->getDependencies()) && !count($this->target->getTasks())) {
255 1
            $this->configurator->project->log(
256 1
                "Warning: target '" . $this->target->getName() .
257 1
                "' has no tasks or dependencies",
258 1
                Project::MSG_WARN
259
            );
260
        }
261
    }
262
}

Read our documentation on viewing source code .

Loading