1
0
mirror of synced 2024-12-05 03:06:05 +03:00

[2.0] Refactoring some common code in to the AnnotationDriver and creating PhpDriver for consistancy

This commit is contained in:
jwage 2009-10-07 22:14:13 +00:00
parent 09a48a896e
commit a7d4e1e466
9 changed files with 176 additions and 111 deletions

View File

@ -44,18 +44,25 @@ class AnnotationDriver implements Driver
{
/** The AnnotationReader. */
private $_reader;
private $_classDirectory;
/**
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
* docblock annotations.
*
* @param AnnotationReader $reader The AnnotationReader to use.
*/
public function __construct(AnnotationReader $reader)
public function __construct(AnnotationReader $reader, $classDirectory = null)
{
$this->_reader = $reader;
$this->_classDirectory = $classDirectory;
}
public function setClassDirectory($classDirectory)
{
$this->_classDirectory = $classDirectory;
}
/**
* {@inheritdoc}
*/
@ -325,6 +332,28 @@ class AnnotationDriver implements Driver
public function preload()
{
return array();
if ($this->_classDirectory) {
$iter = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->_classDirectory),
\RecursiveIteratorIterator::LEAVES_ONLY);
$declared = get_declared_classes();
foreach ($iter as $item) {
$info = pathinfo($item->getPathName());
if (! isset($info['extension']) || $info['extension'] != 'php') {
continue;
}
require_once $item->getPathName();
}
$declared = array_diff(get_declared_classes(), $declared);
foreach ($declared as $className) {
if ( ! $this->isTransient($className)) {
$classes[] = $className;
}
}
return $classes;
} else {
return array();
}
}
}

View File

@ -0,0 +1,95 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\Common\DoctrineException,
Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\DBAL\Schema\AbstractSchemaManager,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException,
Doctrine\Common\Util\Inflector;
/**
* The PhpDriver includes php files which just populate ClassMetadataInfo
* instances with plain php code
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class PhpDriver implements Driver
{
/** The directory path to look in for php files */
private $_directory;
/** The array of class names found and the path to the file */
private $_classPaths = array();
public function __construct($directory)
{
$this->_directory = $directory;
}
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
{
$path = $this->_classPaths[$className];
include $path;
}
public function isTransient($className)
{
return true;
}
/**
* Preloads all mapping information found in any documents within the
* configured paths and returns a list of class names that have been preloaded.
*
* @return array The list of class names that have been preloaded.
*/
public function preload()
{
if ( ! is_dir($this->_directory)) {
throw MappingException::phpDriverRequiresConfiguredDirectoryPath();
}
$iter = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->_directory),
\RecursiveIteratorIterator::LEAVES_ONLY);
$classes = array();
foreach ($iter as $item) {
$info = pathinfo($item->getPathName());
if (! isset($info['extension']) || $info['extension'] != 'php') {
continue;
}
$className = $info['filename'];
$classes[] = $className;
$this->_classPaths[$className] = $item->getPathName();
}
return $classes;
}
}

View File

@ -21,7 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
use Doctrine\ORM\Tools\Export\ClassMetadataExporter,
Doctrine\Common\DoctrineException;
if ( ! class_exists('sfYaml', false)) {
require_once __DIR__ . '/../../../../../vendor/sfYaml/sfYaml.class.php';
@ -137,14 +138,17 @@ class ConvertMappingTask extends AbstractTask
$sourceArg = $source;
$type = $this->_determineSourceType($sourceArg);
if ( ! $type) {
throw DoctrineException::invalidMappingSourceType($sourceArg);
}
$source = $this->_getSourceByType($type, $sourceArg);
$printer->writeln(
sprintf(
'Adding "%s" mapping source',
$printer->format($sourceArg, 'KEYWORD')
),
'INFO'
'Adding "%s" mapping source which contains the "%s" format',
$printer->format($sourceArg, 'KEYWORD'),
$printer->format($type, 'KEYWORD')
)
);
$cme->addMappingSource($source, $type);
@ -163,11 +167,10 @@ class ConvertMappingTask extends AbstractTask
$printer->writeln(
sprintf(
'Exporting %s mapping information to directory "%s"',
'Exporting "%s" mapping information to directory "%s"',
$printer->format($args['to'], 'KEYWORD'),
$printer->format($args['dest'], 'KEYWORD')
),
'INFO'
)
);
$exporter->setMetadatas($metadatas);

