]> git.sur5r.net Git - bacula/bacula/blob - gui/baculum/framework/3rdParty/WsdlGen/WsdlGenerator.php
Add Baculum
[bacula/bacula] / gui / baculum / framework / 3rdParty / WsdlGen / WsdlGenerator.php
1 <?php
2 /**
3  * WsdlGenerator file.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the BSD License.
7  *
8  * Copyright(c) 2005 by Marcus Nyeholt. All rights reserved.
9  *
10  * To contact the author write to {@link mailto:tanus@users.sourceforge.net Marcus Nyeholt}
11  * This file is part of the PRADO framework from {@link http://www.xisc.com}
12  *
13  * @author Marcus Nyeholt               <tanus@users.sourceforge.net>
14  * @version $Id: WsdlGenerator.php 3314 2013-08-20 10:00:47Z ctrlaltca $
15  * @package System.Web.Services.SOAP
16  */
17
18 require_once(dirname(__FILE__).'/Wsdl.php');
19 require_once(dirname(__FILE__).'/WsdlMessage.php');
20 require_once(dirname(__FILE__).'/WsdlOperation.php');
21
22 /**
23  * Generator for the wsdl.
24  * Special thanks to Cristian Losada for implementing the Complex Types section of the WSDL.
25  * @author              Marcus Nyeholt          <tanus@users.sourceforge.net>
26  * @author              Cristian Losada         <cristian@teaxul.com>
27  * @version     $Revision$
28  */
29 class WsdlGenerator
30 {
31         /**
32          * The instance.
33          * var          WsdlGenerator
34          */
35         private static $instance;
36
37         /**
38          * The name of this service (the classname)
39          * @var         string
40          */
41         private $serviceName = '';
42
43         /**
44          * The complex types to use in the wsdl
45          * @var         Array
46          */
47         private $types = array();
48
49         /**
50          * The operations available in this wsdl
51          * @var         ArrayObject
52          */
53         private $operations;
54
55         /**
56          * The wsdl object.
57          * @var         object
58          */
59         private $wsdlDocument;
60
61         /**
62          * The actual wsdl string
63          * @var         string
64          */
65         private $wsdl = '';
66
67         /**
68          * The singleton instance for the generator
69          */
70         public static function getInstance()
71         {
72                 if (is_null(self::$instance)) {
73                         self::$instance = new WsdlGenerator();
74                 }
75                 return self::$instance;
76         }
77
78         /**
79          * Get the Wsdl generated
80          * @return      string          The Wsdl for this wsdl
81          */
82         public function getWsdl()
83         {
84                 return $this->wsdl;
85         }
86
87         /**
88          * Generates WSDL for a passed in class, and saves it in the current object. The
89          * WSDL can then be retrieved by calling
90          * @param       string          $className              The name of the class to generate for
91          * @param       string          $serviceUri             The URI of the service that handles this WSDL
92          * @param string $encoding character encoding.
93          * @return      void
94          */
95         public function generateWsdl($className, $serviceUri='',$encoding='')
96         {
97                 $this->wsdlDocument = new Wsdl($className, $serviceUri, $encoding);
98
99                 $classReflect = new ReflectionClass($className);
100                 $methods = $classReflect->getMethods();
101
102                 foreach ($methods as $method) {
103                         // Only process public methods
104                         if ($method->isPublic()) {
105                                 $this->processMethod($method);
106                         }
107                 }
108
109                 foreach($this->types as $type => $elements) {
110                         $this->wsdlDocument->addComplexType($type, $elements);
111                 }
112
113                 $this->wsdl = $this->wsdlDocument->getWsdl();
114         }
115
116         /**
117          * Static method that generates and outputs the generated wsdl
118          * @param               string          $className              The name of the class to export
119          * @param               string          $serviceUri             The URI of the service that handles this WSDL
120          * @param string $encoding character encoding.
121          */
122         public static function generate($className, $serviceUri='', $encoding='')
123         {
124                 $generator = WsdlGenerator::getInstance();
125                 $generator->generateWsdl($className, $serviceUri,$encoding);
126                 //header('Content-type: text/xml');
127                 return $generator->getWsdl();
128                 //exit();
129
130         }
131
132         /**
133          * Process a method found in the passed in class.
134          * @param               ReflectionMethod                $method         The method to process
135          */
136         protected function processMethod(ReflectionMethod $method)
137         {
138                 $comment = $method->getDocComment();
139                 if (strpos($comment, '@soapmethod') === false) {
140                         return;
141                 }
142                 $comment = preg_replace("/(^[\\s]*\\/\\*\\*)
143                                  |(^[\\s]\\*\\/)
144                                  |(^[\\s]*\\*?\\s)
145                                  |(^[\\s]*)
146                                  |(^[\\t]*)/ixm", "", $comment);
147
148             $comment = str_replace("\r", "", $comment);
149             $comment = preg_replace("/([\\t])+/", "\t", $comment);
150             $commentLines = explode("\n", $comment);
151
152                 $methodDoc = '';
153                 $params = array();
154                 $return = array();
155                 $gotDesc = false;
156                 $gotParams = false;
157
158                 foreach ($commentLines as $line) {
159                         if ($line == '') continue;
160                         if ($line{0} == '@') {
161                                 $gotDesc = true;
162                                 if (preg_match('/^@param\s+([\w\[\]()]+)\s+\$([\w()]+)\s*(.*)/i', $line, $match)) {
163                                         $param = array();
164                                         $param['type'] = $this->convertType($match[1]);
165                                         $param['name'] = $match[2];
166                                         $param['desc'] = $match[3];
167                                         $params[] = $param;
168                                 }
169                                 else if (preg_match('/^@return\s+([\w\[\]()]+)\s*(.*)/i', $line, $match)) {
170                                         $gotParams = true;
171                                         $return['type'] = $this->convertType($match[1]);
172                                         $return['desc'] = $match[2];
173                                         $return['name'] = 'return';
174                                 }
175                         }
176                         else {
177                                 if (!$gotDesc) {
178                                         $methodDoc .= trim($line);
179                                 }
180                                 else if (!$gotParams) {
181                                         $params[count($params)-1]['desc'] .= trim($line);
182                                 }
183                                 else {
184                                         if ($line == '*/') continue;
185                                         $return['desc'] .= trim($line);
186                                 }
187                         }
188                 }
189
190                 $methodName = $method->getName();
191                 $operation = new WsdlOperation($methodName, $methodDoc);
192
193                 $operation->setInputMessage(new WsdlMessage($methodName.'Request', $params));
194                 $operation->setOutputMessage(new WsdlMessage($methodName.'Response', array($return)));
195
196                 $this->wsdlDocument->addOperation($operation);
197
198         }
199
200         /**
201          * Converts from a PHP type into a WSDL type. This is borrowed from
202          * Cerebral Cortex (let me know and I'll remove asap).
203          *
204          * TODO: date and dateTime
205          * @param               string          $type           The php type to convert
206          * @return              string                                  The XSD type.
207          */
208         private function convertType($type)
209         {
210                  switch ($type) {
211              case 'string':
212              case 'str':
213                  return 'xsd:string';
214                  break;
215              case 'int':
216              case 'integer':
217                  return 'xsd:int';
218                  break;
219              case 'float':
220              case 'double':
221                  return 'xsd:float';
222                  break;
223              case 'boolean':
224              case 'bool':
225                  return 'xsd:boolean';
226                  break;
227              case 'date':
228                  return 'xsd:date';
229                  break;
230              case 'time':
231                  return 'xsd:time';
232                  break;
233              case 'dateTime':
234                  return 'xsd:dateTime';
235                  break;
236              case 'array':
237                  return 'soap-enc:Array';
238                  break;
239              case 'object':
240                  return 'xsd:struct';
241                  break;
242              case 'mixed':
243                  return 'xsd:anyType';
244                  break;
245              case 'void':
246                  return '';
247              default:
248                  if(strpos($type, '[]'))  // if it is an array
249                  {
250                         $className = substr($type, 0, strlen($type) - 2);
251                         $type = $className . 'Array';
252                         $this->types[$type] = '';
253                         $this->convertType($className);
254                  }
255                  else
256                  {
257                          if(!isset($this->types[$type]))
258                                 $this->extractClassProperties($type);
259                  }
260                  return 'tns:' . $type;
261          }
262         }
263
264         /**
265          * Extract the type and the name of all properties of the $className class and saves it in the $types array
266          * This method extract properties from PHPDoc formatted comments for variables. Unfortunately the reflectionproperty
267          * class doesn't have a getDocComment method to extract comments about it, so we have to extract the information
268          * about the variables manually. Thanks heaps to Cristian Losada for implementing this.
269          * @param string $className The name of the class
270          */
271         private function extractClassProperties($className)
272         {
273                 /**
274                  * modified by Qiang Xue, Jan. 2, 2007
275                  * Using Reflection's DocComment to obtain property definitions
276                  * DocComment is available since PHP 5.1
277                  */
278                 $reflection = new ReflectionClass($className);
279                 $properties = $reflection->getProperties();
280                 foreach($properties as $property)
281                 {
282                         $comment = $property->getDocComment();
283                         if(strpos($comment, '@soapproperty') !== false)
284                         {
285                                 if(preg_match('/@var\s+([\w\.]+(\[\s*\])?)\s*?\$(.*)$/mi',$comment,$matches))
286                                 {
287                                         // support nillable, minOccurs, maxOccurs attributes
288                                         $nillable=$minOccurs=$maxOccurs=false;
289                                         if(preg_match('/{(.+)}/',$matches[3],$attr))
290                                         {
291                                                 $matches[3]=str_replace($attr[0],'',$matches[3]);
292                                                 if(preg_match_all('/((\w+)\s*=\s*(\w+))/mi',$attr[1],$attr))
293                                                 {
294                                                         foreach($attr[2] as $id=>$prop)
295                                                         {
296                                                                 if(strcasecmp($prop,'nillable')===0)
297                                                                         $nillable=$attr[3][$id] ? 'true' : 'false';
298                                                                 elseif(strcasecmp($prop,'minOccurs')===0)
299                                                                         $minOccurs=(int)$attr[3][$id];
300                                                                 elseif(strcasecmp($prop,'maxOccurs')===0)
301                                                                         $maxOccurs=(int)$attr[3][$id];
302                                                         }
303                                                 }
304                                         }
305
306                                         $param = array();
307                                         $param['type'] = $this->convertType($matches[1]);
308                                         $param['name'] = trim($matches[3]);
309                                         $param['nil'] = $nillable;
310                                         $param['minOc'] = $minOccurs;
311                                         $param['maxOc'] = $maxOccurs;
312                                         $this->types[$className][] = $param;
313
314                                 }
315                         }
316                 }
317         }
318 }