Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/*
3
 *  $Id: UnknownElement.php 205 2007-07-29 21:04:42Z hans $
4
 *
5
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
 *
17
 * This software consists of voluntary contributions made by many individuals
18
 * and is licensed under the LGPL. For more information please see
19
 * <http://phing.info>.
20
 */
21
 
22
require_once 'phing/Task.php';
23
 
24
/**
25
 * Wrapper class that holds all information necessary to create a task
26
 * that did not exist when Phing started.
27
 *
28
 * <em> This has something to do with phing encountering an task XML element
29
 * it is not aware of at start time. This is a situation where special steps
30
 * need to be taken so that the element is then known.</em>
31
 *
32
 * @author    Andreas Aderhold <andi@binarycloud.com>
33
 * @author    Hans Lellelid <hans@xmpl.org>
34
 * @version   $Revision: 1.9 $
35
 * @package   phing
36
 */
37
class UnknownElement extends Task {
38
 
39
    private $elementName;
40
    private $realThing;
41
    private $children = array();
42
 
43
    /**
44
     * Constructs a UnknownElement object
45
     *
46
     * @param    string  The XML element name that is unknown
47
     * @access   public
48
     */
49
    function __construct($elementName) {
50
        $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
    public function getTag() {
60
        return (string) $this->elementName;
61
    }
62
 
63
    /**
64
     * Tries to configure the unknown element
65
     *
66
     * @throws  BuildException if the element can not be configured
67
     */
68
    public function maybeConfigure() {
69
 
70
        $this->realThing = $this->makeObject($this, $this->wrapper);
71
        $this->wrapper->setProxy($this->realThing);
72
        if ($this->realThing instanceof Task) {
73
            $this->realThing->setRuntimeConfigurableWrapper($this->wrapper);
74
        }
75
 
76
        $this->handleChildren($this->realThing, $this->wrapper);
77
        $this->wrapper->maybeConfigure($this->getProject());
78
 
79
    }
80
 
81
    /**
82
     * Called when the real task has been configured for the first time.
83
     *
84
     * @throws  BuildException if the task can not be created
85
     */
86
    public function main() {
87
 
88
        if ($this->realThing === null) {
89
            // plain impossible to get here, maybeConfigure should
90
            // have thrown an exception.
91
            throw new BuildException("Should not be executing UnknownElement::main() -- task/type: {$this->elementName}");
92
        }
93
 
94
        if ($this->realThing instanceof Task) {
95
            $this->realThing->main();
96
        }
97
 
98
    }
99
 
100
    /**
101
     * Add a child element to the unknown element
102
     *
103
     * @param   object  The object representing the child element
104
     */
105
    public function addChild(UnknownElement $child) {
106
        $this->children[] = $child;
107
    }
108
 
109
    /**
110
     *  Handle child elemets of the unknown element, if any.
111
     *
112
     *  @param ProjectComponent The parent object the unkown element belongs to
113
     *  @param object The parent wrapper object
114
     */
115
    function handleChildren(ProjectComponent $parent, $parentWrapper) {
116
 
117
        if ($parent instanceof TaskAdapter) {
118
            $parent = $parent->getProxy();
119
        }
120
 
121
        $parentClass = get_class($parent);
122
        $ih = IntrospectionHelper::getHelper($parentClass);
123
 
124
        for ($i=0, $childrenCount=count($this->children); $i < $childrenCount; $i++) {
125
 
126
            $childWrapper = $parentWrapper->getChild($i);
127
            $child = $this->children[$i];
128
            $realChild = null;
129
            if ($parent instanceof TaskContainer) {
130
                $realChild = $this->makeTask($child, $childWrapper, false);
131
                $parent->addTask($realChild);
132
            } else {
133
				$project = $this->project === null ? $parent->project : $this->project;
134
				$realChild = $ih->createElement($project, $parent, $child->getTag());
135
            }
136
 
137
            $childWrapper->setProxy($realChild);
138
            if ($realChild instanceof Task) {
139
                $realChild->setRuntimeConfigurableWrapper($childWrapper);
140
            }
141
 
142
            if ($realChild instanceof ProjectComponent) {
143
            	$child->handleChildren($realChild, $childWrapper);
144
            }
145
 
146
            if ($realChild instanceof Task) {
147
                $realChild->maybeConfigure();
148
            }
149
        }
150
    }
151
 
152
    /**
153
     * Creates a named task or data type. If the real object is a task,
154
     * it is configured up to the init() stage.
155
     *
156
     * @param UnknownElement $ue The unknown element to create the real object for.
157
     *           Must not be <code>null</code>.
158
     * @param RuntimeConfigurable $w  Ignored in this implementation.
159
     * @return object The Task or DataType represented by the given unknown element.
160
     */
161
    protected function makeObject(UnknownElement $ue, RuntimeConfigurable $w) {
162
        $o = $this->makeTask($ue, $w, true);
163
        if ($o === null) {
164
            $o = $this->project->createDataType($ue->getTag());
165
        }
166
        if ($o === null) {
167
            throw new BuildException("Could not create task/type: '".$ue->getTag()."'. Make sure that this class has been declared using taskdef / typedef.");
168
        }
169
        return $o;
170
    }
171
 
172
    /**
173
     *  Create a named task and configure it up to the init() stage.
174
     *
175
     * @param UnknownElement $ue The unknwon element to create a task from
176
     * @param RuntimeConfigurable $w The wrapper object
177
     * @param boolean $onTopLevel Whether to treat this task as if it is top-level.
178
     * @return Task The freshly created task
179
     */
180
    protected function makeTask(UnknownElement $ue, RuntimeConfigurable $w, $onTopLevel = false) {
181
 
182
        $task = $this->project->createTask($ue->getTag());
183
 
184
        if ($task === null) {
185
            if (!$onTopLevel) {
186
                throw new BuildException("Could not create task of type: '".$this->elementName."'. Make sure that this class has been declared using taskdef.");
187
            }
188
            return null;
189
        }
190
 
191
        // used to set the location within the xmlfile so that exceptions can
192
        // give detailed messages
193
 
194
        $task->setLocation($this->getLocation());
195
        $attrs = $w->getAttributes();
196
        if (isset($attrs['id'])) {
197
            $this->project->addReference($attrs['id'], $task);
198
        }
199
 
200
        // UnknownElement always has an associated target
201
        $task->setOwningTarget($this->target);
202
 
203
        $task->init();
204
        return $task;
205
    }
206
 
207
    /**
208
     *  Get the name of the task to use in logging messages.
209
     *
210
     *  @return  string  The task's name
211
     */
212
    function getTaskName() {
213
        return $this->realThing === null ? parent::getTaskName() : $this->realThing->getTaskName();
214
    }
215
}