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 #!/usr/bin/env php
TMBOY 44:c1d8923072ba 2 <?php
TMBOY 44:c1d8923072ba 3 /**
TMBOY 44:c1d8923072ba 4 * JSON schema validator
TMBOY 44:c1d8923072ba 5 *
TMBOY 44:c1d8923072ba 6 * @author Christian Weiske <christian.weiske@netresearch.de>
TMBOY 44:c1d8923072ba 7 */
TMBOY 44:c1d8923072ba 8
TMBOY 44:c1d8923072ba 9 /**
TMBOY 44:c1d8923072ba 10 * Dead simple autoloader
TMBOY 44:c1d8923072ba 11 *
TMBOY 44:c1d8923072ba 12 * @param string $className Name of class to load
TMBOY 44:c1d8923072ba 13 *
TMBOY 44:c1d8923072ba 14 * @return void
TMBOY 44:c1d8923072ba 15 */
TMBOY 44:c1d8923072ba 16 function __autoload($className)
TMBOY 44:c1d8923072ba 17 {
TMBOY 44:c1d8923072ba 18 $className = ltrim($className, '\\');
TMBOY 44:c1d8923072ba 19 $fileName = '';
TMBOY 44:c1d8923072ba 20 $namespace = '';
TMBOY 44:c1d8923072ba 21 if ($lastNsPos = strrpos($className, '\\')) {
TMBOY 44:c1d8923072ba 22 $namespace = substr($className, 0, $lastNsPos);
TMBOY 44:c1d8923072ba 23 $className = substr($className, $lastNsPos + 1);
TMBOY 44:c1d8923072ba 24 $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
TMBOY 44:c1d8923072ba 25 }
TMBOY 44:c1d8923072ba 26 $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
TMBOY 44:c1d8923072ba 27 if (stream_resolve_include_path($fileName)) {
TMBOY 44:c1d8923072ba 28 require_once $fileName;
TMBOY 44:c1d8923072ba 29 }
TMBOY 44:c1d8923072ba 30 }
TMBOY 44:c1d8923072ba 31
TMBOY 44:c1d8923072ba 32 /**
TMBOY 44:c1d8923072ba 33 * Show the json parse error that happened last
TMBOY 44:c1d8923072ba 34 *
TMBOY 44:c1d8923072ba 35 * @return void
TMBOY 44:c1d8923072ba 36 */
TMBOY 44:c1d8923072ba 37 function showJsonError()
TMBOY 44:c1d8923072ba 38 {
TMBOY 44:c1d8923072ba 39 $constants = get_defined_constants(true);
TMBOY 44:c1d8923072ba 40 $json_errors = array();
TMBOY 44:c1d8923072ba 41 foreach ($constants['json'] as $name => $value) {
TMBOY 44:c1d8923072ba 42 if (!strncmp($name, 'JSON_ERROR_', 11)) {
TMBOY 44:c1d8923072ba 43 $json_errors[$value] = $name;
TMBOY 44:c1d8923072ba 44 }
TMBOY 44:c1d8923072ba 45 }
TMBOY 44:c1d8923072ba 46
TMBOY 44:c1d8923072ba 47 echo 'JSON parse error: ' . $json_errors[json_last_error()] . "\n";
TMBOY 44:c1d8923072ba 48 }
TMBOY 44:c1d8923072ba 49
TMBOY 44:c1d8923072ba 50 function getUrlFromPath($path)
TMBOY 44:c1d8923072ba 51 {
TMBOY 44:c1d8923072ba 52 if (parse_url($path, PHP_URL_SCHEME) !== null) {
TMBOY 44:c1d8923072ba 53 //already an URL
TMBOY 44:c1d8923072ba 54 return $path;
TMBOY 44:c1d8923072ba 55 }
TMBOY 44:c1d8923072ba 56 if ($path{0} == '/') {
TMBOY 44:c1d8923072ba 57 //absolute path
TMBOY 44:c1d8923072ba 58 return 'file://' . $path;
TMBOY 44:c1d8923072ba 59 }
TMBOY 44:c1d8923072ba 60
TMBOY 44:c1d8923072ba 61 //relative path: make absolute
TMBOY 44:c1d8923072ba 62 return 'file://' . getcwd() . '/' . $path;
TMBOY 44:c1d8923072ba 63 }
TMBOY 44:c1d8923072ba 64
TMBOY 44:c1d8923072ba 65 /**
TMBOY 44:c1d8923072ba 66 * Take a HTTP header value and split it up into parts.
TMBOY 44:c1d8923072ba 67 *
TMBOY 44:c1d8923072ba 68 * @param $headerValue
TMBOY 44:c1d8923072ba 69 * @return array Key "_value" contains the main value, all others
TMBOY 44:c1d8923072ba 70 * as given in the header value
TMBOY 44:c1d8923072ba 71 */
TMBOY 44:c1d8923072ba 72 function parseHeaderValue($headerValue)
TMBOY 44:c1d8923072ba 73 {
TMBOY 44:c1d8923072ba 74 if (strpos($headerValue, ';') === false) {
TMBOY 44:c1d8923072ba 75 return array('_value' => $headerValue);
TMBOY 44:c1d8923072ba 76 }
TMBOY 44:c1d8923072ba 77
TMBOY 44:c1d8923072ba 78 $parts = explode(';', $headerValue);
TMBOY 44:c1d8923072ba 79 $arData = array('_value' => array_shift($parts));
TMBOY 44:c1d8923072ba 80 foreach ($parts as $part) {
TMBOY 44:c1d8923072ba 81 list($name, $value) = explode('=', $part);
TMBOY 44:c1d8923072ba 82 $arData[$name] = trim($value, ' "\'');
TMBOY 44:c1d8923072ba 83 }
TMBOY 44:c1d8923072ba 84 return $arData;
TMBOY 44:c1d8923072ba 85 }
TMBOY 44:c1d8923072ba 86
TMBOY 44:c1d8923072ba 87
TMBOY 44:c1d8923072ba 88 // support running this tool from git checkout
TMBOY 44:c1d8923072ba 89 if (is_dir(__DIR__ . '/../src/JsonSchema')) {
TMBOY 44:c1d8923072ba 90 set_include_path(__DIR__ . '/../src' . PATH_SEPARATOR . get_include_path());
TMBOY 44:c1d8923072ba 91 }
TMBOY 44:c1d8923072ba 92
TMBOY 44:c1d8923072ba 93 $arOptions = array();
TMBOY 44:c1d8923072ba 94 $arArgs = array();
TMBOY 44:c1d8923072ba 95 array_shift($argv);//script itself
TMBOY 44:c1d8923072ba 96 foreach ($argv as $arg) {
TMBOY 44:c1d8923072ba 97 if ($arg{0} == '-') {
TMBOY 44:c1d8923072ba 98 $arOptions[$arg] = true;
TMBOY 44:c1d8923072ba 99 } else {
TMBOY 44:c1d8923072ba 100 $arArgs[] = $arg;
TMBOY 44:c1d8923072ba 101 }
TMBOY 44:c1d8923072ba 102 }
TMBOY 44:c1d8923072ba 103
TMBOY 44:c1d8923072ba 104 if (count($arArgs) == 0
TMBOY 44:c1d8923072ba 105 || isset($arOptions['--help']) || isset($arOptions['-h'])
TMBOY 44:c1d8923072ba 106 ) {
TMBOY 44:c1d8923072ba 107 echo <<<HLP
TMBOY 44:c1d8923072ba 108 Validate schema
TMBOY 44:c1d8923072ba 109 Usage: validate-json data.json
TMBOY 44:c1d8923072ba 110 or: validate-json data.json schema.json
TMBOY 44:c1d8923072ba 111
TMBOY 44:c1d8923072ba 112 Options:
TMBOY 44:c1d8923072ba 113 --dump-schema Output full schema and exit
TMBOY 44:c1d8923072ba 114 --dump-schema-url Output URL of schema
TMBOY 44:c1d8923072ba 115 -h --help Show this help
TMBOY 44:c1d8923072ba 116
TMBOY 44:c1d8923072ba 117 HLP;
TMBOY 44:c1d8923072ba 118 exit(1);
TMBOY 44:c1d8923072ba 119 }
TMBOY 44:c1d8923072ba 120
TMBOY 44:c1d8923072ba 121 if (count($arArgs) == 1) {
TMBOY 44:c1d8923072ba 122 $pathData = $arArgs[0];
TMBOY 44:c1d8923072ba 123 $pathSchema = null;
TMBOY 44:c1d8923072ba 124 } else {
TMBOY 44:c1d8923072ba 125 $pathData = $arArgs[0];
TMBOY 44:c1d8923072ba 126 $pathSchema = getUrlFromPath($arArgs[1]);
TMBOY 44:c1d8923072ba 127 }
TMBOY 44:c1d8923072ba 128
TMBOY 44:c1d8923072ba 129 $urlData = getUrlFromPath($pathData);
TMBOY 44:c1d8923072ba 130
TMBOY 44:c1d8923072ba 131 $context = stream_context_create(
TMBOY 44:c1d8923072ba 132 array(
TMBOY 44:c1d8923072ba 133 'http' => array(
TMBOY 44:c1d8923072ba 134 'header' => array(
TMBOY 44:c1d8923072ba 135 'Accept: */*',
TMBOY 44:c1d8923072ba 136 'Connection: Close'
TMBOY 44:c1d8923072ba 137 ),
TMBOY 44:c1d8923072ba 138 'max_redirects' => 5
TMBOY 44:c1d8923072ba 139 )
TMBOY 44:c1d8923072ba 140 )
TMBOY 44:c1d8923072ba 141 );
TMBOY 44:c1d8923072ba 142 $dataString = file_get_contents($pathData, false, $context);
TMBOY 44:c1d8923072ba 143 if ($dataString == '') {
TMBOY 44:c1d8923072ba 144 echo "Data file is not readable or empty.\n";
TMBOY 44:c1d8923072ba 145 exit(3);
TMBOY 44:c1d8923072ba 146 }
TMBOY 44:c1d8923072ba 147
TMBOY 44:c1d8923072ba 148 $data = json_decode($dataString);
TMBOY 44:c1d8923072ba 149 unset($dataString);
TMBOY 44:c1d8923072ba 150 if ($data === null) {
TMBOY 44:c1d8923072ba 151 echo "Error loading JSON data file\n";
TMBOY 44:c1d8923072ba 152 showJsonError();
TMBOY 44:c1d8923072ba 153 exit(5);
TMBOY 44:c1d8923072ba 154 }
TMBOY 44:c1d8923072ba 155
TMBOY 44:c1d8923072ba 156 if ($pathSchema === null) {
TMBOY 44:c1d8923072ba 157 if (isset($http_response_header)) {
TMBOY 44:c1d8923072ba 158 array_shift($http_response_header);//HTTP/1.0 line
TMBOY 44:c1d8923072ba 159 foreach ($http_response_header as $headerLine) {
TMBOY 44:c1d8923072ba 160 list($hName, $hValue) = explode(':', $headerLine, 2);
TMBOY 44:c1d8923072ba 161 $hName = strtolower($hName);
TMBOY 44:c1d8923072ba 162 if ($hName == 'link') {
TMBOY 44:c1d8923072ba 163 //Link: <http://example.org/schema#>; rel="describedBy"
TMBOY 44:c1d8923072ba 164 $hParts = parseHeaderValue($hValue);
TMBOY 44:c1d8923072ba 165 if (isset($hParts['rel']) && $hParts['rel'] == 'describedBy') {
TMBOY 44:c1d8923072ba 166 $pathSchema = trim($hParts['_value'], ' <>');
TMBOY 44:c1d8923072ba 167 }
TMBOY 44:c1d8923072ba 168 } else if ($hName == 'content-type') {
TMBOY 44:c1d8923072ba 169 //Content-Type: application/my-media-type+json;
TMBOY 44:c1d8923072ba 170 // profile=http://example.org/schema#
TMBOY 44:c1d8923072ba 171 $hParts = parseHeaderValue($hValue);
TMBOY 44:c1d8923072ba 172 if (isset($hParts['profile'])) {
TMBOY 44:c1d8923072ba 173 $pathSchema = $hParts['profile'];
TMBOY 44:c1d8923072ba 174 }
TMBOY 44:c1d8923072ba 175
TMBOY 44:c1d8923072ba 176 }
TMBOY 44:c1d8923072ba 177 }
TMBOY 44:c1d8923072ba 178 }
TMBOY 44:c1d8923072ba 179 if (is_object($data) && property_exists($data, '$schema')) {
TMBOY 44:c1d8923072ba 180 $pathSchema = $data->{'$schema'};
TMBOY 44:c1d8923072ba 181 }
TMBOY 44:c1d8923072ba 182
TMBOY 44:c1d8923072ba 183 //autodetect schema
TMBOY 44:c1d8923072ba 184 if ($pathSchema === null) {
TMBOY 44:c1d8923072ba 185 echo "JSON data must be an object and have a \$schema property.\n";
TMBOY 44:c1d8923072ba 186 echo "You can pass the schema file on the command line as well.\n";
TMBOY 44:c1d8923072ba 187 echo "Schema autodetection failed.\n";
TMBOY 44:c1d8923072ba 188 exit(6);
TMBOY 44:c1d8923072ba 189 }
TMBOY 44:c1d8923072ba 190 }
TMBOY 44:c1d8923072ba 191 if ($pathSchema{0} == '/') {
TMBOY 44:c1d8923072ba 192 $pathSchema = 'file://' . $pathSchema;
TMBOY 44:c1d8923072ba 193 }
TMBOY 44:c1d8923072ba 194
TMBOY 44:c1d8923072ba 195 $resolver = new JsonSchema\Uri\UriResolver();
TMBOY 44:c1d8923072ba 196 $retriever = new JsonSchema\Uri\UriRetriever();
TMBOY 44:c1d8923072ba 197 try {
TMBOY 44:c1d8923072ba 198 $urlSchema = $resolver->resolve($pathSchema, $urlData);
TMBOY 44:c1d8923072ba 199
TMBOY 44:c1d8923072ba 200 if (isset($arOptions['--dump-schema-url'])) {
TMBOY 44:c1d8923072ba 201 echo $urlSchema . "\n";
TMBOY 44:c1d8923072ba 202 exit();
TMBOY 44:c1d8923072ba 203 }
TMBOY 44:c1d8923072ba 204 } catch (Exception $e) {
TMBOY 44:c1d8923072ba 205 echo "Error loading JSON schema file\n";
TMBOY 44:c1d8923072ba 206 echo $urlSchema . "\n";
TMBOY 44:c1d8923072ba 207 echo $e->getMessage() . "\n";
TMBOY 44:c1d8923072ba 208 exit(2);
TMBOY 44:c1d8923072ba 209 }
TMBOY 44:c1d8923072ba 210 $refResolver = new JsonSchema\RefResolver($retriever, $resolver);
TMBOY 44:c1d8923072ba 211 $schema = $refResolver->resolve($urlSchema);
TMBOY 44:c1d8923072ba 212
TMBOY 44:c1d8923072ba 213 if (isset($arOptions['--dump-schema'])) {
TMBOY 44:c1d8923072ba 214 $options = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0;
TMBOY 44:c1d8923072ba 215 echo json_encode($schema, $options) . "\n";
TMBOY 44:c1d8923072ba 216 exit();
TMBOY 44:c1d8923072ba 217 }
TMBOY 44:c1d8923072ba 218
TMBOY 44:c1d8923072ba 219 try {
TMBOY 44:c1d8923072ba 220 $validator = new JsonSchema\Validator();
TMBOY 44:c1d8923072ba 221 $validator->check($data, $schema);
TMBOY 44:c1d8923072ba 222
TMBOY 44:c1d8923072ba 223 if ($validator->isValid()) {
TMBOY 44:c1d8923072ba 224 echo "OK. The supplied JSON validates against the schema.\n";
TMBOY 44:c1d8923072ba 225 } else {
TMBOY 44:c1d8923072ba 226 echo "JSON does not validate. Violations:\n";
TMBOY 44:c1d8923072ba 227 foreach ($validator->getErrors() as $error) {
TMBOY 44:c1d8923072ba 228 echo sprintf("[%s] %s\n", $error['property'], $error['message']);
TMBOY 44:c1d8923072ba 229 }
TMBOY 44:c1d8923072ba 230 exit(23);
TMBOY 44:c1d8923072ba 231 }
TMBOY 44:c1d8923072ba 232 } catch (Exception $e) {
TMBOY 44:c1d8923072ba 233 echo "JSON does not validate. Error:\n";
TMBOY 44:c1d8923072ba 234 echo $e->getMessage() . "\n";
TMBOY 44:c1d8923072ba 235 echo "Error code: " . $e->getCode() . "\n";
TMBOY 44:c1d8923072ba 236 exit(24);
TMBOY 44:c1d8923072ba 237 }