[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/celerity/ -> CelerityResourceMap.php (source)

   1  <?php
   2  
   3  /**
   4   * Interface to the static resource map, which is a graph of available
   5   * resources, resource dependencies, and packaging information. You generally do
   6   * not need to invoke it directly; instead, you call higher-level Celerity APIs
   7   * and it uses the resource map to satisfy your requests.
   8   */
   9  final class CelerityResourceMap {
  10  
  11    private static $instances = array();
  12  
  13    private $resources;
  14    private $symbolMap;
  15    private $requiresMap;
  16    private $packageMap;
  17    private $nameMap;
  18    private $hashMap;
  19  
  20    public function __construct(CelerityResources $resources) {
  21      $this->resources = $resources;
  22  
  23      $map = $resources->loadMap();
  24      $this->symbolMap = idx($map, 'symbols', array());
  25      $this->requiresMap = idx($map, 'requires', array());
  26      $this->packageMap = idx($map, 'packages', array());
  27      $this->nameMap = idx($map, 'names', array());
  28  
  29      // We derive these reverse maps at runtime.
  30  
  31      $this->hashMap = array_flip($this->nameMap);
  32      $this->componentMap = array();
  33      foreach ($this->packageMap as $package_name => $symbols) {
  34        foreach ($symbols as $symbol) {
  35          $this->componentMap[$symbol] = $package_name;
  36        }
  37      }
  38    }
  39  
  40    public static function getNamedInstance($name) {
  41      if (empty(self::$instances[$name])) {
  42        $resources_list = CelerityPhysicalResources::getAll();
  43        if (empty($resources_list[$name])) {
  44          throw new Exception(
  45            pht(
  46              'No resource source exists with name "%s"!', $name));
  47        }
  48  
  49        $instance = new CelerityResourceMap($resources_list[$name]);
  50        self::$instances[$name] = $instance;
  51      }
  52  
  53      return self::$instances[$name];
  54    }
  55  
  56    public function getNameMap() {
  57      return $this->nameMap;
  58    }
  59  
  60    public function getSymbolMap() {
  61      return $this->symbolMap;
  62    }
  63  
  64    public function getRequiresMap() {
  65      return $this->requiresMap;
  66    }
  67  
  68    public function getPackageMap() {
  69      return $this->packageMap;
  70    }
  71  
  72    public function getPackagedNamesForSymbols(array $symbols) {
  73      $resolved = $this->resolveResources($symbols);
  74      return $this->packageResources($resolved);
  75    }
  76  
  77    private function resolveResources(array $symbols) {
  78      $map = array();
  79      foreach ($symbols as $symbol) {
  80        if (!empty($map[$symbol])) {
  81          continue;
  82        }
  83        $this->resolveResource($map, $symbol);
  84      }
  85  
  86      return $map;
  87    }
  88  
  89    private function resolveResource(array &$map, $symbol) {
  90      if (empty($this->symbolMap[$symbol])) {
  91        throw new Exception(
  92          pht(
  93            'Attempting to resolve unknown resource, "%s".',
  94            $symbol));
  95      }
  96  
  97      $hash = $this->symbolMap[$symbol];
  98  
  99      $map[$symbol] = $hash;
 100  
 101      if (isset($this->requiresMap[$hash])) {
 102        $requires = $this->requiresMap[$hash];
 103      } else {
 104        $requires = array();
 105      }
 106  
 107      foreach ($requires as $required_symbol) {
 108        if (!empty($map[$required_symbol])) {
 109          continue;
 110        }
 111        $this->resolveResource($map, $required_symbol);
 112      }
 113    }
 114  
 115    private function packageResources(array $resolved_map) {
 116      $packaged = array();
 117      $handled = array();
 118      foreach ($resolved_map as $symbol => $hash) {
 119        if (isset($handled[$symbol])) {
 120          continue;
 121        }
 122  
 123        if (empty($this->componentMap[$symbol])) {
 124          $packaged[] = $this->hashMap[$hash];
 125        } else {
 126          $package_name = $this->componentMap[$symbol];
 127          $packaged[] = $package_name;
 128  
 129          $package_symbols = $this->packageMap[$package_name];
 130          foreach ($package_symbols as $package_symbol) {
 131            $handled[$package_symbol] = true;
 132          }
 133        }
 134      }
 135  
 136      return $packaged;
 137    }
 138  
 139    public function getResourceDataForName($resource_name) {
 140      return $this->resources->getResourceData($resource_name);
 141    }
 142  
 143    public function getResourceNamesForPackageName($package_name) {
 144      $package_symbols = idx($this->packageMap, $package_name);
 145      if (!$package_symbols) {
 146        return null;
 147      }
 148  
 149      $resource_names = array();
 150      foreach ($package_symbols as $symbol) {
 151        $resource_names[] = $this->hashMap[$this->symbolMap[$symbol]];
 152      }
 153  
 154      return $resource_names;
 155    }
 156  
 157  
 158    /**
 159     * Get the epoch timestamp of the last modification time of a symbol.
 160     *
 161     * @param string Resource symbol to lookup.
 162     * @return int Epoch timestamp of last resource modification.
 163     */
 164    public function getModifiedTimeForName($name) {
 165      if ($this->isPackageResource($name)) {
 166        $names = array();
 167        foreach ($this->packageMap[$name] as $symbol) {
 168          $names[] = $this->getResourceNameForSymbol($symbol);
 169        }
 170      } else {
 171        $names = array($name);
 172      }
 173  
 174      $mtime = 0;
 175      foreach ($names as $name) {
 176        $mtime = max($mtime, $this->resources->getResourceModifiedTime($name));
 177      }
 178  
 179      return $mtime;
 180    }
 181  
 182  
 183    /**
 184     * Return the absolute URI for the resource associated with a symbol. This
 185     * method is fairly low-level and ignores packaging.
 186     *
 187     * @param string Resource symbol to lookup.
 188     * @return string|null Resource URI, or null if the symbol is unknown.
 189     */
 190    public function getURIForSymbol($symbol) {
 191      $hash = idx($this->symbolMap, $symbol);
 192      return $this->getURIForHash($hash);
 193    }
 194  
 195  
 196    /**
 197     * Return the absolute URI for the resource associated with a resource name.
 198     * This method is fairly low-level and ignores packaging.
 199     *
 200     * @param string Resource name to lookup.
 201     * @return string|null  Resource URI, or null if the name is unknown.
 202     */
 203    public function getURIForName($name) {
 204      $hash = idx($this->nameMap, $name);
 205      return $this->getURIForHash($hash);
 206    }
 207  
 208  
 209    /**
 210     * Return the absolute URI for a resource, identified by hash.
 211     * This method is fairly low-level and ignores packaging.
 212     *
 213     * @param string Resource hash to lookup.
 214     * @return string|null Resource URI, or null if the hash is unknown.
 215     */
 216    private function getURIForHash($hash) {
 217      if ($hash === null) {
 218        return null;
 219      }
 220      return $this->resources->getResourceURI($hash, $this->hashMap[$hash]);
 221    }
 222  
 223  
 224    /**
 225     * Return the resource symbols required by a named resource.
 226     *
 227     * @param string Resource name to lookup.
 228     * @return list<string>|null  List of required symbols, or null if the name
 229     *                            is unknown.
 230     */
 231    public function getRequiredSymbolsForName($name) {
 232      $hash = idx($this->nameMap, $name);
 233      if ($hash === null) {
 234        return null;
 235      }
 236      return idx($this->requiresMap, $hash, array());
 237    }
 238  
 239  
 240    /**
 241     * Return the resource name for a given symbol.
 242     *
 243     * @param string Resource symbol to lookup.
 244     * @return string|null Resource name, or null if the symbol is unknown.
 245     */
 246    public function getResourceNameForSymbol($symbol) {
 247      $hash = idx($this->symbolMap, $symbol);
 248      return idx($this->hashMap, $hash);
 249    }
 250  
 251    public function isPackageResource($name) {
 252      return isset($this->packageMap[$name]);
 253    }
 254  
 255    public function getResourceTypeForName($name) {
 256      return $this->resources->getResourceType($name);
 257    }
 258  
 259  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1