Skip to content

Commit

Permalink
Added ability to get configured metadata classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
jstout24 committed Dec 17, 2012
1 parent a965c62 commit 9c74000
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 6 deletions.
36 changes: 36 additions & 0 deletions src/Metadata/AdvancedMetadataFactoryInterface.php
@@ -0,0 +1,36 @@
<?php

/*
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Metadata;

/**
* Interface for advanced Metadata Factory implementations.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Jordan Stout <j@jrdn.org>
*/
interface AdvancedMetadataFactoryInterface extends MetadataFactoryInterface
{
/**
* Gets all the possible classes.
*
* @throws \RuntimeException if driver does not an advanced driver.
* @return array
*/
public function getAllClassNames();
}
17 changes: 16 additions & 1 deletion src/Metadata/Driver/AbstractFileDriver.php
Expand Up @@ -7,8 +7,11 @@
* *
* @author Johannes M. Schmitt <schmittjoh@gmail.com> * @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/ */
abstract class AbstractFileDriver implements DriverInterface abstract class AbstractFileDriver implements AdvancedDriverInterface
{ {
/**
* @var FileLocatorInterface|FileLocator
*/
private $locator; private $locator;


public function __construct(FileLocatorInterface $locator) public function __construct(FileLocatorInterface $locator)
Expand All @@ -25,6 +28,18 @@ public function loadMetadataForClass(\ReflectionClass $class)
return $this->loadMetadataFromFile($class, $path); return $this->loadMetadataFromFile($class, $path);
} }


/**
* {@inheritDoc}
*/
public function getAllClassNames()
{
if (!$this->locator instanceof AdvancedFileLocatorInterface) {
throw new \RuntimeException('Locator "%s" must be an instance of "AdvancedFileLocatorInterface".');
}

return $this->locator->findAllClasses($this->getExtension());
}

/** /**
* Parses the content of the file, and converts it to the desired metadata. * Parses the content of the file, and converts it to the desired metadata.
* *
Expand Down
34 changes: 34 additions & 0 deletions src/Metadata/Driver/AdvancedDriverInterface.php
@@ -0,0 +1,34 @@
<?php

/*
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Metadata\Driver;

/**
* Forces advanced logic to drivers.
*
* @author Jordan Stout <j@jrdn.org>
*/
interface AdvancedDriverInterface extends DriverInterface
{
/**
* Gets all the metadata class names known to this driver.
*
* @return array
*/
public function getAllClassNames();
}
36 changes: 36 additions & 0 deletions src/Metadata/Driver/AdvancedFileLocatorInterface.php
@@ -0,0 +1,36 @@
<?php

/*
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Metadata\Driver;

/**
* Forces advanced logic on a file locator.
*
* @author Jordan Stout <j@jrdn.org>
*/
interface AdvancedFileLocatorInterface extends FileLocatorInterface
{
/**
* Finds all possible metadata files.
*
* @param string $extension
*
* @return array
*/
public function findAllClasses($extension);
}
27 changes: 26 additions & 1 deletion src/Metadata/Driver/DriverChain.php
Expand Up @@ -18,7 +18,7 @@


namespace Metadata\Driver; namespace Metadata\Driver;


final class DriverChain implements DriverInterface final class DriverChain implements AdvancedDriverInterface
{ {
private $drivers; private $drivers;


Expand All @@ -37,4 +37,29 @@ public function loadMetadataForClass(\ReflectionClass $class)


return null; return null;
} }

/**
* {@inheritDoc}
*/
public function getAllClassNames()
{
$classes = array();
foreach ($this->drivers as $driver) {
if (!$driver instanceof AdvancedDriverInterface) {
throw new \RuntimeException(
sprintf(
'Driver "%s" must be an instance of "AdvancedDriverInterface" to use '.
'"DriverChain::getAllClassNames()".',
get_class($driver)
)
);
}
$driverClasses = $driver->getAllClassNames();
if (!empty($driverClasses)) {
$classes = array_merge($classes, $driverClasses);
}
}

return $classes;
}
} }
26 changes: 25 additions & 1 deletion src/Metadata/Driver/FileLocator.php
Expand Up @@ -2,7 +2,7 @@


namespace Metadata\Driver; namespace Metadata\Driver;


class FileLocator implements FileLocatorInterface class FileLocator implements AdvancedFileLocatorInterface
{ {
private $dirs; private $dirs;


Expand Down Expand Up @@ -35,4 +35,28 @@ public function findFileForClass(\ReflectionClass $class, $extension)


return null; return null;
} }

/**
* {@inheritDoc}
*/
public function findAllClasses($extension)
{
$classes = array();
foreach ($this->dirs as $prefix => $dir) {
/** @var $iterator \RecursiveIteratorIterator|\SplFileInfo[] */
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($dir),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
if (($fileName = $file->getBasename('.'.$extension)) == $file->getBasename()) {
continue;
}

$classes[] = ($prefix !== '' ? $prefix.'\\' : '').str_replace('.', '\\', $fileName);
}
}

return $classes;
}
} }
17 changes: 16 additions & 1 deletion src/Metadata/MetadataFactory.php
Expand Up @@ -18,10 +18,11 @@


namespace Metadata; namespace Metadata;


use Metadata\Driver\AdvancedDriverInterface;
use Metadata\Driver\DriverInterface; use Metadata\Driver\DriverInterface;
use Metadata\Cache\CacheInterface; use Metadata\Cache\CacheInterface;


