Passed
Push — master ( d68b8d...e5c614 )
by Siad
10:45
created

UnknownElement::configure()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5.0073

Importance

Changes 0
Metric Value
cc 5
eloc 15
c 0
b 0
f 0
nc 7
nop 1
dl 0
loc 23
ccs 14
cts 15
cp 0.9333
crap 5.0073
rs 9.4555
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
 * Wrapper class that holds all information necessary to create a task
22
 * that did not exist when Phing started.
23
 *
24
 * <em> This has something to do with phing encountering an task XML element
25
 * it is not aware of at start time. This is a situation where special steps
26
 * need to be taken so that the element is then known.</em>
27
 *
28
 * @author  Andreas Aderhold <[email protected]>
29
 * @author  Hans Lellelid <[email protected]>
30
 * @package phing
31
 */
32
class UnknownElement extends Task
33
{
34
    private $elementName;
35
    private $realThing;
36
    private $children = [];
37
38
    /**
39
     * Constructs a UnknownElement object
40
     *
41
     * @param string  The XML element name that is unknown
42
     */
43 778
    public function __construct($elementName)
44
    {
45 778
        parent::__construct();
46 778
        $this->elementName = (string) $elementName;
47 778
    }
48
49
    /**
50
     * Return the XML element name that this <code>UnnownElement</code>
51
     * handles.
52
     *
53
     * @return string The XML element name that is unknown
54
     */
55 641
    public function getTag()
56
    {
57 641
        return (string) $this->elementName;
58
    }
59
60
    /**
61
     * Tries to configure the unknown element
62
     *
63
     * @throws BuildException if the element can not be configured
64
     */
65 641
    public function maybeConfigure()
66
    {
67 641
        if ($this->realThing !== null) {
68 1
            return;
69
        }
70 641
        $this->configure($this->makeObject($this, $this->wrapper));
71 639
    }
72
73 641
    public function configure($realObj)
74
    {
75 641
        if ($realObj === null) {
76
            return;
77
        }
78 641
        $this->realThing = $realObj;
79 641
        $this->wrapper->setProxy($this->realThing);
80
81 641
        $task = null;
82 641
        if ($this->realThing instanceof Task) {
83 636
            $task = $this->realThing;
84 636
            $task->setRuntimeConfigurableWrapper($this->wrapper);
85 636
            if ($this->getWrapper()->getId() !== null) {
86 11
                $this->getOwningTarget()->replaceChild($this, $this->realThing);
87
            }
88
        }
89
90 641
        if ($task !== null) {
91 636
            $task->maybeConfigure();
92
        } else {
93 69
            $this->getWrapper()->maybeConfigure($this->getProject());
94
        }
95 640
        $this->handleChildren($this->realThing, $this->wrapper);
96 639
    }
97
98
    /**
99
     * Called when the real task has been configured for the first time.
100
     *
101
     * @throws BuildException if the task can not be created
102
     */
103 639
    public function main()
104
    {
105 639
        if ($this->realThing === null) {
106
            // plain impossible to get here, maybeConfigure should
107
            // have thrown an exception.
108
            throw new BuildException("Should not be executing UnknownElement::main() -- task/type: {$this->elementName}");
109
        }
110
111 639
        if ($this->realThing instanceof Task) {
112 634
            $this->realThing->main();
113
        }
114 606
    }
115
116
    /**
117
     * Add a child element to the unknown element
118
     *
119
     * @param    UnknownElement $child
120
     * @internal param The $object object representing the child element
121
     */
122 491
    public function addChild(UnknownElement $child)
123
    {
124 491
        $this->children[] = $child;
125 491
    }
126
127
    /**
128
     *  Handle child elemets of the unknown element, if any.
129
     *
130
     * @param object $parent The parent object the unknown element belongs to
131
     * @param object $parentWrapper The parent wrapper object
132
     */
133 640
    public function handleChildren($parent, $parentWrapper)
134
    {
135 640
        if ($parent instanceof TypeAdapter) {
136 229
            $parent = $parent->getProxy();
137
        }
138
139 640
        $parentClass = $parent === null ? get_class() : get_class($parent);
140 640
        $ih = IntrospectionHelper::getHelper($parentClass);
141
142 640
        for ($i = 0, $childrenCount = count($this->children); $i < $childrenCount; $i++) {
143 405
            $childWrapper = $parentWrapper->getChild($i);
144 405
            $child = $this->children[$i];
145
146 405
            $realChild = null;
147 405
            if ($parent instanceof TaskContainer) {
148 192
                $parent->addTask($child);
149 192
                continue;
150
            }
151
152 401
            $project = $this->project ?? $parent->getProject();
153 401
            $realChild = $ih->createElement($project, $parent, $child->getTag());
154
155 401
            $childWrapper->setProxy($realChild);
156 401
            if ($realChild instanceof Task) {
157 200
                $realChild->setRuntimeConfigurableWrapper($childWrapper);
158
            }
159
160 401
            $childWrapper->maybeConfigure($this->project);
161 399
            $child->handleChildren($realChild, $childWrapper);
162
        }
163 640
    }
164
165
    /**
166
     * Creates a named task or data type. If the real object is a task,
167
     * it is configured up to the init() stage.
168
     *
169
     * @param  UnknownElement $ue The unknown element to create the real object for.
170
     *                                 Must not be <code>null</code>.
171
     * @param  RuntimeConfigurable $w Ignored in this implementation.
172
     * @throws BuildException
173
     * @return object              The Task or DataType represented by the given unknown element.
174
     */
175 641
    protected function makeObject(UnknownElement $ue, RuntimeConfigurable $w)
176
    {
177 641
        $o = $this->makeTask($ue, $w, true);
178 641
        if ($o === null) {
179 69
            $o = $this->project->createDataType($ue->getTag());
180
        }
181 641
        if ($o === null) {
182
            throw new BuildException(
183
                "Could not create task/type: '" . $ue->getTag() . "'. Make sure that this class has been declared using taskdef / typedef."
184
            );
185
        }
186 641
        if ($o instanceof Task) {
187 636
            $o->setOwningTarget($this->getOwningTarget());
188
        }
189 641
        if ($o instanceof ProjectComponent) {
190 641
            $o->setLocation($this->getLocation());
191
        }
192
193 641
        return $o;
194
    }
195
196
    /**
197
     *  Create a named task and configure it up to the init() stage.
198
     *
199
     * @param  UnknownElement $ue The unknwon element to create a task from
200
     * @param  RuntimeConfigurable $w The wrapper object
201
     * @param  boolean $onTopLevel Whether to treat this task as if it is top-level.
202
     * @throws BuildException
203
     * @return Task                The freshly created task
204
     */
205 641
    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

205
    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...
206
    {
207 641
        $task = $this->project->createTask($ue->getTag());
208
209 641
        if ($task === null) {
210 69
            if (!$onTopLevel) {
211
                throw new BuildException("Could not create task of type: '" . $this->elementName . "'. Make sure that this class has been declared using taskdef.");
212
            }
213
214 69
            return null;
215
        }
216 636
        $task->setLocation($this->getLocation());
217 636
        if ($this->target !== null) {
218 636
            $task->setOwningTarget($this->target);
219
        }
220 636
        $task->init();
221 636
        return $task;
222
    }
223
224
    /**
225
     *  Get the name of the task to use in logging messages.
226
     *
227
     * @return string The task's name
228
     */
229 7
    public function getTaskName()
230
    {
231 7
        return $this->realThing === null || !$this->realThing instanceof Task
232 6
            ? parent::getTaskName()
233 7
            : $this->realThing->getTaskName();
234
    }
235
236
    /**
237
     * Returns the task instance after it has been created and if it is a task.
238
     *
239
     * @return Task a task instance or <code>null</code> if the real object is not
240
     *              a task.
241
     */
242
    public function getTask()
243
    {
244
        if ($this->realThing instanceof Task) {
245
            return $this->realThing;
246
        }
247
        return null;
248
    }
249
250
    /**
251
     * Return the configured object
252
     *
253
     * @return object the real thing whatever it is
254
     */
255 639
    public function getRealThing()
256
    {
257 639
        return $this->realThing;
258
    }
259
260
    /**
261
     * Set the configured object
262
     *
263
     * @param object $realThing the configured object
264
     */
265 606
    public function setRealThing($realThing)
266
    {
267 606
        $this->realThing = $realThing;
268 606
    }
269
}
270