AnnotationRegistry.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. *
  15. * This software consists of voluntary contributions made by many individuals
  16. * and is licensed under the MIT license. For more information, see
  17. * <http://www.doctrine-project.org>.
  18. */
  19. namespace Doctrine\Common\Annotations;
  20. /**
  21. * AnnotationRegistry
  22. */
  23. final class AnnotationRegistry
  24. {
  25. /**
  26. * A map of namespaces to use for autoloading purposes based on a PSR-0 convention.
  27. *
  28. * Contains the namespace as key and an array of directories as value. If the value is NULL
  29. * the include path is used for checking for the corresponding file.
  30. *
  31. * This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own.
  32. *
  33. * @var array
  34. */
  35. static private $autoloadNamespaces = array();
  36. /**
  37. * A map of autoloader callables.
  38. *
  39. * @var array
  40. */
  41. static private $loaders = array();
  42. static public function reset()
  43. {
  44. self::$autoloadNamespaces = array();
  45. self::$loaders = array();
  46. }
  47. /**
  48. * Register file
  49. *
  50. * @param string $file
  51. */
  52. static public function registerFile($file)
  53. {
  54. require_once $file;
  55. }
  56. /**
  57. * Add a namespace with one or many directories to look for files or null for the include path.
  58. *
  59. * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
  60. *
  61. * @param string $namespace
  62. * @param string|array|null $dirs
  63. */
  64. static public function registerAutoloadNamespace($namespace, $dirs = null)
  65. {
  66. self::$autoloadNamespaces[$namespace] = $dirs;
  67. }
  68. /**
  69. * Register multiple namespaces
  70. *
  71. * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
  72. *
  73. * @param array $namespaces
  74. */
  75. static public function registerAutoloadNamespaces(array $namespaces)
  76. {
  77. self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces);
  78. }
  79. /**
  80. * Register an autoloading callable for annotations, much like spl_autoload_register().
  81. *
  82. * NOTE: These class loaders HAVE to be silent when a class was not found!
  83. * IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class.
  84. *
  85. * @param callable $callable
  86. *
  87. * @throws \InvalidArgumentException
  88. */
  89. static public function registerLoader($callable)
  90. {
  91. if (!is_callable($callable)) {
  92. throw new \InvalidArgumentException("A callable is expected in AnnotationRegistry::registerLoader().");
  93. }
  94. self::$loaders[] = $callable;
  95. }
  96. /**
  97. * Autoload an annotation class silently.
  98. *
  99. * @param string $class
  100. * @return boolean
  101. */
  102. static public function loadAnnotationClass($class)
  103. {
  104. foreach (self::$autoloadNamespaces AS $namespace => $dirs) {
  105. if (strpos($class, $namespace) === 0) {
  106. $file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php";
  107. if ($dirs === null) {
  108. if ($path = stream_resolve_include_path($file)) {
  109. require $path;
  110. return true;
  111. }
  112. } else {
  113. foreach((array)$dirs AS $dir) {
  114. if (is_file($dir . DIRECTORY_SEPARATOR . $file)) {
  115. require $dir . DIRECTORY_SEPARATOR . $file;
  116. return true;
  117. }
  118. }
  119. }
  120. }
  121. }
  122. foreach (self::$loaders AS $loader) {
  123. if (call_user_func($loader, $class) === true) {
  124. return true;
  125. }
  126. }
  127. return false;
  128. }
  129. }