[DependencyInjection] added a way to retrieve loaded resources

This commit is contained in:
Fabien Potencier 2010-01-17 11:21:31 +01:00
parent e9e2899cda
commit 53980bb55e
10 changed files with 226 additions and 39 deletions

View File

@ -23,6 +23,7 @@ class BuilderConfiguration
protected $definitions = array();
protected $parameters = array();
protected $aliases = array();
protected $resources = array();
public function __construct(array $definitions = array(), array $parameters = array())
{
@ -30,6 +31,26 @@ class BuilderConfiguration
$this->setParameters($parameters);
}
/**
* Returns an array of resources loaded to build this configuration.
*
* @return array An array of resources
*/
public function getResources()
{
return $this->resources;
}
/**
* Adds a resource for this configuration.
*
* @param ResourceInterface $resource A resource instance
*/
public function addResource(ResourceInterface $resource)
{
$this->resources[] = $resource;
}
/**
* Merges a BuilderConfiguration with the current one.
*
@ -45,6 +66,11 @@ class BuilderConfiguration
$this->addDefinitions($configuration->getDefinitions());
$this->addAliases($configuration->getAliases());
$this->addParameters($configuration->getParameters());
foreach ($configuration->getResources() as $resource)
{
$this->addResource($resource);
}
}
/**

View File

@ -0,0 +1,66 @@
<?php
namespace Symfony\Components\DependencyInjection;
/*
* This file is part of the symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
/**
* FileResource represents a resource stored on the filesystem.
*
* @package symfony
* @subpackage dependency_injection
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class FileResource implements ResourceInterface
{
protected $resource;
/**
* Constructor.
*
* @param string $resource The file path to the resource
*/
public function __construct($resource)
{
$this->resource = $resource;
}
/**
* Returns the resource tied to this Resource.
*
* @return mixed The resource
*/
public function getResource()
{
return $this->resource;
}
/**
* Returns true if the resource has not been updated since the given timestamp.
*
* @param timestamp $timestamp The last time the resource was loaded
*
* @return Boolean true if the resource has not been updated, false otherwise
*/
public function isUptodate($timestamp = null)
{
if (!file_exists($this->resource))
{
return false;
}
if (null === $timestamp)
{
$timestamp = time();
}
return filemtime($this->resource) < $timestamp;
}
}

View File

@ -37,6 +37,17 @@ abstract class FileLoader extends Loader
$this->paths = $paths;
}
protected function findFile($file)
{
$path = $this->getAbsolutePath($file);
if (!file_exists($path))
{
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s).', $file, implode(', ', $this->paths)));
}
return realpath($path);
}
protected function getAbsolutePath($file, $currentPath = null)
{
if (self::isAbsolutePath($file))

View File

@ -3,6 +3,7 @@
namespace Symfony\Components\DependencyInjection\Loader;
use Symfony\Components\DependencyInjection\BuilderConfiguration;
use Symfony\Components\DependencyInjection\FileResource;
/*
* This file is part of the symfony framework.
@ -31,13 +32,11 @@ class IniFileLoader extends FileLoader
*/
public function load($file)
{
$path = $this->findFile($file);
$configuration = new BuilderConfiguration();
$path = $this->getAbsolutePath($file);
if (!file_exists($path))
{
throw new \InvalidArgumentException(sprintf('The %s file does not exist.', $file));
}
$configuration->addResource(new FileResource($path));
$result = parse_ini_file($path, true);
if (false === $result || array() === $result)

View File

@ -6,6 +6,7 @@ use Symfony\Components\DependencyInjection\Definition;
use Symfony\Components\DependencyInjection\Reference;
use Symfony\Components\DependencyInjection\BuilderConfiguration;
use Symfony\Components\DependencyInjection\SimpleXMLElement;
use Symfony\Components\DependencyInjection\FileResource;
/*
* This file is part of the symfony framework.
@ -34,9 +35,13 @@ class XmlFileLoader extends FileLoader
*/
public function load($file)
{
$path = $this->findFile($file);
$xml = $this->parseFile($path);
$configuration = new BuilderConfiguration();
$xml = $this->loadFile($file);
$configuration->addResource(new FileResource($path));
// anonymous services
$xml = $this->processAnonymousServices($configuration, $xml, $file);
@ -165,25 +170,18 @@ class XmlFileLoader extends FileLoader
$configuration->setDefinition($id, $definition);
}
protected function loadFile($file)
protected function parseFile($file)
{
$path = $this->getAbsolutePath($file);
if (!file_exists($path))
{
throw new \InvalidArgumentException(sprintf('The service file "%s" does not exist (in: %s).', $file, implode(', ', $this->paths)));
}
$dom = new \DOMDocument();
libxml_use_internal_errors(true);
if (!$dom->load(realpath($path), LIBXML_COMPACT))
if (!$dom->load($file, LIBXML_COMPACT))
{
throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors()));
}
$dom->validateOnParse = true;
$dom->normalizeDocument();
libxml_use_internal_errors(false);
$this->validate($dom, $path);
$this->validate($dom, $file);
return simplexml_import_dom($dom, 'Symfony\\Components\\DependencyInjection\\SimpleXMLElement');
}

