Passed
Push — master ( e1f86a...4e1a3a )
by Siad
05:23
created

TargetHandler::init()   F

Complexity

Conditions 30
Paths 2186

Size

Total Lines 136
Code Lines 102

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 77
CRAP Score 36.9754

Importance

Changes 0
Metric Value
cc 30
eloc 102
nc 2186
nop 2
dl 0
loc 136
ccs 77
cts 96
cp 0.8021
crap 36.9754
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
namespace Phing\Parser;
21
22
use Phing\Parser\ElementHandler;
23
use Phing\Parser\ExpatParseException;
24
use Phing\ExtensionPoint;
25
use Phing\Exception\BuildException;
26
use Phing\Parser\AbstractHandler;
27
use Phing\Parser\AbstractSAXParser;
28
use Phing\Util\StringHelper;
29
use Phing\Parser\XmlContext;
30
use Phing\Project;
31
use Phing\Parser\ProjectConfigurator;
32
use Phing\Target;
33
34
/**
35
 * The target handler class.
36
 *
37
 * This class handles the occurrence of a <target> tag and it's possible
38
 * nested tags (datatypes and tasks).
39
 *
40
 * @author    Andreas Aderhold <[email protected]>
41
 * @copyright 2001,2002 THYRELL. All rights reserved
42
 * @package   phing.parser
43
 */
