vendor/doctrine-common/lib/Doctrine/Common/Annotations/CachedReader.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 /*
       
     3  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
     4  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
     5  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
     6  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
     7  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
     8  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
     9  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    10  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    11  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    12  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    13  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    14  *
       
    15  * This software consists of voluntary contributions made by many individuals
       
    16  * and is licensed under the LGPL. For more information, see
       
    17  * <http://www.doctrine-project.org>.
       
    18  */
       
    19 
       
    20 namespace Doctrine\Common\Annotations;
       
    21 
       
    22 use Doctrine\Common\Cache\Cache;
       
    23 
       
    24 /**
       
    25  * A cache aware annotation reader.
       
    26  *
       
    27  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
       
    28  * @author Benjamin Eberlei <kontakt@beberlei.de>
       
    29  */
       
    30 final class CachedReader implements Reader
       
    31 {
       
    32     private static $CACHE_SALT = '@[Annot]';
       
    33 
       
    34     /**
       
    35      * @var Reader
       
    36      */
       
    37     private $delegate;
       
    38 
       
    39     /**
       
    40      * @var Cache
       
    41      */
       
    42     private $cache;
       
    43 
       
    44     /**
       
    45      * @var boolean
       
    46      */
       
    47     private $debug;
       
    48 
       
    49     /**
       
    50      * @var array
       
    51      */
       
    52     private $loadedAnnotations;
       
    53 
       
    54     /**
       
    55      * @param Reader $reader
       
    56      * @param Cache $cache
       
    57      */
       
    58     public function __construct(Reader $reader, Cache $cache, $debug = false)
       
    59     {
       
    60         $this->delegate = $reader;
       
    61         $this->cache = $cache;
       
    62         $this->debug = $debug;
       
    63     }
       
    64 
       
    65     public function getClassAnnotations(\ReflectionClass $class)
       
    66     {
       
    67         $cacheKey = $class->getName() . self::$CACHE_SALT;
       
    68 
       
    69         if (isset($this->loadedAnnotations[$cacheKey])) {
       
    70             return $this->loadedAnnotations[$cacheKey];
       
    71         }
       
    72 
       
    73         // Attempt to grab data from cache
       
    74         if (($data = $this->cache->fetch($cacheKey)) !== false) {
       
    75             if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
       
    76                 return $data;
       
    77             }
       
    78         }
       
    79 
       
    80         $annots = $this->delegate->getClassAnnotations($class);
       
    81         $this->cache->save($cacheKey, $annots);
       
    82         $this->cache->save('[C]'.$cacheKey, time());
       
    83 
       
    84         return $this->loadedAnnotations[$cacheKey] = $annots;
       
    85     }
       
    86 
       
    87     public function getClassAnnotation(\ReflectionClass $class, $annotationName)
       
    88     {
       
    89         foreach ($this->getClassAnnotations($class) as $annot) {
       
    90             if ($annot instanceof $annotationName) {
       
    91                 return $annot;
       
    92             }
       
    93         }
       
    94 
       
    95         return null;
       
    96     }
       
    97 
       
    98     public function getPropertyAnnotations(\ReflectionProperty $property)
       
    99     {
       
   100         $class = $property->getDeclaringClass();
       
   101         $cacheKey = $class->getName().'$'.$property->getName().self::$CACHE_SALT;
       
   102 
       
   103         if (isset($this->loadedAnnotations[$cacheKey])) {
       
   104             return $this->loadedAnnotations[$cacheKey];
       
   105         }
       
   106 
       
   107         // Attempt to grab data from cache
       
   108         if (($data = $this->cache->fetch($cacheKey)) !== false) {
       
   109             if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
       
   110                 return $data;
       
   111             }
       
   112         }
       
   113 
       
   114         $annots = $this->delegate->getPropertyAnnotations($property);
       
   115         $this->cache->save($cacheKey, $annots);
       
   116         $this->cache->save('[C]'.$cacheKey, time());
       
   117 
       
   118         return $this->loadedAnnotations[$cacheKey] = $annots;
       
   119     }
       
   120 
       
   121     public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
       
   122     {
       
   123         foreach ($this->getPropertyAnnotations($property) as $annot) {
       
   124             if ($annot instanceof $annotationName) {
       
   125                 return $annot;
       
   126             }
       
   127         }
       
   128 
       
   129         return null;
       
   130     }
       
   131 
       
   132     public function getMethodAnnotations(\ReflectionMethod $method)
       
   133     {
       
   134         $class = $method->getDeclaringClass();
       
   135         $cacheKey = $class->getName().'#'.$method->getName().self::$CACHE_SALT;
       
   136 
       
   137         if (isset($this->loadedAnnotations[$cacheKey])) {
       
   138             return $this->loadedAnnotations[$cacheKey];
       
   139         }
       
   140 
       
   141        // Attempt to grab data from cache
       
   142         if (($data = $this->cache->fetch($cacheKey)) !== false) {
       
   143             if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
       
   144                 return $data;
       
   145             }
       
   146         }
       
   147 
       
   148         $annots = $this->delegate->getMethodAnnotations($method);
       
   149         $this->cache->save($cacheKey, $annots);
       
   150         $this->cache->save('[C]'.$cacheKey, time());
       
   151 
       
   152         return $this->loadedAnnotations[$cacheKey] = $annots;
       
   153     }
       
   154 
       
   155     public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
       
   156     {
       
   157         foreach ($this->getMethodAnnotations($method) as $annot) {
       
   158             if ($annot instanceof $annotationName) {
       
   159                 return $annot;
       
   160             }
       
   161         }
       
   162 
       
   163         return null;
       
   164     }
       
   165 
       
   166     public function clearLoadedAnnotations()
       
   167     {
       
   168         $this->loadedAnnotations = array();
       
   169     }
       
   170 
       
   171     private function isCacheFresh($cacheKey, \ReflectionClass $class)
       
   172     {
       
   173         if (false === $filename = $class->getFilename()) {
       
   174             return true;
       
   175         }
       
   176 
       
   177         return $this->cache->fetch('[C]'.$cacheKey) >= filemtime($filename);
       
   178     }
       
   179 }