Cezar Andrei has proposed merging lp:~zorba-coders/zorba/jsound-validator into 
lp:zorba.

Commit message:
New core module: JSound validator implemented in JSONiq.

Requested reviews:
  Juan Zacarias (juan457)
  Ghislain Fourny (gislenius)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/jsound-validator/+merge/186908

New core module: JSound validator implemented in JSONiq.
-- 
https://code.launchpad.net/~zorba-coders/zorba/jsound-validator/+merge/186908
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'modules/CMakeLists.txt'
--- modules/CMakeLists.txt	2013-09-09 23:47:17 +0000
+++ modules/CMakeLists.txt	2013-09-21 04:53:29 +0000
@@ -23,6 +23,7 @@
 ADD_SUBDIRECTORY(xml)
 ADD_SUBDIRECTORY(http-client)
 ADD_SUBDIRECTORY(json)
+ADD_SUBDIRECTORY(jsound)
 ADD_SUBDIRECTORY(structured-items)
 ADD_SUBDIRECTORY(item)
 

=== modified file 'modules/http-client/json/http-client.jsd'
--- modules/http-client/json/http-client.jsd	2013-07-11 20:57:49 +0000
+++ modules/http-client/json/http-client.jsd	2013-09-21 04:53:29 +0000
@@ -2,104 +2,122 @@
   "$namespace": "http://zorba.io/modules/http-client";,
   "$about": "This JSound schema defines the types of requests and
              responses used in the http://28.io/http-client module",
