PageRenderTime 35ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/php/PHP/Depend/Metrics/AnalyzerClassFileSystemLocator.php

https://github.com/Proudio-Interactive/pdepend
PHP | 196 lines | 70 code | 16 blank | 110 comment | 9 complexity | caa1cb822f05fef855ba5a34de6746e8 MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of PHP_Depend.
  4. *
  5. * PHP Version 5
  6. *
  7. * Copyright (c) 2008-2011, Manuel Pichler <mapi@pdepend.org>.
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. *
  14. * * Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. *
  17. * * Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in
  19. * the documentation and/or other materials provided with the
  20. * distribution.
  21. *
  22. * * Neither the name of Manuel Pichler nor the names of his
  23. * contributors may be used to endorse or promote products derived
  24. * from this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  29. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  30. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  31. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  32. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  33. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  34. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  36. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37. * POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. * @category QualityAssurance
  40. * @package PHP_Depend
  41. * @subpackage Metrics
  42. * @author Manuel Pichler <mapi@pdepend.org>
  43. * @copyright 2008-2011 Manuel Pichler. All rights reserved.
  44. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  45. * @version SVN: $Id$
  46. * @link http://pdepend.org/
  47. * @since 0.9.10
  48. */
  49. /**
  50. * Locator that searches for PHP_Depend analyzers that follow the PHP_Depend
  51. * convention and are present the PHP_Depend source tree.
  52. *
  53. * @category QualityAssurance
  54. * @package PHP_Depend
  55. * @subpackage Metrics
  56. * @author Manuel Pichler <mapi@pdepend.org>
  57. * @copyright 2008-2011 Manuel Pichler. All rights reserved.
  58. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  59. * @version Release: @package_version@
  60. * @link http://pdepend.org/
  61. * @since 0.9.10
  62. */
  63. class PHP_Depend_Metrics_AnalyzerClassFileSystemLocator
  64. implements PHP_Depend_Metrics_AnalyzerClassLocator
  65. {
  66. /**
  67. * The root search directory.
  68. *
  69. * @var string
  70. */
  71. private $_classPath = null;
  72. /**
  73. * Array containing reflection classes for all found analyzer implementations.
  74. *
  75. * @var array(ReflectionClass)
  76. */
  77. private $_analyzers = null;
  78. /**
  79. * Constructs a new locator instance.
  80. *
  81. * @param string $classPath The root search directory.
  82. */
  83. public function __construct($classPath = null)
  84. {
  85. if ($classPath === null) {
  86. $classPath = dirname(__FILE__) . '/../../../';
  87. }
  88. $this->_classPath = realpath($classPath) . DIRECTORY_SEPARATOR;
  89. }
  90. /**
  91. * Returns an array with reflection instances for all analyzer classes.
  92. *
  93. * @return array(ReflectionClass)
  94. */
  95. public function findAll()
  96. {
  97. if ($this->_analyzers === null) {
  98. $this->_analyzers = $this->_find();
  99. }
  100. return $this->_analyzers;
  101. }
  102. /**
  103. * Performs a recursive search for analyzers in the configured class path
  104. * directory.
  105. *
  106. * @return array(ReflectionClass)
  107. */
  108. private function _find()
  109. {
  110. $result = array();
  111. if (0 === stripos(PHP_OS, 'win')) {
  112. $paths = explode(PATH_SEPARATOR, get_include_path());
  113. } else {
  114. preg_match_all('(:?(([a-z]+://)?[^:]+):?)i', get_include_path(), $match);
  115. $paths = $match[1];
  116. }
  117. foreach ($paths as $path) {
  118. $dir = $path.'/PHP/Depend/Metrics/';
  119. if (!is_dir($dir)) {
  120. continue;
  121. }
  122. $this->_classPath = $dir;
  123. $iterator = new RecursiveIteratorIterator(
  124. new RecursiveDirectoryIterator($dir)
  125. );
  126. foreach ($iterator as $file) {
  127. if ($file->getFilename() === 'Analyzer.php') {
  128. $className = $this->_createClassNameFromPath(
  129. $dir, $file->getPathname()
  130. );
  131. if (!class_exists($className)) {
  132. include_once $file->getPathname();
  133. }
  134. if ($this->_isAnalyzerClass($className)) {
  135. $result[$className] = new ReflectionClass($className);
  136. }
  137. }
  138. }
  139. }
  140. ksort($result);
  141. return array_values($result);
  142. }
  143. /**
  144. * Creates a possible analyzer class name from a given absolute file path
  145. * name.
  146. *
  147. * @param string $classPath The currently processed class path.
  148. * @param string $path Path of a possible analyzer class.
  149. *
  150. * @return string
  151. */
  152. private function _createClassNameFromPath($classPath, $path)
  153. {
  154. $localPath = substr($path, strlen($classPath), -4);
  155. return 'PHP_Depend_Metrics_' . strtr($localPath, DIRECTORY_SEPARATOR, '_');
  156. }
  157. /**
  158. * Checks if the given class name represents a valid analyzer implementation.
  159. *
  160. * @param string $className Class name of a possible analyzer implementation.
  161. *
  162. * @return boolean
  163. */
  164. private function _isAnalyzerClass($className)
  165. {
  166. return class_exists($className) && $this->_implementsInterface($className);
  167. }
  168. /**
  169. * Checks if the given class implements the analyzer interface.
  170. *
  171. * @param string $className Class name of a possible analyzer implementation.
  172. *
  173. * @return boolean
  174. */
  175. private function _implementsInterface($className)
  176. {
  177. $expectedType = 'PHP_Depend_Metrics_AnalyzerI';
  178. return in_array($expectedType, class_implements($className));
  179. }
  180. }