2 // ============LICENSE_START====================================================
\r
3 // Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
\r
4 // =============================================================================
\r
5 // Licensed under the Apache License, Version 2.0 (the "License");
\r
6 // you may not use this file except in compliance with the License.
\r
7 // You may obtain a copy of the License at
\r
9 // http://www.apache.org/licenses/LICENSE-2.0
\r
11 // Unless required by applicable law or agreed to in writing, software
\r
12 // distributed under the License is distributed on an "AS IS" BASIS,
\r
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
14 // See the License for the specific language governing permissions and
\r
15 // limitations under the License.
\r
16 // ============LICENSE_END======================================================
\r
18 // ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
19 import { Component, Input, OnInit, OnChanges} from '@angular/core';
\r
20 import { MdToolbarModule, MdButton, MdInputModule, MdSelectModule} from '@angular/material';
\r
21 import {ValidateMetaSchemaService} from './validate-metaschema.service';
\r
22 import {ValidateJSONService} from './validate-json.service';
\r
23 import {MetaSchemaService} from './metaschema.service';
\r
24 import * as Ajv from 'ajv';
\r
27 selector: 'app-df-jsoninput',
\r
28 templateUrl: './df-jsoninput.component.html',
\r
29 styleUrls: [ './df-jsoninput.component.css']
\r
31 export class DFJSONInputComponent implements OnInit /*, OnChanges */ {
\r
33 public dfschema = '';
\r
34 private jsonTestObject: any;
\r
35 private validJSON = false;
\r
36 public metaDisplay = false;
\r
37 public metaButton = 'Display MetaSchema';
\r
38 public schemaMsg: string;
\r
39 public schemaErrMsgs: string[] = [];
\r
40 private ajvService: any;
\r
41 private hideMeta = 'Hide MetaSchema';
\r
42 private displayMeta = 'Display Metaschema';
\r
43 private schemaValidate: Object;
\r
44 private validateMetaSchema: ValidateMetaSchemaService;
\r
45 private jsonValidate: ValidateJSONService;
\r
46 private metaSchema: MetaSchemaService;
\r
47 private validSchema = false;
\r
48 public dfmetaschema: string;
\r
49 public dfjson: string;
\r
50 public jsonMsg: string;
\r
51 public jsonErrMsgs: string[] = [];
\r
53 constructor (validateMetaSchemaService: ValidateMetaSchemaService, validateJSONService: ValidateJSONService, metaSchemaService: MetaSchemaService) {
\r
54 this.validateMetaSchema = validateMetaSchemaService;
\r
55 this.metaSchema = metaSchemaService;
\r
56 this.dfmetaschema = this.metaSchema.currentMetaSchemaFormatted();
\r
57 this.jsonValidate = validateJSONService;
\r
64 toggleMetaSchema(): void {
\r
65 this.metaDisplay = !this.metaDisplay;
\r
66 if (this.metaDisplay === true) {
\r
67 this.metaButton = this.hideMeta;
\r
69 this.metaButton = this.displayMeta;
\r
72 doDFSchemaChange(ev: any) {
\r
73 this.schemaMsg = '';
\r
74 this.schemaErrMsgs = [];
\r
75 this.validSchema = false;
\r
76 this.dfschema = ev.target.value;
\r
77 if (this.dfschema.length == 0) {
\r
78 if (this.validJSON) {
\r
79 this.jsonMsg = 'Enter a Valid Schema';
\r
80 this.jsonErrMsgs = [];
\r
84 if (this.jsonValidate.validate(this.dfschema) === false) {
\r
85 // assumes simple message - TBD???
\r
86 this.schemaMsg = this.jsonValidate.validateMsgs();
\r
87 if (this.validJSON) {
\r
88 this.jsonMsg = 'Enter a valid Schema';
\r
89 this.jsonErrMsgs = [];
\r
93 const pschema = JSON.parse(this.dfschema);
\r
94 if (!pschema.hasOwnProperty('jsonschema')) {
\r
95 this.schemaMsg = 'Invalid Schema - must specify jsonschema';
\r
96 if (this.validJSON) {
\r
97 this.jsonMsg = 'Enter a valid Schema';
\r
98 this.jsonErrMsgs = [];
\r
102 const jsonSchema = pschema.jsonschema;
\r
103 if (jsonSchema.hasOwnProperty('$schema')) {
\r
105 if (!(jsonSchema.$schema === 'http://json-schema.org/draft-04/schema#') ) {
\r
106 this.schemaMsg = 'Invalid JSON Schema Data Format - jsonschema$schema version must be 04';
\r
107 if (this.validJSON) {
\r
108 this.jsonMsg = 'Enter a Valid Schema';
\r
109 this.jsonErrMsgs = [];
\r
113 } catch(schemaVersionErr) {
\r
114 this.schemaMsg = 'Invalid JSON Schema Data Format - jsonschema$schema version must be 04';
\r
115 if (this.validJSON) {
\r
116 this.jsonMsg = 'Enter a Valid Schema';
\r
117 this.jsonErrMsgs = [];
\r
122 this.schemaMsg = 'Invalid JSON Schema Data Format - jsonschema$schema must specified';
\r
123 if (this.validJSON) {
\r
124 this.jsonMsg = 'Enter a Valid Schema';
\r
125 this.jsonErrMsgs = [];
\r
129 if (this.validateMetaSchema.validate(this.dfschema) === false) {
\r
130 this.schemaMsg = 'Invalid Data Format Schema';
\r
131 this.schemaErrMsgs = this.validateMetaSchema.validateMsgs();
\r
132 if (this.validJSON) {
\r
133 this.jsonMsg = 'Enter a valid Schema';
\r
134 this.jsonErrMsgs = [];
\r
137 this.schemaMsg = 'Valid Data Format Schema';
\r
138 this.validSchema = true;
\r
139 if (this.validJSON ) {
\r
140 this.validateJSON();
\r
145 // no reuse - so no service
\r
147 this.jsonErrMsgs = [];
\r
149 this.validJSON = false;
\r
150 if (this.dfjson.length == 0) {
\r
153 if (this.jsonValidate.validate(this.dfjson) === false) {
\r
154 this.jsonMsg = this.jsonValidate.validateMsgs();
\r
155 this.jsonErrMsgs = [];
\r
158 this.validJSON = true;
\r
159 if (!this.validSchema) {
\r
160 this.jsonMsg = 'Enter a Valid Schema';
\r
161 this.jsonErrMsgs = [];
\r
164 // check for jsonschema in Schema file and validate based on version
\r
165 const valpschema = JSON.parse(this.dfschema);
\r
166 const valjsonSchema = valpschema.jsonschema;
\r
167 const schemaVersion = valjsonSchema.$schema;
\r
170 if (schemaVersion === 'http://json-schema.org/draft-04/schema#') {
\r
171 this.ajvService = new Ajv({
\r
172 meta: false, // optional, to prevent adding draft-06 meta-schema
\r
173 extendRefs: true, // optional, current default is to 'fail', spec behaviour is to 'ignore'
\r
175 unknownFormats: 'ignore' // optional, current default is true (fail)
\r
177 // change this to http get at some point TBD
\r
178 const schemav4: any = { 'id': 'http://json-schema.org/draft-04/schema#', '$schema': 'http://json-schema.org/draft-04/schema#', 'description': 'Core schema meta-schema', 'definitions': { 'schemaArray': { 'type': 'array', 'minItems': 1, 'items': { '$ref': '#' } }, 'positiveInteger': { 'type': 'integer', 'minimum': 0 }, 'positiveIntegerDefault0': { 'allOf': [ { '$ref': '#/definitions/positiveInteger' }, { 'default': 0 } ] }, 'simpleTypes': { 'enum': [ 'array', 'boolean', 'integer', 'null', 'number', 'object', 'string' ] }, 'stringArray': { 'type': 'array', 'items': { 'type': 'string' }, 'minItems': 1, 'uniqueItems': true } }, 'type': 'object', 'properties': { 'id': { 'type': 'string', 'format': 'uri' }, '$schema': { 'type': 'string', 'format': 'uri' }, 'title': { 'type': 'string' }, 'description': { 'type': 'string' }, 'default': {}, 'multipleOf': { 'type': 'number', 'minimum': 0, 'exclusiveMinimum': true }, 'maximum': { 'type': 'number' }, 'exclusiveMaximum': { 'type': 'boolean', 'default': false }, 'minimum': { 'type': 'number' }, 'exclusiveMinimum': { 'type': 'boolean', 'default': false }, 'maxLength': { '$ref': '#/definitions/positiveInteger' }, 'minLength': { '$ref': '#/definitions/positiveIntegerDefault0' }, 'pattern': { 'type': 'string', 'format': 'regex' }, 'additionalItems': { 'anyOf': [ { 'type': 'boolean' }, { '$ref': '#' } ], 'default': {} }, 'items': { 'anyOf': [ { '$ref': '#' }, { '$ref': '#/definitions/schemaArray' } ], 'default': {} }, 'maxItems': { '$ref': '#/definitions/positiveInteger' }, 'minItems': { '$ref': '#/definitions/positiveIntegerDefault0' }, 'uniqueItems': { 'type': 'boolean', 'default': false }, 'maxProperties': { '$ref': '#/definitions/positiveInteger' }, 'minProperties': { '$ref': '#/definitions/positiveIntegerDefault0' }, 'required': { '$ref': '#/definitions/stringArray' }, 'additionalProperties': { 'anyOf': [ { 'type': 'boolean' }, { '$ref': '#' } ], 'default': {} }, 'definitions': { 'type': 'object', 'additionalProperties': { '$ref': '#' }, 'default': {} }, 'properties': { 'type': 'object', 'additionalProperties': { '$ref': '#' }, 'default': {} }, 'patternProperties': { 'type': 'object', 'additionalProperties': { '$ref': '#' }, 'default': {} }, 'dependencies': { 'type': 'object', 'additionalProperties': { 'anyOf': [ { '$ref': '#' }, { '$ref': '#/definitions/stringArray' } ] } }, 'enum': { 'type': 'array', 'minItems': 1, 'uniqueItems': true }, 'type': { 'anyOf': [ { '$ref': '#/definitions/simpleTypes' }, { 'type': 'array', 'items': { '$ref': '#/definitions/simpleTypes' }, 'minItems': 1, 'uniqueItems': true } ] }, 'allOf': { '$ref': '#/definitions/schemaArray' }, 'anyOf': { '$ref': '#/definitions/schemaArray' }, 'oneOf': { '$ref': '#/definitions/schemaArray' }, 'not': { '$ref': '#' } }, 'dependencies': { 'exclusiveMaximum': [ 'maximum' ], 'exclusiveMinimum': [ 'minimum' ] }, 'default': {}}
\r
180 const metaSchema = schemav4;
\r
182 this.ajvService.addMetaSchema(metaSchema);
\r
183 this.ajvService._opts.defaultMeta = metaSchema.id;
\r
185 // Optionally you can also disable keywords defined in draft-06
\r
186 this.ajvService.removeKeyword('propertyNames');
\r
187 this.ajvService.removeKeyword('contains');
\r
188 this.ajvService.removeKeyword('const');
\r
191 this.jsonMsg = 'Invalid JSON Schema Data Format - jsonschema$schema version must be 04';
\r
192 this.jsonErrMsgs = [];
\r
195 } catch (ajvErrMsg) {
\r
197 this.jsonMsg = 'Failed - Schema checking initialization: ' + ajvErrMsg;
\r
198 this.jsonErrMsgs = [];
\r
204 const pschema = JSON.parse(this.dfschema);
\r
205 const jsonSchema = pschema.jsonschema;
\r
207 const sValidate = this.ajvService.compile(jsonSchema);
\r
208 const result = sValidate(JSON.parse(this.dfjson));
\r
211 if (result === false) {
\r
212 for ( const errMsg of Object.keys(sValidate.errors)) {
\r
213 let msg = sValidate.errors[errMsg].message;
\r
214 if (sValidate.errors[errMsg].hasOwnProperty('params')) {
\r
215 if (sValidate.errors[errMsg].params.hasOwnProperty('additionalProperty')) {
\r
217 msg = msg + sValidate.errors[errMsg].params.additionalProperty;
\r
220 let dupMsg = false;
\r
221 for (const k in this.jsonErrMsgs) {
\r
222 if ( this.jsonErrMsgs[k] === msg) {
\r
226 if (dupMsg === false) {
\r
227 this.jsonErrMsgs[j] = msg;
\r
231 this.jsonMsg = 'JSON Input does not match Schema:';
\r
234 } catch (schemaError) {
\r
235 this.jsonMsg = 'Unexpected Schema Validation Error' + schemaError;
\r
238 this.jsonMsg = 'JSON Input Validated';
\r
239 this.jsonErrMsgs = [];
\r
242 doDFJSONChange(ev: any) {
\r
243 this.dfjson = ev.target.value;
\r
244 this.validateJSON();
\r