-  "$types": [
+  "$types": 
+  [
     {
-	  "$kind": "object",
-	  "$name": "headers",
-	  "$about": "This type represents a set of headers. Each header is represented
-	             by a different name-value pair.",
-	  "$constraints" : "every $key in keys($$) satisfies $$.$key instance of string"
-	  
+      "$kind": "object",
+	    "$name": "headers",
+	    "$about": "This type represents a set of headers. Each header is represented
+	               by a different name-value pair.",
+	    "$constraints" : "every $key in keys($$) satisfies $$.$key instance of string",
+	    "$content" : {}	  
     },
     {
-	  "$kind": "object",
-	  "$name": "body",
-	  "$about": "This type represents the body of an HTTP request or an HTTP 
+      "$kind": "object",
+	    "$name": "body",
+	    "$about": "This type represents the body of an HTTP request or an HTTP 
 	             response. In multi-part requests and responses, it represents the
 				 body of a single part.",
-	  "$content": {
-	    "media-type": {
-		   "$type": "string",
-		   "$about": "This field is the media type of the body."
-		 },
-        "src": {
-		   "$type": "anyURI",
-		   "$about": "This field, used only in HTTP requests, is used to specify the URL at
-		              which the request can be found. It is mutually exclusive with the content
-		              field.",
-		   "$optional": true
-		 },
- 		"content": {
-		  "$type": "string",
-		  "$about": "The HTTP request or response body.  It is mutually exclusive with the src
-		              field.",
-		  "$optional": true
-		  }
-	   },
-	   "$constraints" : "count($$.src) + count($$.content) le 1"      
+	    "$content": 
+	    {
+	      "media-type": 
+	      {
+		      "$type": "string",
+		      "$about": "This field is the media type of the body."
+		    },
+        "src": 
+        {
+		      "$type": "anyURI",
+		      "$about": "This field, used only in HTTP requests, is used to specify the URL at
+		                 which the request can be found. It is mutually exclusive with the content
+		                 field.",
+		      "$optional": true
+		    },
+ 		    "content": 
+ 		    {
+		      "$type": "string",
+		      "$about": "The HTTP request or response body.  It is mutually exclusive with the src
+		                 field.",
+		      "$optional": true
+		    }
+	    },
+	    "$constraints" : "count($$.src) + count($$.content) le 1"      
     },
-	{
-	  "$kind": "object",
-	  "$name": "part",
-	  "$about": "This type represents each single part of a multipart HTTP request or 
+	  {
+	    "$kind": "object",
+	    "$name": "part",
+	    "$about": "This type represents each single part of a multipart HTTP request or 
                  response.",
-	  "$content": {
-	    "headers": {
-		  "$type": "headers",		  
-		  "$optional": true,
-		  "$about": "This field specifies the part headers."
-		},
-		"body": {"$type": "body"}
-	  }
-	},
-	{
-	   "$kind": "object",
-	   "$name": "multipart",
-	   "$about": "This type represents a multipart HTTP request or response.",
-	   "$content": {
-	     "media-type": {
-		   "$type": "string"
-		   "$about": "The media-type attribute is the media type of the request or 
-		              response, and has to be a multipart media type (that is, its
-                      main type must be multipart)."
-		},
-		 "boundary": {
-		   "$type": "string",
-		   "$optional": true,
-		   "$about": "The boundary attribute is the boundary marker used to separate 
-		              the several parts in the message (the value of the attribute is
-					  prefixed with "--" to form the actual boundary marker in the 
-					  request; on the other way, this prefix is removed from the boundary 
-					  marker in the response to set the value of the attribute."
-		 },		 
-		 "parts": {
+	    "$content": 
+	    {
+	      "headers": 
+	      {
+		      "$type": "headers",		  
+		      "$optional": true,
+		      "$about": "This field specifies the part headers."
+		    },
+  		  "body": 
+  		  { 
+  		    "$type": "body" 
+  		  }
+	    }
+	  },
+	  {
+	    "$kind": "object",
+	    "$name": "multipart",
+	    "$about": "This type represents a multipart HTTP request or response.",
+      "$content": 
+      {
+        "media-type": 
+        {
+          "$type": "string",
+		      "$about": "The media-type attribute is the media type of the request or 
+		                 response, and has to be a multipart media type (that is, its
+                     main type must be multipart)."
+		    },
+        "boundary": 
+        {
+	        "$type": "string",
+		      "$optional": true,
+		      "$about": "The boundary attribute is the boundary marker used to separate 
+		                 the several parts in the message (the value of the attribute is
+		                 prefixed with '--' to form the actual boundary marker in the 
+					           request; on the other way, this prefix is removed from the boundary 
+					           marker in the response to set the value of the attribute."
+		    },		 
+        "parts": 
+        {
 	        "$kind": "array",
 	        "$content": ["part"],
-			"$about": "The parts of the multipart request.",
-			"$optional": true
-		 }		
-	  }      
+			    "$about": "The parts of the multipart request.",
+			    "$optional": true
+		    }
+	    }      
     },
     {
       "$kind": "object",
       "$name": "options",
-	  "$about": "This type represents an HTTP request options.",
-      "$content": {
-        "status-only": {
-		  "$type": "boolean",
-		  "$optional": true,
-		  "$about": "Controls how the response will look like; if true, only the status code
+	    "$about": "This type represents an HTTP request options.",
+      "$content": 
+      {
+        "status-only": 
+        {
+		      "$type": "boolean",
+		      "$optional": true,
+		      "$about": "Controls how the response will look like; if true, only the status code
                      and the headers are returned, the content is not."
-		},
-		"override-media-type": {
-		  "$type": "string",
-		  "$about": "Is a MIME type that will override the Content-Type header returned
+		    },
+		    "override-media-type": 
+		    {
+		      "$type": "string",
+		      "$about": "Is a MIME type that will override the Content-Type header returned
                      by the server.",
-		  "$optional": true
-		},
-		"follow-redirect": {
-		  "$type": "boolean",
-		  "$optional": true,
+		      "$optional": true
+		    },
+		    "follow-redirect": 
+		    {
+		      "$type": "boolean",
+		      "$optional": true,
           "$about": "Control whether an http redirect is automatically followed or not. If
                      it is false, the http redirect is returned as the response. If it is
                      true (the default) the function tries to follow the redirect, by
@@ -107,109 +125,129 @@
                      and authentication credentials.) Maximum one redirect is followed
                      (there is no attempt to follow a redirect in response to following a
                      first redirect.)"
-		},
-		"timeout": {
-		  "$type": "integer",
-		  "$optional": true,
-		  "$about": "Is the maximum number of seconds to wait for the server to respond. If
+		    },
+		    "timeout": 
+		    {
+          "$type": "integer",
+          "$optional": true,
+          "$about": "Is the maximum number of seconds to wait for the server to respond. If
                      this time duration is reached, an error is thrown."
-		},
-        "user-agent": {
-		  "$type": "string",
-		  "$optional": true,
-		  "$about": "The user agent sent to the server when issuing the request."
-		},
-	  }	 
+	 	    },
+        "user-agent": 
+        {
+		      "$type": "string",
+		      "$optional": true,
+		      "$about": "The user agent sent to the server when issuing the request."
+    	  }
+	    }	 
     },	
-	{
-      "$kind": "object",
-      "$name": "authentication",
-	  "$about": "This type represents an HTTP authentication.",
-      "$content": {
-        "username": {
-		  "$type": "string",
-		  "$about": "The authentication username."
-		},	   
-		"password": {
-		  "$type": "string",
-		  "$about": "The authentication password."
-		},
-		"auth-method": {
-		  "$type": "string",
-		  "$about": "The authentication method."
-		}
+	  {
+     "$kind": "object",
+     "$name": "authentication",
+	   "$about": "This type represents an HTTP authentication.",
+     "$content": 
+     {
+       "username": 
+       {
+		     "$type": "string",
+		     "$about": "The authentication username."
+		   },	   
+		   "password": 
+		   {
+		     "$type": "string",
+		     "$about": "The authentication password."
+		   },
+		   "auth-method": 
+		   {
+		     "$type": "string",
+		     "$about": "The authentication method."
+		   }
+	   }
+	 },
+	 {
+	   "$kind": "object",
+	   "$name": "request",
+	   "$content": 
+	   {
+	     "method": 
+	     {
+		     "$type": "string",
+		     "$about": "Is the http verb to use, as GET, POST, etc. It is case insensitive."
+		   },
+		   "href": 
+		   {
+		     "$type": "anyURI",		  
+		     "$about": "Is the URI the request has to be sent to. It can be overridden by the
+                    parameter $href."
+		   },
+		   "authentication": 
+		   {
+		     "$type": "authentication",
+		     "$optional": true,
+		     "$about": "Specifies the HTTP authentication when sending the request."
+		   },
+		   "options": 
+		   {
+		     "$type": "options",
+		     "$optional": true,
+		     "$about": "Specifies the HTTP request options."
+		   },
+		   "headers": 
+		   {
+		     "$type": "headers",
+		     "$optional": true,
+		     "$about": "Specifies the HTTP request headers."
+		   },
+		   "body": 
+		   {
+         "$type": "body",
+		     "$optional": true,
+		     "$about": "Specifies the body of a non-multipart HTTP request."
+		   },
+	     "multipart": 
+	     {
+         "$type": "multipart",
+		     "$optional": true,
+		     "$about": "Specifies a multipart HTTP request."
+		   }
+	   },
+	   "$constraints" : "count($$.body) + count($$.multipart) le 1"
+	  },
+    {
+	    "$kind": "object",
+	    "$name": "response",
+      "$content": 
+	    {
+	      "status": 
+        {
+		      "$type": "integer",
+		      "$about": "This is the HTTP status code returned by the server."
+		    },
+		    "message": 
+        {
+		      "$type": "string",
+		      "$about": "This is the message returned by the server on the status line."
+		    },
+		    "headers": 
+        {
+		      "$type": "headers",
+		      "$optional": true,
+		      "$about": "The reponse headers returned by the server."
+		    },
+		    "body": 
+        {
+          "$type": "body",
+		      "$optional": true,
+		      "$about": "The body of a non-multipart HTTP response."
+		    },
+        "multipart": 
+        {
+          "$type": "multipart",
+		      "$optional": true,
+		      "$about": "Specifies a multipart HTTP response."
+		    }
+	    },
+	    "$constraints" : "count($$.body) + count($$.multipart) le 1"
 	  }
-	},
-	{
-	  "$kind": "object",
-	  "$name": "request",
-	  "$content": {
-	    "method": {
-		  "$type": "string",
-		  "$about: "Is the http verb to use, as GET, POST, etc. It is case insensitive."
-		},
-		"href": {
-		  "$type": "anyURI",		  
-		  "$about": "Is the URI the request has to be sent to. It can be overridden by the
-                     parameter $href."
-		},
-		"authentication": {
-		  "$type": "authentication",
-		  "$optional": true,
-		  "$about": "Specifies the HTTP authentication when sending the request."
-		},
-		"options": {
-		  "$type": "options",
-		  "$optional": true,
-		  "$about": "Specifies the HTTP request options."
-		},
-		"headers": {
-		  "$type": "headers",
-		  "$optional": true,
-		  "$about": "Specifies the HTTP request headers."
-		},
-		"body": {
-          "$type": "body",
-		  "$optional": true,
-		  "$about": "Specifies the body of a non-multipart HTTP request."
-		},
-	    "multipart": {
-          "$type": "multipart",
-		  "$optional": true,
-		  "$about": "Specifies a multipart HTTP request."
-		}
-	  },
-	  "$constraints" : "count($$.body) + count($$.multipart) le 1"
-	},
-	{
-	  "$kind": "object",
-	  "$name": "response",
-	  "$content": {
-	    "status": {
-		  "$type": "integer",
-		  "$about": "This is the HTTP status code returned by the server."
-		},
-		"message": {
-		  "$type": "string",
-		  "$about": "This is the message returned by the server on the status line."
-		},
-		"headers": {
-		  "$type": "headers",
-		  "$optional": true,
-		  "$about": "The reponse headers returned by the server."
-		},
-		"body": {
-          "$type": "body",
-		  "$optional": true,
-		  "$about": "The body of a non-multipart HTTP response."
-		},
-	    "multipart": {
-          "$type": "multipart",
-		  "$optional": true,
-		  "$about": "Specifies a multipart HTTP response."
-		}
-	  },
-	  "$constraints" : "count($$.body) + count($$.multipart) le 1"
-	}
   ]
 }
\ No newline at end of file

=== added directory 'modules/jsound'
=== added file 'modules/jsound/CMakeLists.txt'
--- modules/jsound/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ modules/jsound/CMakeLists.txt	2013-09-21 04:53:29 +0000
@@ -0,0 +1,19 @@
+# Copyright 2013 The FLWOR Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DECLARE_ZORBA_MODULE(FILE jsound.jq VERSION 1.0
+  URI "http://jsound.io/modules/validate";)
+  
+DECLARE_ZORBA_MODULE(FILE map.jq VERSION 1.0
+  URI "http://jsound.io/modules/validate/map";)

=== added file 'modules/jsound/jsound.jq'
--- modules/jsound/jsound.jq	1970-01-01 00:00:00 +0000
+++ modules/jsound/jsound.jq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,624 @@
+jsoniq version "1.0";
+
+
+(:
+ : Copyright 2006-2013 The FLWOR Foundation.
+ :
+ : Licensed under the Apache License, Version 2.0 (the "License");
+ : you may not use this file except in compliance with the License.
+ : You may obtain a copy of the License at
+ :
+ : http://www.apache.org/licenses/LICENSE-2.0
+ :
+ : Unless required by applicable law or agreed to in writing, software
+ : distributed under the License is distributed on an "AS IS" BASIS,
+ : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ : See the License for the specific language governing permissions and
+ : limitations under the License.
+ :)
+
+(:~
+ : JSound simple validator
+ : This is a JSONiq implemenation of the JSound (the schema for JSON) validator.
+ :
+ : @author Cezar Andrei
+ :)
+
+module namespace jsv = "http://jsound.io/modules/validate";; 
+
+import module namespace jn = "http://jsoniq.org/functions";;
+import module namespace map = "http://jsound.io/modules/validate/map";;
+
+
+declare namespace an = "http://zorba.io/annotations";;
+
+
+declare %an:sequential function 
+jsv:jsd-valid($jsd as object, $name as string, $ns as string,
+  $instance as item) as boolean
+{
+  variable $jstypes := { "foo" : 5 };
+
+  switch( false )
+  case  $jsd instance of object  
+  return
+    fn:error(QName("jsv", "BadJSoundFormat"), 
+      "The specified JSON document is not a valid JSound schema: top item not an object.");
+      
+  case exists($jsd("$namespace")) and exists($jsd("$types")) 
+  return
+    fn:error(QName("jsv", "BadJSoundFormat"), 
+      "Not a valid JSound doc: must contain '$types' and '$namespace' keys.");
+        
+  case $jsd("$namespace") instance of string
+  return
+    fn:error(QName("jsv", "BadJSoundFormat"), 
+      "Not a valid JSound doc: value of '$namespace' must be a string.");
+  
+  case $jsd("$namespace") eq $ns
+  return
+    fn:error(QName("jsv", "Invalid"), 
+            "Requested type namespace not matching schema document namespace.");
+  
+  case $jsd("$types") instance of array
+  return
+    fn:error(QName("jsv", "BadJSoundFormat"), 
+              "Not a valid JSound doc: value of '$types' must be an array.");
+          
+  default
+  return 
+    jsv:check-types( $jstypes, $jsd("$types") ); 
+         
+  (: todo: validate all type refs :)
+  
+  jsv:validate-instance($jstypes, $name, $instance)
+};
+
+
+(: The check-xxx functions just checks if the JSound schema definitions are valid. :)
+
+declare %an:sequential function
+jsv:check-types($jstypes as object, $types as array) as boolean
+{
+  every $i in
+    for $type in jn:members($types)
+    return
+      jsv:check-type($jstypes, $type )
+  satisfies $i eq true
+};
+
+
+declare %an:sequential function
+jsv:check-type($jstypes as object, $type as item) as boolean
+{
+  if( $type instance of object )
+  then 
+    if ( exists($type("$kind")) and $type("$kind") instance of string )
+    then
+      switch( $type("$kind") )
+      case "atomic" return jsv:check-atomic-type($jstypes, $type)
+      case "object" return jsv:check-object-type($jstypes, $type)
+      case "array"  return jsv:check-array-type ($jstypes, $type)
+      case "union"  return jsv:check-union-type ($jstypes, $type)
+
+      default return
+        fn:error(QName("jsv", "BadJSoundFormat"), 
+          "Not a valid JSound doc: type $kind unknown:" || $type("$kind") )
+
+    else
+      fn:error(QName("jsv", "BadJSoundFormat"), 
+        "Not a valid JSound doc: type definition must contain '$kind' key with string value.")
+  else 
+    if( $type instance of string )
+    then 
+      jsv:check-ref-type($jstypes, $type)
+    else
+      fn:error(QName("jsv", "BadJSoundFormat"), 
+        "Not a valid JSound doc: type item not an object."  )
+};
+
+
+declare %an:sequential function
+jsv:check-atomic-type($jstypes as object, $type as object) as boolean
+{
+  (: fn:trace( $type("$name"), "check-atomic-type"); :)
+  
+  if( exists($type("$baseType")) and $type("$baseType") instance of string )
+  then
+    jsv:save-type($jstypes, $type)
+  else
+    fn:error(QName("jsv", "BadJSoundFormat"), 
+      "Not a valid JSound doc: atomic type definition must contain '$baseType' key with string value.")
+      
+  (: todo: add facets checks: length, min/max Inclusive/Exclusive, etc. :)
+}; 
+
+
+declare %an:sequential function
+jsv:check-object-type($jstypes as object, $type as object) as boolean
+{
+  (: todo: check the reast of "object" type :)
+  jsv:save-type($jstypes, $type);
+  (: fn:trace( $type("$name"), "check-object-type"); :)
+
+  if( exists($type("$content")) )
+  then
+    if( $type("$content") instance of object )
+    then
+      every $i in
+        for $k in jn:keys($type("$content"))
+        return
+          if( $type("$content")($k) instance of object )
+          then
+            if( exists( $type("$content")($k)("$type")) )
+            then
+              jsv:check-type($jstypes, $type("$content")($k)("$type") )
+            else
+              if( exists( $type("$content")($k)("$kind")) )
+              then
+                jsv:check-type($jstypes, $type("$content")($k) )
+              else
+                fn:error(QName("jsv", "BadJSoundFormat"), 
+                  "Not a valid JSound doc: Key  does not contain a $type definition.")
+          else
+            fn:error(QName("jsv", "BadJSoundFormat"), 
+              "Not a valid JSound doc: Key " || $k || " in $content must have an object value.")
+          
+      satisfies $i eq true
+    else
+      fn:error(QName("jsv", "BadJSoundFormat"), 
+              "Not a valid JSound doc: $content definion of object type must be an object.")
+  else
+    fn:error(QName("jsv", "BadJSoundFormat"), 
+             "Not a valid JSound doc: Object type does not contain $content.")
+};
+
+
+declare %an:sequential function
+jsv:check-array-type($jstypes as object, $type as object) as boolean
+{
+  (: fn:trace( $type("$name"), "check-array-type"); :)
+
+  (: check all the contents :)
+  let $content := $type("$content")
+  let $checkContent :=
+    if( empty($content) )
+    then
+      fn:error(QName("jsv", "BadJSoundFormat"), 
+        "Not a valid JSound doc: $kind array must have a $content key.")
+    else
+      if( $content instance of array and jn:size($content) eq 1 )
+      then      
+      {
+        jsv:save-type($jstypes, $type);
+
+        typeswitch( $content(1) )
+        case string return
+          true
+        case object return
+            jsv:check-type($jstypes, $content(1))
+        default return
+          fn:error(QName("jsv", "BadJSoundFormat"), 
+            "Not a valid JSound doc: for $kind array, $content[1] must be string or array.")  
+      }
+      else
+        fn:error(QName("jsv", "BadJSoundFormat"), 
+          "Not a valid JSound doc: for $kind array, $content must be an array of size 1.")
+  
+  let $checkMinLength :=
+      if( fn:exists($type("$minLength")) )
+      then
+        if( $type("$minLength") instance of integer  )
+        then true
+        else fn:error(QName("jsv", "BadJSoundFormat"), 
+                      "Not a valid JSound doc: for $kind array, $minLength must be an integer.")
+      else true
+
+  let $checkMaxLength :=
+      if( fn:exists($type("$maxLength")) )
+      then
+        if( $type("$maxLength") instance of integer  )
+        then true
+        else fn:error(QName("jsv", "BadJSoundFormat"), 
+                      "Not a valid JSound doc: for $kind array, $maxLength must be an integer.")
+      else true
+    
+  return
+    $checkContent and $checkMinLength and $checkMaxLength
+};
+
+
+declare %an:sequential function
+jsv:check-union-type($jstypes as object, $type as object) as boolean
+{
+  (: fn:trace( $type("$name"), "check-union-type"); :)
+
+  let $content := $type("$content")
+  return
+    if( empty($content) )
+    then
+      fn:error(QName("jsv", "BadJSoundFormat"), 
+        "Not a valid JSound doc: $kind union must have a $content key.")
+    else
+      if( $content instance of array )
+      then      
+      {
+        jsv:save-type($jstypes, $type);
+        
+        every $i in 
+          for $c in jn:members($content)
+          return
+            typeswitch( $c )
+            case string return
+              true
+            case object return
+                jsv:check-type($jstypes, $c)
+            default return
+              fn:error(QName("jsv", "BadJSoundFormat"), 
+                "Not a valid JSound doc: for $kind union, $content items must be strings or objects.")  
+        satisfies $i eq true
+      }
+      else
+        fn:error(QName("jsv", "BadJSoundFormat"), 
+          "Not a valid JSound doc: for $kind union, $content must be an array.")
+};
+
+
+declare function
+jsv:check-ref-type($jstypes as object, $type as string) as boolean
+{
+  switch( $type )
+  case "string" return true
+  case "integer" return true
+  case "boolean" return true
+  case "anyURI"  return true
+  default return 
+  {
+    if( map:has-key($jstypes, $type) )
+    then
+      true
+    else
+     (: todo: save all refs, check them at the end to see if they exist :)
+     true
+  }
+
+  (: todo: apply resolution rules :)
+};
+
+
+declare %an:sequential function 
+jsv:save-type($jstypes as object, $type as item) as boolean
+{  
+  switch( false )
+  case fn:exists( $type("$name") )
+    return false
+  case $type("$name") instance of string
+    return fn:error(QName("jsv", "BadJSoundFormat"), 
+                    "Not a valid JSound doc: for $type, $name must be a string.")
+  case map:set-if-empty($jstypes, $type("$name"), $type)
+    return fn:error(QName("jsv", "BadJSoundFormat"), 
+          "Not a valid JSound doc: type '" || $type("$name") || "' already defined.")
+  default return true()
+};
+
+
+
+
+
+(: The validate-xxx functions actualy do the validation of the instance :)
+
+
+declare function 
+jsv:validate-instance($jstypes as object, $name as string, $instance as item)
+ as boolean
+{
+  let $type := map:get($jstypes, $name)
+  return
+    if( exists($type) )
+    then
+      jsv:validate-type($jstypes, $type, $instance)
+    else
+      fn:error(QName("jsv", "Invalid"),
+             "Requested type name not present in schema: " || $name)
+};
+
+
+declare function
+jsv:validate-type($jstypes as object, $type as item, $instance as item) as boolean
+{
+  switch( $type("$kind") )
+  case "atomic" return jsv:validate-atomic-type($jstypes, $type, $instance)
+  case "object" return jsv:validate-object-type($jstypes, $type, $instance)
+  case "array"  return jsv:validate-array-type($jstypes, $type, $instance)
+  case "union"  return jsv:validate-union-type($jstypes, $type, $instance)
+
+  default return 
+    fn:error(QName("jsv", "BadJSoundFormat"), 
+      "Not a valid JSound doc: type $kind unknown:" || $type("$kind") )
+};
+
+
+declare function
+jsv:validate-type-ref($jstypes as object, $type as string, $instance as item) as boolean
+{
+  (: todo: check first between the defined types in $jstypes and then the build-in ones, this is per spec :)
+
+  if( map:has-key($jstypes, $type) )
+  then
+    jsv:validate-type($jstypes, map:get($jstypes, $type), $instance)
+  else
+    switch( $type )
+    case "string" return
+      if ( $instance instance of string )
+      then
+        true 
+      else
+        fn:error(QName("jsv", "Invalid"), "Expected string value.")
+    case "integer" return
+      if ( $instance instance of integer or 
+           $instance instance of int )
+      then
+        true
+      else
+        fn:error(QName("jsv", "Invalid"), "Expected integer value.")
+    case "anyURI" return
+      if ( $instance instance of anyURI )
+      then
+        true
+      else
+        fn:error(QName("jsv", "Invalid"), "Expected anyURI value.")
+    case "boolean" return
+      if ( $instance instance of boolean )
+      then
+        true
+      else
+        fn:error(QName("jsv", "Invalid"), "Expected boolean value.")
+        
+    default return
+        fn:error(QName("jsv", "Invalid"), 
+          fn:concat("Type ref not defined or a built-in type: ", $type) )
+};
+
+
+declare function
+jsv:validate-atomic-type($jstypes as object, $type as object, $instance as item) as boolean
+{
+  (: fn:trace( $type("$name"), "validate-atomic-type"); :)
+  (: todo: check first between the defined types in $jstypes and then the build-in ones, this is per spec :)
+
+  if ( exists($type("$baseType")) and $type("$baseType") instance of string )
+  then
+    switch( $type("$baseType") )
+    case "integer" return
+      if ( $instance instance of integer or $instance instance of int )
+      then
+        jsv:validate-enumeration($jstypes, $type, $instance)
+      else
+        fn:error(QName("jsv", "Invalid"), "Expected integer or int value")
+
+    case "string" return
+      if ( $instance instance of string )
+      then
+        jsv:validate-enumeration($jstypes, $type, $instance)
+      else
+        fn:error( QName("jsv", "Invalid"), "Expected string value")
+
+    case "anyURI" return
+      if ( $instance instance of anyURI )
+      then
+        jsv:validate-enumeration($jstypes, $type, $instance)
+      else
+        fn:error(QName("jsv", "Invalid"), "Expected anyURI value")
+        
+    case "boolean" return
+      if ( $instance instance of boolean )
+      then
+        jsv:validate-enumeration($jstypes, $type, $instance)
+      else
+        fn:error(QName("jsv", "Invalid"), "Expected boolean value")
+    
+    default return
+      fn:error(QName("jsv", "NYI"), 
+        "$baseType: not yet implemented" || $type("$baseType") )
+  else
+    fn:error(QName("jsv", "BadJSoundFormat"), 
+      "Not a valid JSound doc: atomic type definition must contain '$baseType' key with string value.")
+      
+  (: todo: add facets checks: length, min/max Inclusive/Exclusive, etc. :)
+};
+
+declare function
+jsv:validate-enumeration($jstypes as object, $type as object, $instance as item) as boolean
+{
+  variable $enum := $type("$enumeration");
+  if( exists($enum) )
+  then
+    if( $enum instance of array )
+    then
+      if( some $v in jn:members($enum) satisfies $v eq $instance )
+      then 
+        true
+      else
+        fn:error(QName("jsv", "Invalid"), "Instance value not in the enumeration list.")
+    else
+      fn:error(QName("jsv", "BadJSoundFormat"), 
+        "Not a valid JSound doc: the value of '$enumeration' must be an array.")
+  else
+    true
+};
+
+declare function
+jsv:validate-object-type($jstypes as object, $type as object, $instance as item) as boolean
+{ 
+  (: fn:trace( $type("$name"), "validate-object-type"); :)
+  
+  variable $open := $type("$open");
+  
+  if ( $instance instance of object )
+  then 
+    if( (not exists($open)) or (exists($open) and $open eq true()) )
+    then
+      (: object is open: i.e. extra keys alowed but all defined keys must be in 
+         the instance except the default and optional ones :)
+      (
+        every $k in jn:keys($instance) 
+        satisfies 
+          let $ctype := $type("$content")($k)("$type")
+          return     
+            typeswitch( $ctype )
+            case string return
+              jsv:validate-type-ref($jstypes, $ctype, $instance($k) )
+            case object return
+              jsv:validate-type($jstypes, $ctype, $instance($k) )
+            default return
+              fn:error(QName("jsv", "BadJSoundFormat"), 
+                "Not a valid JSound doc: for $kind object, $content $type must be string or array.")
+      ) and 
+      (
+        every $k in 
+          jsv:value-except(jn:keys($type("$content")), jn:keys($instance))
+        satisfies
+          let $optional := $type("$content")($k)("$optional")
+          return 
+            if( exists($optional) and $optional eq true )
+            then true
+            else
+              fn:error(QName("jsv", "Invalid"), 
+                fn:concat("Required key not present in instance: ", $k) )
+      )
+    else
+      (: object is closed: i.e. all defined keys must be in the instance except 
+         the default ones, no extra keys alowed :)
+      (
+        every $k in jn:keys($instance) 
+        satisfies 
+          let $ctype := $type("$content")($k)("$type")
+          return     
+            typeswitch( $ctype )
+            case string return
+              jsv:validate-type-ref($jstypes, $ctype, $instance($k) )
+            case object return
+              jsv:validate-type($jstypes, $ctype, $instance($k) )
+            default return
+              fn:error(QName("jsv", "BadJSoundFormat"), 
+                "Not a valid JSound doc: for $kind object, $content $type must be string or array.")
+      ) and (
+        every $k in (: jn:keys($type("$content")) except jn:keys($instance) :)
+          jsv:value-except(jn:keys($type("$content")), jn:keys($instance)) 
+        satisfies
+          let $optional := $type("$content")($k)("$optional")
+          return 
+            if( exists($optional) and $optional eq true )
+            then true
+            else
+              fn:error(QName("jsv", "Invalid"),
+                fn:concat("Required key not present in instance: ", $k) )
+      )
+  else
+    fn:error( QName("jsv", "Invalid"),
+      fn:concat("Instance not an object specified by type: ", jsv:get-type-name($type)) )  
+};
+
+declare function
+jsv:validate-array-type($jstypes as object, $type as object, $instance as item) as boolean
+{
+  (: fn:trace( $type("$name"), "validate-array-type"); :)
+
+  if( $instance instance of array )
+  then
+    (: check all the contents :)
+    let $content := $type("$content")
+    let $validateContent :=
+        typeswitch( $content(1) )
+        case string return
+          every $i in jn:members($instance) satisfies jsv:validate-type-ref($jstypes, $content(1), $i)
+        case object return
+          every $i in jn:members($instance) satisfies jsv:validate-type($jstypes, $content(1), $i)
+        default return
+          fn:error(QName("jsv", "BadJSoundFormat"), 
+            "Not a valid JSound doc: for $kind array, $content[1] must be string or array.")  
+    let $validateMinLength :=
+      if( fn:exists($type("$minLength")) )
+      then
+        if ( $type("$minLength") le size($instance) )
+        then true
+        else fn:error(QName("jsv", "Invalid"), 
+                      "Invalid array size, smaller then $minLength facet constraint.")
+      else true
+    let $validateMaxLength :=
+      if( fn:exists($type("$maxLength")) )
+      then
+        if( $type("$maxLength") ge size($instance) )
+        then true
+        else fn:error(QName("jsv", "Invalid"), 
+                      "Invalid array size, bigger than $maxLength facet constraint.")
+      else true
+    return
+      $validateContent and $validateMinLength and $validateMaxLength
+  else
+    fn:error(QName("jsv", "Invalid"), 
+      fn:concat("Instance not an array for type: ", jsv:get-type-name($type)) )
+    
+  (: check array facets :)
+};
+
+
+declare function
+jsv:validate-union-type($jstypes as object, $type as object, $instance as item) as boolean
+{
+  let $content := $type("$content")
+  return
+    if( 
+      some $i in 
+        for $c in jn:members($content)
+        return
+          try
+          {
+            typeswitch( $c )
+            case string return
+              true
+            case object return
+                jsv:validate-type($jstypes, $c, $instance)
+            default return
+              fn:error(QName("jsv", "BadJSoundFormat"), 
+                "Not a valid JSound doc: for $kind union, $content items must be strings or objects.")  
+          }
+          catch Invalid
+          {
+             false
+          }
+      satisfies $i eq true
+    )
+    then true
+    else
+      fn:error(QName("jsv", "Invalid"), 
+        fn:concat("Instance not valid for union type: ", jsv:get-type-name($type)) )
+};
+
+
+(:---- Util functions ---------:)
+
+declare function
+jsv:get-type-name($type as object) as string
+{
+  let $name := $type("$name")
+  return
+    if ( exists($name) and $name instance of string )
+    then
+      $name
+    else
+      "N/A"
+};
+
+
+declare function 
+jsv:value-except($arg1 as xs:anyAtomicType*, $arg2 as xs:anyAtomicType*)  
+  as xs:anyAtomicType* 
+{      
+  (: fn:distinct-values( $arg1[ not($$ eq $arg2) ] ) :)
+  fn:distinct-values(
+    for $i in $arg1
+    where not( some $x in $arg2 satisfies $i eq $x )
+    return $i 
+  )
+};

=== added file 'modules/jsound/map.jq'
--- modules/jsound/map.jq	1970-01-01 00:00:00 +0000
+++ modules/jsound/map.jq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,75 @@
+jsoniq version "1.0";
+
+(:
+ : Copyright 2006-2013 The FLWOR Foundation.
+ :
+ : Licensed under the Apache License, Version 2.0 (the "License");
+ : you may not use this file except in compliance with the License.
+ : You may obtain a copy of the License at
+ :
+ : http://www.apache.org/licenses/LICENSE-2.0
+ :
+ : Unless required by applicable law or agreed to in writing, software
+ : distributed under the License is distributed on an "AS IS" BASIS,
+ : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ : See the License for the specific language governing permissions and
+ : limitations under the License.
+ :)
+
+(:~
+ : Map utility
+ :
+ :)
+ 
+module namespace map = "http://jsound.io/modules/validate/map";;
+ 
+declare namespace an = "http://zorba.io/annotations";;
+
+declare %an:sequential function 
+map:set($map as object, $key as xs:string, $value as item) as boolean
+{
+  if( keys($map) = $key ) then
+    insert json { $key : $value } into $map;
+  else
+    replace value of json $map.$key with $value;
+    
+  true
+};
+
+
+declare %an:sequential function 
+map:set-if-empty($map as object, $key as xs:string, $value as item) as boolean
+{
+  if( keys($map) = $key ) 
+  then
+    false
+  else
+  {
+    insert json { $key : $value } into $map;
+    true
+  }
+};
+
+
+
+declare function 
+map:get($map as object, $key as string) as item
+{
+  $map.$key
+};
+
+
+declare function
+map:has-key($map as object, $key as string) as boolean
+{
+  keys($map) = $key
+};
+
+
+
+(:
+variable $foo := { "foo" : 5 };
+local:set($foo, "foo", 6);
+local:set($foo, "bar", 7);
+$foo
+:)

=== added file 'test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-array.xml.res'
--- test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-array.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-array.xml.res	2013-09-21 04:53:29 +0000
@@ -0,0 +1,1 @@
+true

=== added file 'test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-integer.xml.res'
--- test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-integer.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-integer.xml.res	2013-09-21 04:53:29 +0000
@@ -0,0 +1,1 @@
+true

=== added file 'test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-str-enum.xml.res'
--- test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-str-enum.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-str-enum.xml.res	2013-09-21 04:53:29 +0000
@@ -0,0 +1,1 @@
+true

=== added file 'test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-string.xml.res'
--- test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-string.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/modules/jsound-atomic-string.xml.res	2013-09-21 04:53:29 +0000
@@ -0,0 +1,1 @@
+true

=== added file 'test/rbkt/ExpQueryResults/zorba/modules/jsound-object1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/modules/jsound-object1.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/modules/jsound-object1.xml.res	2013-09-21 04:53:29 +0000
@@ -0,0 +1,1 @@
+true

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-01.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-01.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-01.csv	2013-09-21 04:53:29 +0000
@@ -1,6 +1,6 @@
-first,second,third
-one,two,three
-"quoted","embedded "" quote","embedded
-newline"
-""" leading quote","","trailing quote """
-last,three,fields
+first,second,third
+one,two,three
+"quoted","embedded "" quote","embedded
+newline"
+""" leading quote","","trailing quote """
+last,three,fields

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-cast-01.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-cast-01.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-cast-01.csv	2013-09-21 04:53:29 +0000
@@ -1,2 +1,2 @@
-string,integer,decimal,double,boolean,null
-foo,42,98.6,1E4,false,null
+string,integer,decimal,double,boolean,null
+foo,42,98.6,1E4,false,null

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-extra-01.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-extra-01.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-extra-01.csv	2013-09-21 04:53:29 +0000
@@ -1,3 +1,3 @@
-first,second,third
-one,two,three,four
-last,three,fields
+first,second,third
+one,two,three,four
+last,three,fields

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-missing-01.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-missing-01.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-missing-01.csv	2013-09-21 04:53:29 +0000
@@ -1,3 +1,3 @@
-first,second,third
-,two,three
-last,three,fields
+first,second,third
+,two,three
+last,three,fields

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-missing-02.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-missing-02.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-missing-02.csv	2013-09-21 04:53:29 +0000
@@ -1,3 +1,3 @@
-first,second,third
-one,,three
-last,three,fields
+first,second,third
+one,,three
+last,three,fields

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-missing-03.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-missing-03.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-missing-03.csv	2013-09-21 04:53:29 +0000
@@ -1,3 +1,3 @@
-first,second,third
-one,two,
-last,three,fields
+first,second,third
+one,two,
+last,three,fields

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-missing-04.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-missing-04.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-missing-04.csv	2013-09-21 04:53:29 +0000
@@ -1,3 +1,3 @@
-first,second,third
-one,two
-last,three,fields
+first,second,third
+one,two
+last,three,fields

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-no-field-names-01.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-no-field-names-01.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-no-field-names-01.csv	2013-09-21 04:53:29 +0000
@@ -1,5 +1,5 @@
-one,two,three
-"quoted","embedded "" quote","embedded
-newline"
-""" leading quote","","trailing quote """
-last,three,fields
+one,two,three
+"quoted","embedded "" quote","embedded
+newline"
+""" leading quote","","trailing quote """
+last,three,fields

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-quote-char-01.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-quote-char-01.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-quote-char-01.csv	2013-09-21 04:53:29 +0000
@@ -1,6 +1,6 @@
-first,second,third
-one,two,three
-'quoted','embedded '' quote','embedded
-newline'
-''' leading quote','','trailing quote '''
-last,three,fields
+first,second,third
+one,two,three
+'quoted','embedded '' quote','embedded
+newline'
+''' leading quote','','trailing quote '''
+last,three,fields

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-quote-escape-01.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-quote-escape-01.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-quote-escape-01.csv	2013-09-21 04:53:29 +0000
@@ -1,6 +1,6 @@
-first,second,third
-one,two,three
-"quoted","embedded \" quote","embedded
-newline"
-"\" leading quote","","trailing quote \""
-last,three,fields
+first,second,third
+one,two,three
+"quoted","embedded \" quote","embedded
+newline"
+"\" leading quote","","trailing quote \""
+last,three,fields

=== modified file 'test/rbkt/Queries/zorba/csv/sample_files/csv-separator-01.csv'
--- test/rbkt/Queries/zorba/csv/sample_files/csv-separator-01.csv	2013-09-20 12:26:56 +0000
+++ test/rbkt/Queries/zorba/csv/sample_files/csv-separator-01.csv	2013-09-21 04:53:29 +0000
@@ -1,6 +1,6 @@
-first|second|third
-one|two|three
-"quoted"|"embedded "" quote"|"embedded
-newline"
-""" leading quote"|""|"trailing quote """
-last|three|fields
+first|second|third
+one|two|three
+"quoted"|"embedded "" quote"|"embedded
+newline"
+""" leading quote"|""|"trailing quote """
+last|three|fields

=== added file 'test/rbkt/Queries/zorba/modules/jsound-array-length-err.spec'
--- test/rbkt/Queries/zorba/modules/jsound-array-length-err.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-array-length-err.spec	2013-09-21 04:53:29 +0000
@@ -0,0 +1,1 @@
+Error: jsv:Invalid : Invalid array size, bigger than $maxLength facet constraint.

=== added file 'test/rbkt/Queries/zorba/modules/jsound-array-length-err.xq'
--- test/rbkt/Queries/zorba/modules/jsound-array-length-err.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-array-length-err.xq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,51 @@
+import module namespace jsv = "http://jsound.io/modules/validate";; 
+
+let $jsd :=
+{
+ "$namespace" : "http://zorba.io/modules/images/";,
+ "$types" : [
+  {
+    "$name" : "pointType",
+    "$kind" : "array",
+    "$content" : [ "integer" ],
+    "$minLength" : 2,
+    "$maxLength" : 2
+  },
+  {
+    "$name" : "line",
+    "$kind" : "object",
+    "$content" : 
+    {
+      "start" : 
+      {
+        "$type" : "pointType"
+      },
+      "end" : 
+      {
+        "$type" : "integer"
+      },
+      "strokeWidth" : 
+      {
+        "$type" : "double",
+        "$optional" : true
+      },
+      "antiAliasing" : 
+      {
+        "$type" : "boolean",
+        "$optional" : true
+      }
+    }
+  }  
+ ]
+}
+
+
+
+let $instance := 
+  {
+    "start": [1, 2, 5],
+    "end": 5
+  }
+
+return
+  jsv:jsd-valid($jsd, "line", "http://zorba.io/modules/images/";, $instance)

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-array-err.spec'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-array-err.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-array-err.spec	2013-09-21 04:53:29 +0000
@@ -0,0 +1,1 @@
+Error: jsv:Invalid : Expected string value.

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-array-err.xq'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-array-err.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-array-err.xq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,19 @@
+import module namespace jsv = "http://jsound.io/modules/validate";; 
+
+let $jsd :=
+{
+  "$namespace" : "http://www.example.com/my-schema";,
+  "$types" : [
+    {
+      "$kind" : "array",
+      "$name" : "a-string-array",
+      "$content" : [ "string" ]
+    }
+  ]
+}
+
+
+let $instance := ["", "a", "abc", 123]
+
+return
+  jsv:jsd-valid($jsd, "a-string-array", "http://www.example.com/my-schema";, $instance)

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-array.xq'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-array.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-array.xq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,19 @@
+import module namespace jsv = "http://jsound.io/modules/validate";; 
+
+let $jsd :=
+{
+  "$namespace" : "http://www.example.com/my-schema";,
+  "$types" : [
+    {
+      "$kind" : "array",
+      "$name" : "a-string-array",
+      "$content" : [ "string" ]
+    }
+  ]
+}
+
+
+let $instance := ["", "a", "abc"]
+
+return
+  jsv:jsd-valid($jsd, "a-string-array", "http://www.example.com/my-schema";, $instance)

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-integer.xq'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-integer.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-integer.xq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,19 @@
+import module namespace jsv = "http://jsound.io/modules/validate";; 
+
+let $jsd :=
+{
+  "$namespace" : "http://www.example.com/my-schema";,
+  "$types" : [
+    {
+      "$kind" : "atomic",
+      "$name" : "small-number",
+      "$baseType" : "integer"
+    }
+  ]
+}
+
+
+let $instance := 5
+
+return
+  jsv:jsd-valid($jsd, "small-number", "http://www.example.com/my-schema";, $instance)

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-str-enum-err.spec'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-str-enum-err.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-str-enum-err.spec	2013-09-21 04:53:29 +0000
@@ -0,0 +1,1 @@
+Error: jsv:Invalid : Instance value not in the enumeration list.

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-str-enum-err.xq'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-str-enum-err.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-str-enum-err.xq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,20 @@
+import module namespace jsv = "http://jsound.io/modules/validate";; 
+
+let $jsd :=
+{
+  "$namespace" : "http://www.example.com/my-schema";,
+  "$types" : [
+    {
+      "$kind" : "atomic",
+      "$name" : "a-string-enum",
+      "$baseType" : "string",
+      "$enumeration" : [ "foo", "bar"]
+    }
+  ]
+}
+
+
+let $instance := "baz-not-valid"
+
+return
+  jsv:jsd-valid($jsd, "a-string-enum", "http://www.example.com/my-schema";, $instance)

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-str-enum.xq'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-str-enum.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-str-enum.xq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,20 @@
+import module namespace jsv = "http://jsound.io/modules/validate";; 
+
+let $jsd :=
+{
+  "$namespace" : "http://www.example.com/my-schema";,
+  "$types" : [
+    {
+      "$kind" : "atomic",
+      "$name" : "a-string-enum",
+      "$baseType" : "string",
+      "$enumeration" : [ "foo", "bar"]
+    }
+  ]
+}
+
+
+let $instance := "bar"
+
+return
+  jsv:jsd-valid($jsd, "a-string-enum", "http://www.example.com/my-schema";, $instance)

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-string-err1.spec'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-string-err1.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-string-err1.spec	2013-09-21 04:53:29 +0000
@@ -0,0 +1,1 @@
+Error: jsv:Invalid : Expected string value

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-string-err1.xq'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-string-err1.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-string-err1.xq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,19 @@
+import module namespace jsv = "http://jsound.io/modules/validate";; 
+
+let $jsd :=
+{
+  "$namespace" : "http://www.example.com/my-schema";,
+  "$types" : [
+    {
+      "$kind" : "atomic",
+      "$name" : "a-string",
+      "$baseType" : "string"
+    }
+  ]
+}
+
+
+let $instance := 1
+
+return
+  jsv:jsd-valid($jsd, "a-string", "http://www.example.com/my-schema";, $instance)

=== added file 'test/rbkt/Queries/zorba/modules/jsound-atomic-string.xq'
--- test/rbkt/Queries/zorba/modules/jsound-atomic-string.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-atomic-string.xq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,19 @@
+import module namespace jsv = "http://jsound.io/modules/validate";; 
+
+let $jsd :=
+{
+  "$namespace" : "http://www.example.com/my-schema";,
+  "$types" : [
+    {
+      "$kind" : "atomic",
+      "$name" : "a-string",
+      "$baseType" : "string"
+    }
+  ]
+}
+
+
+let $instance := "hello"
+
+return
+  jsv:jsd-valid($jsd, "a-string", "http://www.example.com/my-schema";, $instance)

=== added file 'test/rbkt/Queries/zorba/modules/jsound-object1.xq'
--- test/rbkt/Queries/zorba/modules/jsound-object1.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/modules/jsound-object1.xq	2013-09-21 04:53:29 +0000
@@ -0,0 +1,51 @@
+import module namespace jsv = "http://jsound.io/modules/validate";; 
+
+let $jsd :=
+{
+ "$namespace" : "http://zorba.io/modules/images/";,
+ "$types" : [
+  {
+    "$name" : "pointType",
+    "$kind" : "array",
+    "$content" : [ "integer" ],
+    "$minLength" : 2,
+    "$maxLength" : 2
+  },
+  {
+    "$name" : "line",
+    "$kind" : "object",
+    "$content" : 
+    {
+      "start" : 
+      {
+        "$type" : "pointType"
+      },
+      "end" : 
+      {
+        "$type" : "integer"
+      },
+      "strokeWidth" : 
+      {
+        "$type" : "double",
+        "$optional" : true
+      },
+      "antiAliasing" : 
+      {
+        "$type" : "boolean",
+        "$optional" : true
+      }
+    }
+  }  
+ ]
+}
+
+
+
+let $instance := 
+  {
+    "start": [1, 2],
+    "end": 5
+  }
+
+return
+  jsv:jsd-valid($jsd, "line", "http://zorba.io/modules/images/";, $instance)

-- 
Mailing list: https://launchpad.net/~zorba-coders
Post to     : zorba-coders@lists.launchpad.net
Unsubscribe : https://launchpad.net/~zorba-coders
More help   : https://help.launchpad.net/ListHelp

Reply via email to