View File

@ -14,7 +14,7 @@ use Doctrine\Common\DoctrineException,
*
* This task has the following arguments:
*
* <tt>--classdir=<path></tt>
* <tt>--class-dir=<path></tt>
* Specifies the directory where to start looking for mapped classes.
* This argument is required when the annotation metadata driver is used,
* otherwise it has no effect.
@ -71,7 +71,7 @@ class SchemaToolTask extends AbstractTask
->write('--dump-sql', 'OPT_ARG')
->writeln("\t\tInstead of try to apply generated SQLs into EntityManager, output them.")
->write(PHP_EOL)
->write('--classdir=<path>', 'OPT_ARG')
->write('--class-dir=<path>', 'OPT_ARG')
->writeln("\tOptional class directory to fetch for Entities.");
}
@ -87,7 +87,7 @@ class SchemaToolTask extends AbstractTask
{
$printer->write('schema-tool', 'KEYWORD')
->write(' (--create | --drop | --update)', 'REQ_ARG')
->writeln(' [--dump-sql] [--classdir=<path>]', 'OPT_ARG');
->writeln(' [--dump-sql] [--class-dir=<path>]', 'OPT_ARG');
}
/**
@ -115,11 +115,15 @@ class SchemaToolTask extends AbstractTask
return false;
}
if ($this->_em->getConfiguration()->getMetadataDriverImpl() instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver
&& ! isset($args['classdir'])) {
$printer->writeln("The supplied configuration uses the annotation metadata driver."
. " The 'classdir' argument is required for this driver.", 'ERROR');
return false;
$metadataDriver = $this->_em->getConfiguration()->getMetadataDriverImpl();
if ($metadataDriver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) {
if ( ! isset($args['class-dir'])) {
$printer->writeln("The supplied configuration uses the annotation metadata driver."
. " The 'class-dir' argument is required for this driver.", 'ERROR');
return false;
} else {
$metadataDriver->setClassDirectory($args['class-dir']);
}
}
return true;
@ -140,33 +144,11 @@ class SchemaToolTask extends AbstractTask
$driver = $this->_em->getConfiguration()->getMetadataDriverImpl();
$classes = array();
if ($driver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) {
$iter = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($args['classdir']),
\RecursiveIteratorIterator::LEAVES_ONLY);
$declared = get_declared_classes();
foreach ($iter as $item) {
$info = pathinfo($item->getPathName());
if (! isset($info['extension']) || $info['extension'] != 'php') {
continue;
}
require_once $item->getPathName();
}
$declared = array_diff(get_declared_classes(), $declared);
foreach ($declared as $className) {
if ( ! $driver->isTransient($className)) {
$classes[] = $cmf->getMetadataFor($className);
}
}
} else {
$preloadedClasses = $driver->preload(true);
foreach ($preloadedClasses as $className) {
$classes[] = $cmf->getMetadataFor($className);
}
$preloadedClasses = $driver->preload(true);
foreach ($preloadedClasses as $className) {
$classes[] = $cmf->getMetadataFor($className);
}
$printer = $this->getPrinter();
$tool = new SchemaTool($this->_em);

View File

@ -66,6 +66,7 @@ class ClassMetadataExporter
'yaml' => 'Doctrine\ORM\Mapping\Driver\YamlDriver',
'yml' => 'Doctrine\ORM\Mapping\Driver\YamlDriver',
'xml' => 'Doctrine\ORM\Mapping\Driver\XmlDriver',
'php' => 'Doctrine\ORM\Mapping\Driver\PhpDriver',
'database' => 'Doctrine\ORM\Mapping\Driver\DatabaseDriver'
);
@ -86,16 +87,12 @@ class ClassMetadataExporter
*/
public function addMappingSource($source, $type)
{
if ($type === 'php') {
$this->_mappingSources[] = array($source, $type);
} else {
if ( ! isset($this->_mappingDrivers[$type])) {
throw DoctrineException::invalidMappingDriverType($type);
}
$driver = $this->getMappingDriver($type, $source);
$this->_mappingSources[] = array($source, $driver);
if ( ! isset($this->_mappingDrivers[$type])) {
throw DoctrineException::invalidMappingDriverType($type);
}
$driver = $this->getMappingDriver($type, $source);
$this->_mappingSources[] = array($source, $driver);
}
/**
@ -119,9 +116,9 @@ class ClassMetadataExporter
} else if ($class == 'Doctrine\ORM\Mapping\Driver\AnnotationDriver') {
$reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache);
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
$driver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader);
} else if ($class == 'Doctrine\ORM\Mapping\Driver\DatabaseDriver') {
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($source);
$driver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, $source);
} else {
$driver = new $class($source);
}
return $driver;
}
@ -149,61 +146,21 @@ class ClassMetadataExporter
foreach ($this->_mappingSources as $d) {
list($source, $driver) = $d;
if ($driver == 'php') {
$iter = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source),
\RecursiveIteratorIterator::LEAVES_ONLY);
foreach ($iter as $item) {
$info = pathinfo($item->getPathName());
if (! isset($info['extension']) || $info['extension'] != 'php') {
continue;
}
include $item->getPathName();
$vars = get_defined_vars();
foreach ($vars as $var) {
if ($var instanceof \Doctrine\ORM\Mapping\ClassMetadataInfo) {
$classes[$var->name] = $var;
}
}
}
} else {
if ($driver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) {
$iter = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source),
\RecursiveIteratorIterator::LEAVES_ONLY);
$declared = get_declared_classes();
foreach ($iter as $item) {
$info = pathinfo($item->getPathName());
if (! isset($info['extension']) || $info['extension'] != 'php') {
continue;
}
require_once $item->getPathName();
}
$declared = array_diff(get_declared_classes(), $declared);
foreach ($declared as $className) {
if ( ! $driver->isTransient($className)) {
$metadata = new ClassMetadata($className);
$driver->loadMetadataForClass($className, $metadata);
$classes[$metadata->name] = $metadata;
}
}
$preloadedClasses = $driver->preload(true);
foreach ($preloadedClasses as $className) {
if (class_exists($className, false)) {
$metadata = new ClassMetadata($className);
} else {
$preloadedClasses = $driver->preload(true);
foreach ($preloadedClasses as $className) {
$metadata = new ClassMetadataInfo($className);
$driver->loadMetadataForClass($className, $metadata);
$classes[$metadata->name] = $metadata;
}
$metadata = new ClassMetadataInfo($className);
}
$driver->loadMetadataForClass($className, $metadata);
if ( ! $metadata->isMappedSuperclass) {
$classes[$metadata->name] = $metadata;
}
}
}
foreach ($classes as $key => $class) {
if ($class->isMappedSuperclass) {
unset($classes[$key]);
}
}
return $classes;
}

View File

@ -84,7 +84,7 @@ abstract class AbstractExporter
}
foreach ($this->_metadatas as $metadata) {
$outputPath = $this->_outputDir . '/' . str_replace('\\', '.', $metadata->name) . $this->_extension;
$outputPath = $this->_outputDir . '/' . $metadata->name . $this->_extension;
$output = $this->exportClassMetadata($metadata);
file_put_contents($outputPath, $output);
}

View File

@ -51,7 +51,6 @@ class PhpExporter extends AbstractExporter
$lines[] = null;
$lines[] = 'use Doctrine\ORM\Mapping\ClassMetadataInfo;';
$lines[] = null;
$lines[] = "\$metadata = new ClassMetadataInfo('" . $metadata->name . "');";
if ($metadata->isMappedSuperclass) {
$lines[] = '$metadata->isMappedSuperclass = true;';

View File

@ -73,7 +73,7 @@ class ClassMetadataExporterTest extends \Doctrine\Tests\OrmTestCase
$this->assertTrue($mappingSources[0][1] instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver);
$this->assertEquals($mappingSources[1][0], __DIR__.'/php');
$this->assertEquals('php', $mappingSources[1][1]);
$this->assertTrue($mappingSources[1][1] instanceof \Doctrine\ORM\Mapping\Driver\PhpDriver);
$this->assertEquals($mappingSources[2][0], __DIR__.'/xml');
$this->assertTrue($mappingSources[2][1] instanceof \Doctrine\ORM\Mapping\Driver\XmlDriver);

View File

@ -29,5 +29,5 @@ $connectionOptions = array(
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
$args = array(
'classdir' => './Entities'
'class-dir' => './Entities'
);