44
class TargetHandler extends AbstractHandler
45
{
46
47
    /**
48
     * Reference to the target object that represents the currently parsed
49
     * target.
50
     *
51
     * @var Target the target instance
52
     */
53
    private $target;
54
55
    /**
56
     * The phing project configurator object
57
     *
58
     * @var ProjectConfigurator
59
     */
60
    private $configurator;
61
62
    /**
63
     * @var XmlContext
64
     */
65
    private $context;
66
67
    /**
68
     * Constructs a new TargetHandler
69
     *
70
     * @param AbstractSAXParser $parser
71
     * @param AbstractHandler $parentHandler
72
     * @param ProjectConfigurator $configurator
73
     * @param XmlContext $context
74
     * @internal param the $object ExpatParser object
75
     * @internal param the $object parent handler that invoked this handler
76
     * @internal param the $object ProjectConfigurator object
77
     */
78 837
    public function __construct(
79
        AbstractSAXParser $parser,
80
        AbstractHandler $parentHandler,
81
        ProjectConfigurator $configurator,
82
        XmlContext $context
83
    ) {
84 837
        parent::__construct($parser, $parentHandler);
85 837
        $this->configurator = $configurator;
86 837
        $this->context = $context;
87 837
    }
88
89
    /**
90
     * Executes initialization actions required to setup the data structures
91
     * related to the tag.
92
     * <p>
93
     * This includes:
94
     * <ul>
95
     * <li>creation of the target object</li>
96
     * <li>calling the setters for attributes</li>
97
     * <li>adding the target to the project</li>
98
     * <li>adding a reference to the target (if id attribute is given)</li>
99
     * </ul>
100
     *
101
     * @param    $tag
102
     * @param    $attrs
103
     * @throws   BuildException
104
     * @throws   ExpatParseException
105
     * @internal param the $string tag that comes in
106
     * @internal param attributes $array the tag carries
107
     */
108 837
    public function init($tag, $attrs)
109
    {
110 837
        $name = null;
111 837
        $depends = "";
112 837
        $extensionPoint = null;//'fail';
113 837
        $extensionPointMissing = null;
114 837
        $ifCond = null;
115 837
        $unlessCond = null;
116 837
        $id = null;
117 837
        $description = null;
118 837
        $isHidden = false;
119 837
        $logskipped = false;
120
121 837
        foreach ($attrs as $key => $value) {
122 837
            switch ($key) {
123 837
                case "name":
124 837
                    $name = (string) $value;
125 837
                    break;
126 421
                case "depends":
127 257
                    $depends = (string) $value;
128 257
                    break;
129 198
                case "if":
130 2
                    $ifCond = (string) $value;
131 2
                    break;
132 198
                case "unless":
133 7
                    $unlessCond = (string) $value;
134 7
                    break;
135 191
                case "id":
136
                    $id = (string) $value;
137
                    break;
138 191
                case "hidden":
139
                    $isHidden = ($value === 'true' || $value === '1');
140
                    break;
141 191
                case "description":
142 183
                    $description = (string) $value;
143 183
                    break;
144 8
                case "logskipped":
145
                    $logskipped = $value;
146
                    break;
147 8
                case "extensionof":
148 7
                    $extensionPoint = $value;
149 7
                    break;
150 3
                case "onmissingextensionpoint":
151 3
                    if (!in_array($value, ['fail', 'warn', 'ignore'], true)) {
152
                        throw new BuildException('Invalid onMissingExtensionPoint ' . $value);
153
                    }
154 3
                    $extensionPointMissing = $value;
155 3
                    break;
156
                default:
157
                    throw new ExpatParseException("Unexpected attribute '$key'", $this->parser->getLocation());
0 ignored issues
show
Bug introduced by
The method getLocation() does not exist on Phing\Parser\AbstractSAXParser. Since it exists in all sub-types, consider adding an abstract or default implementation to Phing\Parser\AbstractSAXParser. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

157
                    throw new ExpatParseException("Unexpected attribute '$key'", $this->parser->/** @scrutinizer ignore-call */ getLocation());
Loading history...
158
            }
159
        }
160
161 837
        if ($name === null) {
162
            throw new ExpatParseException(
163
                "target element appears without a name attribute",
164
                $this->parser->getLocation()
165
            );
166
        }
167
168
        // shorthand
169 837
        $project = $this->configurator->project;
170
171
        // check to see if this target is a dup within the same file
172 837
        if (isset($this->context->getCurrentTargets()[$name])) {
173
            throw new BuildException(
174
                "Duplicate target: $name",
175
                $this->parser->getLocation()
176
            );
177
        }
178
179 837
        $this->target = $tag === 'target' ? new Target() : new ExtensionPoint();
180 837
        $this->target->setProject($project);
181 837
        $this->target->setLocation($this->parser->getLocation());
182 837
        $this->target->setHidden($isHidden);
183 837
        $this->target->setIf($ifCond);
184 837
        $this->target->setUnless($unlessCond);
185 837
        $this->target->setDescription($description);
186 837
        $this->target->setLogSkipped(StringHelper::booleanValue($logskipped));
187
        // take care of dependencies
188 837
        if ($depends !== '') {
189 257
            $this->target->setDepends($depends);
190
        }
191
192
        // check to see if target with same name is already defined
193 837
        $projectTargets = $project->getTargets();
194 837
        if (isset($projectTargets[$name])) {
195
            if (
196 92
                $this->configurator->isIgnoringProjectTag()
197 92
                && $this->configurator->getCurrentProjectName() != null
198 92
                && strlen($this->configurator->getCurrentProjectName()) != 0
199
            ) {
200
                // In an impored file (and not completely
201
                // ignoring the project tag)
202 92
                $newName = $this->configurator->getCurrentProjectName() . "." . $name;
203 92
                $project->log(
204
                    "Already defined in main or a previous import, " .
205 92
                    "define {$name} as {$newName}",
206 92
                    Project::MSG_VERBOSE
207
                );
208 92
                $name = $newName;
209
            } else {
210
                $project->log(
211
                    "Already defined in main or a previous import, " .
212
                    "ignore {$name}",
213
                    Project::MSG_VERBOSE
214
                );
215
                $name = null;
216
            }
217
        }
218
219 837
        if ($name !== null) {
220 837
            $this->target->setName($name);
221 837
            $project->addOrReplaceTarget($name, $this->target);
222 837
            if ($id !== null && $id !== "") {
223
                $project->addReference($id, $this->target);
224
            }
225
        }
226
227 837
        if ($extensionPointMissing !== null && $extensionPoint === null) {
228 1
            throw new BuildException(
229
                "onMissingExtensionPoint attribute cannot " .
230 1
                "be specified unless extensionOf is specified",
231 1
                $this->target->getLocation()
232
            );
233
        }
234 837
        if ($extensionPoint !== null) {
235 7
            foreach (Target::parseDepends($extensionPoint, $name, 'extensionof') as $extPointName) {
236 7
                if ($extensionPointMissing === null) {
237 5
                    $extensionPointMissing = 'fail';
238
                }
239 7
                $this->context->addExtensionPoint([
240 7
                    $extPointName,
241 7
                    $this->target->getName(),
242 7
                    $extensionPointMissing,
243
                    null
244
                ]);
245
            }
246
        }
247 837
    }
248
249
    /**
250
     * Checks for nested tags within the current one. Creates and calls
251
     * handlers respectively.
252
     *
253
     * @param string $name the tag that comes in
254
     * @param array $attrs attributes the tag carries
255
     */
256 827
    public function startElement($name, $attrs)
257
    {
258 827
        $tmp = new ElementHandler($this->parser, $this, $this->configurator, null, null, $this->target);
259 827
        $tmp->init($name, $attrs);
260 827
    }
261
262
    /**
263
     * Checks if this target has dependencies and/or nested tasks.
264
     * If the target has neither, show a warning.
265
     */
266 837
    protected function finished()
267
    {
268 837
        if (!$this->target instanceof ExtensionPoint && !count($this->target->getDependencies()) && !count($this->target->getTasks())) {
269 158
            $this->configurator->project->log(
270 158
                "Warning: target '" . $this->target->getName() .
271 158
                "' has no tasks or dependencies",
272 158
                Project::MSG_WARN
273
            );
274
        }
275 837
    }
276
}
277