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