ex
Fork of mbed-os-example-mbed5-blinky by
dumi_doc-master/schema/vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php@44:c1d8923072ba, 2017-07-18 (annotated)
- Committer:
- TMBOY
- Date:
- Tue Jul 18 16:27:22 2017 +0800
- Revision:
- 44:c1d8923072ba
?
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| TMBOY | 44:c1d8923072ba | 1 | <?php |
| TMBOY | 44:c1d8923072ba | 2 | |
| TMBOY | 44:c1d8923072ba | 3 | /* |
| TMBOY | 44:c1d8923072ba | 4 | * This file is part of the JsonSchema package. |
| TMBOY | 44:c1d8923072ba | 5 | * |
| TMBOY | 44:c1d8923072ba | 6 | * For the full copyright and license information, please view the LICENSE |
| TMBOY | 44:c1d8923072ba | 7 | * file that was distributed with this source code. |
| TMBOY | 44:c1d8923072ba | 8 | */ |
| TMBOY | 44:c1d8923072ba | 9 | |
| TMBOY | 44:c1d8923072ba | 10 | namespace JsonSchema\Uri; |
| TMBOY | 44:c1d8923072ba | 11 | |
| TMBOY | 44:c1d8923072ba | 12 | use JsonSchema\Uri\Retrievers\FileGetContents; |
| TMBOY | 44:c1d8923072ba | 13 | use JsonSchema\Uri\Retrievers\UriRetrieverInterface; |
| TMBOY | 44:c1d8923072ba | 14 | use JsonSchema\UriRetrieverInterface as BaseUriRetrieverInterface; |
| TMBOY | 44:c1d8923072ba | 15 | use JsonSchema\Validator; |
| TMBOY | 44:c1d8923072ba | 16 | use JsonSchema\Exception\InvalidSchemaMediaTypeException; |
| TMBOY | 44:c1d8923072ba | 17 | use JsonSchema\Exception\JsonDecodingException; |
| TMBOY | 44:c1d8923072ba | 18 | use JsonSchema\Exception\ResourceNotFoundException; |
| TMBOY | 44:c1d8923072ba | 19 | |
| TMBOY | 44:c1d8923072ba | 20 | /** |
| TMBOY | 44:c1d8923072ba | 21 | * Retrieves JSON Schema URIs |
| TMBOY | 44:c1d8923072ba | 22 | * |
| TMBOY | 44:c1d8923072ba | 23 | * @author Tyler Akins <fidian@rumkin.com> |
| TMBOY | 44:c1d8923072ba | 24 | */ |
| TMBOY | 44:c1d8923072ba | 25 | class UriRetriever implements BaseUriRetrieverInterface |
| TMBOY | 44:c1d8923072ba | 26 | { |
| TMBOY | 44:c1d8923072ba | 27 | /** |
| TMBOY | 44:c1d8923072ba | 28 | * @var null|UriRetrieverInterface |
| TMBOY | 44:c1d8923072ba | 29 | */ |
| TMBOY | 44:c1d8923072ba | 30 | protected $uriRetriever = null; |
| TMBOY | 44:c1d8923072ba | 31 | |
| TMBOY | 44:c1d8923072ba | 32 | /** |
| TMBOY | 44:c1d8923072ba | 33 | * @var array|object[] |
| TMBOY | 44:c1d8923072ba | 34 | * @see loadSchema |
| TMBOY | 44:c1d8923072ba | 35 | */ |
| TMBOY | 44:c1d8923072ba | 36 | private $schemaCache = array(); |
| TMBOY | 44:c1d8923072ba | 37 | |
| TMBOY | 44:c1d8923072ba | 38 | /** |
| TMBOY | 44:c1d8923072ba | 39 | * Guarantee the correct media type was encountered |
| TMBOY | 44:c1d8923072ba | 40 | * |
| TMBOY | 44:c1d8923072ba | 41 | * @param UriRetrieverInterface $uriRetriever |
| TMBOY | 44:c1d8923072ba | 42 | * @param string $uri |
| TMBOY | 44:c1d8923072ba | 43 | * @return bool|void |
| TMBOY | 44:c1d8923072ba | 44 | */ |
| TMBOY | 44:c1d8923072ba | 45 | public function confirmMediaType($uriRetriever, $uri) |
| TMBOY | 44:c1d8923072ba | 46 | { |
| TMBOY | 44:c1d8923072ba | 47 | $contentType = $uriRetriever->getContentType(); |
| TMBOY | 44:c1d8923072ba | 48 | |
| TMBOY | 44:c1d8923072ba | 49 | if (is_null($contentType)) { |
| TMBOY | 44:c1d8923072ba | 50 | // Well, we didn't get an invalid one |
| TMBOY | 44:c1d8923072ba | 51 | return; |
| TMBOY | 44:c1d8923072ba | 52 | } |
| TMBOY | 44:c1d8923072ba | 53 | |
| TMBOY | 44:c1d8923072ba | 54 | if (in_array($contentType, array(Validator::SCHEMA_MEDIA_TYPE, 'application/json'))) { |
| TMBOY | 44:c1d8923072ba | 55 | return; |
| TMBOY | 44:c1d8923072ba | 56 | } |
| TMBOY | 44:c1d8923072ba | 57 | |
| TMBOY | 44:c1d8923072ba | 58 | if (substr($uri, 0, 23) == 'http://json-schema.org/') { |
| TMBOY | 44:c1d8923072ba | 59 | //HACK; they deliver broken content types |
| TMBOY | 44:c1d8923072ba | 60 | return true; |
| TMBOY | 44:c1d8923072ba | 61 | } |
| TMBOY | 44:c1d8923072ba | 62 | |
| TMBOY | 44:c1d8923072ba | 63 | throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE)); |
| TMBOY | 44:c1d8923072ba | 64 | } |
| TMBOY | 44:c1d8923072ba | 65 | |
| TMBOY | 44:c1d8923072ba | 66 | /** |
| TMBOY | 44:c1d8923072ba | 67 | * Get a URI Retriever |
| TMBOY | 44:c1d8923072ba | 68 | * |
| TMBOY | 44:c1d8923072ba | 69 | * If none is specified, sets a default FileGetContents retriever and |
| TMBOY | 44:c1d8923072ba | 70 | * returns that object. |
| TMBOY | 44:c1d8923072ba | 71 | * |
| TMBOY | 44:c1d8923072ba | 72 | * @return UriRetrieverInterface |
| TMBOY | 44:c1d8923072ba | 73 | */ |
| TMBOY | 44:c1d8923072ba | 74 | public function getUriRetriever() |
| TMBOY | 44:c1d8923072ba | 75 | { |
| TMBOY | 44:c1d8923072ba | 76 | if (is_null($this->uriRetriever)) { |
| TMBOY | 44:c1d8923072ba | 77 | $this->setUriRetriever(new FileGetContents); |
| TMBOY | 44:c1d8923072ba | 78 | } |
| TMBOY | 44:c1d8923072ba | 79 | |
| TMBOY | 44:c1d8923072ba | 80 | return $this->uriRetriever; |
| TMBOY | 44:c1d8923072ba | 81 | } |
| TMBOY | 44:c1d8923072ba | 82 | |
| TMBOY | 44:c1d8923072ba | 83 | /** |
| TMBOY | 44:c1d8923072ba | 84 | * Resolve a schema based on pointer |
| TMBOY | 44:c1d8923072ba | 85 | * |
| TMBOY | 44:c1d8923072ba | 86 | * URIs can have a fragment at the end in the format of |
| TMBOY | 44:c1d8923072ba | 87 | * #/path/to/object and we are to look up the 'path' property of |
| TMBOY | 44:c1d8923072ba | 88 | * the first object then the 'to' and 'object' properties. |
| TMBOY | 44:c1d8923072ba | 89 | * |
| TMBOY | 44:c1d8923072ba | 90 | * @param object $jsonSchema JSON Schema contents |
| TMBOY | 44:c1d8923072ba | 91 | * @param string $uri JSON Schema URI |
| TMBOY | 44:c1d8923072ba | 92 | * @return object JSON Schema after walking down the fragment pieces |
| TMBOY | 44:c1d8923072ba | 93 | * |
| TMBOY | 44:c1d8923072ba | 94 | * @throws ResourceNotFoundException |
| TMBOY | 44:c1d8923072ba | 95 | */ |
| TMBOY | 44:c1d8923072ba | 96 | public function resolvePointer($jsonSchema, $uri) |
| TMBOY | 44:c1d8923072ba | 97 | { |
| TMBOY | 44:c1d8923072ba | 98 | $resolver = new UriResolver(); |
| TMBOY | 44:c1d8923072ba | 99 | $parsed = $resolver->parse($uri); |
| TMBOY | 44:c1d8923072ba | 100 | if (empty($parsed['fragment'])) { |
| TMBOY | 44:c1d8923072ba | 101 | return $jsonSchema; |
| TMBOY | 44:c1d8923072ba | 102 | } |
| TMBOY | 44:c1d8923072ba | 103 | |
| TMBOY | 44:c1d8923072ba | 104 | $path = explode('/', $parsed['fragment']); |
| TMBOY | 44:c1d8923072ba | 105 | while ($path) { |
| TMBOY | 44:c1d8923072ba | 106 | $pathElement = array_shift($path); |
| TMBOY | 44:c1d8923072ba | 107 | if (! empty($pathElement)) { |
| TMBOY | 44:c1d8923072ba | 108 | $pathElement = str_replace('~1', '/', $pathElement); |
| TMBOY | 44:c1d8923072ba | 109 | $pathElement = str_replace('~0', '~', $pathElement); |
| TMBOY | 44:c1d8923072ba | 110 | if (! empty($jsonSchema->$pathElement)) { |
| TMBOY | 44:c1d8923072ba | 111 | $jsonSchema = $jsonSchema->$pathElement; |
| TMBOY | 44:c1d8923072ba | 112 | } else { |
| TMBOY | 44:c1d8923072ba | 113 | throw new ResourceNotFoundException( |
| TMBOY | 44:c1d8923072ba | 114 | 'Fragment "' . $parsed['fragment'] . '" not found' |
| TMBOY | 44:c1d8923072ba | 115 | . ' in ' . $uri |
| TMBOY | 44:c1d8923072ba | 116 | ); |
| TMBOY | 44:c1d8923072ba | 117 | } |
| TMBOY | 44:c1d8923072ba | 118 | |
| TMBOY | 44:c1d8923072ba | 119 | if (! is_object($jsonSchema)) { |
| TMBOY | 44:c1d8923072ba | 120 | throw new ResourceNotFoundException( |
| TMBOY | 44:c1d8923072ba | 121 | 'Fragment part "' . $pathElement . '" is no object ' |
| TMBOY | 44:c1d8923072ba | 122 | . ' in ' . $uri |
| TMBOY | 44:c1d8923072ba | 123 | ); |
| TMBOY | 44:c1d8923072ba | 124 | } |
| TMBOY | 44:c1d8923072ba | 125 | } |
| TMBOY | 44:c1d8923072ba | 126 | } |
| TMBOY | 44:c1d8923072ba | 127 | |
| TMBOY | 44:c1d8923072ba | 128 | return $jsonSchema; |
| TMBOY | 44:c1d8923072ba | 129 | } |
| TMBOY | 44:c1d8923072ba | 130 | |
| TMBOY | 44:c1d8923072ba | 131 | /** |
| TMBOY | 44:c1d8923072ba | 132 | * {@inheritdoc} |
| TMBOY | 44:c1d8923072ba | 133 | */ |
| TMBOY | 44:c1d8923072ba | 134 | public function retrieve($uri, $baseUri = null) |
| TMBOY | 44:c1d8923072ba | 135 | { |
| TMBOY | 44:c1d8923072ba | 136 | $resolver = new UriResolver(); |
| TMBOY | 44:c1d8923072ba | 137 | $resolvedUri = $fetchUri = $resolver->resolve($uri, $baseUri); |
| TMBOY | 44:c1d8923072ba | 138 | |
| TMBOY | 44:c1d8923072ba | 139 | //fetch URL without #fragment |
| TMBOY | 44:c1d8923072ba | 140 | $arParts = $resolver->parse($resolvedUri); |
| TMBOY | 44:c1d8923072ba | 141 | if (isset($arParts['fragment'])) { |
| TMBOY | 44:c1d8923072ba | 142 | unset($arParts['fragment']); |
| TMBOY | 44:c1d8923072ba | 143 | $fetchUri = $resolver->generate($arParts); |
| TMBOY | 44:c1d8923072ba | 144 | } |
| TMBOY | 44:c1d8923072ba | 145 | |
| TMBOY | 44:c1d8923072ba | 146 | $jsonSchema = $this->loadSchema($fetchUri); |
| TMBOY | 44:c1d8923072ba | 147 | |
| TMBOY | 44:c1d8923072ba | 148 | // Use the JSON pointer if specified |
| TMBOY | 44:c1d8923072ba | 149 | $jsonSchema = $this->resolvePointer($jsonSchema, $resolvedUri); |
| TMBOY | 44:c1d8923072ba | 150 | |
| TMBOY | 44:c1d8923072ba | 151 | if ($jsonSchema instanceof \stdClass) { |
| TMBOY | 44:c1d8923072ba | 152 | $jsonSchema->id = $resolvedUri; |
| TMBOY | 44:c1d8923072ba | 153 | } |
| TMBOY | 44:c1d8923072ba | 154 | |
| TMBOY | 44:c1d8923072ba | 155 | return $jsonSchema; |
| TMBOY | 44:c1d8923072ba | 156 | } |
| TMBOY | 44:c1d8923072ba | 157 | |
| TMBOY | 44:c1d8923072ba | 158 | /** |
| TMBOY | 44:c1d8923072ba | 159 | * Fetch a schema from the given URI, json-decode it and return it. |
| TMBOY | 44:c1d8923072ba | 160 | * Caches schema objects. |
| TMBOY | 44:c1d8923072ba | 161 | * |
| TMBOY | 44:c1d8923072ba | 162 | * @param string $fetchUri Absolute URI |
| TMBOY | 44:c1d8923072ba | 163 | * |
| TMBOY | 44:c1d8923072ba | 164 | * @return object JSON schema object |
| TMBOY | 44:c1d8923072ba | 165 | */ |
| TMBOY | 44:c1d8923072ba | 166 | protected function loadSchema($fetchUri) |
| TMBOY | 44:c1d8923072ba | 167 | { |
| TMBOY | 44:c1d8923072ba | 168 | if (isset($this->schemaCache[$fetchUri])) { |
| TMBOY | 44:c1d8923072ba | 169 | return $this->schemaCache[$fetchUri]; |
| TMBOY | 44:c1d8923072ba | 170 | } |
| TMBOY | 44:c1d8923072ba | 171 | |
| TMBOY | 44:c1d8923072ba | 172 | $uriRetriever = $this->getUriRetriever(); |
| TMBOY | 44:c1d8923072ba | 173 | $contents = $this->uriRetriever->retrieve($fetchUri); |
| TMBOY | 44:c1d8923072ba | 174 | $this->confirmMediaType($uriRetriever, $fetchUri); |
| TMBOY | 44:c1d8923072ba | 175 | $jsonSchema = json_decode($contents); |
| TMBOY | 44:c1d8923072ba | 176 | |
| TMBOY | 44:c1d8923072ba | 177 | if (JSON_ERROR_NONE < $error = json_last_error()) { |
| TMBOY | 44:c1d8923072ba | 178 | throw new JsonDecodingException($error); |
| TMBOY | 44:c1d8923072ba | 179 | } |
| TMBOY | 44:c1d8923072ba | 180 | |
| TMBOY | 44:c1d8923072ba | 181 | $this->schemaCache[$fetchUri] = $jsonSchema; |
| TMBOY | 44:c1d8923072ba | 182 | |
| TMBOY | 44:c1d8923072ba | 183 | return $jsonSchema; |
| TMBOY | 44:c1d8923072ba | 184 | } |
| TMBOY | 44:c1d8923072ba | 185 | |
| TMBOY | 44:c1d8923072ba | 186 | /** |
| TMBOY | 44:c1d8923072ba | 187 | * Set the URI Retriever |
| TMBOY | 44:c1d8923072ba | 188 | * |
| TMBOY | 44:c1d8923072ba | 189 | * @param UriRetrieverInterface $uriRetriever |
| TMBOY | 44:c1d8923072ba | 190 | * @return $this for chaining |
| TMBOY | 44:c1d8923072ba | 191 | */ |
| TMBOY | 44:c1d8923072ba | 192 | public function setUriRetriever(UriRetrieverInterface $uriRetriever) |
| TMBOY | 44:c1d8923072ba | 193 | { |
| TMBOY | 44:c1d8923072ba | 194 | $this->uriRetriever = $uriRetriever; |
| TMBOY | 44:c1d8923072ba | 195 | |
| TMBOY | 44:c1d8923072ba | 196 | return $this; |
| TMBOY | 44:c1d8923072ba | 197 | } |
| TMBOY | 44:c1d8923072ba | 198 | |
| TMBOY | 44:c1d8923072ba | 199 | /** |
| TMBOY | 44:c1d8923072ba | 200 | * Parses a URI into five main components |
| TMBOY | 44:c1d8923072ba | 201 | * |
| TMBOY | 44:c1d8923072ba | 202 | * @param string $uri |
| TMBOY | 44:c1d8923072ba | 203 | * @return array |
| TMBOY | 44:c1d8923072ba | 204 | */ |
| TMBOY | 44:c1d8923072ba | 205 | public function parse($uri) |
| TMBOY | 44:c1d8923072ba | 206 | { |
| TMBOY | 44:c1d8923072ba | 207 | preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match); |
| TMBOY | 44:c1d8923072ba | 208 | |
| TMBOY | 44:c1d8923072ba | 209 | $components = array(); |
| TMBOY | 44:c1d8923072ba | 210 | if (5 < count($match)) { |
| TMBOY | 44:c1d8923072ba | 211 | $components = array( |
| TMBOY | 44:c1d8923072ba | 212 | 'scheme' => $match[2], |
| TMBOY | 44:c1d8923072ba | 213 | 'authority' => $match[4], |
| TMBOY | 44:c1d8923072ba | 214 | 'path' => $match[5] |
| TMBOY | 44:c1d8923072ba | 215 | ); |
| TMBOY | 44:c1d8923072ba | 216 | } |
| TMBOY | 44:c1d8923072ba | 217 | |
| TMBOY | 44:c1d8923072ba | 218 | if (7 < count($match)) { |
| TMBOY | 44:c1d8923072ba | 219 | $components['query'] = $match[7]; |
| TMBOY | 44:c1d8923072ba | 220 | } |
| TMBOY | 44:c1d8923072ba | 221 | |
| TMBOY | 44:c1d8923072ba | 222 | if (9 < count($match)) { |
| TMBOY | 44:c1d8923072ba | 223 | $components['fragment'] = $match[9]; |
| TMBOY | 44:c1d8923072ba | 224 | } |
| TMBOY | 44:c1d8923072ba | 225 | |
| TMBOY | 44:c1d8923072ba | 226 | return $components; |
| TMBOY | 44:c1d8923072ba | 227 | } |
| TMBOY | 44:c1d8923072ba | 228 | |
| TMBOY | 44:c1d8923072ba | 229 | /** |
| TMBOY | 44:c1d8923072ba | 230 | * Builds a URI based on n array with the main components |
| TMBOY | 44:c1d8923072ba | 231 | * |
| TMBOY | 44:c1d8923072ba | 232 | * @param array $components |
| TMBOY | 44:c1d8923072ba | 233 | * @return string |
| TMBOY | 44:c1d8923072ba | 234 | */ |
| TMBOY | 44:c1d8923072ba | 235 | public function generate(array $components) |
| TMBOY | 44:c1d8923072ba | 236 | { |
| TMBOY | 44:c1d8923072ba | 237 | $uri = $components['scheme'] . '://' |
| TMBOY | 44:c1d8923072ba | 238 | . $components['authority'] |
| TMBOY | 44:c1d8923072ba | 239 | . $components['path']; |
| TMBOY | 44:c1d8923072ba | 240 | |
| TMBOY | 44:c1d8923072ba | 241 | if (array_key_exists('query', $components)) { |
| TMBOY | 44:c1d8923072ba | 242 | $uri .= $components['query']; |
| TMBOY | 44:c1d8923072ba | 243 | } |
| TMBOY | 44:c1d8923072ba | 244 | |
| TMBOY | 44:c1d8923072ba | 245 | if (array_key_exists('fragment', $components)) { |
| TMBOY | 44:c1d8923072ba | 246 | $uri .= $components['fragment']; |
| TMBOY | 44:c1d8923072ba | 247 | } |
| TMBOY | 44:c1d8923072ba | 248 | |
| TMBOY | 44:c1d8923072ba | 249 | return $uri; |
| TMBOY | 44:c1d8923072ba | 250 | } |
| TMBOY | 44:c1d8923072ba | 251 | |
| TMBOY | 44:c1d8923072ba | 252 | /** |
| TMBOY | 44:c1d8923072ba | 253 | * Resolves a URI |
| TMBOY | 44:c1d8923072ba | 254 | * |
| TMBOY | 44:c1d8923072ba | 255 | * @param string $uri Absolute or relative |
| TMBOY | 44:c1d8923072ba | 256 | * @param string $baseUri Optional base URI |
| TMBOY | 44:c1d8923072ba | 257 | * @return string |
| TMBOY | 44:c1d8923072ba | 258 | */ |
| TMBOY | 44:c1d8923072ba | 259 | public function resolve($uri, $baseUri = null) |
| TMBOY | 44:c1d8923072ba | 260 | { |
| TMBOY | 44:c1d8923072ba | 261 | $components = $this->parse($uri); |
| TMBOY | 44:c1d8923072ba | 262 | $path = $components['path']; |
| TMBOY | 44:c1d8923072ba | 263 | |
| TMBOY | 44:c1d8923072ba | 264 | if ((array_key_exists('scheme', $components)) && ('http' === $components['scheme'])) { |
| TMBOY | 44:c1d8923072ba | 265 | return $uri; |
| TMBOY | 44:c1d8923072ba | 266 | } |
| TMBOY | 44:c1d8923072ba | 267 | |
| TMBOY | 44:c1d8923072ba | 268 | $baseComponents = $this->parse($baseUri); |
| TMBOY | 44:c1d8923072ba | 269 | $basePath = $baseComponents['path']; |
| TMBOY | 44:c1d8923072ba | 270 | |
| TMBOY | 44:c1d8923072ba | 271 | $baseComponents['path'] = UriResolver::combineRelativePathWithBasePath($path, $basePath); |
| TMBOY | 44:c1d8923072ba | 272 | |
| TMBOY | 44:c1d8923072ba | 273 | return $this->generate($baseComponents); |
| TMBOY | 44:c1d8923072ba | 274 | } |
| TMBOY | 44:c1d8923072ba | 275 | |
| TMBOY | 44:c1d8923072ba | 276 | /** |
| TMBOY | 44:c1d8923072ba | 277 | * @param string $uri |
| TMBOY | 44:c1d8923072ba | 278 | * @return boolean |
| TMBOY | 44:c1d8923072ba | 279 | */ |
| TMBOY | 44:c1d8923072ba | 280 | public function isValid($uri) |
| TMBOY | 44:c1d8923072ba | 281 | { |
| TMBOY | 44:c1d8923072ba | 282 | $components = $this->parse($uri); |
| TMBOY | 44:c1d8923072ba | 283 | |
| TMBOY | 44:c1d8923072ba | 284 | return !empty($components); |
| TMBOY | 44:c1d8923072ba | 285 | } |
| TMBOY | 44:c1d8923072ba | 286 | } |
