summaryrefslogtreecommitdiff
path: root/js/dojo/dojox/json/schema.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo/dojox/json/schema.js')
-rw-r--r--js/dojo/dojox/json/schema.js223
1 files changed, 223 insertions, 0 deletions
diff --git a/js/dojo/dojox/json/schema.js b/js/dojo/dojox/json/schema.js
new file mode 100644
index 0000000..6659956
--- /dev/null
+++ b/js/dojo/dojox/json/schema.js
@@ -0,0 +1,223 @@
+//>>built
+define("dojox/json/schema", ["dojo/_base/kernel", "dojox", "dojo/_base/array"], function(dojo, dojox){
+
+dojo.getObject("json.schema", true, dojox);
+
+
+dojox.json.schema.validate = function(/*Any*/instance,/*Object*/schema){
+ // summary:
+ // To use the validator call this with an instance object and an optional schema object.
+ // If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating),
+ // that schema will be used to validate and the schema parameter is not necessary (if both exist,
+ // both validations will occur).
+ // instance:
+ // The instance value/object to validate
+ // schema:
+ // The schema to use to validate
+ // description:
+ // The validate method will return an object with two properties:
+ // valid: A boolean indicating if the instance is valid by the schema
+ // errors: An array of validation errors. If there are no errors, then an
+ // empty list will be returned. A validation error will have two properties:
+ // property: which indicates which property had the error
+ // message: which indicates what the error was
+ //
+ return this._validate(instance,schema,false);
+};
+dojox.json.schema.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/ property){
+ // summary:
+ // The checkPropertyChange method will check to see if an value can legally be in property with the given schema
+ // This is slightly different than the validate method in that it will fail if the schema is readonly and it will
+ // not check for self-validation, it is assumed that the passed in value is already internally valid.
+ // The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for
+ // information.
+ // value:
+ // The new instance value/object to check
+ // schema:
+ // The schema to use to validate
+ // return:
+ // see dojox.validate.jsonSchema.validate
+ //
+ return this._validate(value,schema, property || "property");
+};
+dojox.json.schema.mustBeValid = function(result){
+ // summary:
+ // This checks to ensure that the result is valid and will throw an appropriate error message if it is not
+ // result: the result returned from checkPropertyChange or validate
+ if(!result.valid){
+ throw new TypeError(dojo.map(result.errors,function(error){return "for property " + error.property + ': ' + error.message;}).join(", "));
+ }
+}
+dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolean*/ _changing){
+
+ var errors = [];
+ // validate a value against a property definition
+ function checkProp(value, schema, path,i){
+ var l;
+ path += path ? typeof i == 'number' ? '[' + i + ']' : typeof i == 'undefined' ? '' : '.' + i : i;
+ function addError(message){
+ errors.push({property:path,message:message});
+ }
+
+ if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function')){
+ if(typeof schema == 'function'){
+ if(!(Object(value) instanceof schema)){
+ addError("is not an instance of the class/constructor " + schema.name);
+ }
+ }else if(schema){
+ addError("Invalid schema/property definition " + schema);
+ }
+ return null;
+ }
+ if(_changing && schema.readonly){
+ addError("is a readonly field, it can not be changed");
+ }
+ if(schema['extends']){ // if it extends another schema, it must pass that schema as well
+ checkProp(value,schema['extends'],path,i);
+ }
+ // validate a value against a type definition
+ function checkType(type,value){
+ if(type){
+ if(typeof type == 'string' && type != 'any' &&
+ (type == 'null' ? value !== null : typeof value != type) &&
+ !(value instanceof Array && type == 'array') &&
+ !(type == 'integer' && value%1===0)){
+ return [{property:path,message:(typeof value) + " value found, but a " + type + " is required"}];
+ }
+ if(type instanceof Array){
+ var unionErrors=[];
+ for(var j = 0; j < type.length; j++){ // a union type
+ if(!(unionErrors=checkType(type[j],value)).length){
+ break;
+ }
+ }
+ if(unionErrors.length){
+ return unionErrors;
+ }
+ }else if(typeof type == 'object'){
+ var priorErrors = errors;
+ errors = [];
+ checkProp(value,type,path);
+ var theseErrors = errors;
+ errors = priorErrors;
+ return theseErrors;
+ }
+ }
+ return [];
+ }
+ if(value === undefined){
+ if(!schema.optional){
+ addError("is missing and it is not optional");
+ }
+ }else{
+ errors = errors.concat(checkType(schema.type,value));
+ if(schema.disallow && !checkType(schema.disallow,value).length){
+ addError(" disallowed value was matched");
+ }
+ if(value !== null){
+ if(value instanceof Array){
+ if(schema.items){
+ if(schema.items instanceof Array){
+ for(i=0,l=value.length; i<l; i++){
+ errors.concat(checkProp(value[i],schema.items[i],path,i));
+ }
+ }else{
+ for(i=0,l=value.length; i<l; i++){
+ errors.concat(checkProp(value[i],schema.items,path,i));
+ }
+ }
+ }
+ if(schema.minItems && value.length < schema.minItems){
+ addError("There must be a minimum of " + schema.minItems + " in the array");
+ }
+ if(schema.maxItems && value.length > schema.maxItems){
+ addError("There must be a maximum of " + schema.maxItems + " in the array");
+ }
+ }else if(schema.properties){
+ errors.concat(checkObj(value,schema.properties,path,schema.additionalProperties));
+ }
+ if(schema.pattern && typeof value == 'string' && !value.match(schema.pattern)){
+ addError("does not match the regex pattern " + schema.pattern);
+ }
+ if(schema.maxLength && typeof value == 'string' && value.length > schema.maxLength){
+ addError("may only be " + schema.maxLength + " characters long");
+ }
+ if(schema.minLength && typeof value == 'string' && value.length < schema.minLength){
+ addError("must be at least " + schema.minLength + " characters long");
+ }
+ if(typeof schema.minimum !== undefined && typeof value == typeof schema.minimum &&
+ schema.minimum > value){
+ addError("must have a minimum value of " + schema.minimum);
+ }
+ if(typeof schema.maximum !== undefined && typeof value == typeof schema.maximum &&
+ schema.maximum < value){
+ addError("must have a maximum value of " + schema.maximum);
+ }
+ if(schema['enum']){
+ var enumer = schema['enum'];
+ l = enumer.length;
+ var found;
+ for(var j = 0; j < l; j++){
+ if(enumer[j]===value){
+ found=1;
+ break;
+ }
+ }
+ if(!found){
+ addError("does not have a value in the enumeration " + enumer.join(", "));
+ }
+ }
+ if(typeof schema.maxDecimal == 'number' &&
+ (value.toString().match(new RegExp("\\.[0-9]{" + (schema.maxDecimal + 1) + ",}")))){
+ addError("may only have " + schema.maxDecimal + " digits of decimal places");
+ }
+ }
+ }
+ return null;
+ }
+ // validate an object against a schema
+ function checkObj(instance,objTypeDef,path,additionalProp){
+
+ if(typeof objTypeDef =='object'){
+ if(typeof instance != 'object' || instance instanceof Array){
+ errors.push({property:path,message:"an object is required"});
+ }
+
+ for(var i in objTypeDef){
+ if(objTypeDef.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_')){
+ var value = instance[i];
+ var propDef = objTypeDef[i];
+ checkProp(value,propDef,path,i);
+ }
+ }
+ }
+ for(i in instance){
+ if(instance.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_') && objTypeDef && !objTypeDef[i] && additionalProp===false){
+ errors.push({property:path,message:(typeof value) + "The property " + i +
+ " is not defined in the schema and the schema does not allow additional properties"});
+ }
+ var requires = objTypeDef && objTypeDef[i] && objTypeDef[i].requires;
+ if(requires && !(requires in instance)){
+ errors.push({property:path,message:"the presence of the property " + i + " requires that " + requires + " also be present"});
+ }
+ value = instance[i];
+ if(objTypeDef && typeof objTypeDef == 'object' && !(i in objTypeDef)){
+ checkProp(value,additionalProp,path,i);
+ }
+ if(!_changing && value && value.$schema){
+ errors = errors.concat(checkProp(value,value.$schema,path,i));
+ }
+ }
+ return errors;
+ }
+ if(schema){
+ checkProp(instance,schema,'',_changing || '');
+ }
+ if(!_changing && instance && instance.$schema){
+ checkProp(instance,instance.$schema,'','');
+ }
+ return {valid:!errors.length,errors:errors};
+};
+
+return dojox.json.schema;
+});