View File

@ -6,6 +6,7 @@ use Symfony\Components\DependencyInjection\Container;
use Symfony\Components\DependencyInjection\Definition;
use Symfony\Components\DependencyInjection\Reference;
use Symfony\Components\DependencyInjection\BuilderConfiguration;
use Symfony\Components\DependencyInjection\FileResource;
use Symfony\Components\YAML\YAML;
/*
@ -37,10 +38,14 @@ class YamlFileLoader extends FileLoader
*/
public function load($file)
{
$content = $this->loadFile($file);
$path = $this->findFile($file);
$content = $this->loadFile($path);
$configuration = new BuilderConfiguration();
$configuration->addResource(new FileResource($path));
if (!$content)
{
return $configuration;
@ -166,14 +171,7 @@ class YamlFileLoader extends FileLoader
protected function loadFile($file)
{
$path = $this->getAbsolutePath($file);
if (!file_exists($path))
{
throw new \InvalidArgumentException(sprintf('The service file "%s" does not exist (in: %s).', $file, implode(', ', $this->paths)));
}
return $this->validate(YAML::load($path), $path);
return $this->validate(YAML::load($file), $file);
}
protected function validate($content, $file)

View File

@ -0,0 +1,38 @@
<?php
namespace Symfony\Components\DependencyInjection;
/*
* This file is part of the symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
/**
* ResourceInterface is the interface that must be implemented by all Resource classes.
*
* @package symfony
* @subpackage dependency_injection
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
interface ResourceInterface
{
/**
* Returns true if the resource has not been updated since the given timestamp.
*
* @param timestamp $timestamp The last time the resource was loaded
*
* @return Boolean true if the resource has not been updated, false otherwise
*/
function isUptodate($timestamp = null);
/**
* Returns the resource tied to this Resource.
*
* @return mixed The resource
*/
function getResource();
}

View File

@ -14,10 +14,11 @@ use Symfony\Components\DependencyInjection\Builder;
use Symfony\Components\DependencyInjection\BuilderConfiguration;
use Symfony\Components\DependencyInjection\Definition;
use Symfony\Components\DependencyInjection\Reference;
use Symfony\Components\DependencyInjection\FileResource;
$fixturesPath = __DIR__.'/../../../../fixtures/Symfony/Components/DependencyInjection/';
$t = new LimeTest(37);
$t = new LimeTest(39);
// __construct()
$t->diag('__construct()');
@ -62,6 +63,13 @@ $config->setDefinition('foo', new Definition('BazClass'));
$configuration->merge($config);
$t->is($configuration->getDefinition('foo')->getClass(), 'BazClass', '->merge() overrides already defined services');
$configuration = new BuilderConfiguration();
$configuration->addResource($a = new FileResource('foo.xml'));
$config = new BuilderConfiguration();
$config->addResource($b = new FileResource('foo.yml'));
$configuration->merge($config);
$t->is($configuration->getResources(), array($a, $b), '->merge() merges resources');
// ->setParameters() ->getParameters()
$t->diag('->setParameters() ->getParameters()');
@ -175,3 +183,10 @@ $configuration = new BuilderConfiguration(array('foo' => $definition = new Defin
$configuration->setAlias('bar', 'foo');
$configuration->setAlias('foobar', 'bar');
$t->is($configuration->findDefinition('foobar'), $definition, '->findDefinition() returns a Definition');
// ->addResource() ->getResources()
$t->diag('->addResource() ->getResources()');
$configuration = new BuilderConfiguration();
$configuration->addResource($a = new FileResource('foo.xml'));
$configuration->addResource($b = new FileResource('foo.yml'));
$t->is($configuration->getResources(), array($a, $b), '->getResources() returns an array of resources read for the current configuration');

View File

@ -0,0 +1,33 @@
<?php
/*
* This file is part of the symfony package.
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require_once __DIR__.'/../../../bootstrap.php';
use Symfony\Components\DependencyInjection\FileResource;
$t = new LimeTest(5);
// ->getResource()
$t->diag('->getResource()');
$file = sys_get_temp_dir().'/tmp.xml';
touch($file);
$resource = new FileResource($file);
$t->is($resource->getResource(), $file, '->getResource() returns the path to the resource');
// ->isUptodate()
$t->diag('->isUptodate()');
sleep(1);
$t->ok($resource->isUptodate(), '->isUptodate() returns true if the resource has not changed');
$t->ok($resource->isUptodate(time() + 10), '->isUptodate() returns true if the resource has not changed');
$t->ok(!$resource->isUptodate(time() - 86400), '->isUptodate() returns false if the resource has been updated');
unlink($file);
$resource = new FileResource('/____foo/foobar'.rand(1, 999999));
$t->ok(!$resource->isUptodate(), '->isUptodate() returns false if the resource does not exist');

View File

@ -24,20 +24,20 @@ require_once $fixturesPath.'/includes/ProjectExtension.php';
class ProjectLoader extends XmlFileLoader
{
public function loadFile($file)
public function parseFile($file)
{
return parent::loadFile($file);
return parent::parseFile($file);
}
}
// ->loadFile()
$t->diag('->loadFile()');
// ->load()
$t->diag('->load()');
$loader = new ProjectLoader($fixturesPath.'/ini');
try
{
$loader->loadFile('foo.xml');
$loader->load('foo.xml');
$t->fail('->load() throws an InvalidArgumentException if the loaded file does not exist');
}
catch (InvalidArgumentException $e)
@ -45,30 +45,33 @@ catch (InvalidArgumentException $e)
$t->pass('->load() throws an InvalidArgumentException if the loaded file does not exist');
}
// ->parseFile()
$t->diag('->parseFile()');
try
{
$loader->loadFile('parameters.ini');
$t->fail('->load() throws an InvalidArgumentException if the loaded file is not a valid XML file');
$loader->parseFile($fixturesPath.'/ini/parameters.ini');
$t->fail('->parseFile() throws an InvalidArgumentException if the loaded file is not a valid XML file');
}
catch (InvalidArgumentException $e)
{
$t->pass('->load() throws an InvalidArgumentException if the loaded file is not a valid XML file');
$t->pass('->parseFile() throws an InvalidArgumentException if the loaded file is not a valid XML file');
}
$loader = new ProjectLoader($fixturesPath.'/xml');
try
{
$loader->loadFile('nonvalid.xml');
$t->fail('->load() throws an InvalidArgumentException if the loaded file does not validate the XSD');
$loader->parseFile($fixturesPath.'/xml/nonvalid.xml');
$t->fail('->parseFile() throws an InvalidArgumentException if the loaded file does not validate the XSD');
}
catch (InvalidArgumentException $e)
{
$t->pass('->load() throws an InvalidArgumentException if the loaded file does not validate the XSD');
$t->pass('->parseFile() throws an InvalidArgumentException if the loaded file does not validate the XSD');
}
$xml = $loader->loadFile('services1.xml');
$t->is(get_class($xml), 'Symfony\\Components\\DependencyInjection\\SimpleXMLElement', '->loadFile() returns an SimpleXMLElement object');
$xml = $loader->parseFile($fixturesPath.'/xml/services1.xml');
$t->is(get_class($xml), 'Symfony\\Components\\DependencyInjection\\SimpleXMLElement', '->parseFile() returns an SimpleXMLElement object');
// ->load() # parameters
$t->diag('->load() # parameters');