ex

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

Committer:
TMBOY
Date:
Tue Jul 18 16:27:22 2017 +0800
Revision:
44:c1d8923072ba
?

Who changed what in which revision?

UserRevisionLine numberNew 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 }