UnknownElement::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the LGPL. For more information please see
18
 * <http://phing.info>.
19
 */
20
21
namespace Phing;
22
23
use Phing\Exception\BuildException;
24
25
/**
26
 * Wrapper class that holds all information necessary to create a task
27
 * that did not exist when Phing started.
28
 *
29
 * <em> This has something to do with phing encountering an task XML element
30
 * it is not aware of at start time. This is a situation where special steps
31
 * need to be taken so that the element is then known.</em>
32
 *
33
 * @author  Andreas Aderhold <[email protected]>
34
 * @author  Hans Lellelid <[email protected]>
35
 */
36
class UnknownElement extends Task
37
{
38
    private $elementName;
39
    private $realThing;
40
    private $children = [];
41
42
    /**
43
     * Constructs a UnknownElement object.
44
     *
45
     * @param string $elementName The XML element name that is unknown
46
     */
47 902
    public function __construct($elementName)
48
    {
49 902
        parent::__construct();
50 902
        $this->elementName = (string) $elementName;
51
    }
52
53
    /**
54
     * Return the XML element name that this <code>UnnownElement</code>
55
     * handles.
56
     *
57
     * @return string The XML element name that is unknown
58
     */
59 768
    public function getTag()
60
    {
61 768
        return (string) $this->elementName;
62
    }
63
64
    /**
65
     * Tries to configure the unknown element.
66
     *
67
     * @throws BuildException if the element can not be configured
68
     */
69 768
    public function maybeConfigure()
70
    {
71 768
        if (null !== $this->realThing) {
72 1
            return;
73
        }
74 768
        $this->configure($this->makeObject($this, $this->wrapper));
75
    }
76
77 768
    public function configure($realObj)
78
    {
79 768
        if (null === $realObj) {
80
            return;
81
        }
82 768
        $this->realThing = $realObj;
83 768
        $this->wrapper->setProxy($this->realThing);
84
85 768
        $task = null;
86 768
        if ($this->realThing instanceof Task) {
87 763
            $task = $this->realThing;
88 763
            $task->setRuntimeConfigurableWrapper($this->wrapper);
89 763
            if (null !== $this->getWrapper()->getId()) {
90 11
                $this->getOwningTarget()->replaceChild($this, $this->realThing);
91
            }
92
        }
93
94 768
        if (null !== $task) {
95 763
            $task->maybeConfigure();
96
        } else {
97 86
            $this->getWrapper()->maybeConfigure($this->getProject());
98
        }
99 768
        $this->handleChildren($this->realThing, $this->wrapper);
100
    }
101
102
    /**
103
     * Called when the real task has been configured for the first time.
104
     *
105
     * @throws BuildException if the task can not be created
106
     */
107 766
    public function main()
108
    {
109 766
        if (null === $this->realThing) {
110
            // plain impossible to get here, maybeConfigure should
111
            // have thrown an exception.
112
            throw new BuildException("Should not be executing UnknownElement::main() -- task/type: {$this->elementName}");
113
        }
114
115 766
        if ($this->realThing instanceof Task) {
116 761
            $this->realThing->main();
117
        }
118
    }
119
120
    /**
121
     * Add a child element to the unknown element.
122
     *
123
     * @internal param The $object object representing the child element
124
     */
125 569
    public function addChild(UnknownElement $child)
126
    {
127 569
        $this->children[] = $child;
128
    }
129
130
    /**
131
     *  Handle child elemets of the unknown element, if any.
132
     *
133
     * @param object $parent        The parent object the unknown element belongs to
134
     * @param object $parentWrapper The parent wrapper object
135
     */
136 768
    public function handleChildren($parent, $parentWrapper)
137
    {
138 768
        if ($parent instanceof TypeAdapter) {
139 235
            $parent = $parent->getProxy();
140
        }
141
142 768
        $parentClass = null === $parent ? get_class() : get_class($parent);
143 768
        $ih = IntrospectionHelper::getHelper($parentClass);
144
145 768
        for ($i = 0, $childrenCount = count($this->children); $i < $childrenCount; ++$i) {
146 475
            $childWrapper = $parentWrapper->getChild($i);
147 475
            $child = $this->children[$i];
148
149 475
            $realChild = null;
150 475
            if ($parent instanceof TaskContainer) {
151 204
                $parent->addTask($child);
152
153 204
                continue;
154
            }
155
156 471
            $project = $this->project ?? $parent->getProject();
157 471
            $realChild = $ih->createElement($project, $parent, $child->getTag());
158
159 471
            $childWrapper->setProxy($realChild);
160 471
            if ($realChild instanceof Task) {
161 212
                $realChild->setRuntimeConfigurableWrapper($childWrapper);
162
            }
163
164 471
            $childWrapper->maybeConfigure($this->project);
165 469
            $child->handleChildren($realChild, $childWrapper);
166
        }
167
    }
168
169
    /**
170
     *  Get the name of the task to use in logging messages.
171
     *
172
     * @return string The task's name
173
     */
174 12
    public function getTaskName()
175
    {
176 12
        return null === $this->realThing || !$this->realThing instanceof Task
177 11
            ? parent::getTaskName()
178 12
            : $this->realThing->getTaskName();
179
    }
180
181
    /**
182
     * Returns the task instance after it has been created and if it is a task.
183
     *
184
     * @return Task a task instance or <code>null</code> if the real object is not
185
     *              a task
186
     */
187
    public function getTask()
188
    {
189
        if ($this->realThing instanceof Task) {
190
            return $this->realThing;
191
        }
192
193
        return null;
194
    }
195
196
    /**
197
     * Return the configured object.
198
     *
199
     * @return object the real thing whatever it is
200
     */
201 767
    public function getRealThing()
202
    {
203 767
        return $this->realThing;
204
    }
205
206
    /**
207
     * Set the configured object.
208
     *
209
     * @param object $realThing the configured object
210
     */
211 731
    public function setRealThing($realThing)
212
    {
213 731
        $this->realThing = $realThing;
214
    }
215
216
    /**
217
     * Creates a named task or data type. If the real object is a task,
218
     * it is configured up to the init() stage.
219
     *
220
     * @param UnknownElement      $ue The unknown element to create the real object for.
221
     *                                Must not be <code>null</code>.
222
     * @param RuntimeConfigurable $w  ignored in this implementation
223
     *
224
     * @throws BuildException
225
     *
226
     * @return object the Task or DataType represented by the given unknown element
227
     */
228 768
    protected function makeObject(UnknownElement $ue, RuntimeConfigurable $w)
229
    {
230 768
        $o = $this->makeTask($ue, $w, true);
231 768
        if (null === $o) {
232 86
            $o = $this->project->createDataType($ue->getTag());
233
        }
234 768
        if (null === $o) {
0 ignored issues
show
introduced by
The condition null === $o is always false.
Loading history...
235
            throw new BuildException(
236
                "Could not create task/type: '" . $ue->getTag() . "'. Make sure that this class has been declared using taskdef / typedef."
237
            );
238
        }
239 768
        if ($o instanceof Task) {
240 763
            $o->setOwningTarget($this->getOwningTarget());
241
        }
242 768
        if ($o instanceof ProjectComponent) {
243 768
            $o->setLocation($this->getLocation());
244
        }
245
246 768
        return $o;
247
    }
248
249
    /**
250
     *  Create a named task and configure it up to the init() stage.
251
     *
252
     * @param UnknownElement      $ue         The unknwon element to create a task from
253
     * @param RuntimeConfigurable $w          The wrapper object
254
     * @param bool                $onTopLevel whether to treat this task as if it is top-level
255
     *
256
     * @throws BuildException
257
     *
258
     * @return Task The freshly created task
259
     */
260 768
    protected function makeTask(UnknownElement $ue, RuntimeConfigurable $w, $onTopLevel = false)
0 ignored issues
show
Unused Code introduced by
The parameter $w is not used and could be removed. ( Ignorable by Annotation )

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

260
    protected function makeTask(UnknownElement $ue, /** @scrutinizer ignore-unused */ RuntimeConfigurable $w, $onTopLevel = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
261
    {
262 768
        $task = $this->project->createTask($ue->getTag());
263
264 768
        if (null === $task) {
265 86
            if (!$onTopLevel) {
266
                throw new BuildException("Could not create task of type: '" . $this->elementName . "'. Make sure that this class has been declared using taskdef.");
267
            }
268
269 86
            return null;
270
        }
271 763
        $task->setLocation($this->getLocation());
272 763
        if (null !== $this->target) {
273 763
            $task->setOwningTarget($this->target);
274
        }
275 763
        $task->init();
276
277 763
        return $task;
278
    }
279
}
280