2011-01-25 18:59:31 +01:00
|
|
|
<?php
|
|
|
|
|
2011-07-04 20:22:42 +02:00
|
|
|
/**
|
|
|
|
* Interface to the static resource map, which is a graph of available
|
|
|
|
* resources, resource dependencies, and packaging information. You generally do
|
|
|
|
* not need to invoke it directly; instead, you call higher-level Celerity APIs
|
|
|
|
* and it uses the resource map to satisfy your requests.
|
|
|
|
*/
|
2011-01-25 18:59:31 +01:00
|
|
|
final class CelerityResourceMap {
|
|
|
|
|
2014-01-01 16:46:18 +01:00
|
|
|
private static $instances = array();
|
2014-01-01 03:04:25 +01:00
|
|
|
|
|
|
|
private $resources;
|
|
|
|
private $symbolMap;
|
|
|
|
private $requiresMap;
|
2011-01-30 01:10:05 +01:00
|
|
|
private $packageMap;
|
2014-01-01 03:04:25 +01:00
|
|
|
private $nameMap;
|
|
|
|
private $hashMap;
|
2011-01-25 18:59:31 +01:00
|
|
|
|
2014-01-01 03:04:25 +01:00
|
|
|
public function __construct(CelerityResources $resources) {
|
|
|
|
$this->resources = $resources;
|
|
|
|
|
|
|
|
$map = $resources->loadMap();
|
|
|
|
$this->symbolMap = idx($map, 'symbols', array());
|
|
|
|
$this->requiresMap = idx($map, 'requires', array());
|
|
|
|
$this->packageMap = idx($map, 'packages', array());
|
|
|
|
$this->nameMap = idx($map, 'names', array());
|
|
|
|
|
|
|
|
// We derive these reverse maps at runtime.
|
|
|
|
|
|
|
|
$this->hashMap = array_flip($this->nameMap);
|
|
|
|
$this->componentMap = array();
|
|
|
|
foreach ($this->packageMap as $package_name => $symbols) {
|
|
|
|
foreach ($symbols as $symbol) {
|
|
|
|
$this->componentMap[$symbol] = $package_name;
|
2011-01-25 18:59:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-01 16:46:18 +01:00
|
|
|
public static function getNamedInstance($name) {
|
|
|
|
if (empty(self::$instances[$name])) {
|
|
|
|
$resources_list = CelerityPhysicalResources::getAll();
|
|
|
|
if (empty($resources_list[$name])) {
|
|
|
|
throw new Exception(
|
|
|
|
pht(
|
2015-05-22 09:27:56 +02:00
|
|
|
'No resource source exists with name "%s"!',
|
|
|
|
$name));
|
2014-01-01 16:46:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$instance = new CelerityResourceMap($resources_list[$name]);
|
|
|
|
self::$instances[$name] = $instance;
|
2014-01-01 03:04:25 +01:00
|
|
|
}
|
2014-01-01 16:46:18 +01:00
|
|
|
|
|
|
|
return self::$instances[$name];
|
2011-01-25 18:59:31 +01:00
|
|
|
}
|
|
|
|
|
2014-09-22 10:50:20 +02:00
|
|
|
public function getNameMap() {
|
|
|
|
return $this->nameMap;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getSymbolMap() {
|
|
|
|
return $this->symbolMap;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRequiresMap() {
|
|
|
|
return $this->requiresMap;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getPackageMap() {
|
|
|
|
return $this->packageMap;
|
|
|
|
}
|
|
|
|
|
2014-01-01 03:03:24 +01:00
|
|
|
public function getPackagedNamesForSymbols(array $symbols) {
|
|
|
|
$resolved = $this->resolveResources($symbols);
|
|
|
|
return $this->packageResources($resolved);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function resolveResources(array $symbols) {
|
2011-01-25 18:59:31 +01:00
|
|
|
$map = array();
|
|
|
|
foreach ($symbols as $symbol) {
|
|
|
|
if (!empty($map[$symbol])) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$this->resolveResource($map, $symbol);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $map;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function resolveResource(array &$map, $symbol) {
|
2014-01-01 03:04:25 +01:00
|
|
|
if (empty($this->symbolMap[$symbol])) {
|
2011-01-25 18:59:31 +01:00
|
|
|
throw new Exception(
|
2014-01-01 03:04:25 +01:00
|
|
|
pht(
|
|
|
|
'Attempting to resolve unknown resource, "%s".',
|
|
|
|
$symbol));
|
|
|
|
}
|
|
|
|
|
|
|
|
$hash = $this->symbolMap[$symbol];
|
|
|
|
|
|
|
|
$map[$symbol] = $hash;
|
|
|
|
|
|
|
|
if (isset($this->requiresMap[$hash])) {
|
|
|
|
$requires = $this->requiresMap[$hash];
|
|
|
|
} else {
|
|
|
|
$requires = array();
|
2011-01-25 18:59:31 +01:00
|
|
|
}
|
|
|
|
|
2014-01-01 03:04:25 +01:00
|
|
|
foreach ($requires as $required_symbol) {
|
|
|
|
if (!empty($map[$required_symbol])) {
|
2011-01-25 18:59:31 +01:00
|
|
|
continue;
|
|
|
|
}
|
2014-01-01 03:04:25 +01:00
|
|
|
$this->resolveResource($map, $required_symbol);
|
2011-01-25 18:59:31 +01:00
|
|
|
}
|
2011-01-30 01:10:05 +01:00
|
|
|
}
|
2011-01-31 20:55:26 +01:00
|
|
|
|
2014-01-01 03:03:24 +01:00
|
|
|
private function packageResources(array $resolved_map) {
|
2011-01-30 01:10:05 +01:00
|
|
|
$packaged = array();
|
|
|
|
$handled = array();
|
2014-01-01 03:04:25 +01:00
|
|
|
foreach ($resolved_map as $symbol => $hash) {
|
2011-01-30 01:10:05 +01:00
|
|
|
if (isset($handled[$symbol])) {
|
|
|
|
continue;
|
|
|
|
}
|
2014-01-01 03:03:24 +01:00
|
|
|
|
2014-01-01 03:04:25 +01:00
|
|
|
if (empty($this->componentMap[$symbol])) {
|
|
|
|
$packaged[] = $this->hashMap[$hash];
|
2014-01-01 03:03:24 +01:00
|
|
|
} else {
|
2014-01-01 03:04:25 +01:00
|
|
|
$package_name = $this->componentMap[$symbol];
|
|
|
|
$packaged[] = $package_name;
|
|
|
|
|
|
|
|
$package_symbols = $this->packageMap[$package_name];
|
|
|
|
foreach ($package_symbols as $package_symbol) {
|
|
|
|
$handled[$package_symbol] = true;
|
|
|
|
}
|
2014-01-01 03:03:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-01 03:04:25 +01:00
|
|
|
return $packaged;
|
2011-01-30 01:10:05 +01:00
|
|
|
}
|
2011-01-31 20:55:26 +01:00
|
|
|
|
2014-01-01 03:03:17 +01:00
|
|
|
public function getResourceDataForName($resource_name) {
|
2014-01-01 03:04:25 +01:00
|
|
|
return $this->resources->getResourceData($resource_name);
|
2014-01-01 03:03:17 +01:00
|
|
|
}
|
|
|
|
|
2014-01-01 03:04:25 +01:00
|
|
|
public function getResourceNamesForPackageName($package_name) {
|
|
|
|
$package_symbols = idx($this->packageMap, $package_name);
|
|
|
|
if (!$package_symbols) {
|
2011-01-30 01:10:05 +01:00
|
|
|
return null;
|
|
|
|
}
|
2011-01-31 20:55:26 +01:00
|
|
|
|
2014-01-01 03:04:25 +01:00
|
|
|
$resource_names = array();
|
|
|
|
foreach ($package_symbols as $symbol) {
|
|
|
|
$resource_names[] = $this->hashMap[$this->symbolMap[$symbol]];
|
2011-01-30 01:10:05 +01:00
|
|
|
}
|
2011-01-31 20:55:26 +01:00
|
|
|
|
2014-01-01 03:04:25 +01:00
|
|
|
return $resource_names;
|
Bring Javelin into Phabricator via git submodule, not copy-and-paste
Summary:
Javelin is currently embedded in Phabricator via copy-and-paste of prebuilt
packages. This is not so great.
Pull it in as a submodule instead and make all the Phabriator resources declare
proper dependency trees. Add Javelin linting.
Test Plan:
I tried to run through pretty much all the JS functionality on the site. This is
still a high-risk change, but I did a pretty thorough test
Differential: inline comments, revealing diffs, list tokenizers, comment
preview, editing/deleting comments, add review action.
Maniphest: list tokenizer, comment actions
Herald: rule editing, tokenizers, add/remove rows
Reviewed By: tomo
Reviewers: aran, tomo, mroch, jungejason, tuomaspelkonen
CC: aran, tomo, epriestley
Differential Revision: 223
2011-05-04 00:11:55 +02:00
|
|
|
}
|
|
|
|
|
2014-01-01 03:02:56 +01:00
|
|
|
|
2014-01-01 03:03:09 +01:00
|
|
|
/**
|
|
|
|
* Get the epoch timestamp of the last modification time of a symbol.
|
|
|
|
*
|
|
|
|
* @param string Resource symbol to lookup.
|
|
|
|
* @return int Epoch timestamp of last resource modification.
|
|
|
|
*/
|
2014-01-01 03:03:24 +01:00
|
|
|
public function getModifiedTimeForName($name) {
|
2014-01-01 03:04:25 +01:00
|
|
|
if ($this->isPackageResource($name)) {
|
|
|
|
$names = array();
|
|
|
|
foreach ($this->packageMap[$name] as $symbol) {
|
|
|
|
$names[] = $this->getResourceNameForSymbol($symbol);
|
2014-01-01 03:03:24 +01:00
|
|
|
}
|
2014-01-01 03:04:25 +01:00
|
|
|
} else {
|
|
|
|
$names = array($name);
|
2014-01-01 03:03:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$mtime = 0;
|
2014-01-01 03:04:25 +01:00
|
|
|
foreach ($names as $name) {
|
|
|
|
$mtime = max($mtime, $this->resources->getResourceModifiedTime($name));
|
2014-01-01 03:03:09 +01:00
|
|
|
}
|
2014-01-01 03:03:24 +01:00
|
|
|
|
|
|
|
return $mtime;
|
2014-01-01 03:03:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2014-01-01 03:03:24 +01:00
|
|
|
* Return the absolute URI for the resource associated with a symbol. This
|
|
|
|
* method is fairly low-level and ignores packaging.
|
2014-01-01 03:03:09 +01:00
|
|
|
*
|
|
|
|
* @param string Resource symbol to lookup.
|
2014-01-01 03:04:25 +01:00
|
|
|
* @return string|null Resource URI, or null if the symbol is unknown.
|
2014-01-01 03:03:09 +01:00
|
|
|
*/
|
2014-01-01 03:03:24 +01:00
|
|
|
public function getURIForSymbol($symbol) {
|
2014-01-01 03:04:25 +01:00
|
|
|
$hash = idx($this->symbolMap, $symbol);
|
|
|
|
return $this->getURIForHash($hash);
|
2014-01-01 03:03:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-01 03:02:56 +01:00
|
|
|
/**
|
2014-01-01 03:03:24 +01:00
|
|
|
* Return the absolute URI for the resource associated with a resource name.
|
|
|
|
* This method is fairly low-level and ignores packaging.
|
2014-01-01 03:02:56 +01:00
|
|
|
*
|
|
|
|
* @param string Resource name to lookup.
|
2014-01-01 03:04:25 +01:00
|
|
|
* @return string|null Resource URI, or null if the name is unknown.
|
2014-01-01 03:02:56 +01:00
|
|
|
*/
|
2014-01-01 03:03:24 +01:00
|
|
|
public function getURIForName($name) {
|
2014-01-01 03:04:25 +01:00
|
|
|
$hash = idx($this->nameMap, $name);
|
|
|
|
return $this->getURIForHash($hash);
|
|
|
|
}
|
2014-01-01 03:03:24 +01:00
|
|
|
|
|
|
|
|
2014-01-01 03:04:25 +01:00
|
|
|
/**
|
|
|
|
* Return the absolute URI for a resource, identified by hash.
|
|
|
|
* This method is fairly low-level and ignores packaging.
|
|
|
|
*
|
|
|
|
* @param string Resource hash to lookup.
|
|
|
|
* @return string|null Resource URI, or null if the hash is unknown.
|
|
|
|
*/
|
|
|
|
private function getURIForHash($hash) {
|
|
|
|
if ($hash === null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return $this->resources->getResourceURI($hash, $this->hashMap[$hash]);
|
2014-01-01 03:02:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the resource symbols required by a named resource.
|
|
|
|
*
|
|
|
|
* @param string Resource name to lookup.
|
2014-01-01 03:03:09 +01:00
|
|
|
* @return list<string>|null List of required symbols, or null if the name
|
|
|
|
* is unknown.
|
2014-01-01 03:02:56 +01:00
|
|
|
*/
|
|
|
|
public function getRequiredSymbolsForName($name) {
|
2014-01-13 21:23:20 +01:00
|
|
|
$hash = idx($this->nameMap, $name);
|
2014-01-01 03:04:25 +01:00
|
|
|
if ($hash === null) {
|
|
|
|
return null;
|
2014-01-01 03:02:56 +01:00
|
|
|
}
|
2014-01-01 03:04:25 +01:00
|
|
|
return idx($this->requiresMap, $hash, array());
|
2014-01-01 03:02:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-01 03:03:09 +01:00
|
|
|
/**
|
|
|
|
* Return the resource name for a given symbol.
|
|
|
|
*
|
|
|
|
* @param string Resource symbol to lookup.
|
|
|
|
* @return string|null Resource name, or null if the symbol is unknown.
|
|
|
|
*/
|
|
|
|
public function getResourceNameForSymbol($symbol) {
|
2014-01-01 03:04:25 +01:00
|
|
|
$hash = idx($this->symbolMap, $symbol);
|
|
|
|
return idx($this->hashMap, $hash);
|
2014-01-01 03:03:09 +01:00
|
|
|
}
|
|
|
|
|
2014-01-01 03:04:25 +01:00
|
|
|
public function isPackageResource($name) {
|
|
|
|
return isset($this->packageMap[$name]);
|
|
|
|
}
|
2014-01-01 03:03:09 +01:00
|
|
|
|
2014-01-02 20:59:35 +01:00
|
|
|
public function getResourceTypeForName($name) {
|
|
|
|
return $this->resources->getResourceType($name);
|
|
|
|
}
|
|
|
|
|
2011-01-25 18:59:31 +01:00
|
|
|
}
|