PageRenderTime 141ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/OData Producer for PHP/Dispatcher.php

#
PHP | 212 lines | 118 code | 13 blank | 81 comment | 8 complexity | 53bbb0c20dd629faf8c1003453269956 MD5 | raw file
  1. <?php
  2. /**
  3. * Defines the dispatcher class
  4. *
  5. * PHP version 5.3
  6. *
  7. * @category ODataProducer
  8. * @package ODataProducer
  9. * @author Anu T Chandy <odataphpproducer_alias@microsoft.com>
  10. * @author Neelesh Vijaivargia <odataphpproducer_alias@microsoft.com>
  11. * @copyright 2011 Microsoft Corp. (http://www.microsoft.com)
  12. * @license New BSD license, (http://www.opensource.org/licenses/bsd-license.php)
  13. * @version SVN: 1.0
  14. * @link http://odataphpproducer.codeplex.com
  15. *
  16. */
  17. use ODataProducer\Common\Messages;
  18. use ODataProducer\Common\HttpStatus;
  19. use ODataProducer\Common\ODataConstants;
  20. use ODataProducer\Common\ODataException;
  21. use ODataProducer\OperationContext\DataServiceHost;
  22. use ODataProducer\Common\ServiceConfig;
  23. use ODataProducer\OperationContext\Web\WebOperationContext;
  24. use ODataProducer\OperationContext\Web\IncomingRequest;
  25. use ODataProducer\OperationContext\Web\OutgoingResponse;
  26. use ODataProducer\HttpOutput;
  27. /**
  28. * Class which responsible to delegate the request processing to handleRequest and
  29. * also responsible to send the response to the client
  30. *
  31. * @category ODataProducer
  32. * @package ODataProducer
  33. * @author Anu T Chandy <odataphpproducer_alias@microsoft.com>
  34. * @author Neelesh Vijaivargia <odataphpproducer_alias@microsoft.com>
  35. * @copyright 2011 Microsoft Corp. (http://www.microsoft.com)
  36. * @license New BSD license, (http://www.opensource.org/licenses/bsd-license.php)
  37. * @version Release: 1.0
  38. * @link http://odataphpproducer.codeplex.com
  39. */
  40. class Dispatcher
  41. {
  42. /**
  43. * Reference to the instance of underlying DataServiceHost
  44. *
  45. * @var DataServiceHost
  46. */
  47. private $_dataServiceHost;
  48. /**
  49. * Array holds details of current requested service.
  50. *
  51. * @var ServiceConfig
  52. */
  53. private $_serviceInfo;
  54. /**
  55. * This function is initializes the properties of Dispatcher class.
  56. *
  57. * @return Object of WebOperationContext class
  58. */
  59. function __construct()
  60. {
  61. try {
  62. $this->_dataServiceHost = new DataServiceHost();
  63. } catch(\Exception $exception) {
  64. self::_handleException(
  65. $exception->getMessage(),
  66. $exception->getStatusCode()
  67. );
  68. }
  69. try {
  70. ServiceConfig::validateAndGetsServiceInfo(
  71. $this->_getServiceNameFromRequestUri(),
  72. $this->_serviceInfo
  73. );
  74. $this->_dataServiceHost->setAbsoluteServiceUri(
  75. $this->_serviceInfo['SERVICE_BASEURL']
  76. );
  77. } catch(ODataException $exception) {
  78. self::_handleException(
  79. $exception->getMessage(),
  80. $exception->getStatusCode()
  81. );
  82. }
  83. }
  84. /**
  85. * Gets reference to the data service host.
  86. *
  87. * @return DataServiceHost
  88. */
  89. public function getHost()
  90. {
  91. return $this->_dataServiceHost;
  92. }
  93. /**
  94. * Gets the service name from the request uri.
  95. *
  96. * @return string
  97. */
  98. private function _getServiceNameFromRequestUri()
  99. {
  100. $url = $this->_dataServiceHost->getAbsoluteRequestUri();
  101. $segments = $url->getSegments();
  102. for ($i = count($segments) - 1; $i >= 0; $i--) {
  103. if (stripos($segments[$i], '.svc') !== false) {
  104. return $segments[$i];
  105. }
  106. }
  107. return null;
  108. }
  109. /**
  110. * This function perform the following steps:
  111. * 1) Resolve and validate the service
  112. * 2) Creates the instance of requested service
  113. * 3) Calls the handleRequest() to process the request
  114. * 4) Calls the handleresponse() to sendback the o/p to the client
  115. *
  116. * @return void
  117. */
  118. public function dispatch()
  119. {
  120. $dataService = null;
  121. include_once $this->_serviceInfo['SERVICE_PATH'];
  122. try {
  123. $reflectionClass = new \ReflectionClass($this->_serviceInfo['SERVICE_CLASS']);
  124. $dataService = $reflectionClass->newInstance();
  125. } catch(\Exception $exception) {
  126. $this->_handleException(
  127. $exception->getMessage(), HttpStatus::CODE_INTERNAL_SERVER_ERROR
  128. );
  129. }
  130. $interfaces = class_implements($dataService);
  131. if (array_key_exists('ODataProducer\IDataService', $interfaces)) {
  132. $dataService->setHost($this->_dataServiceHost);
  133. if (array_key_exists('ODataProducer\IRequestHandler', $interfaces)) {
  134. // DataService::handleRequest will never throw an error
  135. // All exception that can occur while parsing the request and
  136. // serializing the result will be handled by
  137. // DataService::handleRequest
  138. $dataService->handleRequest();
  139. } else {
  140. $this->_handleException(
  141. Messages::dispatcherServiceClassShouldImplementIRequestHandler(),
  142. HttpStatus::CODE_INTERNAL_SERVER_ERROR
  143. );
  144. }
  145. } else {
  146. $this->_handleException(
  147. Messages::dispatcherServiceClassShouldImplementIDataService(),
  148. HttpStatus::CODE_INTERNAL_SERVER_ERROR
  149. );
  150. }
  151. $this->_writeResponse(
  152. $dataService->getHost()->getWebOperationContext()->outgoingResponse()
  153. );
  154. }
  155. /**
  156. * Handles exception occured in dispatcher.
  157. *
  158. * @param string $message The error message.
  159. * @param string $statusCode The status code.
  160. *
  161. * @return void
  162. */
  163. private static function _handleException($message, $statusCode)
  164. {
  165. header(
  166. ODataConstants::HTTPRESPONSE_HEADER_CONTENTTYPE .
  167. ':' .
  168. ODataConstants::MIME_TEXTPLAIN
  169. );
  170. $statusDescription = HttpStatus::getStatusDescription($statusCode);
  171. if (!is_null($statusDescription)) {
  172. $statusDescription = ' ' . $statusDescription;
  173. }
  174. header(
  175. ODataConstants::HTTPRESPONSE_HEADER_STATUS .
  176. ':' .
  177. $statusCode . $statusDescription
  178. );
  179. echo $message;
  180. exit;
  181. }
  182. /**
  183. * Write the response (header and response body).
  184. *
  185. * @param OutgoingResponse &$outGoingResponse Headers and streams to output.
  186. *
  187. * @return void
  188. */
  189. private function _writeResponse(OutgoingResponse &$outGoingResponse)
  190. {
  191. foreach ($outGoingResponse->getHeaders() as $headerName => $headerValue) {
  192. if (!is_null($headerValue)) {
  193. header($headerName . ':' . $headerValue);
  194. }
  195. }
  196. echo $outGoingResponse->getStream();
  197. }
  198. }
  199. ?>