final class MetadataFactory implements MetadataFactoryInterface final class MetadataFactory implements AdvancedMetadataFactoryInterface
{ {
private $driver; private $driver;
private $cache; private $cache;
Expand Down Expand Up @@ -98,6 +99,20 @@ public function getMetadataForClass($className)
return $this->loadedMetadata[$className] = $metadata; return $this->loadedMetadata[$className] = $metadata;
} }


/**
* {@inheritDoc}
*/
public function getAllClassNames()
{
if (!$this->driver instanceof AdvancedDriverInterface) {
throw new \RuntimeException(
sprintf('Driver "%s" must be an instance of "AdvancedDriverInterface".', get_class($this->driver))
);
}

return $this->driver->getAllClassNames();
}

/** /**
* @param ClassMetadata $toAdd * @param ClassMetadata $toAdd
*/ */
Expand Down
85 changes: 85 additions & 0 deletions tests/Metadata/Tests/Driver/AbstractFileDriverTest.php
@@ -0,0 +1,85 @@
<?php

namespace Metadata\Tests\Driver;

use Metadata\ClassMetadata;

/**
* @author Jordan Stout <j@jrdn.org>
*/
class AbstractFileDriverTest extends \PHPUnit_Framework_TestCase
{
private static $extension = 'jms_metadata.yml';

/** @var \PHPUnit_Framework_MockObject_MockObject */
private $locator;

/** @var \PHPUnit_Framework_MockObject_MockObject */
private $driver;

public function setUp()
{
$this->locator = $this->getMock('Metadata\Driver\FileLocator', array(), array(), '', false);
$this->driver = $this->getMockBuilder('Metadata\Driver\AbstractFileDriver')
->setConstructorArgs(array($this->locator))
->getMockForAbstractClass();

$this->driver->expects($this->any())->method('getExtension')->will($this->returnValue(self::$extension));
}

public function testLoadMetadataForClass()
{
$class = new \ReflectionClass('\stdClass');
$this->locator
->expects($this->once())
->method('findFileForClass')
->with($class, self::$extension)
->will($this->returnValue('Some\Path'));

$this->driver
->expects($this->once())
->method('loadMetadataFromFile')
->with($class, 'Some\Path')
->will($this->returnValue($metadata = new ClassMetadata('\stdClass')));

$this->assertSame($metadata, $this->driver->loadMetadataForClass($class));
}

public function testLoadMetadataForClassWillReturnNull()
{
$class = new \ReflectionClass('\stdClass');
$this->locator
->expects($this->once())
->method('findFileForClass')
->with($class, self::$extension)
->will($this->returnValue(null));

$this->assertSame(null, $this->driver->loadMetadataForClass($class));
}

public function testGetAllClassNames()
{
$class = new \ReflectionClass('\stdClass');
$this->locator
->expects($this->once())
->method('findAllClasses')
->with(self::$extension)
->will($this->returnValue(array('\stdClass')));

$this->assertSame(array('\stdClass'), $this->driver->getAllClassNames($class));
}

public function testGetAllClassNamesThrowsRuntimeException()
{
$this->setExpectedException('RuntimeException');

$locator = $this->getMock('Metadata\Driver\FileLocatorInterface', array(), array(), '', false);
$driver = $this->getMockBuilder('Metadata\Driver\AbstractFileDriver')
->setConstructorArgs(array($locator))
->getMockForAbstractClass();
$class = new \ReflectionClass('\stdClass');
$locator->expects($this->never())->method('findAllClasses');

$driver->getAllClassNames($class);
}
}
28 changes: 28 additions & 0 deletions tests/Metadata/Tests/Driver/DriverChainTest.php
Expand Up @@ -20,6 +20,25 @@ public function testLoadMetadataForClass()
$this->assertSame($metadata, $chain->loadMetadataForClass(new \ReflectionClass('\stdClass'))); $this->assertSame($metadata, $chain->loadMetadataForClass(new \ReflectionClass('\stdClass')));
} }


public function testGetAllClassNames()
{
$driver1 = $this->getMock('Metadata\\Driver\\AdvancedDriverInterface');
$driver1
->expects($this->once())
->method('getAllClassNames')
->will($this->returnValue(array('Foo')));

$driver2 = $this->getMock('Metadata\\Driver\\AdvancedDriverInterface');
$driver2
->expects($this->once())
->method('getAllClassNames')
->will($this->returnValue(array('Bar')));

$chain = new DriverChain(array($driver1, $driver2));

$this->assertSame(array('Foo', 'Bar'), $chain->getAllClassNames());
}

public function testLoadMetadataForClassReturnsNullWhenNoMetadataIsFound() public function testLoadMetadataForClassReturnsNullWhenNoMetadataIsFound()
{ {
$driver = new DriverChain(array()); $driver = new DriverChain(array());
Expand All @@ -34,4 +53,13 @@ public function testLoadMetadataForClassReturnsNullWhenNoMetadataIsFound()
$driverChain = new DriverChain(array($driver)); $driverChain = new DriverChain(array($driver));
$this->assertNull($driver->loadMetadataForClass(new \ReflectionClass('\stdClass'))); $this->assertNull($driver->loadMetadataForClass(new \ReflectionClass('\stdClass')));
} }

public function testGetAllClassNamesThrowsException()
{
$this->setExpectedException('RuntimeException');
$driver = $this->getMock('Metadata\\Driver\\DriverInterface');
$driver->expects($this->never())->method('getAllClassNames');
$chain = new DriverChain(array($driver));
$chain->getAllClassNames();
}
} }

0 comments on commit 9c74000

Please sign in to comment.