| 1 | <?php |
|---|
| 2 | |
|---|
| 3 | /* |
|---|
| 4 | * $Id$ |
|---|
| 5 | * |
|---|
| 6 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|---|
| 7 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|---|
| 8 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|---|
| 9 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|---|
| 10 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|---|
| 11 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|---|
| 12 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|---|
| 13 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|---|
| 14 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|---|
| 15 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|---|
| 16 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|---|
| 17 | * |
|---|
| 18 | * This software consists of voluntary contributions made by many individuals |
|---|
| 19 | * and is licensed under the LGPL. For more information please see |
|---|
| 20 | * <http://phing.info>. |
|---|
| 21 | */ |
|---|
| 22 | |
|---|
| 23 | /** TODO: Create a better base class for PropertyTask and XmlPropertyTask that |
|---|
| 24 | * only contains common functionality (instead of inheriting from PropertyTask). |
|---|
| 25 | */ |
|---|
| 26 | |
|---|
| 27 | require_once 'phing/tasks/system/PropertyTask.php'; |
|---|
| 28 | require_once('phing/util/properties/PropertySetImpl.php'); |
|---|
| 29 | |
|---|
| 30 | /** |
|---|
| 31 | * Task for setting properties from an XML file in buildfiles. |
|---|
| 32 | * |
|---|
| 33 | * @author Jonathan Bond-Caron <jbondc@openmv.com> |
|---|
| 34 | * @author Matthias Pigulla <mp@webfactory.de> |
|---|
| 35 | * @version $Revision$ |
|---|
| 36 | * @package phing.tasks.ext |
|---|
| 37 | * @since 2.4.0 |
|---|
| 38 | * @see http://ant.apache.org/manual/CoreTasks/xmlproperty.html |
|---|
| 39 | */ |
|---|
| 40 | class XmlPropertyTask extends PropertyTask { |
|---|
| 41 | |
|---|
| 42 | private $_keepRoot = true; |
|---|
| 43 | private $_collapseAttr = false; |
|---|
| 44 | private $_delimiter = ','; |
|---|
| 45 | |
|---|
| 46 | /** |
|---|
| 47 | * Keep the xml root tag as the first value in the property name |
|---|
| 48 | * |
|---|
| 49 | * @param bool $yesNo |
|---|
| 50 | */ |
|---|
| 51 | public function setKeepRoot($yesNo) { |
|---|
| 52 | $this->_keepRoot = (bool)$yesNo; |
|---|
| 53 | } |
|---|
| 54 | |
|---|
| 55 | /** |
|---|
| 56 | * @return bool |
|---|
| 57 | */ |
|---|
| 58 | public function getKeepRoot() { |
|---|
| 59 | return $this->_keepRoot; |
|---|
| 60 | } |
|---|
| 61 | |
|---|
| 62 | /** |
|---|
| 63 | * Treat attributes as nested elements. |
|---|
| 64 | * |
|---|
| 65 | * @param bool $yesNo |
|---|
| 66 | */ |
|---|
| 67 | public function setCollapseAttributes($yesNo) { |
|---|
| 68 | $this->_collapseAttr = (bool)$yesNo; |
|---|
| 69 | } |
|---|
| 70 | |
|---|
| 71 | /** |
|---|
| 72 | * @return bool |
|---|
| 73 | */ |
|---|
| 74 | public function getCollapseAttributes() { |
|---|
| 75 | return $this->_collapseAttr; |
|---|
| 76 | } |
|---|
| 77 | |
|---|
| 78 | /** |
|---|
| 79 | * Delimiter for splitting multiple values. |
|---|
| 80 | * |
|---|
| 81 | * @param string $d |
|---|
| 82 | */ |
|---|
| 83 | public function setDelimiter($d) { |
|---|
| 84 | $this->_delimiter = $d; |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | /** |
|---|
| 88 | * @return string |
|---|
| 89 | */ |
|---|
| 90 | public function getDelimiter() { |
|---|
| 91 | return $this->_delimiter; |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | /** |
|---|
| 95 | * set the property in the project to the value. |
|---|
| 96 | * if the task was give a file or env attribute |
|---|
| 97 | * here is where it is loaded |
|---|
| 98 | */ |
|---|
| 99 | public function main() { |
|---|
| 100 | |
|---|
| 101 | if ($this->file === null ) { |
|---|
| 102 | throw new BuildException("You must specify file to load properties from", $this->getLocation()); |
|---|
| 103 | } |
|---|
| 104 | |
|---|
| 105 | $this->loadFile($this->file); |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | protected function fetchPropertiesFromFile(PhingFile $f) { |
|---|
| 109 | |
|---|
| 110 | if (($xml = simplexml_load_file($f)) === false) |
|---|
| 111 | throw new IOException("Unable to parse XML file $f"); |
|---|
| 112 | |
|---|
| 113 | $prop = new PropertySetImpl(); |
|---|
| 114 | $path = array(); |
|---|
| 115 | |
|---|
| 116 | if ($this->_keepRoot) { |
|---|
| 117 | $this->addNode($xml, $this->prefix, $prop); |
|---|
| 118 | } else { |
|---|
| 119 | foreach ($xml as $tag => $node) |
|---|
| 120 | $this->addNode($node, "{$this->prefix}$tag.", $prop); |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | return $prop; |
|---|
| 124 | } |
|---|
| 125 | |
|---|
| 126 | /** |
|---|
| 127 | * Adds an XML node |
|---|
| 128 | * |
|---|
| 129 | * @param SimpleXMLElement $node |
|---|
| 130 | * @param array $path Path to this node |
|---|
| 131 | * @param Properties $prop Properties will be added as they are found (by reference here) |
|---|
| 132 | * |
|---|
| 133 | * @return void |
|---|
| 134 | */ |
|---|
| 135 | protected function addNode($node, $prefix, PropertySet $prop) { |
|---|
| 136 | |
|---|
| 137 | $pre = $prefix . $node->getName(); |
|---|
| 138 | $index = null; |
|---|
| 139 | |
|---|
| 140 | // Check for attributes |
|---|
| 141 | foreach($node->attributes() as $attribute => $val) { |
|---|
| 142 | |
|---|
| 143 | if ($attribute == '_index') { $index = (string) $val; continue; } |
|---|
| 144 | |
|---|
| 145 | if ($this->_collapseAttr) |
|---|
| 146 | $prop["$pre.$attribute"] = (string) $val; |
|---|
| 147 | else |
|---|
| 148 | $prop["$pre($attribute)"] = (string) $val; |
|---|
| 149 | |
|---|
| 150 | } |
|---|
| 151 | |
|---|
| 152 | if (count($node->children())) { |
|---|
| 153 | foreach ($node as $tag => $child) |
|---|
| 154 | $this->addNode($child, "$pre.", $prop); |
|---|
| 155 | } else { |
|---|
| 156 | $val = (string) $node; |
|---|
| 157 | |
|---|
| 158 | if (isset($prop[$pre])) { |
|---|
| 159 | if (!is_array($prop[$pre])) |
|---|
| 160 | $a = array($prop[$pre]); |
|---|
| 161 | else |
|---|
| 162 | $a = $prop[$pre]; |
|---|
| 163 | |
|---|
| 164 | if ($index) |
|---|
| 165 | $a[$index] = $val; |
|---|
| 166 | else |
|---|
| 167 | $a[] = $val; |
|---|
| 168 | |
|---|
| 169 | $prop[$pre] = $a; |
|---|
| 170 | } else if ($index) { |
|---|
| 171 | $prop[$pre] = array($index => $val); |
|---|
| 172 | } else |
|---|
| 173 | $prop[$pre] = $val; |
|---|
| 174 | } |
|---|
| 175 | } |
|---|
| 176 | } |
|---|