diff --git a/lib/Doctrine/Locator.php b/lib/Doctrine/Locator.php new file mode 100644 index 000000000..77c55dbba --- /dev/null +++ b/lib/Doctrine/Locator.php @@ -0,0 +1,182 @@ +. + */ + +/** + * Doctrine_Locator + * + * @package Doctrine + * @subpackage Doctrine_Locator + * @category Locator + * @license http://www.gnu.org/licenses/lgpl.txt LGPL + * @link http://www.phpdoctrine.net + * @author Janne Vanhala + * @author Konsta Vesterinen + * @author Eevert Saukkokoski + * @version $Revision$ + * @since 1.0 + */ +class Doctrine_Locator implements Countable, IteratorAggregate +{ + /** + * @var array $_resources an array of bound resources + */ + protected $_resources = array(); + /** + * @var string $_classPrefix the default class prefix + */ + protected $_classPrefix = 'Sensei_'; + /** + * @var array $_instances a pool of this object's instances + */ + protected static $_instances = array(); + /** + * Constructor. Provide an array of resources to set initial contents. + * + * @param array + * @return void + */ + public function __construct(array $defaults = null) + { + if (null !== $defaults) { + foreach ($defaults as $name => $resource) { + if ($resource instanceof Doctrine_Locator_Injectable) { + $resource->setLocator($this); + } + $this->_resources[$name] = $resource; + } + } + self::$_instances[] = $this; + } + /** + * instance + * + * @return Sensei_Locator + */ + public static function instance() + { + if (empty(self::$_instances)) { + $obj = new Sensei_Locator(); + } + return current(self::$_instances); + } + /** + * setClassPrefix + * + * @param string $prefix + */ + public function setClassPrefix($prefix) + { + $this->_classPrefix = $prefix; + } + /** + * getClassPrefix + * + * @return string + */ + public function getClassPrefix() + { + return $this->_classPrefix; + } + /** + * contains + * checks if a resource exists under the given name + * + * @return boolean whether or not given resource name exists + */ + public function contains($name) + { + return isset($this->_resources[$name]); + } + /** + * bind + * binds a resource to a name + * + * @param string $name the name of the resource to bind + * @param mixed $value the value of the resource + * @return Sensei_Locator this object + */ + public function bind($name, $value) + { + $this->_resources[$name] = $value; + + return $this; + } + /** + * locate + * locates a resource by given name and returns it + * + * @throws Doctrine_Locator_Exception if the resource could not be found + * @param string $name the name of the resource + * @return mixed the located resource + */ + public function locate($name) + { + if (isset($this->_resources[$name])) { + return $this->_resources[$name]; + } else { + $className = $name; + + if ( ! class_exists($className)) { + $className = $this->_classPrefix . str_replace('.', '_', $name); + + if ( ! class_exists($className)) { + throw new Doctrine_Locator_Exception("Couldn't locate resource " . $className); + } + } + + $this->_resources[$name] = new $className(); + + if ($this->_resources[$name] instanceof Doctrine_Locator_Injectable) { + $this->_resources[$name]->setLocator($this); + } + + return $this->_resources[$name]; + } + + throw new Doctrine_Locator_Exception("Couldn't locate resource " . $name); + } + + /** + * count + * returns the number of bound resources associated with + * this object + * + * @see Countable interface + * @return integer the number of resources + */ + public function count() + { + return count($this->_resources); + } + + /** + * getIterator + * returns an ArrayIterator that iterates through all + * bound resources + * + * @return ArrayIterator an iterator for iterating through + * all bound resources + */ + public function getIterator() + { + return new ArrayIterator($this->_resources); + } +} diff --git a/lib/Doctrine/Locator/Exception.php b/lib/Doctrine/Locator/Exception.php new file mode 100644 index 000000000..6aa79402b --- /dev/null +++ b/lib/Doctrine/Locator/Exception.php @@ -0,0 +1,36 @@ +. + */ + +/** + * Doctrine_Locator_Exception + * + * @package Doctrine + * @subpackage Doctrine_Locator + * @category Locator + * @license http://www.gnu.org/licenses/lgpl.txt LGPL + * @link http://www.phpdoctrine.net + * @author Janne Vanhala + * @author Konsta Vesterinen + * @version $Revision$ + * @since 1.0 + */ +class Doctrine_Locator_Exception extends Doctrine_Exception +{ } diff --git a/lib/Doctrine/Locator/Injectable.php b/lib/Doctrine/Locator/Injectable.php new file mode 100644 index 000000000..fb78db082 --- /dev/null +++ b/lib/Doctrine/Locator/Injectable.php @@ -0,0 +1,118 @@ +. + */ + +/** + * Doctrine_Locator_Injectable + * + * @package Doctrine + * @subpackage Doctrine_Locator + * @category Locator + * @license http://www.gnu.org/licenses/lgpl.txt LGPL + * @link http://www.phpdoctrine.net + * @author Janne Vanhala + * @author Konsta Vesterinen + * @author Eevert Saukkokoski + * @version $Revision$ + * @since 1.0 + */ +class Doctrine_Locator_Injectable +{ + /** + * @var Doctrine_Locator the locator object + */ + protected $_locator; + /** + * @var array an array of bound resources + */ + protected $_resources = array(); + + /** + * setLocator + * this method can be used for setting the locator object locally + * + * @param Doctrine_Locator the locator object + * @return Doctrine_Locator_Injectable this instance + */ + public function setLocator(Doctrine_Locator $locator) + { + $this->_locator = $locator; + return $this; + } + /** + * getLocator + * returns the locator associated with this object + * + * if there are no locator locally associated then + * this method tries to fetch the current global locator + * + * @return Doctrine_Locator + */ + public function getLocator() + { + if ( ! isset($this->_locator)) { + $this->_locator = Doctrine_Locator::instance(); + + } + return $this->_locator; + } + /** + * locate + * locates a resource by given name and returns it + * + * if the resource cannot be found locally this method tries + * to use the global locator for finding the resource + * + * @see Doctrine_Locator::locate() + * @throws Doctrine_Locator_Exception if the resource could not be found + * @param string $name the name of the resource + * @return mixed the located resource + */ + public function locate($name) + { + if (isset($this->_resources[$name])) { + if (is_object($this->_resources[$name])) { + return $this->_resources[$name]; + } else { + // get the name of the concrete implementation + $concreteImpl = $this->_resources[$name]; + + return $this->getLocator()->get($concreteImpl); + } + } else { + return $this->getLocator()->get($name); + } + } + /** + * bind + * binds a resource to a name + * + * @param string $name the name of the resource to bind + * @param mixed $value the value of the resource + * @return Doctrine_Locator this object + */ + public function bind($name, $resource) + { + $this->_resources[$name] = $resource; + + return $this; + } + +}