/PHP/Test/vendor/jms/metadata/src/Metadata/MetadataFactory.php

https://bitbucket.org/AdriVanHoudt/school · PHP · 154 lines · 100 code · 25 blank · 29 comment · 17 complexity · ba48c7a76298d05559c96c3f51ff9045 MD5 · raw file

  1. <?php
  2. /*
  3. * Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. namespace Metadata;
  18. use Metadata\Driver\DriverInterface;
  19. use Metadata\Cache\CacheInterface;
  20. final class MetadataFactory implements MetadataFactoryInterface
  21. {
  22. private $driver;
  23. private $cache;
  24. private $loadedMetadata = array();
  25. private $loadedClassMetadata = array();
  26. private $hierarchyMetadataClass;
  27. private $includeInterfaces = false;
  28. private $debug;
  29. /**
  30. * @param boolean $debug
  31. */
  32. public function __construct(DriverInterface $driver, $hierarchyMetadataClass = 'Metadata\ClassHierarchyMetadata', $debug = false)
  33. {
  34. $this->driver = $driver;
  35. $this->hierarchyMetadataClass = $hierarchyMetadataClass;
  36. $this->debug = $debug;
  37. }
  38. /**
  39. * @param boolean $bool
  40. */
  41. public function setIncludeInterfaces($bool)
  42. {
  43. $this->includeInterfaces = (Boolean) $bool;
  44. }
  45. public function setCache(CacheInterface $cache)
  46. {
  47. $this->cache = $cache;
  48. }
  49. /**
  50. * @param string $className
  51. */
  52. public function getMetadataForClass($className)
  53. {
  54. if (isset($this->loadedMetadata[$className])) {
  55. return $this->loadedMetadata[$className];
  56. }
  57. $metadata = null;
  58. foreach ($this->getClassHierarchy($className) as $class) {
  59. if (isset($this->loadedClassMetadata[$name = $class->getName()])) {
  60. $this->addClassMetadata($metadata, $this->loadedClassMetadata[$name]);
  61. continue;
  62. }
  63. // check the cache
  64. if (null !== $this->cache
  65. && (null !== $classMetadata = $this->cache->loadClassMetadataFromCache($class))) {
  66. if ($this->debug && !$classMetadata->isFresh()) {
  67. $this->cache->evictClassMetadataFromCache($classMetadata->reflection);
  68. } else {
  69. $this->loadedClassMetadata[$name] = $classMetadata;
  70. $this->addClassMetadata($metadata, $classMetadata);
  71. continue;
  72. }
  73. }
  74. // load from source
  75. if (null !== $classMetadata = $this->driver->loadMetadataForClass($class)) {
  76. $this->loadedClassMetadata[$name] = $classMetadata;
  77. $this->addClassMetadata($metadata, $classMetadata);
  78. if (null !== $this->cache) {
  79. $this->cache->putClassMetadataInCache($classMetadata);
  80. }
  81. continue;
  82. }
  83. }
  84. return $this->loadedMetadata[$className] = $metadata;
  85. }
  86. /**
  87. * @param ClassMetadata $toAdd
  88. */
  89. private function addClassMetadata(&$metadata, $toAdd)
  90. {
  91. if ($toAdd instanceof MergeableInterface) {
  92. if (null === $metadata) {
  93. $metadata = clone $toAdd;
  94. } else {
  95. $metadata->merge($toAdd);
  96. }
  97. } else {
  98. if (null === $metadata) {
  99. $metadata = new $this->hierarchyMetadataClass;
  100. }
  101. $metadata->addClassMetadata($toAdd);
  102. }
  103. }
  104. private function getClassHierarchy($class)
  105. {
  106. $classes = array();
  107. $refl = new \ReflectionClass($class);
  108. do {
  109. $classes[] = $refl;
  110. } while (false !== $refl = $refl->getParentClass());
  111. $classes = array_reverse($classes, false);
  112. if (!$this->includeInterfaces) {
  113. return $classes;
  114. }
  115. $addedInterfaces = array();
  116. $newHierarchy = array();
  117. foreach ($classes as $class) {
  118. foreach ($class->getInterfaces() as $interface) {
  119. if (isset($addedInterfaces[$interface->getName()])) {
  120. continue;
  121. }
  122. $addedInterfaces[$interface->getName()] = true;
  123. $newHierarchy[] = $interface;
  124. }
  125. $newHierarchy[] = $class;
  126. }
  127. return $newHierarchy;
  128. }
  129. }