diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 6f8ee80b2..713024e9c 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -24,10 +24,9 @@ use ReflectionException, Doctrine\ORM\EntityManager, Doctrine\DBAL\Platforms, Doctrine\ORM\Events, - Doctrine\Common\Util\ClassUtils, - Doctrine\Common\Persistence\Mapping\RuntimeReflectionService, Doctrine\Common\Persistence\Mapping\ReflectionService, - Doctrine\Common\Persistence\Mapping\ClassMetadataFactory as ClassMetadataFactoryInterface; + Doctrine\Common\Persistence\Mapping\ClassMetadata as ClassMetadataInterface, + Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory; /** * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the @@ -40,7 +39,7 @@ use ReflectionException, * @author Jonathan Wage * @author Roman Borschel */ -class ClassMetadataFactory implements ClassMetadataFactoryInterface +class ClassMetadataFactory extends AbstractClassMetadataFactory { /** * @var EntityManager @@ -62,26 +61,6 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface */ private $evm; - /** - * @var \Doctrine\Common\Cache\Cache - */ - private $cacheDriver; - - /** - * @var array - */ - private $loadedMetadata = array(); - - /** - * @var bool - */ - private $initialized = false; - - /** - * @var ReflectionService - */ - private $reflectionService; - /** * @param EntityManager $$em */ @@ -91,55 +70,9 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface } /** - * Sets the cache driver used by the factory to cache ClassMetadata instances. - * - * @param \Doctrine\Common\Cache\Cache $cacheDriver + * {@inheritDoc}. */ - public function setCacheDriver($cacheDriver) - { - $this->cacheDriver = $cacheDriver; - } - - /** - * Gets the cache driver used by the factory to cache ClassMetadata instances. - * - * @return \Doctrine\Common\Cache\Cache - */ - public function getCacheDriver() - { - return $this->cacheDriver; - } - - public function getLoadedMetadata() - { - return $this->loadedMetadata; - } - - /** - * Forces the factory to load the metadata of all classes known to the underlying - * mapping driver. - * - * @return array The ClassMetadata instances of all mapped classes. - */ - public function getAllMetadata() - { - if ( ! $this->initialized) { - $this->initialize(); - } - - $metadata = array(); - foreach ($this->driver->getAllClassNames() as $className) { - $metadata[] = $this->getMetadataFor($className); - } - - return $metadata; - } - - /** - * Lazy initialization of this stuff, especially the metadata driver, - * since these are not needed at all when a metadata cache is active. - */ - private function initialize() + protected function initialize() { $this->driver = $this->em->getConfiguration()->getMetadataDriverImpl(); $this->targetPlatform = $this->em->getConnection()->getDatabasePlatform(); @@ -148,104 +81,8 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface } /** - * Gets the class metadata descriptor for a class. - * - * @param string $className The name of the class. - * @return \Doctrine\ORM\Mapping\ClassMetadata - */ - public function getMetadataFor($className) - { - if (isset($this->loadedMetadata[$className])) { - return $this->loadedMetadata[$className]; - } + * {@inheritDoc} - $realClassName = $className; - - // Check for namespace alias - if (strpos($className, ':') !== false) { - list($namespaceAlias, $simpleClassName) = explode(':', $className); - $realClassName = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName; - } else { - $realClassName = ClassUtils::getRealClass($realClassName); - } - - if (isset($this->loadedMetadata[$realClassName])) { - // We do not have the alias name in the map, include it - $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; - return $this->loadedMetadata[$realClassName]; - } - - if ($this->cacheDriver) { - if (($cached = $this->cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) { - $this->wakeupReflection($cached, $this->getReflectionService()); - $this->loadedMetadata[$realClassName] = $cached; - } else { - foreach ($this->loadMetadata($realClassName) as $loadedClassName) { - $this->cacheDriver->save( - "$loadedClassName\$CLASSMETADATA", $this->loadedMetadata[$loadedClassName], null - ); - } - } - } else { - $this->loadMetadata($realClassName); - } - - if ($className != $realClassName) { - // We do not have the alias name in the map, include it - $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; - } - - return $this->loadedMetadata[$className]; - } - - /** - * Checks whether the factory has the metadata for a class loaded already. - * - * @param string $className - * @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise. - */ - public function hasMetadataFor($className) - { - return isset($this->loadedMetadata[$className]); - } - - /** - * Sets the metadata descriptor for a specific class. - * - * NOTE: This is only useful in very special cases, like when generating proxy classes. - * - * @param string $className - * @param ClassMetadata $class - */ - public function setMetadataFor($className, $class) - { - $this->loadedMetadata[$className] = $class; - } - - /** - * Get array of parent classes for the given entity class - * - * @param string $name - * @return array $parentClasses - */ - protected function getParentClasses($name) - { - // Collect parent classes, ignoring transient (not-mapped) classes. - $parentClasses = array(); - foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) { - if ( ! $this->driver->isTransient($parentClass)) { - $parentClasses[] = $parentClass; - } - } - return $parentClasses; - } - - /** - * Loads the metadata of the class in question and all it's ancestors whose metadata - * is still not loaded. - * - * @param string $name The name of the class for which the metadata should get loaded. - * @param array $tables The metadata collection to which the loaded metadata is added. */ protected function loadMetadata($name) { @@ -263,8 +100,8 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface $rootEntityFound = false; $visited = array(); foreach ($parentClasses as $className) { - if (isset($this->loadedMetadata[$className])) { - $parent = $this->loadedMetadata[$className]; + if ($this->hasMetadataFor($className)) { + $parent = $this->getMetadataFor($className); if ( ! $parent->isMappedSuperclass) { $rootEntityFound = true; array_unshift($visited, $className); @@ -352,7 +189,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface $this->validateRuntimeMetadata($class, $parent); - $this->loadedMetadata[$className] = $class; + $this->setMetadataFor($className, $class); $parent = $class; @@ -404,10 +241,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface } /** - * Creates a new ClassMetadata instance for the given class name. - * - * @param string $className - * @return \Doctrine\ORM\Mapping\ClassMetadata + * {@inheritDoc} */ protected function newClassMetadataInstance($className) { @@ -469,40 +303,6 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface return strtolower(end($parts)); } - /** - * Cache the metadata - * - * @param $className - * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata - */ - private function cacheMetadata($className, ClassMetadata $metadata) - { - $this->cacheDriver->save( - "$className\$CLASSMETADATA", $metadata, null - ); - } - - /** - * Verify if metadata is cached - * - * @param $className - * @return bool - */ - private function cacheContainsMetadata($className) - { - return $this->cacheDriver->contains("$className\$CLASSMETADATA"); - } - - /** - * Fetch metadata from cache - * - * @param $className - */ - private function fetchMetadataFromCache($className) - { - return $this->cacheDriver->fetch("$className\$CLASSMETADATA"); - } - /** * Adds inherited fields to the subclass mapping. * @@ -725,10 +525,9 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface } /** - * Check if this class is mapped by this EntityManager + ClassMetadata configuration + * {@inheritDoc} * - * @param $class - * @return bool + * @todo remove after doctrine/common#138 is merged */ public function isTransient($class) { @@ -739,56 +538,52 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface // Check for namespace alias if (strpos($class, ':') !== false) { list($namespaceAlias, $simpleClassName) = explode(':', $class); - $class = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName; + $class = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName); } return $this->driver->isTransient($class); } /** - * Get reflectionService. - * - * @return \Doctrine\Common\Persistence\Mapping\ReflectionService + * {@inheritDoc} */ - public function getReflectionService() - { - if ($this->reflectionService === null) { - $this->reflectionService = new RuntimeReflectionService(); - } - return $this->reflectionService; - } - - /** - * Set reflectionService. - * - * @param reflectionService the value to set. - */ - public function setReflectionService(ReflectionService $reflectionService) - { - $this->reflectionService = $reflectionService; - } - - /** - * Wakeup reflection after ClassMetadata gets unserialized from cache. - * - * @param ClassMetadataInfo $class - * @param ReflectionService $reflService - * @return void - */ - protected function wakeupReflection(ClassMetadataInfo $class, ReflectionService $reflService) + protected function wakeupReflection(ClassMetadataInterface $class, ReflectionService $reflService) { $class->wakeupReflection($reflService); } /** - * Initialize Reflection after ClassMetadata was constructed. - * - * @param ClassMetadataInfo $class - * @param ReflectionService $reflService - * @return void + * {@inheritDoc} */ - protected function initializeReflection(ClassMetadataInfo $class, ReflectionService $reflService) + protected function initializeReflection(ClassMetadataInterface $class, ReflectionService $reflService) { $class->initializeReflection($reflService); } + + /** + * {@inheritDoc} + */ + protected function getFqcnFromAlias($namespaceAlias, $simpleClassName) + { + return $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName; + } + + /** + * {@inheritDoc} + */ + protected function getDriver() + { + return $this->driver; + } + + /** + * {@inheritDoc} + */ + protected function doLoadMetadata($class, $parent, $rootEntityFound) + { + throw new \LogicException( + 'Not implemented because Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory ' + . 'behavior differs in how Doctrine\ORM\Mapping\MetadataFactory works' + ); + } }