mirror of
				https://github.com/linuxkit/linuxkit.git
				synced 2025-10-31 03:40:16 +00:00 
			
		
		
		
	| @@ -30,6 +30,9 @@ github.com/spf13/cobra 7be4beda01ec05d0b93d80b3facd2b6f44080d94 | ||||
| github.com/spf13/pflag 9ff6c6923cfffbcd502984b8e0c80539a94968b7 | ||||
| github.com/surma/gocpio fcb68777e7dc4ea43ffce871b552c0d073c17495 | ||||
| github.com/vaughan0/go-ini a98ad7ee00ec53921f08832bc06ecf7fd600e6a1 | ||||
| github.com/xeipuuv/gojsonpointer 6fe8760cad3569743d51ddbb243b26f8456742dc | ||||
| github.com/xeipuuv/gojsonreference e02fc20de94c78484cd5ffb007f8af96be030a45 | ||||
| github.com/xeipuuv/gojsonschema 702b404897d4364af44dc8dcabc9815947942325 | ||||
| golang.org/x/crypto 573951cbe80bb6352881271bb276f48749eab6f4 | ||||
| golang.org/x/net a6577fac2d73be281a500b310739095313165611 | ||||
| golang.org/x/oauth2 1611bb46e67abc64a71ecc5c3ae67f1cbbc2b921 | ||||
|   | ||||
							
								
								
									
										202
									
								
								vendor/github.com/xeipuuv/gojsonpointer/LICENSE-APACHE-2.0.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/xeipuuv/gojsonpointer/LICENSE-APACHE-2.0.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | ||||
|  | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|                         http://www.apache.org/licenses/ | ||||
|  | ||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||
|  | ||||
|    1. Definitions. | ||||
|  | ||||
|       "License" shall mean the terms and conditions for use, reproduction, | ||||
|       and distribution as defined by Sections 1 through 9 of this document. | ||||
|  | ||||
|       "Licensor" shall mean the copyright owner or entity authorized by | ||||
|       the copyright owner that is granting the License. | ||||
|  | ||||
|       "Legal Entity" shall mean the union of the acting entity and all | ||||
|       other entities that control, are controlled by, or are under common | ||||
|       control with that entity. For the purposes of this definition, | ||||
|       "control" means (i) the power, direct or indirect, to cause the | ||||
|       direction or management of such entity, whether by contract or | ||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||
|       outstanding shares, or (iii) beneficial ownership of such entity. | ||||
|  | ||||
|       "You" (or "Your") shall mean an individual or Legal Entity | ||||
|       exercising permissions granted by this License. | ||||
|  | ||||
|       "Source" form shall mean the preferred form for making modifications, | ||||
|       including but not limited to software source code, documentation | ||||
|       source, and configuration files. | ||||
|  | ||||
|       "Object" form shall mean any form resulting from mechanical | ||||
|       transformation or translation of a Source form, including but | ||||
|       not limited to compiled object code, generated documentation, | ||||
|       and conversions to other media types. | ||||
|  | ||||
|       "Work" shall mean the work of authorship, whether in Source or | ||||
|       Object form, made available under the License, as indicated by a | ||||
|       copyright notice that is included in or attached to the work | ||||
|       (an example is provided in the Appendix below). | ||||
|  | ||||
|       "Derivative Works" shall mean any work, whether in Source or Object | ||||
|       form, that is based on (or derived from) the Work and for which the | ||||
|       editorial revisions, annotations, elaborations, or other modifications | ||||
|       represent, as a whole, an original work of authorship. For the purposes | ||||
|       of this License, Derivative Works shall not include works that remain | ||||
|       separable from, or merely link (or bind by name) to the interfaces of, | ||||
|       the Work and Derivative Works thereof. | ||||
|  | ||||
|       "Contribution" shall mean any work of authorship, including | ||||
|       the original version of the Work and any modifications or additions | ||||
|       to that Work or Derivative Works thereof, that is intentionally | ||||
|       submitted to Licensor for inclusion in the Work by the copyright owner | ||||
|       or by an individual or Legal Entity authorized to submit on behalf of | ||||
|       the copyright owner. For the purposes of this definition, "submitted" | ||||
|       means any form of electronic, verbal, or written communication sent | ||||
|       to the Licensor or its representatives, including but not limited to | ||||
|       communication on electronic mailing lists, source code control systems, | ||||
|       and issue tracking systems that are managed by, or on behalf of, the | ||||
|       Licensor for the purpose of discussing and improving the Work, but | ||||
|       excluding communication that is conspicuously marked or otherwise | ||||
|       designated in writing by the copyright owner as "Not a Contribution." | ||||
|  | ||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||
|       on behalf of whom a Contribution has been received by Licensor and | ||||
|       subsequently incorporated within the Work. | ||||
|  | ||||
|    2. Grant of Copyright License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       copyright license to reproduce, prepare Derivative Works of, | ||||
|       publicly display, publicly perform, sublicense, and distribute the | ||||
|       Work and such Derivative Works in Source or Object form. | ||||
|  | ||||
|    3. Grant of Patent License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       (except as stated in this section) patent license to make, have made, | ||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||
|       where such license applies only to those patent claims licensable | ||||
|       by such Contributor that are necessarily infringed by their | ||||
|       Contribution(s) alone or by combination of their Contribution(s) | ||||
|       with the Work to which such Contribution(s) was submitted. If You | ||||
|       institute patent litigation against any entity (including a | ||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||
|       or a Contribution incorporated within the Work constitutes direct | ||||
|       or contributory patent infringement, then any patent licenses | ||||
|       granted to You under this License for that Work shall terminate | ||||
|       as of the date such litigation is filed. | ||||
|  | ||||
|    4. Redistribution. You may reproduce and distribute copies of the | ||||
|       Work or Derivative Works thereof in any medium, with or without | ||||
|       modifications, and in Source or Object form, provided that You | ||||
|       meet the following conditions: | ||||
|  | ||||
|       (a) You must give any other recipients of the Work or | ||||
|           Derivative Works a copy of this License; and | ||||
|  | ||||
|       (b) You must cause any modified files to carry prominent notices | ||||
|           stating that You changed the files; and | ||||
|  | ||||
|       (c) You must retain, in the Source form of any Derivative Works | ||||
|           that You distribute, all copyright, patent, trademark, and | ||||
|           attribution notices from the Source form of the Work, | ||||
|           excluding those notices that do not pertain to any part of | ||||
|           the Derivative Works; and | ||||
|  | ||||
|       (d) If the Work includes a "NOTICE" text file as part of its | ||||
|           distribution, then any Derivative Works that You distribute must | ||||
|           include a readable copy of the attribution notices contained | ||||
|           within such NOTICE file, excluding those notices that do not | ||||
|           pertain to any part of the Derivative Works, in at least one | ||||
|           of the following places: within a NOTICE text file distributed | ||||
|           as part of the Derivative Works; within the Source form or | ||||
|           documentation, if provided along with the Derivative Works; or, | ||||
|           within a display generated by the Derivative Works, if and | ||||
|           wherever such third-party notices normally appear. The contents | ||||
|           of the NOTICE file are for informational purposes only and | ||||
|           do not modify the License. You may add Your own attribution | ||||
|           notices within Derivative Works that You distribute, alongside | ||||
|           or as an addendum to the NOTICE text from the Work, provided | ||||
|           that such additional attribution notices cannot be construed | ||||
|           as modifying the License. | ||||
|  | ||||
|       You may add Your own copyright statement to Your modifications and | ||||
|       may provide additional or different license terms and conditions | ||||
|       for use, reproduction, or distribution of Your modifications, or | ||||
|       for any such Derivative Works as a whole, provided Your use, | ||||
|       reproduction, and distribution of the Work otherwise complies with | ||||
|       the conditions stated in this License. | ||||
|  | ||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||
|       any Contribution intentionally submitted for inclusion in the Work | ||||
|       by You to the Licensor shall be under the terms and conditions of | ||||
|       this License, without any additional terms or conditions. | ||||
|       Notwithstanding the above, nothing herein shall supersede or modify | ||||
|       the terms of any separate license agreement you may have executed | ||||
|       with Licensor regarding such Contributions. | ||||
|  | ||||
|    6. Trademarks. This License does not grant permission to use the trade | ||||
|       names, trademarks, service marks, or product names of the Licensor, | ||||
|       except as required for reasonable and customary use in describing the | ||||
|       origin of the Work and reproducing the content of the NOTICE file. | ||||
|  | ||||
|    7. Disclaimer of Warranty. Unless required by applicable law or | ||||
|       agreed to in writing, Licensor provides the Work (and each | ||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||
|       implied, including, without limitation, any warranties or conditions | ||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||
|       appropriateness of using or redistributing the Work and assume any | ||||
|       risks associated with Your exercise of permissions under this License. | ||||
|  | ||||
|    8. Limitation of Liability. In no event and under no legal theory, | ||||
|       whether in tort (including negligence), contract, or otherwise, | ||||
|       unless required by applicable law (such as deliberate and grossly | ||||
|       negligent acts) or agreed to in writing, shall any Contributor be | ||||
|       liable to You for damages, including any direct, indirect, special, | ||||
|       incidental, or consequential damages of any character arising as a | ||||
|       result of this License or out of the use or inability to use the | ||||
|       Work (including but not limited to damages for loss of goodwill, | ||||
|       work stoppage, computer failure or malfunction, or any and all | ||||
|       other commercial damages or losses), even if such Contributor | ||||
|       has been advised of the possibility of such damages. | ||||
|  | ||||
|    9. Accepting Warranty or Additional Liability. While redistributing | ||||
|       the Work or Derivative Works thereof, You may choose to offer, | ||||
|       and charge a fee for, acceptance of support, warranty, indemnity, | ||||
|       or other liability obligations and/or rights consistent with this | ||||
|       License. However, in accepting such obligations, You may act only | ||||
|       on Your own behalf and on Your sole responsibility, not on behalf | ||||
|       of any other Contributor, and only if You agree to indemnify, | ||||
|       defend, and hold each Contributor harmless for any liability | ||||
|       incurred by, or claims asserted against, such Contributor by reason | ||||
|       of your accepting any such warranty or additional liability. | ||||
|  | ||||
|    END OF TERMS AND CONDITIONS | ||||
|  | ||||
|    APPENDIX: How to apply the Apache License to your work. | ||||
|  | ||||
|       To apply the Apache License to your work, attach the following | ||||
|       boilerplate notice, with the fields enclosed by brackets "[]" | ||||
|       replaced with your own identifying information. (Don't include | ||||
|       the brackets!)  The text should be enclosed in the appropriate | ||||
|       comment syntax for the file format. We also recommend that a | ||||
|       file or class name and description of purpose be included on the | ||||
|       same "printed page" as the copyright notice for easier | ||||
|       identification within third-party archives. | ||||
|  | ||||
|    Copyright 2015 xeipuuv | ||||
|  | ||||
|    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. | ||||
							
								
								
									
										8
									
								
								vendor/github.com/xeipuuv/gojsonpointer/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/xeipuuv/gojsonpointer/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| # gojsonpointer | ||||
| An implementation of JSON Pointer - Go language | ||||
|  | ||||
| ## References | ||||
| http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 | ||||
|  | ||||
| ### Note | ||||
| The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, the reference token MUST contain either...' is not implemented. | ||||
							
								
								
									
										190
									
								
								vendor/github.com/xeipuuv/gojsonpointer/pointer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								vendor/github.com/xeipuuv/gojsonpointer/pointer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author  			xeipuuv | ||||
| // author-github 	https://github.com/xeipuuv | ||||
| // author-mail		xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name	gojsonpointer | ||||
| // repository-desc	An implementation of JSON Pointer - Go language | ||||
| // | ||||
| // description		Main and unique file. | ||||
| // | ||||
| // created      	25-02-2013 | ||||
|  | ||||
| package gojsonpointer | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	const_empty_pointer     = `` | ||||
| 	const_pointer_separator = `/` | ||||
|  | ||||
| 	const_invalid_start = `JSON pointer must be empty or start with a "` + const_pointer_separator + `"` | ||||
| ) | ||||
|  | ||||
| type implStruct struct { | ||||
| 	mode string // "SET" or "GET" | ||||
|  | ||||
| 	inDocument interface{} | ||||
|  | ||||
| 	setInValue interface{} | ||||
|  | ||||
| 	getOutNode interface{} | ||||
| 	getOutKind reflect.Kind | ||||
| 	outError   error | ||||
| } | ||||
|  | ||||
| type JsonPointer struct { | ||||
| 	referenceTokens []string | ||||
| } | ||||
|  | ||||
| // NewJsonPointer parses the given string JSON pointer and returns an object | ||||
| func NewJsonPointer(jsonPointerString string) (p JsonPointer, err error) { | ||||
|  | ||||
| 	// Pointer to the root of the document | ||||
| 	if len(jsonPointerString) == 0 { | ||||
| 		// Keep referenceTokens nil | ||||
| 		return | ||||
| 	} | ||||
| 	if jsonPointerString[0] != '/' { | ||||
| 		return p, errors.New(const_invalid_start) | ||||
| 	} | ||||
|  | ||||
| 	p.referenceTokens = strings.Split(jsonPointerString[1:], const_pointer_separator) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Uses the pointer to retrieve a value from a JSON document | ||||
| func (p *JsonPointer) Get(document interface{}) (interface{}, reflect.Kind, error) { | ||||
|  | ||||
| 	is := &implStruct{mode: "GET", inDocument: document} | ||||
| 	p.implementation(is) | ||||
| 	return is.getOutNode, is.getOutKind, is.outError | ||||
|  | ||||
| } | ||||
|  | ||||
| // Uses the pointer to update a value from a JSON document | ||||
| func (p *JsonPointer) Set(document interface{}, value interface{}) (interface{}, error) { | ||||
|  | ||||
| 	is := &implStruct{mode: "SET", inDocument: document, setInValue: value} | ||||
| 	p.implementation(is) | ||||
| 	return document, is.outError | ||||
|  | ||||
| } | ||||
|  | ||||
| // Both Get and Set functions use the same implementation to avoid code duplication | ||||
| func (p *JsonPointer) implementation(i *implStruct) { | ||||
|  | ||||
| 	kind := reflect.Invalid | ||||
|  | ||||
| 	// Full document when empty | ||||
| 	if len(p.referenceTokens) == 0 { | ||||
| 		i.getOutNode = i.inDocument | ||||
| 		i.outError = nil | ||||
| 		i.getOutKind = kind | ||||
| 		i.outError = nil | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	node := i.inDocument | ||||
|  | ||||
| 	for ti, token := range p.referenceTokens { | ||||
|  | ||||
| 		isLastToken := ti == len(p.referenceTokens)-1 | ||||
|  | ||||
| 		switch v := node.(type) { | ||||
|  | ||||
| 		case map[string]interface{}: | ||||
| 			decodedToken := decodeReferenceToken(token) | ||||
| 			if _, ok := v[decodedToken]; ok { | ||||
| 				node = v[decodedToken] | ||||
| 				if isLastToken && i.mode == "SET" { | ||||
| 					v[decodedToken] = i.setInValue | ||||
| 				} | ||||
| 			} else { | ||||
| 				i.outError = fmt.Errorf("Object has no key '%s'", decodedToken) | ||||
| 				i.getOutKind = reflect.Map | ||||
| 				i.getOutNode = nil | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 		case []interface{}: | ||||
| 			tokenIndex, err := strconv.Atoi(token) | ||||
| 			if err != nil { | ||||
| 				i.outError = fmt.Errorf("Invalid array index '%s'", token) | ||||
| 				i.getOutKind = reflect.Slice | ||||
| 				i.getOutNode = nil | ||||
| 				return | ||||
| 			} | ||||
| 			if tokenIndex < 0 || tokenIndex >= len(v) { | ||||
| 				i.outError = fmt.Errorf("Out of bound array[0,%d] index '%d'", len(v), tokenIndex) | ||||
| 				i.getOutKind = reflect.Slice | ||||
| 				i.getOutNode = nil | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			node = v[tokenIndex] | ||||
| 			if isLastToken && i.mode == "SET" { | ||||
| 				v[tokenIndex] = i.setInValue | ||||
| 			} | ||||
|  | ||||
| 		default: | ||||
| 			i.outError = fmt.Errorf("Invalid token reference '%s'", token) | ||||
| 			i.getOutKind = reflect.ValueOf(node).Kind() | ||||
| 			i.getOutNode = nil | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	i.getOutNode = node | ||||
| 	i.getOutKind = reflect.ValueOf(node).Kind() | ||||
| 	i.outError = nil | ||||
| } | ||||
|  | ||||
| // Pointer to string representation function | ||||
| func (p *JsonPointer) String() string { | ||||
|  | ||||
| 	if len(p.referenceTokens) == 0 { | ||||
| 		return const_empty_pointer | ||||
| 	} | ||||
|  | ||||
| 	pointerString := const_pointer_separator + strings.Join(p.referenceTokens, const_pointer_separator) | ||||
|  | ||||
| 	return pointerString | ||||
| } | ||||
|  | ||||
| // Specific JSON pointer encoding here | ||||
| // ~0 => ~ | ||||
| // ~1 => / | ||||
| // ... and vice versa | ||||
|  | ||||
| func decodeReferenceToken(token string) string { | ||||
| 	step1 := strings.Replace(token, `~1`, `/`, -1) | ||||
| 	step2 := strings.Replace(step1, `~0`, `~`, -1) | ||||
| 	return step2 | ||||
| } | ||||
|  | ||||
| func encodeReferenceToken(token string) string { | ||||
| 	step1 := strings.Replace(token, `~`, `~0`, -1) | ||||
| 	step2 := strings.Replace(step1, `/`, `~1`, -1) | ||||
| 	return step2 | ||||
| } | ||||
							
								
								
									
										202
									
								
								vendor/github.com/xeipuuv/gojsonreference/LICENSE-APACHE-2.0.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/xeipuuv/gojsonreference/LICENSE-APACHE-2.0.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | ||||
|  | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|                         http://www.apache.org/licenses/ | ||||
|  | ||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||
|  | ||||
|    1. Definitions. | ||||
|  | ||||
|       "License" shall mean the terms and conditions for use, reproduction, | ||||
|       and distribution as defined by Sections 1 through 9 of this document. | ||||
|  | ||||
|       "Licensor" shall mean the copyright owner or entity authorized by | ||||
|       the copyright owner that is granting the License. | ||||
|  | ||||
|       "Legal Entity" shall mean the union of the acting entity and all | ||||
|       other entities that control, are controlled by, or are under common | ||||
|       control with that entity. For the purposes of this definition, | ||||
|       "control" means (i) the power, direct or indirect, to cause the | ||||
|       direction or management of such entity, whether by contract or | ||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||
|       outstanding shares, or (iii) beneficial ownership of such entity. | ||||
|  | ||||
|       "You" (or "Your") shall mean an individual or Legal Entity | ||||
|       exercising permissions granted by this License. | ||||
|  | ||||
|       "Source" form shall mean the preferred form for making modifications, | ||||
|       including but not limited to software source code, documentation | ||||
|       source, and configuration files. | ||||
|  | ||||
|       "Object" form shall mean any form resulting from mechanical | ||||
|       transformation or translation of a Source form, including but | ||||
|       not limited to compiled object code, generated documentation, | ||||
|       and conversions to other media types. | ||||
|  | ||||
|       "Work" shall mean the work of authorship, whether in Source or | ||||
|       Object form, made available under the License, as indicated by a | ||||
|       copyright notice that is included in or attached to the work | ||||
|       (an example is provided in the Appendix below). | ||||
|  | ||||
|       "Derivative Works" shall mean any work, whether in Source or Object | ||||
|       form, that is based on (or derived from) the Work and for which the | ||||
|       editorial revisions, annotations, elaborations, or other modifications | ||||
|       represent, as a whole, an original work of authorship. For the purposes | ||||
|       of this License, Derivative Works shall not include works that remain | ||||
|       separable from, or merely link (or bind by name) to the interfaces of, | ||||
|       the Work and Derivative Works thereof. | ||||
|  | ||||
|       "Contribution" shall mean any work of authorship, including | ||||
|       the original version of the Work and any modifications or additions | ||||
|       to that Work or Derivative Works thereof, that is intentionally | ||||
|       submitted to Licensor for inclusion in the Work by the copyright owner | ||||
|       or by an individual or Legal Entity authorized to submit on behalf of | ||||
|       the copyright owner. For the purposes of this definition, "submitted" | ||||
|       means any form of electronic, verbal, or written communication sent | ||||
|       to the Licensor or its representatives, including but not limited to | ||||
|       communication on electronic mailing lists, source code control systems, | ||||
|       and issue tracking systems that are managed by, or on behalf of, the | ||||
|       Licensor for the purpose of discussing and improving the Work, but | ||||
|       excluding communication that is conspicuously marked or otherwise | ||||
|       designated in writing by the copyright owner as "Not a Contribution." | ||||
|  | ||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||
|       on behalf of whom a Contribution has been received by Licensor and | ||||
|       subsequently incorporated within the Work. | ||||
|  | ||||
|    2. Grant of Copyright License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       copyright license to reproduce, prepare Derivative Works of, | ||||
|       publicly display, publicly perform, sublicense, and distribute the | ||||
|       Work and such Derivative Works in Source or Object form. | ||||
|  | ||||
|    3. Grant of Patent License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       (except as stated in this section) patent license to make, have made, | ||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||
|       where such license applies only to those patent claims licensable | ||||
|       by such Contributor that are necessarily infringed by their | ||||
|       Contribution(s) alone or by combination of their Contribution(s) | ||||
|       with the Work to which such Contribution(s) was submitted. If You | ||||
|       institute patent litigation against any entity (including a | ||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||
|       or a Contribution incorporated within the Work constitutes direct | ||||
|       or contributory patent infringement, then any patent licenses | ||||
|       granted to You under this License for that Work shall terminate | ||||
|       as of the date such litigation is filed. | ||||
|  | ||||
|    4. Redistribution. You may reproduce and distribute copies of the | ||||
|       Work or Derivative Works thereof in any medium, with or without | ||||
|       modifications, and in Source or Object form, provided that You | ||||
|       meet the following conditions: | ||||
|  | ||||
|       (a) You must give any other recipients of the Work or | ||||
|           Derivative Works a copy of this License; and | ||||
|  | ||||
|       (b) You must cause any modified files to carry prominent notices | ||||
|           stating that You changed the files; and | ||||
|  | ||||
|       (c) You must retain, in the Source form of any Derivative Works | ||||
|           that You distribute, all copyright, patent, trademark, and | ||||
|           attribution notices from the Source form of the Work, | ||||
|           excluding those notices that do not pertain to any part of | ||||
|           the Derivative Works; and | ||||
|  | ||||
|       (d) If the Work includes a "NOTICE" text file as part of its | ||||
|           distribution, then any Derivative Works that You distribute must | ||||
|           include a readable copy of the attribution notices contained | ||||
|           within such NOTICE file, excluding those notices that do not | ||||
|           pertain to any part of the Derivative Works, in at least one | ||||
|           of the following places: within a NOTICE text file distributed | ||||
|           as part of the Derivative Works; within the Source form or | ||||
|           documentation, if provided along with the Derivative Works; or, | ||||
|           within a display generated by the Derivative Works, if and | ||||
|           wherever such third-party notices normally appear. The contents | ||||
|           of the NOTICE file are for informational purposes only and | ||||
|           do not modify the License. You may add Your own attribution | ||||
|           notices within Derivative Works that You distribute, alongside | ||||
|           or as an addendum to the NOTICE text from the Work, provided | ||||
|           that such additional attribution notices cannot be construed | ||||
|           as modifying the License. | ||||
|  | ||||
|       You may add Your own copyright statement to Your modifications and | ||||
|       may provide additional or different license terms and conditions | ||||
|       for use, reproduction, or distribution of Your modifications, or | ||||
|       for any such Derivative Works as a whole, provided Your use, | ||||
|       reproduction, and distribution of the Work otherwise complies with | ||||
|       the conditions stated in this License. | ||||
|  | ||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||
|       any Contribution intentionally submitted for inclusion in the Work | ||||
|       by You to the Licensor shall be under the terms and conditions of | ||||
|       this License, without any additional terms or conditions. | ||||
|       Notwithstanding the above, nothing herein shall supersede or modify | ||||
|       the terms of any separate license agreement you may have executed | ||||
|       with Licensor regarding such Contributions. | ||||
|  | ||||
|    6. Trademarks. This License does not grant permission to use the trade | ||||
|       names, trademarks, service marks, or product names of the Licensor, | ||||
|       except as required for reasonable and customary use in describing the | ||||
|       origin of the Work and reproducing the content of the NOTICE file. | ||||
|  | ||||
|    7. Disclaimer of Warranty. Unless required by applicable law or | ||||
|       agreed to in writing, Licensor provides the Work (and each | ||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||
|       implied, including, without limitation, any warranties or conditions | ||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||
|       appropriateness of using or redistributing the Work and assume any | ||||
|       risks associated with Your exercise of permissions under this License. | ||||
|  | ||||
|    8. Limitation of Liability. In no event and under no legal theory, | ||||
|       whether in tort (including negligence), contract, or otherwise, | ||||
|       unless required by applicable law (such as deliberate and grossly | ||||
|       negligent acts) or agreed to in writing, shall any Contributor be | ||||
|       liable to You for damages, including any direct, indirect, special, | ||||
|       incidental, or consequential damages of any character arising as a | ||||
|       result of this License or out of the use or inability to use the | ||||
|       Work (including but not limited to damages for loss of goodwill, | ||||
|       work stoppage, computer failure or malfunction, or any and all | ||||
|       other commercial damages or losses), even if such Contributor | ||||
|       has been advised of the possibility of such damages. | ||||
|  | ||||
|    9. Accepting Warranty or Additional Liability. While redistributing | ||||
|       the Work or Derivative Works thereof, You may choose to offer, | ||||
|       and charge a fee for, acceptance of support, warranty, indemnity, | ||||
|       or other liability obligations and/or rights consistent with this | ||||
|       License. However, in accepting such obligations, You may act only | ||||
|       on Your own behalf and on Your sole responsibility, not on behalf | ||||
|       of any other Contributor, and only if You agree to indemnify, | ||||
|       defend, and hold each Contributor harmless for any liability | ||||
|       incurred by, or claims asserted against, such Contributor by reason | ||||
|       of your accepting any such warranty or additional liability. | ||||
|  | ||||
|    END OF TERMS AND CONDITIONS | ||||
|  | ||||
|    APPENDIX: How to apply the Apache License to your work. | ||||
|  | ||||
|       To apply the Apache License to your work, attach the following | ||||
|       boilerplate notice, with the fields enclosed by brackets "[]" | ||||
|       replaced with your own identifying information. (Don't include | ||||
|       the brackets!)  The text should be enclosed in the appropriate | ||||
|       comment syntax for the file format. We also recommend that a | ||||
|       file or class name and description of purpose be included on the | ||||
|       same "printed page" as the copyright notice for easier | ||||
|       identification within third-party archives. | ||||
|  | ||||
|    Copyright 2015 xeipuuv | ||||
|  | ||||
|    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. | ||||
							
								
								
									
										10
									
								
								vendor/github.com/xeipuuv/gojsonreference/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/xeipuuv/gojsonreference/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| # gojsonreference | ||||
| An implementation of JSON Reference - Go language | ||||
|  | ||||
| ## Dependencies | ||||
| https://github.com/xeipuuv/gojsonpointer | ||||
|  | ||||
| ## References | ||||
| http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 | ||||
|  | ||||
| http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 | ||||
							
								
								
									
										141
									
								
								vendor/github.com/xeipuuv/gojsonreference/reference.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								vendor/github.com/xeipuuv/gojsonreference/reference.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author  			xeipuuv | ||||
| // author-github 	https://github.com/xeipuuv | ||||
| // author-mail		xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name	gojsonreference | ||||
| // repository-desc	An implementation of JSON Reference - Go language | ||||
| // | ||||
| // description		Main and unique file. | ||||
| // | ||||
| // created      	26-02-2013 | ||||
|  | ||||
| package gojsonreference | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"github.com/xeipuuv/gojsonpointer" | ||||
| 	"net/url" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	const_fragment_char = `#` | ||||
| ) | ||||
|  | ||||
| func NewJsonReference(jsonReferenceString string) (JsonReference, error) { | ||||
|  | ||||
| 	var r JsonReference | ||||
| 	err := r.parse(jsonReferenceString) | ||||
| 	return r, err | ||||
|  | ||||
| } | ||||
|  | ||||
| type JsonReference struct { | ||||
| 	referenceUrl     *url.URL | ||||
| 	referencePointer gojsonpointer.JsonPointer | ||||
|  | ||||
| 	HasFullUrl      bool | ||||
| 	HasUrlPathOnly  bool | ||||
| 	HasFragmentOnly bool | ||||
| 	HasFileScheme   bool | ||||
| 	HasFullFilePath bool | ||||
| } | ||||
|  | ||||
| func (r *JsonReference) GetUrl() *url.URL { | ||||
| 	return r.referenceUrl | ||||
| } | ||||
|  | ||||
| func (r *JsonReference) GetPointer() *gojsonpointer.JsonPointer { | ||||
| 	return &r.referencePointer | ||||
| } | ||||
|  | ||||
| func (r *JsonReference) String() string { | ||||
|  | ||||
| 	if r.referenceUrl != nil { | ||||
| 		return r.referenceUrl.String() | ||||
| 	} | ||||
|  | ||||
| 	if r.HasFragmentOnly { | ||||
| 		return const_fragment_char + r.referencePointer.String() | ||||
| 	} | ||||
|  | ||||
| 	return r.referencePointer.String() | ||||
| } | ||||
|  | ||||
| func (r *JsonReference) IsCanonical() bool { | ||||
| 	return (r.HasFileScheme && r.HasFullFilePath) || (!r.HasFileScheme && r.HasFullUrl) | ||||
| } | ||||
|  | ||||
| // "Constructor", parses the given string JSON reference | ||||
| func (r *JsonReference) parse(jsonReferenceString string) (err error) { | ||||
|  | ||||
| 	r.referenceUrl, err = url.Parse(jsonReferenceString) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	refUrl := r.referenceUrl | ||||
|  | ||||
| 	if refUrl.Scheme != "" && refUrl.Host != "" { | ||||
| 		r.HasFullUrl = true | ||||
| 	} else { | ||||
| 		if refUrl.Path != "" { | ||||
| 			r.HasUrlPathOnly = true | ||||
| 		} else if refUrl.RawQuery == "" && refUrl.Fragment != "" { | ||||
| 			r.HasFragmentOnly = true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	r.HasFileScheme = refUrl.Scheme == "file" | ||||
| 	if runtime.GOOS == "windows" { | ||||
| 		// on Windows, a file URL may have an extra leading slash, and if it | ||||
| 		// doesn't then its first component will be treated as the host by the | ||||
| 		// Go runtime | ||||
| 		if refUrl.Host == "" && strings.HasPrefix(refUrl.Path, "/") { | ||||
| 			r.HasFullFilePath = filepath.IsAbs(refUrl.Path[1:]) | ||||
| 		} else { | ||||
| 			r.HasFullFilePath = filepath.IsAbs(refUrl.Host + refUrl.Path) | ||||
| 		} | ||||
| 	} else { | ||||
| 		r.HasFullFilePath = filepath.IsAbs(refUrl.Path) | ||||
| 	} | ||||
|  | ||||
| 	// invalid json-pointer error means url has no json-pointer fragment. simply ignore error | ||||
| 	r.referencePointer, _ = gojsonpointer.NewJsonPointer(refUrl.Fragment) | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Creates a new reference from a parent and a child | ||||
| // If the child cannot inherit from the parent, an error is returned | ||||
| func (r *JsonReference) Inherits(child JsonReference) (*JsonReference, error) { | ||||
| 	childUrl := child.GetUrl() | ||||
| 	parentUrl := r.GetUrl() | ||||
| 	if childUrl == nil { | ||||
| 		return nil, errors.New("childUrl is nil!") | ||||
| 	} | ||||
| 	if parentUrl == nil { | ||||
| 		return nil, errors.New("parentUrl is nil!") | ||||
| 	} | ||||
|  | ||||
| 	ref, err := NewJsonReference(parentUrl.ResolveReference(childUrl).String()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &ref, err | ||||
| } | ||||
							
								
								
									
										202
									
								
								vendor/github.com/xeipuuv/gojsonschema/LICENSE-APACHE-2.0.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/xeipuuv/gojsonschema/LICENSE-APACHE-2.0.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | ||||
|  | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|                         http://www.apache.org/licenses/ | ||||
|  | ||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||
|  | ||||
|    1. Definitions. | ||||
|  | ||||
|       "License" shall mean the terms and conditions for use, reproduction, | ||||
|       and distribution as defined by Sections 1 through 9 of this document. | ||||
|  | ||||
|       "Licensor" shall mean the copyright owner or entity authorized by | ||||
|       the copyright owner that is granting the License. | ||||
|  | ||||
|       "Legal Entity" shall mean the union of the acting entity and all | ||||
|       other entities that control, are controlled by, or are under common | ||||
|       control with that entity. For the purposes of this definition, | ||||
|       "control" means (i) the power, direct or indirect, to cause the | ||||
|       direction or management of such entity, whether by contract or | ||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||
|       outstanding shares, or (iii) beneficial ownership of such entity. | ||||
|  | ||||
|       "You" (or "Your") shall mean an individual or Legal Entity | ||||
|       exercising permissions granted by this License. | ||||
|  | ||||
|       "Source" form shall mean the preferred form for making modifications, | ||||
|       including but not limited to software source code, documentation | ||||
|       source, and configuration files. | ||||
|  | ||||
|       "Object" form shall mean any form resulting from mechanical | ||||
|       transformation or translation of a Source form, including but | ||||
|       not limited to compiled object code, generated documentation, | ||||
|       and conversions to other media types. | ||||
|  | ||||
|       "Work" shall mean the work of authorship, whether in Source or | ||||
|       Object form, made available under the License, as indicated by a | ||||
|       copyright notice that is included in or attached to the work | ||||
|       (an example is provided in the Appendix below). | ||||
|  | ||||
|       "Derivative Works" shall mean any work, whether in Source or Object | ||||
|       form, that is based on (or derived from) the Work and for which the | ||||
|       editorial revisions, annotations, elaborations, or other modifications | ||||
|       represent, as a whole, an original work of authorship. For the purposes | ||||
|       of this License, Derivative Works shall not include works that remain | ||||
|       separable from, or merely link (or bind by name) to the interfaces of, | ||||
|       the Work and Derivative Works thereof. | ||||
|  | ||||
|       "Contribution" shall mean any work of authorship, including | ||||
|       the original version of the Work and any modifications or additions | ||||
|       to that Work or Derivative Works thereof, that is intentionally | ||||
|       submitted to Licensor for inclusion in the Work by the copyright owner | ||||
|       or by an individual or Legal Entity authorized to submit on behalf of | ||||
|       the copyright owner. For the purposes of this definition, "submitted" | ||||
|       means any form of electronic, verbal, or written communication sent | ||||
|       to the Licensor or its representatives, including but not limited to | ||||
|       communication on electronic mailing lists, source code control systems, | ||||
|       and issue tracking systems that are managed by, or on behalf of, the | ||||
|       Licensor for the purpose of discussing and improving the Work, but | ||||
|       excluding communication that is conspicuously marked or otherwise | ||||
|       designated in writing by the copyright owner as "Not a Contribution." | ||||
|  | ||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||
|       on behalf of whom a Contribution has been received by Licensor and | ||||
|       subsequently incorporated within the Work. | ||||
|  | ||||
|    2. Grant of Copyright License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       copyright license to reproduce, prepare Derivative Works of, | ||||
|       publicly display, publicly perform, sublicense, and distribute the | ||||
|       Work and such Derivative Works in Source or Object form. | ||||
|  | ||||
|    3. Grant of Patent License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       (except as stated in this section) patent license to make, have made, | ||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||
|       where such license applies only to those patent claims licensable | ||||
|       by such Contributor that are necessarily infringed by their | ||||
|       Contribution(s) alone or by combination of their Contribution(s) | ||||
|       with the Work to which such Contribution(s) was submitted. If You | ||||
|       institute patent litigation against any entity (including a | ||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||
|       or a Contribution incorporated within the Work constitutes direct | ||||
|       or contributory patent infringement, then any patent licenses | ||||
|       granted to You under this License for that Work shall terminate | ||||
|       as of the date such litigation is filed. | ||||
|  | ||||
|    4. Redistribution. You may reproduce and distribute copies of the | ||||
|       Work or Derivative Works thereof in any medium, with or without | ||||
|       modifications, and in Source or Object form, provided that You | ||||
|       meet the following conditions: | ||||
|  | ||||
|       (a) You must give any other recipients of the Work or | ||||
|           Derivative Works a copy of this License; and | ||||
|  | ||||
|       (b) You must cause any modified files to carry prominent notices | ||||
|           stating that You changed the files; and | ||||
|  | ||||
|       (c) You must retain, in the Source form of any Derivative Works | ||||
|           that You distribute, all copyright, patent, trademark, and | ||||
|           attribution notices from the Source form of the Work, | ||||
|           excluding those notices that do not pertain to any part of | ||||
|           the Derivative Works; and | ||||
|  | ||||
|       (d) If the Work includes a "NOTICE" text file as part of its | ||||
|           distribution, then any Derivative Works that You distribute must | ||||
|           include a readable copy of the attribution notices contained | ||||
|           within such NOTICE file, excluding those notices that do not | ||||
|           pertain to any part of the Derivative Works, in at least one | ||||
|           of the following places: within a NOTICE text file distributed | ||||
|           as part of the Derivative Works; within the Source form or | ||||
|           documentation, if provided along with the Derivative Works; or, | ||||
|           within a display generated by the Derivative Works, if and | ||||
|           wherever such third-party notices normally appear. The contents | ||||
|           of the NOTICE file are for informational purposes only and | ||||
|           do not modify the License. You may add Your own attribution | ||||
|           notices within Derivative Works that You distribute, alongside | ||||
|           or as an addendum to the NOTICE text from the Work, provided | ||||
|           that such additional attribution notices cannot be construed | ||||
|           as modifying the License. | ||||
|  | ||||
|       You may add Your own copyright statement to Your modifications and | ||||
|       may provide additional or different license terms and conditions | ||||
|       for use, reproduction, or distribution of Your modifications, or | ||||
|       for any such Derivative Works as a whole, provided Your use, | ||||
|       reproduction, and distribution of the Work otherwise complies with | ||||
|       the conditions stated in this License. | ||||
|  | ||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||
|       any Contribution intentionally submitted for inclusion in the Work | ||||
|       by You to the Licensor shall be under the terms and conditions of | ||||
|       this License, without any additional terms or conditions. | ||||
|       Notwithstanding the above, nothing herein shall supersede or modify | ||||
|       the terms of any separate license agreement you may have executed | ||||
|       with Licensor regarding such Contributions. | ||||
|  | ||||
|    6. Trademarks. This License does not grant permission to use the trade | ||||
|       names, trademarks, service marks, or product names of the Licensor, | ||||
|       except as required for reasonable and customary use in describing the | ||||
|       origin of the Work and reproducing the content of the NOTICE file. | ||||
|  | ||||
|    7. Disclaimer of Warranty. Unless required by applicable law or | ||||
|       agreed to in writing, Licensor provides the Work (and each | ||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||
|       implied, including, without limitation, any warranties or conditions | ||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||
|       appropriateness of using or redistributing the Work and assume any | ||||
|       risks associated with Your exercise of permissions under this License. | ||||
|  | ||||
|    8. Limitation of Liability. In no event and under no legal theory, | ||||
|       whether in tort (including negligence), contract, or otherwise, | ||||
|       unless required by applicable law (such as deliberate and grossly | ||||
|       negligent acts) or agreed to in writing, shall any Contributor be | ||||
|       liable to You for damages, including any direct, indirect, special, | ||||
|       incidental, or consequential damages of any character arising as a | ||||
|       result of this License or out of the use or inability to use the | ||||
|       Work (including but not limited to damages for loss of goodwill, | ||||
|       work stoppage, computer failure or malfunction, or any and all | ||||
|       other commercial damages or losses), even if such Contributor | ||||
|       has been advised of the possibility of such damages. | ||||
|  | ||||
|    9. Accepting Warranty or Additional Liability. While redistributing | ||||
|       the Work or Derivative Works thereof, You may choose to offer, | ||||
|       and charge a fee for, acceptance of support, warranty, indemnity, | ||||
|       or other liability obligations and/or rights consistent with this | ||||
|       License. However, in accepting such obligations, You may act only | ||||
|       on Your own behalf and on Your sole responsibility, not on behalf | ||||
|       of any other Contributor, and only if You agree to indemnify, | ||||
|       defend, and hold each Contributor harmless for any liability | ||||
|       incurred by, or claims asserted against, such Contributor by reason | ||||
|       of your accepting any such warranty or additional liability. | ||||
|  | ||||
|    END OF TERMS AND CONDITIONS | ||||
|  | ||||
|    APPENDIX: How to apply the Apache License to your work. | ||||
|  | ||||
|       To apply the Apache License to your work, attach the following | ||||
|       boilerplate notice, with the fields enclosed by brackets "[]" | ||||
|       replaced with your own identifying information. (Don't include | ||||
|       the brackets!)  The text should be enclosed in the appropriate | ||||
|       comment syntax for the file format. We also recommend that a | ||||
|       file or class name and description of purpose be included on the | ||||
|       same "printed page" as the copyright notice for easier | ||||
|       identification within third-party archives. | ||||
|  | ||||
|    Copyright 2015 xeipuuv | ||||
|  | ||||
|    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. | ||||
							
								
								
									
										236
									
								
								vendor/github.com/xeipuuv/gojsonschema/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								vendor/github.com/xeipuuv/gojsonschema/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,236 @@ | ||||
| [](https://travis-ci.org/xeipuuv/gojsonschema) | ||||
|  | ||||
| # gojsonschema | ||||
|  | ||||
| ## Description | ||||
|  | ||||
| An implementation of JSON Schema, based on IETF's draft v4 - Go language | ||||
|  | ||||
| References : | ||||
|  | ||||
| * http://json-schema.org | ||||
| * http://json-schema.org/latest/json-schema-core.html | ||||
| * http://json-schema.org/latest/json-schema-validation.html | ||||
|  | ||||
| ## Installation | ||||
|  | ||||
| ``` | ||||
| go get github.com/xeipuuv/gojsonschema | ||||
| ``` | ||||
|  | ||||
| Dependencies : | ||||
| * [github.com/xeipuuv/gojsonpointer](https://github.com/xeipuuv/gojsonpointer) | ||||
| * [github.com/xeipuuv/gojsonreference](https://github.com/xeipuuv/gojsonreference) | ||||
| * [github.com/stretchr/testify/assert](https://github.com/stretchr/testify#assert-package) | ||||
|  | ||||
| ## Usage | ||||
|  | ||||
| ### Example | ||||
|  | ||||
| ```go | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
|     "fmt" | ||||
|     "github.com/xeipuuv/gojsonschema" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|  | ||||
|     schemaLoader := gojsonschema.NewReferenceLoader("file:///home/me/schema.json") | ||||
|     documentLoader := gojsonschema.NewReferenceLoader("file:///home/me/document.json") | ||||
|  | ||||
|     result, err := gojsonschema.Validate(schemaLoader, documentLoader) | ||||
|     if err != nil { | ||||
|         panic(err.Error()) | ||||
|     } | ||||
|  | ||||
|     if result.Valid() { | ||||
|         fmt.Printf("The document is valid\n") | ||||
|     } else { | ||||
|         fmt.Printf("The document is not valid. see errors :\n") | ||||
|         for _, desc := range result.Errors() { | ||||
|             fmt.Printf("- %s\n", desc) | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| ``` | ||||
|  | ||||
| #### Loaders | ||||
|  | ||||
| There are various ways to load your JSON data. | ||||
| In order to load your schemas and documents, | ||||
| first declare an appropriate loader : | ||||
|  | ||||
| * Web / HTTP, using a reference : | ||||
|  | ||||
| ```go | ||||
| loader := gojsonschema.NewReferenceLoader("http://www.some_host.com/schema.json") | ||||
| ``` | ||||
|  | ||||
| * Local file, using a reference : | ||||
|  | ||||
| ```go | ||||
| loader := gojsonschema.NewReferenceLoader("file:///home/me/schema.json") | ||||
| ``` | ||||
|  | ||||
| References use the URI scheme, the prefix (file://) and a full path to the file are required. | ||||
|  | ||||
| * JSON strings : | ||||
|  | ||||
| ```go | ||||
| loader := gojsonschema.NewStringLoader(`{"type": "string"}`) | ||||
| ``` | ||||
|  | ||||
| * Custom Go types : | ||||
|  | ||||
| ```go | ||||
| m := map[string]interface{}{"type": "string"} | ||||
| loader := gojsonschema.NewGoLoader(m) | ||||
| ``` | ||||
|  | ||||
| And | ||||
|  | ||||
| ```go | ||||
| type Root struct { | ||||
| 	Users []User `json:"users"` | ||||
| } | ||||
|  | ||||
| type User struct { | ||||
| 	Name string `json:"name"` | ||||
| } | ||||
|  | ||||
| ... | ||||
|  | ||||
| data := Root{} | ||||
| data.Users = append(data.Users, User{"John"}) | ||||
| data.Users = append(data.Users, User{"Sophia"}) | ||||
| data.Users = append(data.Users, User{"Bill"}) | ||||
|  | ||||
| loader := gojsonschema.NewGoLoader(data) | ||||
| ``` | ||||
|  | ||||
| #### Validation | ||||
|  | ||||
| Once the loaders are set, validation is easy : | ||||
|  | ||||
| ```go | ||||
| result, err := gojsonschema.Validate(schemaLoader, documentLoader) | ||||
| ``` | ||||
|  | ||||
| Alternatively, you might want to load a schema only once and process to multiple validations : | ||||
|  | ||||
| ```go | ||||
| schema, err := gojsonschema.NewSchema(schemaLoader) | ||||
| ... | ||||
| result1, err := schema.Validate(documentLoader1) | ||||
| ... | ||||
| result2, err := schema.Validate(documentLoader2) | ||||
| ... | ||||
| // etc ... | ||||
| ``` | ||||
|  | ||||
| To check the result : | ||||
|  | ||||
| ```go | ||||
|     if result.Valid() { | ||||
|     	fmt.Printf("The document is valid\n") | ||||
|     } else { | ||||
|         fmt.Printf("The document is not valid. see errors :\n") | ||||
|         for _, err := range result.Errors() { | ||||
|         	// Err implements the ResultError interface | ||||
|             fmt.Printf("- %s\n", err) | ||||
|         } | ||||
|     } | ||||
| ``` | ||||
|  | ||||
| ## Working with Errors | ||||
|  | ||||
| The library handles string error codes which you can customize by creating your own gojsonschema.locale and setting it | ||||
| ```go | ||||
| gojsonschema.Locale = YourCustomLocale{} | ||||
| ``` | ||||
|  | ||||
| However, each error contains additional contextual information. | ||||
|  | ||||
| **err.Type()**: *string* Returns the "type" of error that occurred. Note you can also type check. See below | ||||
|  | ||||
| Note: An error of RequiredType has an err.Type() return value of "required" | ||||
|  | ||||
|     "required": RequiredError | ||||
|     "invalid_type": InvalidTypeError | ||||
|     "number_any_of": NumberAnyOfError | ||||
|     "number_one_of": NumberOneOfError | ||||
|     "number_all_of": NumberAllOfError | ||||
|     "number_not": NumberNotError | ||||
|     "missing_dependency": MissingDependencyError | ||||
|     "internal": InternalError | ||||
|     "enum": EnumError | ||||
|     "array_no_additional_items": ArrayNoAdditionalItemsError | ||||
|     "array_min_items": ArrayMinItemsError | ||||
|     "array_max_items": ArrayMaxItemsError | ||||
|     "unique": ItemsMustBeUniqueError | ||||
|     "array_min_properties": ArrayMinPropertiesError | ||||
|     "array_max_properties": ArrayMaxPropertiesError | ||||
|     "additional_property_not_allowed": AdditionalPropertyNotAllowedError | ||||
|     "invalid_property_pattern": InvalidPropertyPatternError | ||||
|     "string_gte": StringLengthGTEError | ||||
|     "string_lte": StringLengthLTEError | ||||
|     "pattern": DoesNotMatchPatternError | ||||
|     "multiple_of": MultipleOfError | ||||
|     "number_gte": NumberGTEError | ||||
|     "number_gt": NumberGTError | ||||
|     "number_lte": NumberLTEError | ||||
|     "number_lt": NumberLTError | ||||
|  | ||||
| **err.Value()**: *interface{}* Returns the value given | ||||
|  | ||||
| **err.Context()**: *gojsonschema.jsonContext* Returns the context. This has a String() method that will print something like this: (root).firstName | ||||
|  | ||||
| **err.Field()**: *string* Returns the fieldname in the format firstName, or for embedded properties, person.firstName. This returns the same as the String() method on *err.Context()* but removes the (root). prefix. | ||||
|  | ||||
| **err.Description()**: *string* The error description. This is based on the locale you are using. See the beginning of this section for overwriting the locale with a custom implementation. | ||||
|  | ||||
| **err.Details()**: *gojsonschema.ErrorDetails* Returns a map[string]interface{} of additional error details specific to the error. For example, GTE errors will have a "min" value, LTE will have a "max" value. See errors.go for a full description of all the error details. Every error always contains a "field" key that holds the value of *err.Field()* | ||||
|  | ||||
| Note in most cases, the err.Details() will be used to generate replacement strings in your locales, and not used directly. These strings follow the text/template format i.e. | ||||
| ``` | ||||
| {{.field}} must be greater than or equal to {{.min}} | ||||
| ``` | ||||
|  | ||||
| ## Formats | ||||
| JSON Schema allows for optional "format" property to validate strings against well-known formats. gojsonschema ships with all of the formats defined in the spec that you can use like this: | ||||
| ````json | ||||
| {"type": "string", "format": "email"} | ||||
| ```` | ||||
| Available formats: date-time, hostname, email, ipv4, ipv6, uri. | ||||
|  | ||||
| For repetitive or more complex formats, you can create custom format checkers and add them to gojsonschema like this: | ||||
|  | ||||
| ```go | ||||
| // Define the format checker | ||||
| type RoleFormatChecker struct {} | ||||
|  | ||||
| // Ensure it meets the gojsonschema.FormatChecker interface | ||||
| func (f RoleFormatChecker) IsFormat(input string) bool { | ||||
|     return strings.HasPrefix("ROLE_", input) | ||||
| } | ||||
|  | ||||
| // Add it to the library | ||||
| gojsonschema.FormatCheckers.Add("role", RoleFormatChecker{}) | ||||
| ```` | ||||
|  | ||||
| Now to use in your json schema: | ||||
| ````json | ||||
| {"type": "string", "format": "role"} | ||||
| ```` | ||||
|  | ||||
| ## Uses | ||||
|  | ||||
| gojsonschema uses the following test suite : | ||||
|  | ||||
| https://github.com/json-schema/JSON-Schema-Test-Suite | ||||
							
								
								
									
										274
									
								
								vendor/github.com/xeipuuv/gojsonschema/errors.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								vendor/github.com/xeipuuv/gojsonschema/errors.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,274 @@ | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"sync" | ||||
| 	"text/template" | ||||
| ) | ||||
|  | ||||
| var errorTemplates errorTemplate = errorTemplate{template.New("errors-new"), sync.RWMutex{}} | ||||
|  | ||||
| // template.Template is not thread-safe for writing, so some locking is done | ||||
| // sync.RWMutex is used for efficiently locking when new templates are created | ||||
| type errorTemplate struct { | ||||
| 	*template.Template | ||||
| 	sync.RWMutex | ||||
| } | ||||
|  | ||||
| type ( | ||||
| 	// RequiredError. ErrorDetails: property string | ||||
| 	RequiredError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// InvalidTypeError. ErrorDetails: expected, given | ||||
| 	InvalidTypeError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// NumberAnyOfError. ErrorDetails: - | ||||
| 	NumberAnyOfError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// NumberOneOfError. ErrorDetails: - | ||||
| 	NumberOneOfError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// NumberAllOfError. ErrorDetails: - | ||||
| 	NumberAllOfError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// NumberNotError. ErrorDetails: - | ||||
| 	NumberNotError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// MissingDependencyError. ErrorDetails: dependency | ||||
| 	MissingDependencyError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// InternalError. ErrorDetails: error | ||||
| 	InternalError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// EnumError. ErrorDetails: allowed | ||||
| 	EnumError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// ArrayNoAdditionalItemsError. ErrorDetails: - | ||||
| 	ArrayNoAdditionalItemsError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// ArrayMinItemsError. ErrorDetails: min | ||||
| 	ArrayMinItemsError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// ArrayMaxItemsError. ErrorDetails: max | ||||
| 	ArrayMaxItemsError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// ItemsMustBeUniqueError. ErrorDetails: type | ||||
| 	ItemsMustBeUniqueError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// ArrayMinPropertiesError. ErrorDetails: min | ||||
| 	ArrayMinPropertiesError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// ArrayMaxPropertiesError. ErrorDetails: max | ||||
| 	ArrayMaxPropertiesError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// AdditionalPropertyNotAllowedError. ErrorDetails: property | ||||
| 	AdditionalPropertyNotAllowedError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// InvalidPropertyPatternError. ErrorDetails: property, pattern | ||||
| 	InvalidPropertyPatternError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// StringLengthGTEError. ErrorDetails: min | ||||
| 	StringLengthGTEError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// StringLengthLTEError. ErrorDetails: max | ||||
| 	StringLengthLTEError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// DoesNotMatchPatternError. ErrorDetails: pattern | ||||
| 	DoesNotMatchPatternError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// DoesNotMatchFormatError. ErrorDetails: format | ||||
| 	DoesNotMatchFormatError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// MultipleOfError. ErrorDetails: multiple | ||||
| 	MultipleOfError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// NumberGTEError. ErrorDetails: min | ||||
| 	NumberGTEError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// NumberGTError. ErrorDetails: min | ||||
| 	NumberGTError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// NumberLTEError. ErrorDetails: max | ||||
| 	NumberLTEError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
|  | ||||
| 	// NumberLTError. ErrorDetails: max | ||||
| 	NumberLTError struct { | ||||
| 		ResultErrorFields | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // newError takes a ResultError type and sets the type, context, description, details, value, and field | ||||
| func newError(err ResultError, context *jsonContext, value interface{}, locale locale, details ErrorDetails) { | ||||
| 	var t string | ||||
| 	var d string | ||||
| 	switch err.(type) { | ||||
| 	case *RequiredError: | ||||
| 		t = "required" | ||||
| 		d = locale.Required() | ||||
| 	case *InvalidTypeError: | ||||
| 		t = "invalid_type" | ||||
| 		d = locale.InvalidType() | ||||
| 	case *NumberAnyOfError: | ||||
| 		t = "number_any_of" | ||||
| 		d = locale.NumberAnyOf() | ||||
| 	case *NumberOneOfError: | ||||
| 		t = "number_one_of" | ||||
| 		d = locale.NumberOneOf() | ||||
| 	case *NumberAllOfError: | ||||
| 		t = "number_all_of" | ||||
| 		d = locale.NumberAllOf() | ||||
| 	case *NumberNotError: | ||||
| 		t = "number_not" | ||||
| 		d = locale.NumberNot() | ||||
| 	case *MissingDependencyError: | ||||
| 		t = "missing_dependency" | ||||
| 		d = locale.MissingDependency() | ||||
| 	case *InternalError: | ||||
| 		t = "internal" | ||||
| 		d = locale.Internal() | ||||
| 	case *EnumError: | ||||
| 		t = "enum" | ||||
| 		d = locale.Enum() | ||||
| 	case *ArrayNoAdditionalItemsError: | ||||
| 		t = "array_no_additional_items" | ||||
| 		d = locale.ArrayNoAdditionalItems() | ||||
| 	case *ArrayMinItemsError: | ||||
| 		t = "array_min_items" | ||||
| 		d = locale.ArrayMinItems() | ||||
| 	case *ArrayMaxItemsError: | ||||
| 		t = "array_max_items" | ||||
| 		d = locale.ArrayMaxItems() | ||||
| 	case *ItemsMustBeUniqueError: | ||||
| 		t = "unique" | ||||
| 		d = locale.Unique() | ||||
| 	case *ArrayMinPropertiesError: | ||||
| 		t = "array_min_properties" | ||||
| 		d = locale.ArrayMinProperties() | ||||
| 	case *ArrayMaxPropertiesError: | ||||
| 		t = "array_max_properties" | ||||
| 		d = locale.ArrayMaxProperties() | ||||
| 	case *AdditionalPropertyNotAllowedError: | ||||
| 		t = "additional_property_not_allowed" | ||||
| 		d = locale.AdditionalPropertyNotAllowed() | ||||
| 	case *InvalidPropertyPatternError: | ||||
| 		t = "invalid_property_pattern" | ||||
| 		d = locale.InvalidPropertyPattern() | ||||
| 	case *StringLengthGTEError: | ||||
| 		t = "string_gte" | ||||
| 		d = locale.StringGTE() | ||||
| 	case *StringLengthLTEError: | ||||
| 		t = "string_lte" | ||||
| 		d = locale.StringLTE() | ||||
| 	case *DoesNotMatchPatternError: | ||||
| 		t = "pattern" | ||||
| 		d = locale.DoesNotMatchPattern() | ||||
| 	case *DoesNotMatchFormatError: | ||||
| 		t = "format" | ||||
| 		d = locale.DoesNotMatchFormat() | ||||
| 	case *MultipleOfError: | ||||
| 		t = "multiple_of" | ||||
| 		d = locale.MultipleOf() | ||||
| 	case *NumberGTEError: | ||||
| 		t = "number_gte" | ||||
| 		d = locale.NumberGTE() | ||||
| 	case *NumberGTError: | ||||
| 		t = "number_gt" | ||||
| 		d = locale.NumberGT() | ||||
| 	case *NumberLTEError: | ||||
| 		t = "number_lte" | ||||
| 		d = locale.NumberLTE() | ||||
| 	case *NumberLTError: | ||||
| 		t = "number_lt" | ||||
| 		d = locale.NumberLT() | ||||
| 	} | ||||
|  | ||||
| 	err.SetType(t) | ||||
| 	err.SetContext(context) | ||||
| 	err.SetValue(value) | ||||
| 	err.SetDetails(details) | ||||
| 	details["field"] = err.Field() | ||||
| 	err.SetDescription(formatErrorDescription(d, details)) | ||||
| } | ||||
|  | ||||
| // formatErrorDescription takes a string in the default text/template | ||||
| // format and converts it to a string with replacements. The fields come | ||||
| // from the ErrorDetails struct and vary for each type of error. | ||||
| func formatErrorDescription(s string, details ErrorDetails) string { | ||||
|  | ||||
| 	var tpl *template.Template | ||||
| 	var descrAsBuffer bytes.Buffer | ||||
| 	var err error | ||||
|  | ||||
| 	errorTemplates.RLock() | ||||
| 	tpl = errorTemplates.Lookup(s) | ||||
| 	errorTemplates.RUnlock() | ||||
|  | ||||
| 	if tpl == nil { | ||||
| 		errorTemplates.Lock() | ||||
| 		tpl = errorTemplates.New(s) | ||||
|  | ||||
| 		tpl, err = tpl.Parse(s) | ||||
| 		errorTemplates.Unlock() | ||||
|  | ||||
| 		if err != nil { | ||||
| 			return err.Error() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	err = tpl.Execute(&descrAsBuffer, details) | ||||
| 	if err != nil { | ||||
| 		return err.Error() | ||||
| 	} | ||||
|  | ||||
| 	return descrAsBuffer.String() | ||||
| } | ||||
							
								
								
									
										194
									
								
								vendor/github.com/xeipuuv/gojsonschema/format_checkers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								vendor/github.com/xeipuuv/gojsonschema/format_checkers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"net" | ||||
| 	"net/url" | ||||
| 	"reflect" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type ( | ||||
| 	// FormatChecker is the interface all formatters added to FormatCheckerChain must implement | ||||
| 	FormatChecker interface { | ||||
| 		IsFormat(input string) bool | ||||
| 	} | ||||
|  | ||||
| 	// FormatCheckerChain holds the formatters | ||||
| 	FormatCheckerChain struct { | ||||
| 		formatters map[string]FormatChecker | ||||
| 	} | ||||
|  | ||||
| 	// EmailFormatter verifies email address formats | ||||
| 	EmailFormatChecker struct{} | ||||
|  | ||||
| 	// IPV4FormatChecker verifies IP addresses in the ipv4 format | ||||
| 	IPV4FormatChecker struct{} | ||||
|  | ||||
| 	// IPV6FormatChecker verifies IP addresses in the ipv6 format | ||||
| 	IPV6FormatChecker struct{} | ||||
|  | ||||
| 	// DateTimeFormatChecker verifies date/time formats per RFC3339 5.6 | ||||
| 	// | ||||
| 	// Valid formats: | ||||
| 	// 		Partial Time: HH:MM:SS | ||||
| 	//		Full Date: YYYY-MM-DD | ||||
| 	// 		Full Time: HH:MM:SSZ-07:00 | ||||
| 	//		Date Time: YYYY-MM-DDTHH:MM:SSZ-0700 | ||||
| 	// | ||||
| 	// 	Where | ||||
| 	//		YYYY = 4DIGIT year | ||||
| 	//		MM = 2DIGIT month ; 01-12 | ||||
| 	//		DD = 2DIGIT day-month ; 01-28, 01-29, 01-30, 01-31 based on month/year | ||||
| 	//		HH = 2DIGIT hour ; 00-23 | ||||
| 	//		MM = 2DIGIT ; 00-59 | ||||
| 	//		SS = 2DIGIT ; 00-58, 00-60 based on leap second rules | ||||
| 	//		T = Literal | ||||
| 	//		Z = Literal | ||||
| 	// | ||||
| 	//	Note: Nanoseconds are also suported in all formats | ||||
| 	// | ||||
| 	// http://tools.ietf.org/html/rfc3339#section-5.6 | ||||
| 	DateTimeFormatChecker struct{} | ||||
|  | ||||
| 	// URIFormatCheckers validates a URI with a valid Scheme per RFC3986 | ||||
| 	URIFormatChecker struct{} | ||||
|  | ||||
| 	// HostnameFormatChecker validates a hostname is in the correct format | ||||
| 	HostnameFormatChecker struct{} | ||||
|  | ||||
| 	// UUIDFormatChecker validates a UUID is in the correct format | ||||
| 	UUIDFormatChecker struct{} | ||||
|  | ||||
| 	// RegexFormatChecker validates a regex is in the correct format | ||||
| 	RegexFormatChecker struct{} | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// Formatters holds the valid formatters, and is a public variable | ||||
| 	// so library users can add custom formatters | ||||
| 	FormatCheckers = FormatCheckerChain{ | ||||
| 		formatters: map[string]FormatChecker{ | ||||
| 			"date-time": DateTimeFormatChecker{}, | ||||
| 			"hostname":  HostnameFormatChecker{}, | ||||
| 			"email":     EmailFormatChecker{}, | ||||
| 			"ipv4":      IPV4FormatChecker{}, | ||||
| 			"ipv6":      IPV6FormatChecker{}, | ||||
| 			"uri":       URIFormatChecker{}, | ||||
| 			"uuid":      UUIDFormatChecker{}, | ||||
| 			"regex":     RegexFormatChecker{}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	// Regex credit: https://github.com/asaskevich/govalidator | ||||
| 	rxEmail = regexp.MustCompile("^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$") | ||||
|  | ||||
| 	// Regex credit: https://www.socketloop.com/tutorials/golang-validate-hostname | ||||
| 	rxHostname = regexp.MustCompile(`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$`) | ||||
|  | ||||
| 	rxUUID = regexp.MustCompile("^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$") | ||||
| ) | ||||
|  | ||||
| // Add adds a FormatChecker to the FormatCheckerChain | ||||
| // The name used will be the value used for the format key in your json schema | ||||
| func (c *FormatCheckerChain) Add(name string, f FormatChecker) *FormatCheckerChain { | ||||
| 	c.formatters[name] = f | ||||
|  | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| // Remove deletes a FormatChecker from the FormatCheckerChain (if it exists) | ||||
| func (c *FormatCheckerChain) Remove(name string) *FormatCheckerChain { | ||||
| 	delete(c.formatters, name) | ||||
|  | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| // Has checks to see if the FormatCheckerChain holds a FormatChecker with the given name | ||||
| func (c *FormatCheckerChain) Has(name string) bool { | ||||
| 	_, ok := c.formatters[name] | ||||
|  | ||||
| 	return ok | ||||
| } | ||||
|  | ||||
| // IsFormat will check an input against a FormatChecker with the given name | ||||
| // to see if it is the correct format | ||||
| func (c *FormatCheckerChain) IsFormat(name string, input interface{}) bool { | ||||
| 	f, ok := c.formatters[name] | ||||
|  | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	if !isKind(input, reflect.String) { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	inputString := input.(string) | ||||
|  | ||||
| 	return f.IsFormat(inputString) | ||||
| } | ||||
|  | ||||
| func (f EmailFormatChecker) IsFormat(input string) bool { | ||||
| 	return rxEmail.MatchString(input) | ||||
| } | ||||
|  | ||||
| // Credit: https://github.com/asaskevich/govalidator | ||||
| func (f IPV4FormatChecker) IsFormat(input string) bool { | ||||
| 	ip := net.ParseIP(input) | ||||
| 	return ip != nil && strings.Contains(input, ".") | ||||
| } | ||||
|  | ||||
| // Credit: https://github.com/asaskevich/govalidator | ||||
| func (f IPV6FormatChecker) IsFormat(input string) bool { | ||||
| 	ip := net.ParseIP(input) | ||||
| 	return ip != nil && strings.Contains(input, ":") | ||||
| } | ||||
|  | ||||
| func (f DateTimeFormatChecker) IsFormat(input string) bool { | ||||
| 	formats := []string{ | ||||
| 		"15:04:05", | ||||
| 		"15:04:05Z07:00", | ||||
| 		"2006-01-02", | ||||
| 		time.RFC3339, | ||||
| 		time.RFC3339Nano, | ||||
| 	} | ||||
|  | ||||
| 	for _, format := range formats { | ||||
| 		if _, err := time.Parse(format, input); err == nil { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (f URIFormatChecker) IsFormat(input string) bool { | ||||
| 	u, err := url.Parse(input) | ||||
| 	if err != nil || u.Scheme == "" { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func (f HostnameFormatChecker) IsFormat(input string) bool { | ||||
| 	return rxHostname.MatchString(input) && len(input) < 256 | ||||
| } | ||||
|  | ||||
| func (f UUIDFormatChecker) IsFormat(input string) bool { | ||||
| 	return rxUUID.MatchString(input) | ||||
| } | ||||
|  | ||||
| // IsFormat implements FormatChecker interface. | ||||
| func (f RegexFormatChecker) IsFormat(input string) bool { | ||||
| 	if input == "" { | ||||
| 		return true | ||||
| 	} | ||||
| 	_, err := regexp.Compile(input) | ||||
| 	if err != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
							
								
								
									
										37
									
								
								vendor/github.com/xeipuuv/gojsonschema/internalLog.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/xeipuuv/gojsonschema/internalLog.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Very simple log wrapper. | ||||
| //					Used for debugging/testing purposes. | ||||
| // | ||||
| // created          01-01-2015 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"log" | ||||
| ) | ||||
|  | ||||
| const internalLogEnabled = false | ||||
|  | ||||
| func internalLog(format string, v ...interface{}) { | ||||
| 	log.Printf(format, v...) | ||||
| } | ||||
							
								
								
									
										72
									
								
								vendor/github.com/xeipuuv/gojsonschema/jsonContext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								vendor/github.com/xeipuuv/gojsonschema/jsonContext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| // Copyright 2013 MongoDB, Inc. | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           tolsen | ||||
| // author-github    https://github.com/tolsen | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Implements a persistent (immutable w/ shared structure) singly-linked list of strings for the purpose of storing a json context | ||||
| // | ||||
| // created          04-09-2013 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import "bytes" | ||||
|  | ||||
| // jsonContext implements a persistent linked-list of strings | ||||
| type jsonContext struct { | ||||
| 	head string | ||||
| 	tail *jsonContext | ||||
| } | ||||
|  | ||||
| func newJsonContext(head string, tail *jsonContext) *jsonContext { | ||||
| 	return &jsonContext{head, tail} | ||||
| } | ||||
|  | ||||
| // String displays the context in reverse. | ||||
| // This plays well with the data structure's persistent nature with | ||||
| // Cons and a json document's tree structure. | ||||
| func (c *jsonContext) String(del ...string) string { | ||||
| 	byteArr := make([]byte, 0, c.stringLen()) | ||||
| 	buf := bytes.NewBuffer(byteArr) | ||||
| 	c.writeStringToBuffer(buf, del) | ||||
|  | ||||
| 	return buf.String() | ||||
| } | ||||
|  | ||||
| func (c *jsonContext) stringLen() int { | ||||
| 	length := 0 | ||||
| 	if c.tail != nil { | ||||
| 		length = c.tail.stringLen() + 1 // add 1 for "." | ||||
| 	} | ||||
|  | ||||
| 	length += len(c.head) | ||||
| 	return length | ||||
| } | ||||
|  | ||||
| func (c *jsonContext) writeStringToBuffer(buf *bytes.Buffer, del []string) { | ||||
| 	if c.tail != nil { | ||||
| 		c.tail.writeStringToBuffer(buf, del) | ||||
|  | ||||
| 		if len(del) > 0 { | ||||
| 			buf.WriteString(del[0]) | ||||
| 		} else { | ||||
| 			buf.WriteString(".") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	buf.WriteString(c.head) | ||||
| } | ||||
							
								
								
									
										340
									
								
								vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,340 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description		Different strategies to load JSON files. | ||||
| // 					Includes References (file and HTTP), JSON strings and Go types. | ||||
| // | ||||
| // created          01-02-2015 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/xeipuuv/gojsonreference" | ||||
| ) | ||||
|  | ||||
| var osFS = osFileSystem(os.Open) | ||||
|  | ||||
| // JSON loader interface | ||||
|  | ||||
| type JSONLoader interface { | ||||
| 	JsonSource() interface{} | ||||
| 	LoadJSON() (interface{}, error) | ||||
| 	JsonReference() (gojsonreference.JsonReference, error) | ||||
| 	LoaderFactory() JSONLoaderFactory | ||||
| } | ||||
|  | ||||
| type JSONLoaderFactory interface { | ||||
| 	New(source string) JSONLoader | ||||
| } | ||||
|  | ||||
| type DefaultJSONLoaderFactory struct { | ||||
| } | ||||
|  | ||||
| type FileSystemJSONLoaderFactory struct { | ||||
| 	fs http.FileSystem | ||||
| } | ||||
|  | ||||
| func (d DefaultJSONLoaderFactory) New(source string) JSONLoader { | ||||
| 	return &jsonReferenceLoader{ | ||||
| 		fs:     osFS, | ||||
| 		source: source, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (f FileSystemJSONLoaderFactory) New(source string) JSONLoader { | ||||
| 	return &jsonReferenceLoader{ | ||||
| 		fs:     f.fs, | ||||
| 		source: source, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // osFileSystem is a functional wrapper for os.Open that implements http.FileSystem. | ||||
| type osFileSystem func(string) (*os.File, error) | ||||
|  | ||||
| func (o osFileSystem) Open(name string) (http.File, error) { | ||||
| 	return o(name) | ||||
| } | ||||
|  | ||||
| // JSON Reference loader | ||||
| // references are used to load JSONs from files and HTTP | ||||
|  | ||||
| type jsonReferenceLoader struct { | ||||
| 	fs     http.FileSystem | ||||
| 	source string | ||||
| } | ||||
|  | ||||
| func (l *jsonReferenceLoader) JsonSource() interface{} { | ||||
| 	return l.source | ||||
| } | ||||
|  | ||||
| func (l *jsonReferenceLoader) JsonReference() (gojsonreference.JsonReference, error) { | ||||
| 	return gojsonreference.NewJsonReference(l.JsonSource().(string)) | ||||
| } | ||||
|  | ||||
| func (l *jsonReferenceLoader) LoaderFactory() JSONLoaderFactory { | ||||
| 	return &FileSystemJSONLoaderFactory{ | ||||
| 		fs: l.fs, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NewReferenceLoader returns a JSON reference loader using the given source and the local OS file system. | ||||
| func NewReferenceLoader(source string) *jsonReferenceLoader { | ||||
| 	return &jsonReferenceLoader{ | ||||
| 		fs:     osFS, | ||||
| 		source: source, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NewReferenceLoaderFileSystem returns a JSON reference loader using the given source and file system. | ||||
| func NewReferenceLoaderFileSystem(source string, fs http.FileSystem) *jsonReferenceLoader { | ||||
| 	return &jsonReferenceLoader{ | ||||
| 		fs:     fs, | ||||
| 		source: source, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (l *jsonReferenceLoader) LoadJSON() (interface{}, error) { | ||||
|  | ||||
| 	var err error | ||||
|  | ||||
| 	reference, err := gojsonreference.NewJsonReference(l.JsonSource().(string)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	refToUrl := reference | ||||
| 	refToUrl.GetUrl().Fragment = "" | ||||
|  | ||||
| 	var document interface{} | ||||
|  | ||||
| 	if reference.HasFileScheme { | ||||
|  | ||||
| 		filename := strings.Replace(refToUrl.GetUrl().Path, "file://", "", -1) | ||||
| 		if runtime.GOOS == "windows" { | ||||
| 			// on Windows, a file URL may have an extra leading slash, use slashes | ||||
| 			// instead of backslashes, and have spaces escaped | ||||
| 			if strings.HasPrefix(filename, "/") { | ||||
| 				filename = filename[1:] | ||||
| 			} | ||||
| 			filename = filepath.FromSlash(filename) | ||||
| 		} | ||||
|  | ||||
| 		document, err = l.loadFromFile(filename) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 	} else { | ||||
|  | ||||
| 		document, err = l.loadFromHTTP(refToUrl.String()) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return document, nil | ||||
|  | ||||
| } | ||||
|  | ||||
| func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error) { | ||||
|  | ||||
| 	resp, err := http.Get(address) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// must return HTTP Status 200 OK | ||||
| 	if resp.StatusCode != http.StatusOK { | ||||
| 		return nil, errors.New(formatErrorDescription(Locale.HttpBadStatus(), ErrorDetails{"status": resp.Status})) | ||||
| 	} | ||||
|  | ||||
| 	bodyBuff, err := ioutil.ReadAll(resp.Body) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return decodeJsonUsingNumber(bytes.NewReader(bodyBuff)) | ||||
|  | ||||
| } | ||||
|  | ||||
| func (l *jsonReferenceLoader) loadFromFile(path string) (interface{}, error) { | ||||
| 	f, err := l.fs.Open(path) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer f.Close() | ||||
|  | ||||
| 	bodyBuff, err := ioutil.ReadAll(f) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return decodeJsonUsingNumber(bytes.NewReader(bodyBuff)) | ||||
|  | ||||
| } | ||||
|  | ||||
| // JSON string loader | ||||
|  | ||||
| type jsonStringLoader struct { | ||||
| 	source string | ||||
| } | ||||
|  | ||||
| func (l *jsonStringLoader) JsonSource() interface{} { | ||||
| 	return l.source | ||||
| } | ||||
|  | ||||
| func (l *jsonStringLoader) JsonReference() (gojsonreference.JsonReference, error) { | ||||
| 	return gojsonreference.NewJsonReference("#") | ||||
| } | ||||
|  | ||||
| func (l *jsonStringLoader) LoaderFactory() JSONLoaderFactory { | ||||
| 	return &DefaultJSONLoaderFactory{} | ||||
| } | ||||
|  | ||||
| func NewStringLoader(source string) *jsonStringLoader { | ||||
| 	return &jsonStringLoader{source: source} | ||||
| } | ||||
|  | ||||
| func (l *jsonStringLoader) LoadJSON() (interface{}, error) { | ||||
|  | ||||
| 	return decodeJsonUsingNumber(strings.NewReader(l.JsonSource().(string))) | ||||
|  | ||||
| } | ||||
|  | ||||
| // JSON bytes loader | ||||
|  | ||||
| type jsonBytesLoader struct { | ||||
| 	source []byte | ||||
| } | ||||
|  | ||||
| func (l *jsonBytesLoader) JsonSource() interface{} { | ||||
| 	return l.source | ||||
| } | ||||
|  | ||||
| func (l *jsonBytesLoader) JsonReference() (gojsonreference.JsonReference, error) { | ||||
| 	return gojsonreference.NewJsonReference("#") | ||||
| } | ||||
|  | ||||
| func (l *jsonBytesLoader) LoaderFactory() JSONLoaderFactory { | ||||
| 	return &DefaultJSONLoaderFactory{} | ||||
| } | ||||
|  | ||||
| func NewBytesLoader(source []byte) *jsonBytesLoader { | ||||
| 	return &jsonBytesLoader{source: source} | ||||
| } | ||||
|  | ||||
| func (l *jsonBytesLoader) LoadJSON() (interface{}, error) { | ||||
| 	return decodeJsonUsingNumber(bytes.NewReader(l.JsonSource().([]byte))) | ||||
| } | ||||
|  | ||||
| // JSON Go (types) loader | ||||
| // used to load JSONs from the code as maps, interface{}, structs ... | ||||
|  | ||||
| type jsonGoLoader struct { | ||||
| 	source interface{} | ||||
| } | ||||
|  | ||||
| func (l *jsonGoLoader) JsonSource() interface{} { | ||||
| 	return l.source | ||||
| } | ||||
|  | ||||
| func (l *jsonGoLoader) JsonReference() (gojsonreference.JsonReference, error) { | ||||
| 	return gojsonreference.NewJsonReference("#") | ||||
| } | ||||
|  | ||||
| func (l *jsonGoLoader) LoaderFactory() JSONLoaderFactory { | ||||
| 	return &DefaultJSONLoaderFactory{} | ||||
| } | ||||
|  | ||||
| func NewGoLoader(source interface{}) *jsonGoLoader { | ||||
| 	return &jsonGoLoader{source: source} | ||||
| } | ||||
|  | ||||
| func (l *jsonGoLoader) LoadJSON() (interface{}, error) { | ||||
|  | ||||
| 	// convert it to a compliant JSON first to avoid types "mismatches" | ||||
|  | ||||
| 	jsonBytes, err := json.Marshal(l.JsonSource()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return decodeJsonUsingNumber(bytes.NewReader(jsonBytes)) | ||||
|  | ||||
| } | ||||
|  | ||||
| type jsonIOLoader struct { | ||||
| 	buf *bytes.Buffer | ||||
| } | ||||
|  | ||||
| func NewReaderLoader(source io.Reader) (*jsonIOLoader, io.Reader) { | ||||
| 	buf := &bytes.Buffer{} | ||||
| 	return &jsonIOLoader{buf: buf}, io.TeeReader(source, buf) | ||||
| } | ||||
|  | ||||
| func NewWriterLoader(source io.Writer) (*jsonIOLoader, io.Writer) { | ||||
| 	buf := &bytes.Buffer{} | ||||
| 	return &jsonIOLoader{buf: buf}, io.MultiWriter(source, buf) | ||||
| } | ||||
|  | ||||
| func (l *jsonIOLoader) JsonSource() interface{} { | ||||
| 	return l.buf.String() | ||||
| } | ||||
|  | ||||
| func (l *jsonIOLoader) LoadJSON() (interface{}, error) { | ||||
| 	return decodeJsonUsingNumber(l.buf) | ||||
| } | ||||
|  | ||||
| func (l *jsonIOLoader) JsonReference() (gojsonreference.JsonReference, error) { | ||||
| 	return gojsonreference.NewJsonReference("#") | ||||
| } | ||||
|  | ||||
| func (l *jsonIOLoader) LoaderFactory() JSONLoaderFactory { | ||||
| 	return &DefaultJSONLoaderFactory{} | ||||
| } | ||||
|  | ||||
| func decodeJsonUsingNumber(r io.Reader) (interface{}, error) { | ||||
|  | ||||
| 	var document interface{} | ||||
|  | ||||
| 	decoder := json.NewDecoder(r) | ||||
| 	decoder.UseNumber() | ||||
|  | ||||
| 	err := decoder.Decode(&document) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return document, nil | ||||
|  | ||||
| } | ||||
							
								
								
									
										280
									
								
								vendor/github.com/xeipuuv/gojsonschema/locales.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								vendor/github.com/xeipuuv/gojsonschema/locales.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,280 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Contains const string and messages. | ||||
| // | ||||
| // created          01-01-2015 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| type ( | ||||
| 	// locale is an interface for defining custom error strings | ||||
| 	locale interface { | ||||
| 		Required() string | ||||
| 		InvalidType() string | ||||
| 		NumberAnyOf() string | ||||
| 		NumberOneOf() string | ||||
| 		NumberAllOf() string | ||||
| 		NumberNot() string | ||||
| 		MissingDependency() string | ||||
| 		Internal() string | ||||
| 		Enum() string | ||||
| 		ArrayNotEnoughItems() string | ||||
| 		ArrayNoAdditionalItems() string | ||||
| 		ArrayMinItems() string | ||||
| 		ArrayMaxItems() string | ||||
| 		Unique() string | ||||
| 		ArrayMinProperties() string | ||||
| 		ArrayMaxProperties() string | ||||
| 		AdditionalPropertyNotAllowed() string | ||||
| 		InvalidPropertyPattern() string | ||||
| 		StringGTE() string | ||||
| 		StringLTE() string | ||||
| 		DoesNotMatchPattern() string | ||||
| 		DoesNotMatchFormat() string | ||||
| 		MultipleOf() string | ||||
| 		NumberGTE() string | ||||
| 		NumberGT() string | ||||
| 		NumberLTE() string | ||||
| 		NumberLT() string | ||||
|  | ||||
| 		// Schema validations | ||||
| 		RegexPattern() string | ||||
| 		GreaterThanZero() string | ||||
| 		MustBeOfA() string | ||||
| 		MustBeOfAn() string | ||||
| 		CannotBeUsedWithout() string | ||||
| 		CannotBeGT() string | ||||
| 		MustBeOfType() string | ||||
| 		MustBeValidRegex() string | ||||
| 		MustBeValidFormat() string | ||||
| 		MustBeGTEZero() string | ||||
| 		KeyCannotBeGreaterThan() string | ||||
| 		KeyItemsMustBeOfType() string | ||||
| 		KeyItemsMustBeUnique() string | ||||
| 		ReferenceMustBeCanonical() string | ||||
| 		NotAValidType() string | ||||
| 		Duplicated() string | ||||
| 		HttpBadStatus() string | ||||
|  | ||||
| 		// ErrorFormat | ||||
| 		ErrorFormat() string | ||||
| 	} | ||||
|  | ||||
| 	// DefaultLocale is the default locale for this package | ||||
| 	DefaultLocale struct{} | ||||
| ) | ||||
|  | ||||
| func (l DefaultLocale) Required() string { | ||||
| 	return `{{.property}} is required` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) InvalidType() string { | ||||
| 	return `Invalid type. Expected: {{.expected}}, given: {{.given}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) NumberAnyOf() string { | ||||
| 	return `Must validate at least one schema (anyOf)` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) NumberOneOf() string { | ||||
| 	return `Must validate one and only one schema (oneOf)` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) NumberAllOf() string { | ||||
| 	return `Must validate all the schemas (allOf)` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) NumberNot() string { | ||||
| 	return `Must not validate the schema (not)` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) MissingDependency() string { | ||||
| 	return `Has a dependency on {{.dependency}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) Internal() string { | ||||
| 	return `Internal Error {{.error}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) Enum() string { | ||||
| 	return `{{.field}} must be one of the following: {{.allowed}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) ArrayNoAdditionalItems() string { | ||||
| 	return `No additional items allowed on array` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) ArrayNotEnoughItems() string { | ||||
| 	return `Not enough items on array to match positional list of schema` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) ArrayMinItems() string { | ||||
| 	return `Array must have at least {{.min}} items` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) ArrayMaxItems() string { | ||||
| 	return `Array must have at most {{.max}} items` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) Unique() string { | ||||
| 	return `{{.type}} items must be unique` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) ArrayMinProperties() string { | ||||
| 	return `Must have at least {{.min}} properties` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) ArrayMaxProperties() string { | ||||
| 	return `Must have at most {{.max}} properties` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) AdditionalPropertyNotAllowed() string { | ||||
| 	return `Additional property {{.property}} is not allowed` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) InvalidPropertyPattern() string { | ||||
| 	return `Property "{{.property}}" does not match pattern {{.pattern}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) StringGTE() string { | ||||
| 	return `String length must be greater than or equal to {{.min}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) StringLTE() string { | ||||
| 	return `String length must be less than or equal to {{.max}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) DoesNotMatchPattern() string { | ||||
| 	return `Does not match pattern '{{.pattern}}'` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) DoesNotMatchFormat() string { | ||||
| 	return `Does not match format '{{.format}}'` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) MultipleOf() string { | ||||
| 	return `Must be a multiple of {{.multiple}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) NumberGTE() string { | ||||
| 	return `Must be greater than or equal to {{.min}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) NumberGT() string { | ||||
| 	return `Must be greater than {{.min}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) NumberLTE() string { | ||||
| 	return `Must be less than or equal to {{.max}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) NumberLT() string { | ||||
| 	return `Must be less than {{.max}}` | ||||
| } | ||||
|  | ||||
| // Schema validators | ||||
| func (l DefaultLocale) RegexPattern() string { | ||||
| 	return `Invalid regex pattern '{{.pattern}}'` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) GreaterThanZero() string { | ||||
| 	return `{{.number}} must be strictly greater than 0` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) MustBeOfA() string { | ||||
| 	return `{{.x}} must be of a {{.y}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) MustBeOfAn() string { | ||||
| 	return `{{.x}} must be of an {{.y}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) CannotBeUsedWithout() string { | ||||
| 	return `{{.x}} cannot be used without {{.y}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) CannotBeGT() string { | ||||
| 	return `{{.x}} cannot be greater than {{.y}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) MustBeOfType() string { | ||||
| 	return `{{.key}} must be of type {{.type}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) MustBeValidRegex() string { | ||||
| 	return `{{.key}} must be a valid regex` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) MustBeValidFormat() string { | ||||
| 	return `{{.key}} must be a valid format {{.given}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) MustBeGTEZero() string { | ||||
| 	return `{{.key}} must be greater than or equal to 0` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) KeyCannotBeGreaterThan() string { | ||||
| 	return `{{.key}} cannot be greater than {{.y}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) KeyItemsMustBeOfType() string { | ||||
| 	return `{{.key}} items must be {{.type}}` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) KeyItemsMustBeUnique() string { | ||||
| 	return `{{.key}} items must be unique` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) ReferenceMustBeCanonical() string { | ||||
| 	return `Reference {{.reference}} must be canonical` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) NotAValidType() string { | ||||
| 	return `{{.type}} is not a valid type -- ` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) Duplicated() string { | ||||
| 	return `{{.type}} type is duplicated` | ||||
| } | ||||
|  | ||||
| func (l DefaultLocale) HttpBadStatus() string { | ||||
| 	return `Could not read schema from HTTP, response status is {{.status}}` | ||||
| } | ||||
|  | ||||
| // Replacement options: field, description, context, value | ||||
| func (l DefaultLocale) ErrorFormat() string { | ||||
| 	return `{{.field}}: {{.description}}` | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	STRING_NUMBER                     = "number" | ||||
| 	STRING_ARRAY_OF_STRINGS           = "array of strings" | ||||
| 	STRING_ARRAY_OF_SCHEMAS           = "array of schemas" | ||||
| 	STRING_SCHEMA                     = "schema" | ||||
| 	STRING_SCHEMA_OR_ARRAY_OF_STRINGS = "schema or array of strings" | ||||
| 	STRING_PROPERTIES                 = "properties" | ||||
| 	STRING_DEPENDENCY                 = "dependency" | ||||
| 	STRING_PROPERTY                   = "property" | ||||
| 	STRING_UNDEFINED                  = "undefined" | ||||
| 	STRING_CONTEXT_ROOT               = "(root)" | ||||
| 	STRING_ROOT_SCHEMA_PROPERTY       = "(root)" | ||||
| ) | ||||
							
								
								
									
										172
									
								
								vendor/github.com/xeipuuv/gojsonschema/result.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								vendor/github.com/xeipuuv/gojsonschema/result.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Result and ResultError implementations. | ||||
| // | ||||
| // created          01-01-2015 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| type ( | ||||
| 	// ErrorDetails is a map of details specific to each error. | ||||
| 	// While the values will vary, every error will contain a "field" value | ||||
| 	ErrorDetails map[string]interface{} | ||||
|  | ||||
| 	// ResultError is the interface that library errors must implement | ||||
| 	ResultError interface { | ||||
| 		Field() string | ||||
| 		SetType(string) | ||||
| 		Type() string | ||||
| 		SetContext(*jsonContext) | ||||
| 		Context() *jsonContext | ||||
| 		SetDescription(string) | ||||
| 		Description() string | ||||
| 		SetValue(interface{}) | ||||
| 		Value() interface{} | ||||
| 		SetDetails(ErrorDetails) | ||||
| 		Details() ErrorDetails | ||||
| 		String() string | ||||
| 	} | ||||
|  | ||||
| 	// ResultErrorFields holds the fields for each ResultError implementation. | ||||
| 	// ResultErrorFields implements the ResultError interface, so custom errors | ||||
| 	// can be defined by just embedding this type | ||||
| 	ResultErrorFields struct { | ||||
| 		errorType   string       // A string with the type of error (i.e. invalid_type) | ||||
| 		context     *jsonContext // Tree like notation of the part that failed the validation. ex (root).a.b ... | ||||
| 		description string       // A human readable error message | ||||
| 		value       interface{}  // Value given by the JSON file that is the source of the error | ||||
| 		details     ErrorDetails | ||||
| 	} | ||||
|  | ||||
| 	Result struct { | ||||
| 		errors []ResultError | ||||
| 		// Scores how well the validation matched. Useful in generating | ||||
| 		// better error messages for anyOf and oneOf. | ||||
| 		score int | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // Field outputs the field name without the root context | ||||
| // i.e. firstName or person.firstName instead of (root).firstName or (root).person.firstName | ||||
| func (v *ResultErrorFields) Field() string { | ||||
| 	if p, ok := v.Details()["property"]; ok { | ||||
| 		if str, isString := p.(string); isString { | ||||
| 			return str | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return strings.TrimPrefix(v.context.String(), STRING_ROOT_SCHEMA_PROPERTY+".") | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) SetType(errorType string) { | ||||
| 	v.errorType = errorType | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) Type() string { | ||||
| 	return v.errorType | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) SetContext(context *jsonContext) { | ||||
| 	v.context = context | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) Context() *jsonContext { | ||||
| 	return v.context | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) SetDescription(description string) { | ||||
| 	v.description = description | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) Description() string { | ||||
| 	return v.description | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) SetValue(value interface{}) { | ||||
| 	v.value = value | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) Value() interface{} { | ||||
| 	return v.value | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) SetDetails(details ErrorDetails) { | ||||
| 	v.details = details | ||||
| } | ||||
|  | ||||
| func (v *ResultErrorFields) Details() ErrorDetails { | ||||
| 	return v.details | ||||
| } | ||||
|  | ||||
| func (v ResultErrorFields) String() string { | ||||
| 	// as a fallback, the value is displayed go style | ||||
| 	valueString := fmt.Sprintf("%v", v.value) | ||||
|  | ||||
| 	// marshal the go value value to json | ||||
| 	if v.value == nil { | ||||
| 		valueString = TYPE_NULL | ||||
| 	} else { | ||||
| 		if vs, err := marshalToJsonString(v.value); err == nil { | ||||
| 			if vs == nil { | ||||
| 				valueString = TYPE_NULL | ||||
| 			} else { | ||||
| 				valueString = *vs | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return formatErrorDescription(Locale.ErrorFormat(), ErrorDetails{ | ||||
| 		"context":     v.context.String(), | ||||
| 		"description": v.description, | ||||
| 		"value":       valueString, | ||||
| 		"field":       v.Field(), | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func (v *Result) Valid() bool { | ||||
| 	return len(v.errors) == 0 | ||||
| } | ||||
|  | ||||
| func (v *Result) Errors() []ResultError { | ||||
| 	return v.errors | ||||
| } | ||||
|  | ||||
| func (v *Result) addError(err ResultError, context *jsonContext, value interface{}, details ErrorDetails) { | ||||
| 	newError(err, context, value, Locale, details) | ||||
| 	v.errors = append(v.errors, err) | ||||
| 	v.score -= 2 // results in a net -1 when added to the +1 we get at the end of the validation function | ||||
| } | ||||
|  | ||||
| // Used to copy errors from a sub-schema to the main one | ||||
| func (v *Result) mergeErrors(otherResult *Result) { | ||||
| 	v.errors = append(v.errors, otherResult.Errors()...) | ||||
| 	v.score += otherResult.score | ||||
| } | ||||
|  | ||||
| func (v *Result) incrementScore() { | ||||
| 	v.score++ | ||||
| } | ||||
							
								
								
									
										930
									
								
								vendor/github.com/xeipuuv/gojsonschema/schema.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										930
									
								
								vendor/github.com/xeipuuv/gojsonschema/schema.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,930 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Defines Schema, the main entry to every subSchema. | ||||
| //                  Contains the parsing logic and error checking. | ||||
| // | ||||
| // created          26-02-2013 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	//	"encoding/json" | ||||
| 	"errors" | ||||
| 	"reflect" | ||||
| 	"regexp" | ||||
|  | ||||
| 	"github.com/xeipuuv/gojsonreference" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// Locale is the default locale to use | ||||
| 	// Library users can overwrite with their own implementation | ||||
| 	Locale locale = DefaultLocale{} | ||||
| ) | ||||
|  | ||||
| func NewSchema(l JSONLoader) (*Schema, error) { | ||||
| 	ref, err := l.JsonReference() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	d := Schema{} | ||||
| 	d.pool = newSchemaPool(l.LoaderFactory()) | ||||
| 	d.documentReference = ref | ||||
| 	d.referencePool = newSchemaReferencePool() | ||||
|  | ||||
| 	var doc interface{} | ||||
| 	if ref.String() != "" { | ||||
| 		// Get document from schema pool | ||||
| 		spd, err := d.pool.GetDocument(d.documentReference) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		doc = spd.Document | ||||
| 	} else { | ||||
| 		// Load JSON directly | ||||
| 		doc, err = l.LoadJSON() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		d.pool.SetStandaloneDocument(doc) | ||||
| 	} | ||||
|  | ||||
| 	err = d.parse(doc) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &d, nil | ||||
| } | ||||
|  | ||||
| type Schema struct { | ||||
| 	documentReference gojsonreference.JsonReference | ||||
| 	rootSchema        *subSchema | ||||
| 	pool              *schemaPool | ||||
| 	referencePool     *schemaReferencePool | ||||
| } | ||||
|  | ||||
| func (d *Schema) parse(document interface{}) error { | ||||
| 	d.rootSchema = &subSchema{property: STRING_ROOT_SCHEMA_PROPERTY} | ||||
| 	return d.parseSchema(document, d.rootSchema) | ||||
| } | ||||
|  | ||||
| func (d *Schema) SetRootSchemaName(name string) { | ||||
| 	d.rootSchema.property = name | ||||
| } | ||||
|  | ||||
| // Parses a subSchema | ||||
| // | ||||
| // Pretty long function ( sorry :) )... but pretty straight forward, repetitive and boring | ||||
| // Not much magic involved here, most of the job is to validate the key names and their values, | ||||
| // then the values are copied into subSchema struct | ||||
| // | ||||
| func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema) error { | ||||
|  | ||||
| 	if !isKind(documentNode, reflect.Map) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.InvalidType(), | ||||
| 			ErrorDetails{ | ||||
| 				"expected": TYPE_OBJECT, | ||||
| 				"given":    STRING_SCHEMA, | ||||
| 			}, | ||||
| 		)) | ||||
| 	} | ||||
|  | ||||
| 	m := documentNode.(map[string]interface{}) | ||||
|  | ||||
| 	if currentSchema == d.rootSchema { | ||||
| 		currentSchema.ref = &d.documentReference | ||||
| 	} | ||||
|  | ||||
| 	// $subSchema | ||||
| 	if existsMapKey(m, KEY_SCHEMA) { | ||||
| 		if !isKind(m[KEY_SCHEMA], reflect.String) { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.InvalidType(), | ||||
| 				ErrorDetails{ | ||||
| 					"expected": TYPE_STRING, | ||||
| 					"given":    KEY_SCHEMA, | ||||
| 				}, | ||||
| 			)) | ||||
| 		} | ||||
| 		schemaRef := m[KEY_SCHEMA].(string) | ||||
| 		schemaReference, err := gojsonreference.NewJsonReference(schemaRef) | ||||
| 		currentSchema.subSchema = &schemaReference | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// $ref | ||||
| 	if existsMapKey(m, KEY_REF) && !isKind(m[KEY_REF], reflect.String) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.InvalidType(), | ||||
| 			ErrorDetails{ | ||||
| 				"expected": TYPE_STRING, | ||||
| 				"given":    KEY_REF, | ||||
| 			}, | ||||
| 		)) | ||||
| 	} | ||||
| 	if k, ok := m[KEY_REF].(string); ok { | ||||
|  | ||||
| 		jsonReference, err := gojsonreference.NewJsonReference(k) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		if jsonReference.HasFullUrl { | ||||
| 			currentSchema.ref = &jsonReference | ||||
| 		} else { | ||||
| 			inheritedReference, err := currentSchema.ref.Inherits(jsonReference) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			currentSchema.ref = inheritedReference | ||||
| 		} | ||||
|  | ||||
| 		if sch, ok := d.referencePool.Get(currentSchema.ref.String() + k); ok { | ||||
| 			currentSchema.refSchema = sch | ||||
|  | ||||
| 		} else { | ||||
| 			err := d.parseReference(documentNode, currentSchema, k) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// definitions | ||||
| 	if existsMapKey(m, KEY_DEFINITIONS) { | ||||
| 		if isKind(m[KEY_DEFINITIONS], reflect.Map) { | ||||
| 			currentSchema.definitions = make(map[string]*subSchema) | ||||
| 			for dk, dv := range m[KEY_DEFINITIONS].(map[string]interface{}) { | ||||
| 				if isKind(dv, reflect.Map) { | ||||
| 					newSchema := &subSchema{property: KEY_DEFINITIONS, parent: currentSchema, ref: currentSchema.ref} | ||||
| 					currentSchema.definitions[dk] = newSchema | ||||
| 					err := d.parseSchema(dv, newSchema) | ||||
| 					if err != nil { | ||||
| 						return errors.New(err.Error()) | ||||
| 					} | ||||
| 				} else { | ||||
| 					return errors.New(formatErrorDescription( | ||||
| 						Locale.InvalidType(), | ||||
| 						ErrorDetails{ | ||||
| 							"expected": STRING_ARRAY_OF_SCHEMAS, | ||||
| 							"given":    KEY_DEFINITIONS, | ||||
| 						}, | ||||
| 					)) | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.InvalidType(), | ||||
| 				ErrorDetails{ | ||||
| 					"expected": STRING_ARRAY_OF_SCHEMAS, | ||||
| 					"given":    KEY_DEFINITIONS, | ||||
| 				}, | ||||
| 			)) | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	// id | ||||
| 	if existsMapKey(m, KEY_ID) && !isKind(m[KEY_ID], reflect.String) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.InvalidType(), | ||||
| 			ErrorDetails{ | ||||
| 				"expected": TYPE_STRING, | ||||
| 				"given":    KEY_ID, | ||||
| 			}, | ||||
| 		)) | ||||
| 	} | ||||
| 	if k, ok := m[KEY_ID].(string); ok { | ||||
| 		currentSchema.id = &k | ||||
| 	} | ||||
|  | ||||
| 	// title | ||||
| 	if existsMapKey(m, KEY_TITLE) && !isKind(m[KEY_TITLE], reflect.String) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.InvalidType(), | ||||
| 			ErrorDetails{ | ||||
| 				"expected": TYPE_STRING, | ||||
| 				"given":    KEY_TITLE, | ||||
| 			}, | ||||
| 		)) | ||||
| 	} | ||||
| 	if k, ok := m[KEY_TITLE].(string); ok { | ||||
| 		currentSchema.title = &k | ||||
| 	} | ||||
|  | ||||
| 	// description | ||||
| 	if existsMapKey(m, KEY_DESCRIPTION) && !isKind(m[KEY_DESCRIPTION], reflect.String) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.InvalidType(), | ||||
| 			ErrorDetails{ | ||||
| 				"expected": TYPE_STRING, | ||||
| 				"given":    KEY_DESCRIPTION, | ||||
| 			}, | ||||
| 		)) | ||||
| 	} | ||||
| 	if k, ok := m[KEY_DESCRIPTION].(string); ok { | ||||
| 		currentSchema.description = &k | ||||
| 	} | ||||
|  | ||||
| 	// type | ||||
| 	if existsMapKey(m, KEY_TYPE) { | ||||
| 		if isKind(m[KEY_TYPE], reflect.String) { | ||||
| 			if k, ok := m[KEY_TYPE].(string); ok { | ||||
| 				err := currentSchema.types.Add(k) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			if isKind(m[KEY_TYPE], reflect.Slice) { | ||||
| 				arrayOfTypes := m[KEY_TYPE].([]interface{}) | ||||
| 				for _, typeInArray := range arrayOfTypes { | ||||
| 					if reflect.ValueOf(typeInArray).Kind() != reflect.String { | ||||
| 						return errors.New(formatErrorDescription( | ||||
| 							Locale.InvalidType(), | ||||
| 							ErrorDetails{ | ||||
| 								"expected": TYPE_STRING + "/" + STRING_ARRAY_OF_STRINGS, | ||||
| 								"given":    KEY_TYPE, | ||||
| 							}, | ||||
| 						)) | ||||
| 					} else { | ||||
| 						currentSchema.types.Add(typeInArray.(string)) | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 			} else { | ||||
| 				return errors.New(formatErrorDescription( | ||||
| 					Locale.InvalidType(), | ||||
| 					ErrorDetails{ | ||||
| 						"expected": TYPE_STRING + "/" + STRING_ARRAY_OF_STRINGS, | ||||
| 						"given":    KEY_TYPE, | ||||
| 					}, | ||||
| 				)) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// properties | ||||
| 	if existsMapKey(m, KEY_PROPERTIES) { | ||||
| 		err := d.parseProperties(m[KEY_PROPERTIES], currentSchema) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// additionalProperties | ||||
| 	if existsMapKey(m, KEY_ADDITIONAL_PROPERTIES) { | ||||
| 		if isKind(m[KEY_ADDITIONAL_PROPERTIES], reflect.Bool) { | ||||
| 			currentSchema.additionalProperties = m[KEY_ADDITIONAL_PROPERTIES].(bool) | ||||
| 		} else if isKind(m[KEY_ADDITIONAL_PROPERTIES], reflect.Map) { | ||||
| 			newSchema := &subSchema{property: KEY_ADDITIONAL_PROPERTIES, parent: currentSchema, ref: currentSchema.ref} | ||||
| 			currentSchema.additionalProperties = newSchema | ||||
| 			err := d.parseSchema(m[KEY_ADDITIONAL_PROPERTIES], newSchema) | ||||
| 			if err != nil { | ||||
| 				return errors.New(err.Error()) | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.InvalidType(), | ||||
| 				ErrorDetails{ | ||||
| 					"expected": TYPE_BOOLEAN + "/" + STRING_SCHEMA, | ||||
| 					"given":    KEY_ADDITIONAL_PROPERTIES, | ||||
| 				}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// patternProperties | ||||
| 	if existsMapKey(m, KEY_PATTERN_PROPERTIES) { | ||||
| 		if isKind(m[KEY_PATTERN_PROPERTIES], reflect.Map) { | ||||
| 			patternPropertiesMap := m[KEY_PATTERN_PROPERTIES].(map[string]interface{}) | ||||
| 			if len(patternPropertiesMap) > 0 { | ||||
| 				currentSchema.patternProperties = make(map[string]*subSchema) | ||||
| 				for k, v := range patternPropertiesMap { | ||||
| 					_, err := regexp.MatchString(k, "") | ||||
| 					if err != nil { | ||||
| 						return errors.New(formatErrorDescription( | ||||
| 							Locale.RegexPattern(), | ||||
| 							ErrorDetails{"pattern": k}, | ||||
| 						)) | ||||
| 					} | ||||
| 					newSchema := &subSchema{property: k, parent: currentSchema, ref: currentSchema.ref} | ||||
| 					err = d.parseSchema(v, newSchema) | ||||
| 					if err != nil { | ||||
| 						return errors.New(err.Error()) | ||||
| 					} | ||||
| 					currentSchema.patternProperties[k] = newSchema | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.InvalidType(), | ||||
| 				ErrorDetails{ | ||||
| 					"expected": STRING_SCHEMA, | ||||
| 					"given":    KEY_PATTERN_PROPERTIES, | ||||
| 				}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// dependencies | ||||
| 	if existsMapKey(m, KEY_DEPENDENCIES) { | ||||
| 		err := d.parseDependencies(m[KEY_DEPENDENCIES], currentSchema) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// items | ||||
| 	if existsMapKey(m, KEY_ITEMS) { | ||||
| 		if isKind(m[KEY_ITEMS], reflect.Slice) { | ||||
| 			for _, itemElement := range m[KEY_ITEMS].([]interface{}) { | ||||
| 				if isKind(itemElement, reflect.Map) { | ||||
| 					newSchema := &subSchema{parent: currentSchema, property: KEY_ITEMS} | ||||
| 					newSchema.ref = currentSchema.ref | ||||
| 					currentSchema.AddItemsChild(newSchema) | ||||
| 					err := d.parseSchema(itemElement, newSchema) | ||||
| 					if err != nil { | ||||
| 						return err | ||||
| 					} | ||||
| 				} else { | ||||
| 					return errors.New(formatErrorDescription( | ||||
| 						Locale.InvalidType(), | ||||
| 						ErrorDetails{ | ||||
| 							"expected": STRING_SCHEMA + "/" + STRING_ARRAY_OF_SCHEMAS, | ||||
| 							"given":    KEY_ITEMS, | ||||
| 						}, | ||||
| 					)) | ||||
| 				} | ||||
| 				currentSchema.itemsChildrenIsSingleSchema = false | ||||
| 			} | ||||
| 		} else if isKind(m[KEY_ITEMS], reflect.Map) { | ||||
| 			newSchema := &subSchema{parent: currentSchema, property: KEY_ITEMS} | ||||
| 			newSchema.ref = currentSchema.ref | ||||
| 			currentSchema.AddItemsChild(newSchema) | ||||
| 			err := d.parseSchema(m[KEY_ITEMS], newSchema) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			currentSchema.itemsChildrenIsSingleSchema = true | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.InvalidType(), | ||||
| 				ErrorDetails{ | ||||
| 					"expected": STRING_SCHEMA + "/" + STRING_ARRAY_OF_SCHEMAS, | ||||
| 					"given":    KEY_ITEMS, | ||||
| 				}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// additionalItems | ||||
| 	if existsMapKey(m, KEY_ADDITIONAL_ITEMS) { | ||||
| 		if isKind(m[KEY_ADDITIONAL_ITEMS], reflect.Bool) { | ||||
| 			currentSchema.additionalItems = m[KEY_ADDITIONAL_ITEMS].(bool) | ||||
| 		} else if isKind(m[KEY_ADDITIONAL_ITEMS], reflect.Map) { | ||||
| 			newSchema := &subSchema{property: KEY_ADDITIONAL_ITEMS, parent: currentSchema, ref: currentSchema.ref} | ||||
| 			currentSchema.additionalItems = newSchema | ||||
| 			err := d.parseSchema(m[KEY_ADDITIONAL_ITEMS], newSchema) | ||||
| 			if err != nil { | ||||
| 				return errors.New(err.Error()) | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.InvalidType(), | ||||
| 				ErrorDetails{ | ||||
| 					"expected": TYPE_BOOLEAN + "/" + STRING_SCHEMA, | ||||
| 					"given":    KEY_ADDITIONAL_ITEMS, | ||||
| 				}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// validation : number / integer | ||||
|  | ||||
| 	if existsMapKey(m, KEY_MULTIPLE_OF) { | ||||
| 		multipleOfValue := mustBeNumber(m[KEY_MULTIPLE_OF]) | ||||
| 		if multipleOfValue == nil { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.InvalidType(), | ||||
| 				ErrorDetails{ | ||||
| 					"expected": STRING_NUMBER, | ||||
| 					"given":    KEY_MULTIPLE_OF, | ||||
| 				}, | ||||
| 			)) | ||||
| 		} | ||||
| 		if *multipleOfValue <= 0 { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.GreaterThanZero(), | ||||
| 				ErrorDetails{"number": KEY_MULTIPLE_OF}, | ||||
| 			)) | ||||
| 		} | ||||
| 		currentSchema.multipleOf = multipleOfValue | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_MINIMUM) { | ||||
| 		minimumValue := mustBeNumber(m[KEY_MINIMUM]) | ||||
| 		if minimumValue == nil { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfA(), | ||||
| 				ErrorDetails{"x": KEY_MINIMUM, "y": STRING_NUMBER}, | ||||
| 			)) | ||||
| 		} | ||||
| 		currentSchema.minimum = minimumValue | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_EXCLUSIVE_MINIMUM) { | ||||
| 		if isKind(m[KEY_EXCLUSIVE_MINIMUM], reflect.Bool) { | ||||
| 			if currentSchema.minimum == nil { | ||||
| 				return errors.New(formatErrorDescription( | ||||
| 					Locale.CannotBeUsedWithout(), | ||||
| 					ErrorDetails{"x": KEY_EXCLUSIVE_MINIMUM, "y": KEY_MINIMUM}, | ||||
| 				)) | ||||
| 			} | ||||
| 			exclusiveMinimumValue := m[KEY_EXCLUSIVE_MINIMUM].(bool) | ||||
| 			currentSchema.exclusiveMinimum = exclusiveMinimumValue | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfA(), | ||||
| 				ErrorDetails{"x": KEY_EXCLUSIVE_MINIMUM, "y": TYPE_BOOLEAN}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_MAXIMUM) { | ||||
| 		maximumValue := mustBeNumber(m[KEY_MAXIMUM]) | ||||
| 		if maximumValue == nil { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfA(), | ||||
| 				ErrorDetails{"x": KEY_MAXIMUM, "y": STRING_NUMBER}, | ||||
| 			)) | ||||
| 		} | ||||
| 		currentSchema.maximum = maximumValue | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_EXCLUSIVE_MAXIMUM) { | ||||
| 		if isKind(m[KEY_EXCLUSIVE_MAXIMUM], reflect.Bool) { | ||||
| 			if currentSchema.maximum == nil { | ||||
| 				return errors.New(formatErrorDescription( | ||||
| 					Locale.CannotBeUsedWithout(), | ||||
| 					ErrorDetails{"x": KEY_EXCLUSIVE_MAXIMUM, "y": KEY_MAXIMUM}, | ||||
| 				)) | ||||
| 			} | ||||
| 			exclusiveMaximumValue := m[KEY_EXCLUSIVE_MAXIMUM].(bool) | ||||
| 			currentSchema.exclusiveMaximum = exclusiveMaximumValue | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfA(), | ||||
| 				ErrorDetails{"x": KEY_EXCLUSIVE_MAXIMUM, "y": STRING_NUMBER}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if currentSchema.minimum != nil && currentSchema.maximum != nil { | ||||
| 		if *currentSchema.minimum > *currentSchema.maximum { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.CannotBeGT(), | ||||
| 				ErrorDetails{"x": KEY_MINIMUM, "y": KEY_MAXIMUM}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// validation : string | ||||
|  | ||||
| 	if existsMapKey(m, KEY_MIN_LENGTH) { | ||||
| 		minLengthIntegerValue := mustBeInteger(m[KEY_MIN_LENGTH]) | ||||
| 		if minLengthIntegerValue == nil { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_MIN_LENGTH, "y": TYPE_INTEGER}, | ||||
| 			)) | ||||
| 		} | ||||
| 		if *minLengthIntegerValue < 0 { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeGTEZero(), | ||||
| 				ErrorDetails{"key": KEY_MIN_LENGTH}, | ||||
| 			)) | ||||
| 		} | ||||
| 		currentSchema.minLength = minLengthIntegerValue | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_MAX_LENGTH) { | ||||
| 		maxLengthIntegerValue := mustBeInteger(m[KEY_MAX_LENGTH]) | ||||
| 		if maxLengthIntegerValue == nil { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_MAX_LENGTH, "y": TYPE_INTEGER}, | ||||
| 			)) | ||||
| 		} | ||||
| 		if *maxLengthIntegerValue < 0 { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeGTEZero(), | ||||
| 				ErrorDetails{"key": KEY_MAX_LENGTH}, | ||||
| 			)) | ||||
| 		} | ||||
| 		currentSchema.maxLength = maxLengthIntegerValue | ||||
| 	} | ||||
|  | ||||
| 	if currentSchema.minLength != nil && currentSchema.maxLength != nil { | ||||
| 		if *currentSchema.minLength > *currentSchema.maxLength { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.CannotBeGT(), | ||||
| 				ErrorDetails{"x": KEY_MIN_LENGTH, "y": KEY_MAX_LENGTH}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_PATTERN) { | ||||
| 		if isKind(m[KEY_PATTERN], reflect.String) { | ||||
| 			regexpObject, err := regexp.Compile(m[KEY_PATTERN].(string)) | ||||
| 			if err != nil { | ||||
| 				return errors.New(formatErrorDescription( | ||||
| 					Locale.MustBeValidRegex(), | ||||
| 					ErrorDetails{"key": KEY_PATTERN}, | ||||
| 				)) | ||||
| 			} | ||||
| 			currentSchema.pattern = regexpObject | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfA(), | ||||
| 				ErrorDetails{"x": KEY_PATTERN, "y": TYPE_STRING}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_FORMAT) { | ||||
| 		formatString, ok := m[KEY_FORMAT].(string) | ||||
| 		if ok && FormatCheckers.Has(formatString) { | ||||
| 			currentSchema.format = formatString | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeValidFormat(), | ||||
| 				ErrorDetails{"key": KEY_FORMAT, "given": m[KEY_FORMAT]}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// validation : object | ||||
|  | ||||
| 	if existsMapKey(m, KEY_MIN_PROPERTIES) { | ||||
| 		minPropertiesIntegerValue := mustBeInteger(m[KEY_MIN_PROPERTIES]) | ||||
| 		if minPropertiesIntegerValue == nil { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_MIN_PROPERTIES, "y": TYPE_INTEGER}, | ||||
| 			)) | ||||
| 		} | ||||
| 		if *minPropertiesIntegerValue < 0 { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeGTEZero(), | ||||
| 				ErrorDetails{"key": KEY_MIN_PROPERTIES}, | ||||
| 			)) | ||||
| 		} | ||||
| 		currentSchema.minProperties = minPropertiesIntegerValue | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_MAX_PROPERTIES) { | ||||
| 		maxPropertiesIntegerValue := mustBeInteger(m[KEY_MAX_PROPERTIES]) | ||||
| 		if maxPropertiesIntegerValue == nil { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_MAX_PROPERTIES, "y": TYPE_INTEGER}, | ||||
| 			)) | ||||
| 		} | ||||
| 		if *maxPropertiesIntegerValue < 0 { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeGTEZero(), | ||||
| 				ErrorDetails{"key": KEY_MAX_PROPERTIES}, | ||||
| 			)) | ||||
| 		} | ||||
| 		currentSchema.maxProperties = maxPropertiesIntegerValue | ||||
| 	} | ||||
|  | ||||
| 	if currentSchema.minProperties != nil && currentSchema.maxProperties != nil { | ||||
| 		if *currentSchema.minProperties > *currentSchema.maxProperties { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.KeyCannotBeGreaterThan(), | ||||
| 				ErrorDetails{"key": KEY_MIN_PROPERTIES, "y": KEY_MAX_PROPERTIES}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_REQUIRED) { | ||||
| 		if isKind(m[KEY_REQUIRED], reflect.Slice) { | ||||
| 			requiredValues := m[KEY_REQUIRED].([]interface{}) | ||||
| 			for _, requiredValue := range requiredValues { | ||||
| 				if isKind(requiredValue, reflect.String) { | ||||
| 					err := currentSchema.AddRequired(requiredValue.(string)) | ||||
| 					if err != nil { | ||||
| 						return err | ||||
| 					} | ||||
| 				} else { | ||||
| 					return errors.New(formatErrorDescription( | ||||
| 						Locale.KeyItemsMustBeOfType(), | ||||
| 						ErrorDetails{"key": KEY_REQUIRED, "type": TYPE_STRING}, | ||||
| 					)) | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_REQUIRED, "y": TYPE_ARRAY}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// validation : array | ||||
|  | ||||
| 	if existsMapKey(m, KEY_MIN_ITEMS) { | ||||
| 		minItemsIntegerValue := mustBeInteger(m[KEY_MIN_ITEMS]) | ||||
| 		if minItemsIntegerValue == nil { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_MIN_ITEMS, "y": TYPE_INTEGER}, | ||||
| 			)) | ||||
| 		} | ||||
| 		if *minItemsIntegerValue < 0 { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeGTEZero(), | ||||
| 				ErrorDetails{"key": KEY_MIN_ITEMS}, | ||||
| 			)) | ||||
| 		} | ||||
| 		currentSchema.minItems = minItemsIntegerValue | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_MAX_ITEMS) { | ||||
| 		maxItemsIntegerValue := mustBeInteger(m[KEY_MAX_ITEMS]) | ||||
| 		if maxItemsIntegerValue == nil { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_MAX_ITEMS, "y": TYPE_INTEGER}, | ||||
| 			)) | ||||
| 		} | ||||
| 		if *maxItemsIntegerValue < 0 { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeGTEZero(), | ||||
| 				ErrorDetails{"key": KEY_MAX_ITEMS}, | ||||
| 			)) | ||||
| 		} | ||||
| 		currentSchema.maxItems = maxItemsIntegerValue | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_UNIQUE_ITEMS) { | ||||
| 		if isKind(m[KEY_UNIQUE_ITEMS], reflect.Bool) { | ||||
| 			currentSchema.uniqueItems = m[KEY_UNIQUE_ITEMS].(bool) | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfA(), | ||||
| 				ErrorDetails{"x": KEY_UNIQUE_ITEMS, "y": TYPE_BOOLEAN}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// validation : all | ||||
|  | ||||
| 	if existsMapKey(m, KEY_ENUM) { | ||||
| 		if isKind(m[KEY_ENUM], reflect.Slice) { | ||||
| 			for _, v := range m[KEY_ENUM].([]interface{}) { | ||||
| 				err := currentSchema.AddEnum(v) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_ENUM, "y": TYPE_ARRAY}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// validation : subSchema | ||||
|  | ||||
| 	if existsMapKey(m, KEY_ONE_OF) { | ||||
| 		if isKind(m[KEY_ONE_OF], reflect.Slice) { | ||||
| 			for _, v := range m[KEY_ONE_OF].([]interface{}) { | ||||
| 				newSchema := &subSchema{property: KEY_ONE_OF, parent: currentSchema, ref: currentSchema.ref} | ||||
| 				currentSchema.AddOneOf(newSchema) | ||||
| 				err := d.parseSchema(v, newSchema) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_ONE_OF, "y": TYPE_ARRAY}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_ANY_OF) { | ||||
| 		if isKind(m[KEY_ANY_OF], reflect.Slice) { | ||||
| 			for _, v := range m[KEY_ANY_OF].([]interface{}) { | ||||
| 				newSchema := &subSchema{property: KEY_ANY_OF, parent: currentSchema, ref: currentSchema.ref} | ||||
| 				currentSchema.AddAnyOf(newSchema) | ||||
| 				err := d.parseSchema(v, newSchema) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_ANY_OF, "y": TYPE_ARRAY}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_ALL_OF) { | ||||
| 		if isKind(m[KEY_ALL_OF], reflect.Slice) { | ||||
| 			for _, v := range m[KEY_ALL_OF].([]interface{}) { | ||||
| 				newSchema := &subSchema{property: KEY_ALL_OF, parent: currentSchema, ref: currentSchema.ref} | ||||
| 				currentSchema.AddAllOf(newSchema) | ||||
| 				err := d.parseSchema(v, newSchema) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_ANY_OF, "y": TYPE_ARRAY}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if existsMapKey(m, KEY_NOT) { | ||||
| 		if isKind(m[KEY_NOT], reflect.Map) { | ||||
| 			newSchema := &subSchema{property: KEY_NOT, parent: currentSchema, ref: currentSchema.ref} | ||||
| 			currentSchema.SetNot(newSchema) | ||||
| 			err := d.parseSchema(m[KEY_NOT], newSchema) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfAn(), | ||||
| 				ErrorDetails{"x": KEY_NOT, "y": TYPE_OBJECT}, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (d *Schema) parseReference(documentNode interface{}, currentSchema *subSchema, reference string) error { | ||||
| 	var refdDocumentNode interface{} | ||||
| 	jsonPointer := currentSchema.ref.GetPointer() | ||||
| 	standaloneDocument := d.pool.GetStandaloneDocument() | ||||
|  | ||||
| 	if standaloneDocument != nil { | ||||
|  | ||||
| 		var err error | ||||
| 		refdDocumentNode, _, err = jsonPointer.Get(standaloneDocument) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 	} else { | ||||
| 		dsp, err := d.pool.GetDocument(*currentSchema.ref) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		refdDocumentNode, _, err = jsonPointer.Get(dsp.Document) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	if !isKind(refdDocumentNode, reflect.Map) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.MustBeOfType(), | ||||
| 			ErrorDetails{"key": STRING_SCHEMA, "type": TYPE_OBJECT}, | ||||
| 		)) | ||||
| 	} | ||||
|  | ||||
| 	// returns the loaded referenced subSchema for the caller to update its current subSchema | ||||
| 	newSchemaDocument := refdDocumentNode.(map[string]interface{}) | ||||
| 	newSchema := &subSchema{property: KEY_REF, parent: currentSchema, ref: currentSchema.ref} | ||||
| 	d.referencePool.Add(currentSchema.ref.String()+reference, newSchema) | ||||
|  | ||||
| 	err := d.parseSchema(newSchemaDocument, newSchema) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	currentSchema.refSchema = newSchema | ||||
|  | ||||
| 	return nil | ||||
|  | ||||
| } | ||||
|  | ||||
| func (d *Schema) parseProperties(documentNode interface{}, currentSchema *subSchema) error { | ||||
|  | ||||
| 	if !isKind(documentNode, reflect.Map) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.MustBeOfType(), | ||||
| 			ErrorDetails{"key": STRING_PROPERTIES, "type": TYPE_OBJECT}, | ||||
| 		)) | ||||
| 	} | ||||
|  | ||||
| 	m := documentNode.(map[string]interface{}) | ||||
| 	for k := range m { | ||||
| 		schemaProperty := k | ||||
| 		newSchema := &subSchema{property: schemaProperty, parent: currentSchema, ref: currentSchema.ref} | ||||
| 		currentSchema.AddPropertiesChild(newSchema) | ||||
| 		err := d.parseSchema(m[k], newSchema) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (d *Schema) parseDependencies(documentNode interface{}, currentSchema *subSchema) error { | ||||
|  | ||||
| 	if !isKind(documentNode, reflect.Map) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.MustBeOfType(), | ||||
| 			ErrorDetails{"key": KEY_DEPENDENCIES, "type": TYPE_OBJECT}, | ||||
| 		)) | ||||
| 	} | ||||
|  | ||||
| 	m := documentNode.(map[string]interface{}) | ||||
| 	currentSchema.dependencies = make(map[string]interface{}) | ||||
|  | ||||
| 	for k := range m { | ||||
| 		switch reflect.ValueOf(m[k]).Kind() { | ||||
|  | ||||
| 		case reflect.Slice: | ||||
| 			values := m[k].([]interface{}) | ||||
| 			var valuesToRegister []string | ||||
|  | ||||
| 			for _, value := range values { | ||||
| 				if !isKind(value, reflect.String) { | ||||
| 					return errors.New(formatErrorDescription( | ||||
| 						Locale.MustBeOfType(), | ||||
| 						ErrorDetails{ | ||||
| 							"key":  STRING_DEPENDENCY, | ||||
| 							"type": STRING_SCHEMA_OR_ARRAY_OF_STRINGS, | ||||
| 						}, | ||||
| 					)) | ||||
| 				} else { | ||||
| 					valuesToRegister = append(valuesToRegister, value.(string)) | ||||
| 				} | ||||
| 				currentSchema.dependencies[k] = valuesToRegister | ||||
| 			} | ||||
|  | ||||
| 		case reflect.Map: | ||||
| 			depSchema := &subSchema{property: k, parent: currentSchema, ref: currentSchema.ref} | ||||
| 			err := d.parseSchema(m[k], depSchema) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			currentSchema.dependencies[k] = depSchema | ||||
|  | ||||
| 		default: | ||||
| 			return errors.New(formatErrorDescription( | ||||
| 				Locale.MustBeOfType(), | ||||
| 				ErrorDetails{ | ||||
| 					"key":  STRING_DEPENDENCY, | ||||
| 					"type": STRING_SCHEMA_OR_ARRAY_OF_STRINGS, | ||||
| 				}, | ||||
| 			)) | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										109
									
								
								vendor/github.com/xeipuuv/gojsonschema/schemaPool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/xeipuuv/gojsonschema/schemaPool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description		Defines resources pooling. | ||||
| //                  Eases referencing and avoids downloading the same resource twice. | ||||
| // | ||||
| // created          26-02-2013 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
|  | ||||
| 	"github.com/xeipuuv/gojsonreference" | ||||
| ) | ||||
|  | ||||
| type schemaPoolDocument struct { | ||||
| 	Document interface{} | ||||
| } | ||||
|  | ||||
| type schemaPool struct { | ||||
| 	schemaPoolDocuments map[string]*schemaPoolDocument | ||||
| 	standaloneDocument  interface{} | ||||
| 	jsonLoaderFactory   JSONLoaderFactory | ||||
| } | ||||
|  | ||||
| func newSchemaPool(f JSONLoaderFactory) *schemaPool { | ||||
|  | ||||
| 	p := &schemaPool{} | ||||
| 	p.schemaPoolDocuments = make(map[string]*schemaPoolDocument) | ||||
| 	p.standaloneDocument = nil | ||||
| 	p.jsonLoaderFactory = f | ||||
|  | ||||
| 	return p | ||||
| } | ||||
|  | ||||
| func (p *schemaPool) SetStandaloneDocument(document interface{}) { | ||||
| 	p.standaloneDocument = document | ||||
| } | ||||
|  | ||||
| func (p *schemaPool) GetStandaloneDocument() (document interface{}) { | ||||
| 	return p.standaloneDocument | ||||
| } | ||||
|  | ||||
| func (p *schemaPool) GetDocument(reference gojsonreference.JsonReference) (*schemaPoolDocument, error) { | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog("Get Document ( %s )", reference.String()) | ||||
| 	} | ||||
|  | ||||
| 	var err error | ||||
|  | ||||
| 	// It is not possible to load anything that is not canonical... | ||||
| 	if !reference.IsCanonical() { | ||||
| 		return nil, errors.New(formatErrorDescription( | ||||
| 			Locale.ReferenceMustBeCanonical(), | ||||
| 			ErrorDetails{"reference": reference}, | ||||
| 		)) | ||||
| 	} | ||||
|  | ||||
| 	refToUrl := reference | ||||
| 	refToUrl.GetUrl().Fragment = "" | ||||
|  | ||||
| 	var spd *schemaPoolDocument | ||||
|  | ||||
| 	// Try to find the requested document in the pool | ||||
| 	for k := range p.schemaPoolDocuments { | ||||
| 		if k == refToUrl.String() { | ||||
| 			spd = p.schemaPoolDocuments[k] | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if spd != nil { | ||||
| 		if internalLogEnabled { | ||||
| 			internalLog(" From pool") | ||||
| 		} | ||||
| 		return spd, nil | ||||
| 	} | ||||
|  | ||||
| 	jsonReferenceLoader := p.jsonLoaderFactory.New(reference.String()) | ||||
| 	document, err := jsonReferenceLoader.LoadJSON() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	spd = &schemaPoolDocument{Document: document} | ||||
| 	// add the document to the pool for potential later use | ||||
| 	p.schemaPoolDocuments[refToUrl.String()] = spd | ||||
|  | ||||
| 	return spd, nil | ||||
| } | ||||
							
								
								
									
										67
									
								
								vendor/github.com/xeipuuv/gojsonschema/schemaReferencePool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								vendor/github.com/xeipuuv/gojsonschema/schemaReferencePool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Pool of referenced schemas. | ||||
| // | ||||
| // created          25-06-2013 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| type schemaReferencePool struct { | ||||
| 	documents map[string]*subSchema | ||||
| } | ||||
|  | ||||
| func newSchemaReferencePool() *schemaReferencePool { | ||||
|  | ||||
| 	p := &schemaReferencePool{} | ||||
| 	p.documents = make(map[string]*subSchema) | ||||
|  | ||||
| 	return p | ||||
| } | ||||
|  | ||||
| func (p *schemaReferencePool) Get(ref string) (r *subSchema, o bool) { | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog(fmt.Sprintf("Schema Reference ( %s )", ref)) | ||||
| 	} | ||||
|  | ||||
| 	if sch, ok := p.documents[ref]; ok { | ||||
| 		if internalLogEnabled { | ||||
| 			internalLog(fmt.Sprintf(" From pool")) | ||||
| 		} | ||||
| 		return sch, true | ||||
| 	} | ||||
|  | ||||
| 	return nil, false | ||||
| } | ||||
|  | ||||
| func (p *schemaReferencePool) Add(ref string, sch *subSchema) { | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog(fmt.Sprintf("Add Schema Reference %s to pool", ref)) | ||||
| 	} | ||||
|  | ||||
| 	p.documents[ref] = sch | ||||
| } | ||||
							
								
								
									
										83
									
								
								vendor/github.com/xeipuuv/gojsonschema/schemaType.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								vendor/github.com/xeipuuv/gojsonschema/schemaType.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Helper structure to handle schema types, and the combination of them. | ||||
| // | ||||
| // created          28-02-2013 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| type jsonSchemaType struct { | ||||
| 	types []string | ||||
| } | ||||
|  | ||||
| // Is the schema typed ? that is containing at least one type | ||||
| // When not typed, the schema does not need any type validation | ||||
| func (t *jsonSchemaType) IsTyped() bool { | ||||
| 	return len(t.types) > 0 | ||||
| } | ||||
|  | ||||
| func (t *jsonSchemaType) Add(etype string) error { | ||||
|  | ||||
| 	if !isStringInSlice(JSON_TYPES, etype) { | ||||
| 		return errors.New(formatErrorDescription(Locale.NotAValidType(), ErrorDetails{"type": etype})) | ||||
| 	} | ||||
|  | ||||
| 	if t.Contains(etype) { | ||||
| 		return errors.New(formatErrorDescription(Locale.Duplicated(), ErrorDetails{"type": etype})) | ||||
| 	} | ||||
|  | ||||
| 	t.types = append(t.types, etype) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (t *jsonSchemaType) Contains(etype string) bool { | ||||
|  | ||||
| 	for _, v := range t.types { | ||||
| 		if v == etype { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (t *jsonSchemaType) String() string { | ||||
|  | ||||
| 	if len(t.types) == 0 { | ||||
| 		return STRING_UNDEFINED // should never happen | ||||
| 	} | ||||
|  | ||||
| 	// Displayed as a list [type1,type2,...] | ||||
| 	if len(t.types) > 1 { | ||||
| 		return fmt.Sprintf("[%s]", strings.Join(t.types, ",")) | ||||
| 	} | ||||
|  | ||||
| 	// Only one type: name only | ||||
| 	return t.types[0] | ||||
| } | ||||
							
								
								
									
										227
									
								
								vendor/github.com/xeipuuv/gojsonschema/subSchema.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								vendor/github.com/xeipuuv/gojsonschema/subSchema.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,227 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Defines the structure of a sub-subSchema. | ||||
| //                  A sub-subSchema can contain other sub-schemas. | ||||
| // | ||||
| // created          27-02-2013 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/xeipuuv/gojsonreference" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	KEY_SCHEMA                = "$subSchema" | ||||
| 	KEY_ID                    = "$id" | ||||
| 	KEY_REF                   = "$ref" | ||||
| 	KEY_TITLE                 = "title" | ||||
| 	KEY_DESCRIPTION           = "description" | ||||
| 	KEY_TYPE                  = "type" | ||||
| 	KEY_ITEMS                 = "items" | ||||
| 	KEY_ADDITIONAL_ITEMS      = "additionalItems" | ||||
| 	KEY_PROPERTIES            = "properties" | ||||
| 	KEY_PATTERN_PROPERTIES    = "patternProperties" | ||||
| 	KEY_ADDITIONAL_PROPERTIES = "additionalProperties" | ||||
| 	KEY_DEFINITIONS           = "definitions" | ||||
| 	KEY_MULTIPLE_OF           = "multipleOf" | ||||
| 	KEY_MINIMUM               = "minimum" | ||||
| 	KEY_MAXIMUM               = "maximum" | ||||
| 	KEY_EXCLUSIVE_MINIMUM     = "exclusiveMinimum" | ||||
| 	KEY_EXCLUSIVE_MAXIMUM     = "exclusiveMaximum" | ||||
| 	KEY_MIN_LENGTH            = "minLength" | ||||
| 	KEY_MAX_LENGTH            = "maxLength" | ||||
| 	KEY_PATTERN               = "pattern" | ||||
| 	KEY_FORMAT                = "format" | ||||
| 	KEY_MIN_PROPERTIES        = "minProperties" | ||||
| 	KEY_MAX_PROPERTIES        = "maxProperties" | ||||
| 	KEY_DEPENDENCIES          = "dependencies" | ||||
| 	KEY_REQUIRED              = "required" | ||||
| 	KEY_MIN_ITEMS             = "minItems" | ||||
| 	KEY_MAX_ITEMS             = "maxItems" | ||||
| 	KEY_UNIQUE_ITEMS          = "uniqueItems" | ||||
| 	KEY_ENUM                  = "enum" | ||||
| 	KEY_ONE_OF                = "oneOf" | ||||
| 	KEY_ANY_OF                = "anyOf" | ||||
| 	KEY_ALL_OF                = "allOf" | ||||
| 	KEY_NOT                   = "not" | ||||
| ) | ||||
|  | ||||
| type subSchema struct { | ||||
|  | ||||
| 	// basic subSchema meta properties | ||||
| 	id          *string | ||||
| 	title       *string | ||||
| 	description *string | ||||
|  | ||||
| 	property string | ||||
|  | ||||
| 	// Types associated with the subSchema | ||||
| 	types jsonSchemaType | ||||
|  | ||||
| 	// Reference url | ||||
| 	ref *gojsonreference.JsonReference | ||||
| 	// Schema referenced | ||||
| 	refSchema *subSchema | ||||
| 	// Json reference | ||||
| 	subSchema *gojsonreference.JsonReference | ||||
|  | ||||
| 	// hierarchy | ||||
| 	parent                      *subSchema | ||||
| 	definitions                 map[string]*subSchema | ||||
| 	definitionsChildren         []*subSchema | ||||
| 	itemsChildren               []*subSchema | ||||
| 	itemsChildrenIsSingleSchema bool | ||||
| 	propertiesChildren          []*subSchema | ||||
|  | ||||
| 	// validation : number / integer | ||||
| 	multipleOf       *float64 | ||||
| 	maximum          *float64 | ||||
| 	exclusiveMaximum bool | ||||
| 	minimum          *float64 | ||||
| 	exclusiveMinimum bool | ||||
|  | ||||
| 	// validation : string | ||||
| 	minLength *int | ||||
| 	maxLength *int | ||||
| 	pattern   *regexp.Regexp | ||||
| 	format    string | ||||
|  | ||||
| 	// validation : object | ||||
| 	minProperties *int | ||||
| 	maxProperties *int | ||||
| 	required      []string | ||||
|  | ||||
| 	dependencies         map[string]interface{} | ||||
| 	additionalProperties interface{} | ||||
| 	patternProperties    map[string]*subSchema | ||||
|  | ||||
| 	// validation : array | ||||
| 	minItems    *int | ||||
| 	maxItems    *int | ||||
| 	uniqueItems bool | ||||
|  | ||||
| 	additionalItems interface{} | ||||
|  | ||||
| 	// validation : all | ||||
| 	enum []string | ||||
|  | ||||
| 	// validation : subSchema | ||||
| 	oneOf []*subSchema | ||||
| 	anyOf []*subSchema | ||||
| 	allOf []*subSchema | ||||
| 	not   *subSchema | ||||
| } | ||||
|  | ||||
| func (s *subSchema) AddEnum(i interface{}) error { | ||||
|  | ||||
| 	is, err := marshalToJsonString(i) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if isStringInSlice(s.enum, *is) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.KeyItemsMustBeUnique(), | ||||
| 			ErrorDetails{"key": KEY_ENUM}, | ||||
| 		)) | ||||
| 	} | ||||
|  | ||||
| 	s.enum = append(s.enum, *is) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *subSchema) ContainsEnum(i interface{}) (bool, error) { | ||||
|  | ||||
| 	is, err := marshalToJsonString(i) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
|  | ||||
| 	return isStringInSlice(s.enum, *is), nil | ||||
| } | ||||
|  | ||||
| func (s *subSchema) AddOneOf(subSchema *subSchema) { | ||||
| 	s.oneOf = append(s.oneOf, subSchema) | ||||
| } | ||||
|  | ||||
| func (s *subSchema) AddAllOf(subSchema *subSchema) { | ||||
| 	s.allOf = append(s.allOf, subSchema) | ||||
| } | ||||
|  | ||||
| func (s *subSchema) AddAnyOf(subSchema *subSchema) { | ||||
| 	s.anyOf = append(s.anyOf, subSchema) | ||||
| } | ||||
|  | ||||
| func (s *subSchema) SetNot(subSchema *subSchema) { | ||||
| 	s.not = subSchema | ||||
| } | ||||
|  | ||||
| func (s *subSchema) AddRequired(value string) error { | ||||
|  | ||||
| 	if isStringInSlice(s.required, value) { | ||||
| 		return errors.New(formatErrorDescription( | ||||
| 			Locale.KeyItemsMustBeUnique(), | ||||
| 			ErrorDetails{"key": KEY_REQUIRED}, | ||||
| 		)) | ||||
| 	} | ||||
|  | ||||
| 	s.required = append(s.required, value) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *subSchema) AddDefinitionChild(child *subSchema) { | ||||
| 	s.definitionsChildren = append(s.definitionsChildren, child) | ||||
| } | ||||
|  | ||||
| func (s *subSchema) AddItemsChild(child *subSchema) { | ||||
| 	s.itemsChildren = append(s.itemsChildren, child) | ||||
| } | ||||
|  | ||||
| func (s *subSchema) AddPropertiesChild(child *subSchema) { | ||||
| 	s.propertiesChildren = append(s.propertiesChildren, child) | ||||
| } | ||||
|  | ||||
| func (s *subSchema) PatternPropertiesString() string { | ||||
|  | ||||
| 	if s.patternProperties == nil || len(s.patternProperties) == 0 { | ||||
| 		return STRING_UNDEFINED // should never happen | ||||
| 	} | ||||
|  | ||||
| 	patternPropertiesKeySlice := []string{} | ||||
| 	for pk := range s.patternProperties { | ||||
| 		patternPropertiesKeySlice = append(patternPropertiesKeySlice, `"`+pk+`"`) | ||||
| 	} | ||||
|  | ||||
| 	if len(patternPropertiesKeySlice) == 1 { | ||||
| 		return patternPropertiesKeySlice[0] | ||||
| 	} | ||||
|  | ||||
| 	return "[" + strings.Join(patternPropertiesKeySlice, ",") + "]" | ||||
|  | ||||
| } | ||||
							
								
								
									
										58
									
								
								vendor/github.com/xeipuuv/gojsonschema/types.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								vendor/github.com/xeipuuv/gojsonschema/types.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Contains const types for schema and JSON. | ||||
| // | ||||
| // created          28-02-2013 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| const ( | ||||
| 	TYPE_ARRAY   = `array` | ||||
| 	TYPE_BOOLEAN = `boolean` | ||||
| 	TYPE_INTEGER = `integer` | ||||
| 	TYPE_NUMBER  = `number` | ||||
| 	TYPE_NULL    = `null` | ||||
| 	TYPE_OBJECT  = `object` | ||||
| 	TYPE_STRING  = `string` | ||||
| ) | ||||
|  | ||||
| var JSON_TYPES []string | ||||
| var SCHEMA_TYPES []string | ||||
|  | ||||
| func init() { | ||||
| 	JSON_TYPES = []string{ | ||||
| 		TYPE_ARRAY, | ||||
| 		TYPE_BOOLEAN, | ||||
| 		TYPE_INTEGER, | ||||
| 		TYPE_NUMBER, | ||||
| 		TYPE_NULL, | ||||
| 		TYPE_OBJECT, | ||||
| 		TYPE_STRING} | ||||
|  | ||||
| 	SCHEMA_TYPES = []string{ | ||||
| 		TYPE_ARRAY, | ||||
| 		TYPE_BOOLEAN, | ||||
| 		TYPE_INTEGER, | ||||
| 		TYPE_NUMBER, | ||||
| 		TYPE_OBJECT, | ||||
| 		TYPE_STRING} | ||||
| } | ||||
							
								
								
									
										208
									
								
								vendor/github.com/xeipuuv/gojsonschema/utils.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								vendor/github.com/xeipuuv/gojsonschema/utils.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,208 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Various utility functions. | ||||
| // | ||||
| // created          26-02-2013 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| func isKind(what interface{}, kind reflect.Kind) bool { | ||||
| 	target := what | ||||
| 	if isJsonNumber(what) { | ||||
| 		// JSON Numbers are strings! | ||||
| 		target = *mustBeNumber(what) | ||||
| 	} | ||||
| 	return reflect.ValueOf(target).Kind() == kind | ||||
| } | ||||
|  | ||||
| func existsMapKey(m map[string]interface{}, k string) bool { | ||||
| 	_, ok := m[k] | ||||
| 	return ok | ||||
| } | ||||
|  | ||||
| func isStringInSlice(s []string, what string) bool { | ||||
| 	for i := range s { | ||||
| 		if s[i] == what { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func marshalToJsonString(value interface{}) (*string, error) { | ||||
|  | ||||
| 	mBytes, err := json.Marshal(value) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	sBytes := string(mBytes) | ||||
| 	return &sBytes, nil | ||||
| } | ||||
|  | ||||
| func isJsonNumber(what interface{}) bool { | ||||
|  | ||||
| 	switch what.(type) { | ||||
|  | ||||
| 	case json.Number: | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func checkJsonNumber(what interface{}) (isValidFloat64 bool, isValidInt64 bool, isValidInt32 bool) { | ||||
|  | ||||
| 	jsonNumber := what.(json.Number) | ||||
|  | ||||
| 	f64, errFloat64 := jsonNumber.Float64() | ||||
| 	s64 := strconv.FormatFloat(f64, 'f', -1, 64) | ||||
| 	_, errInt64 := strconv.ParseInt(s64, 10, 64) | ||||
|  | ||||
| 	isValidFloat64 = errFloat64 == nil | ||||
| 	isValidInt64 = errInt64 == nil | ||||
|  | ||||
| 	_, errInt32 := strconv.ParseInt(s64, 10, 32) | ||||
| 	isValidInt32 = isValidInt64 && errInt32 == nil | ||||
|  | ||||
| 	return | ||||
|  | ||||
| } | ||||
|  | ||||
| // same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER | ||||
| const ( | ||||
| 	max_json_float = float64(1<<53 - 1)  // 9007199254740991.0 	 2^53 - 1 | ||||
| 	min_json_float = -float64(1<<53 - 1) //-9007199254740991.0	-2^53 - 1 | ||||
| ) | ||||
|  | ||||
| func isFloat64AnInteger(f float64) bool { | ||||
|  | ||||
| 	if math.IsNaN(f) || math.IsInf(f, 0) || f < min_json_float || f > max_json_float { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	return f == float64(int64(f)) || f == float64(uint64(f)) | ||||
| } | ||||
|  | ||||
| func mustBeInteger(what interface{}) *int { | ||||
|  | ||||
| 	if isJsonNumber(what) { | ||||
|  | ||||
| 		number := what.(json.Number) | ||||
|  | ||||
| 		_, _, isValidInt32 := checkJsonNumber(number) | ||||
|  | ||||
| 		if isValidInt32 { | ||||
|  | ||||
| 			int64Value, err := number.Int64() | ||||
| 			if err != nil { | ||||
| 				return nil | ||||
| 			} | ||||
|  | ||||
| 			int32Value := int(int64Value) | ||||
| 			return &int32Value | ||||
|  | ||||
| 		} else { | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func mustBeNumber(what interface{}) *float64 { | ||||
|  | ||||
| 	if isJsonNumber(what) { | ||||
|  | ||||
| 		number := what.(json.Number) | ||||
| 		float64Value, err := number.Float64() | ||||
|  | ||||
| 		if err == nil { | ||||
| 			return &float64Value | ||||
| 		} else { | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
|  | ||||
| } | ||||
|  | ||||
| // formats a number so that it is displayed as the smallest string possible | ||||
| func resultErrorFormatJsonNumber(n json.Number) string { | ||||
|  | ||||
| 	if int64Value, err := n.Int64(); err == nil { | ||||
| 		return fmt.Sprintf("%d", int64Value) | ||||
| 	} | ||||
|  | ||||
| 	float64Value, _ := n.Float64() | ||||
|  | ||||
| 	return fmt.Sprintf("%g", float64Value) | ||||
| } | ||||
|  | ||||
| // formats a number so that it is displayed as the smallest string possible | ||||
| func resultErrorFormatNumber(n float64) string { | ||||
|  | ||||
| 	if isFloat64AnInteger(n) { | ||||
| 		return fmt.Sprintf("%d", int64(n)) | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Sprintf("%g", n) | ||||
| } | ||||
|  | ||||
| func convertDocumentNode(val interface{}) interface{} { | ||||
|  | ||||
| 	if lval, ok := val.([]interface{}); ok { | ||||
|  | ||||
| 		res := []interface{}{} | ||||
| 		for _, v := range lval { | ||||
| 			res = append(res, convertDocumentNode(v)) | ||||
| 		} | ||||
|  | ||||
| 		return res | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	if mval, ok := val.(map[interface{}]interface{}); ok { | ||||
|  | ||||
| 		res := map[string]interface{}{} | ||||
|  | ||||
| 		for k, v := range mval { | ||||
| 			res[k.(string)] = convertDocumentNode(v) | ||||
| 		} | ||||
|  | ||||
| 		return res | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return val | ||||
| } | ||||
							
								
								
									
										832
									
								
								vendor/github.com/xeipuuv/gojsonschema/validation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										832
									
								
								vendor/github.com/xeipuuv/gojsonschema/validation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,832 @@ | ||||
| // Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) | ||||
| // | ||||
| // 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. | ||||
|  | ||||
| // author           xeipuuv | ||||
| // author-github    https://github.com/xeipuuv | ||||
| // author-mail      xeipuuv@gmail.com | ||||
| // | ||||
| // repository-name  gojsonschema | ||||
| // repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language. | ||||
| // | ||||
| // description      Extends Schema and subSchema, implements the validation phase. | ||||
| // | ||||
| // created          28-02-2013 | ||||
|  | ||||
| package gojsonschema | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"reflect" | ||||
| 	"regexp" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
|  | ||||
| func Validate(ls JSONLoader, ld JSONLoader) (*Result, error) { | ||||
|  | ||||
| 	var err error | ||||
|  | ||||
| 	// load schema | ||||
|  | ||||
| 	schema, err := NewSchema(ls) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// begine validation | ||||
|  | ||||
| 	return schema.Validate(ld) | ||||
|  | ||||
| } | ||||
|  | ||||
| func (v *Schema) Validate(l JSONLoader) (*Result, error) { | ||||
|  | ||||
| 	// load document | ||||
|  | ||||
| 	root, err := l.LoadJSON() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// begin validation | ||||
|  | ||||
| 	result := &Result{} | ||||
| 	context := newJsonContext(STRING_CONTEXT_ROOT, nil) | ||||
| 	v.rootSchema.validateRecursive(v.rootSchema, root, result, context) | ||||
|  | ||||
| 	return result, nil | ||||
|  | ||||
| } | ||||
|  | ||||
| func (v *subSchema) subValidateWithContext(document interface{}, context *jsonContext) *Result { | ||||
| 	result := &Result{} | ||||
| 	v.validateRecursive(v, document, result, context) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| // Walker function to validate the json recursively against the subSchema | ||||
| func (v *subSchema) validateRecursive(currentSubSchema *subSchema, currentNode interface{}, result *Result, context *jsonContext) { | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog("validateRecursive %s", context.String()) | ||||
| 		internalLog(" %v", currentNode) | ||||
| 	} | ||||
|  | ||||
| 	// Handle referenced schemas, returns directly when a $ref is found | ||||
| 	if currentSubSchema.refSchema != nil { | ||||
| 		v.validateRecursive(currentSubSchema.refSchema, currentNode, result, context) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// Check for null value | ||||
| 	if currentNode == nil { | ||||
| 		if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_NULL) { | ||||
| 			result.addError( | ||||
| 				new(InvalidTypeError), | ||||
| 				context, | ||||
| 				currentNode, | ||||
| 				ErrorDetails{ | ||||
| 					"expected": currentSubSchema.types.String(), | ||||
| 					"given":    TYPE_NULL, | ||||
| 				}, | ||||
| 			) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		currentSubSchema.validateSchema(currentSubSchema, currentNode, result, context) | ||||
| 		v.validateCommon(currentSubSchema, currentNode, result, context) | ||||
|  | ||||
| 	} else { // Not a null value | ||||
|  | ||||
| 		if isJsonNumber(currentNode) { | ||||
|  | ||||
| 			value := currentNode.(json.Number) | ||||
|  | ||||
| 			_, isValidInt64, _ := checkJsonNumber(value) | ||||
|  | ||||
| 			validType := currentSubSchema.types.Contains(TYPE_NUMBER) || (isValidInt64 && currentSubSchema.types.Contains(TYPE_INTEGER)) | ||||
|  | ||||
| 			if currentSubSchema.types.IsTyped() && !validType { | ||||
|  | ||||
| 				givenType := TYPE_INTEGER | ||||
| 				if !isValidInt64 { | ||||
| 					givenType = TYPE_NUMBER | ||||
| 				} | ||||
|  | ||||
| 				result.addError( | ||||
| 					new(InvalidTypeError), | ||||
| 					context, | ||||
| 					currentNode, | ||||
| 					ErrorDetails{ | ||||
| 						"expected": currentSubSchema.types.String(), | ||||
| 						"given":    givenType, | ||||
| 					}, | ||||
| 				) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			currentSubSchema.validateSchema(currentSubSchema, value, result, context) | ||||
| 			v.validateNumber(currentSubSchema, value, result, context) | ||||
| 			v.validateCommon(currentSubSchema, value, result, context) | ||||
| 			v.validateString(currentSubSchema, value, result, context) | ||||
|  | ||||
| 		} else { | ||||
|  | ||||
| 			rValue := reflect.ValueOf(currentNode) | ||||
| 			rKind := rValue.Kind() | ||||
|  | ||||
| 			switch rKind { | ||||
|  | ||||
| 			// Slice => JSON array | ||||
|  | ||||
| 			case reflect.Slice: | ||||
|  | ||||
| 				if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_ARRAY) { | ||||
| 					result.addError( | ||||
| 						new(InvalidTypeError), | ||||
| 						context, | ||||
| 						currentNode, | ||||
| 						ErrorDetails{ | ||||
| 							"expected": currentSubSchema.types.String(), | ||||
| 							"given":    TYPE_ARRAY, | ||||
| 						}, | ||||
| 					) | ||||
| 					return | ||||
| 				} | ||||
|  | ||||
| 				castCurrentNode := currentNode.([]interface{}) | ||||
|  | ||||
| 				currentSubSchema.validateSchema(currentSubSchema, castCurrentNode, result, context) | ||||
|  | ||||
| 				v.validateArray(currentSubSchema, castCurrentNode, result, context) | ||||
| 				v.validateCommon(currentSubSchema, castCurrentNode, result, context) | ||||
|  | ||||
| 			// Map => JSON object | ||||
|  | ||||
| 			case reflect.Map: | ||||
| 				if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_OBJECT) { | ||||
| 					result.addError( | ||||
| 						new(InvalidTypeError), | ||||
| 						context, | ||||
| 						currentNode, | ||||
| 						ErrorDetails{ | ||||
| 							"expected": currentSubSchema.types.String(), | ||||
| 							"given":    TYPE_OBJECT, | ||||
| 						}, | ||||
| 					) | ||||
| 					return | ||||
| 				} | ||||
|  | ||||
| 				castCurrentNode, ok := currentNode.(map[string]interface{}) | ||||
| 				if !ok { | ||||
| 					castCurrentNode = convertDocumentNode(currentNode).(map[string]interface{}) | ||||
| 				} | ||||
|  | ||||
| 				currentSubSchema.validateSchema(currentSubSchema, castCurrentNode, result, context) | ||||
|  | ||||
| 				v.validateObject(currentSubSchema, castCurrentNode, result, context) | ||||
| 				v.validateCommon(currentSubSchema, castCurrentNode, result, context) | ||||
|  | ||||
| 				for _, pSchema := range currentSubSchema.propertiesChildren { | ||||
| 					nextNode, ok := castCurrentNode[pSchema.property] | ||||
| 					if ok { | ||||
| 						subContext := newJsonContext(pSchema.property, context) | ||||
| 						v.validateRecursive(pSchema, nextNode, result, subContext) | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 			// Simple JSON values : string, number, boolean | ||||
|  | ||||
| 			case reflect.Bool: | ||||
|  | ||||
| 				if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_BOOLEAN) { | ||||
| 					result.addError( | ||||
| 						new(InvalidTypeError), | ||||
| 						context, | ||||
| 						currentNode, | ||||
| 						ErrorDetails{ | ||||
| 							"expected": currentSubSchema.types.String(), | ||||
| 							"given":    TYPE_BOOLEAN, | ||||
| 						}, | ||||
| 					) | ||||
| 					return | ||||
| 				} | ||||
|  | ||||
| 				value := currentNode.(bool) | ||||
|  | ||||
| 				currentSubSchema.validateSchema(currentSubSchema, value, result, context) | ||||
| 				v.validateNumber(currentSubSchema, value, result, context) | ||||
| 				v.validateCommon(currentSubSchema, value, result, context) | ||||
| 				v.validateString(currentSubSchema, value, result, context) | ||||
|  | ||||
| 			case reflect.String: | ||||
|  | ||||
| 				if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_STRING) { | ||||
| 					result.addError( | ||||
| 						new(InvalidTypeError), | ||||
| 						context, | ||||
| 						currentNode, | ||||
| 						ErrorDetails{ | ||||
| 							"expected": currentSubSchema.types.String(), | ||||
| 							"given":    TYPE_STRING, | ||||
| 						}, | ||||
| 					) | ||||
| 					return | ||||
| 				} | ||||
|  | ||||
| 				value := currentNode.(string) | ||||
|  | ||||
| 				currentSubSchema.validateSchema(currentSubSchema, value, result, context) | ||||
| 				v.validateNumber(currentSubSchema, value, result, context) | ||||
| 				v.validateCommon(currentSubSchema, value, result, context) | ||||
| 				v.validateString(currentSubSchema, value, result, context) | ||||
|  | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	result.incrementScore() | ||||
| } | ||||
|  | ||||
| // Different kinds of validation there, subSchema / common / array / object / string... | ||||
| func (v *subSchema) validateSchema(currentSubSchema *subSchema, currentNode interface{}, result *Result, context *jsonContext) { | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog("validateSchema %s", context.String()) | ||||
| 		internalLog(" %v", currentNode) | ||||
| 	} | ||||
|  | ||||
| 	if len(currentSubSchema.anyOf) > 0 { | ||||
|  | ||||
| 		validatedAnyOf := false | ||||
| 		var bestValidationResult *Result | ||||
|  | ||||
| 		for _, anyOfSchema := range currentSubSchema.anyOf { | ||||
| 			if !validatedAnyOf { | ||||
| 				validationResult := anyOfSchema.subValidateWithContext(currentNode, context) | ||||
| 				validatedAnyOf = validationResult.Valid() | ||||
|  | ||||
| 				if !validatedAnyOf && (bestValidationResult == nil || validationResult.score > bestValidationResult.score) { | ||||
| 					bestValidationResult = validationResult | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if !validatedAnyOf { | ||||
|  | ||||
| 			result.addError(new(NumberAnyOfError), context, currentNode, ErrorDetails{}) | ||||
|  | ||||
| 			if bestValidationResult != nil { | ||||
| 				// add error messages of closest matching subSchema as | ||||
| 				// that's probably the one the user was trying to match | ||||
| 				result.mergeErrors(bestValidationResult) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(currentSubSchema.oneOf) > 0 { | ||||
|  | ||||
| 		nbValidated := 0 | ||||
| 		var bestValidationResult *Result | ||||
|  | ||||
| 		for _, oneOfSchema := range currentSubSchema.oneOf { | ||||
| 			validationResult := oneOfSchema.subValidateWithContext(currentNode, context) | ||||
| 			if validationResult.Valid() { | ||||
| 				nbValidated++ | ||||
| 			} else if nbValidated == 0 && (bestValidationResult == nil || validationResult.score > bestValidationResult.score) { | ||||
| 				bestValidationResult = validationResult | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if nbValidated != 1 { | ||||
|  | ||||
| 			result.addError(new(NumberOneOfError), context, currentNode, ErrorDetails{}) | ||||
|  | ||||
| 			if nbValidated == 0 { | ||||
| 				// add error messages of closest matching subSchema as | ||||
| 				// that's probably the one the user was trying to match | ||||
| 				result.mergeErrors(bestValidationResult) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	if len(currentSubSchema.allOf) > 0 { | ||||
| 		nbValidated := 0 | ||||
|  | ||||
| 		for _, allOfSchema := range currentSubSchema.allOf { | ||||
| 			validationResult := allOfSchema.subValidateWithContext(currentNode, context) | ||||
| 			if validationResult.Valid() { | ||||
| 				nbValidated++ | ||||
| 			} | ||||
| 			result.mergeErrors(validationResult) | ||||
| 		} | ||||
|  | ||||
| 		if nbValidated != len(currentSubSchema.allOf) { | ||||
| 			result.addError(new(NumberAllOfError), context, currentNode, ErrorDetails{}) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if currentSubSchema.not != nil { | ||||
| 		validationResult := currentSubSchema.not.subValidateWithContext(currentNode, context) | ||||
| 		if validationResult.Valid() { | ||||
| 			result.addError(new(NumberNotError), context, currentNode, ErrorDetails{}) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if currentSubSchema.dependencies != nil && len(currentSubSchema.dependencies) > 0 { | ||||
| 		if isKind(currentNode, reflect.Map) { | ||||
| 			for elementKey := range currentNode.(map[string]interface{}) { | ||||
| 				if dependency, ok := currentSubSchema.dependencies[elementKey]; ok { | ||||
| 					switch dependency := dependency.(type) { | ||||
|  | ||||
| 					case []string: | ||||
| 						for _, dependOnKey := range dependency { | ||||
| 							if _, dependencyResolved := currentNode.(map[string]interface{})[dependOnKey]; !dependencyResolved { | ||||
| 								result.addError( | ||||
| 									new(MissingDependencyError), | ||||
| 									context, | ||||
| 									currentNode, | ||||
| 									ErrorDetails{"dependency": dependOnKey}, | ||||
| 								) | ||||
| 							} | ||||
| 						} | ||||
|  | ||||
| 					case *subSchema: | ||||
| 						dependency.validateRecursive(dependency, currentNode, result, context) | ||||
|  | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	result.incrementScore() | ||||
| } | ||||
|  | ||||
| func (v *subSchema) validateCommon(currentSubSchema *subSchema, value interface{}, result *Result, context *jsonContext) { | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog("validateCommon %s", context.String()) | ||||
| 		internalLog(" %v", value) | ||||
| 	} | ||||
|  | ||||
| 	// enum: | ||||
| 	if len(currentSubSchema.enum) > 0 { | ||||
| 		has, err := currentSubSchema.ContainsEnum(value) | ||||
| 		if err != nil { | ||||
| 			result.addError(new(InternalError), context, value, ErrorDetails{"error": err}) | ||||
| 		} | ||||
| 		if !has { | ||||
| 			result.addError( | ||||
| 				new(EnumError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{ | ||||
| 					"allowed": strings.Join(currentSubSchema.enum, ", "), | ||||
| 				}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	result.incrementScore() | ||||
| } | ||||
|  | ||||
| func (v *subSchema) validateArray(currentSubSchema *subSchema, value []interface{}, result *Result, context *jsonContext) { | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog("validateArray %s", context.String()) | ||||
| 		internalLog(" %v", value) | ||||
| 	} | ||||
|  | ||||
| 	nbValues := len(value) | ||||
|  | ||||
| 	// TODO explain | ||||
| 	if currentSubSchema.itemsChildrenIsSingleSchema { | ||||
| 		for i := range value { | ||||
| 			subContext := newJsonContext(strconv.Itoa(i), context) | ||||
| 			validationResult := currentSubSchema.itemsChildren[0].subValidateWithContext(value[i], subContext) | ||||
| 			result.mergeErrors(validationResult) | ||||
| 		} | ||||
| 	} else { | ||||
| 		if currentSubSchema.itemsChildren != nil && len(currentSubSchema.itemsChildren) > 0 { | ||||
|  | ||||
| 			nbItems := len(currentSubSchema.itemsChildren) | ||||
|  | ||||
| 			// while we have both schemas and values, check them against each other | ||||
| 			for i := 0; i != nbItems && i != nbValues; i++ { | ||||
| 				subContext := newJsonContext(strconv.Itoa(i), context) | ||||
| 				validationResult := currentSubSchema.itemsChildren[i].subValidateWithContext(value[i], subContext) | ||||
| 				result.mergeErrors(validationResult) | ||||
| 			} | ||||
|  | ||||
| 			if nbItems < nbValues { | ||||
| 				// we have less schemas than elements in the instance array, | ||||
| 				// but that might be ok if "additionalItems" is specified. | ||||
|  | ||||
| 				switch currentSubSchema.additionalItems.(type) { | ||||
| 				case bool: | ||||
| 					if !currentSubSchema.additionalItems.(bool) { | ||||
| 						result.addError(new(ArrayNoAdditionalItemsError), context, value, ErrorDetails{}) | ||||
| 					} | ||||
| 				case *subSchema: | ||||
| 					additionalItemSchema := currentSubSchema.additionalItems.(*subSchema) | ||||
| 					for i := nbItems; i != nbValues; i++ { | ||||
| 						subContext := newJsonContext(strconv.Itoa(i), context) | ||||
| 						validationResult := additionalItemSchema.subValidateWithContext(value[i], subContext) | ||||
| 						result.mergeErrors(validationResult) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// minItems & maxItems | ||||
| 	if currentSubSchema.minItems != nil { | ||||
| 		if nbValues < int(*currentSubSchema.minItems) { | ||||
| 			result.addError( | ||||
| 				new(ArrayMinItemsError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{"min": *currentSubSchema.minItems}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
| 	if currentSubSchema.maxItems != nil { | ||||
| 		if nbValues > int(*currentSubSchema.maxItems) { | ||||
| 			result.addError( | ||||
| 				new(ArrayMaxItemsError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{"max": *currentSubSchema.maxItems}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// uniqueItems: | ||||
| 	if currentSubSchema.uniqueItems { | ||||
| 		var stringifiedItems []string | ||||
| 		for _, v := range value { | ||||
| 			vString, err := marshalToJsonString(v) | ||||
| 			if err != nil { | ||||
| 				result.addError(new(InternalError), context, value, ErrorDetails{"err": err}) | ||||
| 			} | ||||
| 			if isStringInSlice(stringifiedItems, *vString) { | ||||
| 				result.addError( | ||||
| 					new(ItemsMustBeUniqueError), | ||||
| 					context, | ||||
| 					value, | ||||
| 					ErrorDetails{"type": TYPE_ARRAY}, | ||||
| 				) | ||||
| 			} | ||||
| 			stringifiedItems = append(stringifiedItems, *vString) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	result.incrementScore() | ||||
| } | ||||
|  | ||||
| func (v *subSchema) validateObject(currentSubSchema *subSchema, value map[string]interface{}, result *Result, context *jsonContext) { | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog("validateObject %s", context.String()) | ||||
| 		internalLog(" %v", value) | ||||
| 	} | ||||
|  | ||||
| 	// minProperties & maxProperties: | ||||
| 	if currentSubSchema.minProperties != nil { | ||||
| 		if len(value) < int(*currentSubSchema.minProperties) { | ||||
| 			result.addError( | ||||
| 				new(ArrayMinPropertiesError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{"min": *currentSubSchema.minProperties}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
| 	if currentSubSchema.maxProperties != nil { | ||||
| 		if len(value) > int(*currentSubSchema.maxProperties) { | ||||
| 			result.addError( | ||||
| 				new(ArrayMaxPropertiesError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{"max": *currentSubSchema.maxProperties}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// required: | ||||
| 	for _, requiredProperty := range currentSubSchema.required { | ||||
| 		_, ok := value[requiredProperty] | ||||
| 		if ok { | ||||
| 			result.incrementScore() | ||||
| 		} else { | ||||
| 			result.addError( | ||||
| 				new(RequiredError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{"property": requiredProperty}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// additionalProperty & patternProperty: | ||||
| 	if currentSubSchema.additionalProperties != nil { | ||||
|  | ||||
| 		switch currentSubSchema.additionalProperties.(type) { | ||||
| 		case bool: | ||||
|  | ||||
| 			if !currentSubSchema.additionalProperties.(bool) { | ||||
|  | ||||
| 				for pk := range value { | ||||
|  | ||||
| 					found := false | ||||
| 					for _, spValue := range currentSubSchema.propertiesChildren { | ||||
| 						if pk == spValue.property { | ||||
| 							found = true | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 					pp_has, pp_match := v.validatePatternProperty(currentSubSchema, pk, value[pk], result, context) | ||||
|  | ||||
| 					if found { | ||||
|  | ||||
| 						if pp_has && !pp_match { | ||||
| 							result.addError( | ||||
| 								new(AdditionalPropertyNotAllowedError), | ||||
| 								context, | ||||
| 								value[pk], | ||||
| 								ErrorDetails{"property": pk}, | ||||
| 							) | ||||
| 						} | ||||
|  | ||||
| 					} else { | ||||
|  | ||||
| 						if !pp_has || !pp_match { | ||||
| 							result.addError( | ||||
| 								new(AdditionalPropertyNotAllowedError), | ||||
| 								context, | ||||
| 								value[pk], | ||||
| 								ErrorDetails{"property": pk}, | ||||
| 							) | ||||
| 						} | ||||
|  | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 		case *subSchema: | ||||
|  | ||||
| 			additionalPropertiesSchema := currentSubSchema.additionalProperties.(*subSchema) | ||||
| 			for pk := range value { | ||||
|  | ||||
| 				found := false | ||||
| 				for _, spValue := range currentSubSchema.propertiesChildren { | ||||
| 					if pk == spValue.property { | ||||
| 						found = true | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				pp_has, pp_match := v.validatePatternProperty(currentSubSchema, pk, value[pk], result, context) | ||||
|  | ||||
| 				if found { | ||||
|  | ||||
| 					if pp_has && !pp_match { | ||||
| 						validationResult := additionalPropertiesSchema.subValidateWithContext(value[pk], context) | ||||
| 						result.mergeErrors(validationResult) | ||||
| 					} | ||||
|  | ||||
| 				} else { | ||||
|  | ||||
| 					if !pp_has || !pp_match { | ||||
| 						validationResult := additionalPropertiesSchema.subValidateWithContext(value[pk], context) | ||||
| 						result.mergeErrors(validationResult) | ||||
| 					} | ||||
|  | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
|  | ||||
| 		for pk := range value { | ||||
|  | ||||
| 			pp_has, pp_match := v.validatePatternProperty(currentSubSchema, pk, value[pk], result, context) | ||||
|  | ||||
| 			if pp_has && !pp_match { | ||||
|  | ||||
| 				result.addError( | ||||
| 					new(InvalidPropertyPatternError), | ||||
| 					context, | ||||
| 					value[pk], | ||||
| 					ErrorDetails{ | ||||
| 						"property": pk, | ||||
| 						"pattern":  currentSubSchema.PatternPropertiesString(), | ||||
| 					}, | ||||
| 				) | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	result.incrementScore() | ||||
| } | ||||
|  | ||||
| func (v *subSchema) validatePatternProperty(currentSubSchema *subSchema, key string, value interface{}, result *Result, context *jsonContext) (has bool, matched bool) { | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog("validatePatternProperty %s", context.String()) | ||||
| 		internalLog(" %s %v", key, value) | ||||
| 	} | ||||
|  | ||||
| 	has = false | ||||
|  | ||||
| 	validatedkey := false | ||||
|  | ||||
| 	for pk, pv := range currentSubSchema.patternProperties { | ||||
| 		if matches, _ := regexp.MatchString(pk, key); matches { | ||||
| 			has = true | ||||
| 			subContext := newJsonContext(key, context) | ||||
| 			validationResult := pv.subValidateWithContext(value, subContext) | ||||
| 			result.mergeErrors(validationResult) | ||||
| 			if validationResult.Valid() { | ||||
| 				validatedkey = true | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if !validatedkey { | ||||
| 		return has, false | ||||
| 	} | ||||
|  | ||||
| 	result.incrementScore() | ||||
|  | ||||
| 	return has, true | ||||
| } | ||||
|  | ||||
| func (v *subSchema) validateString(currentSubSchema *subSchema, value interface{}, result *Result, context *jsonContext) { | ||||
|  | ||||
| 	// Ignore JSON numbers | ||||
| 	if isJsonNumber(value) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// Ignore non strings | ||||
| 	if !isKind(value, reflect.String) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog("validateString %s", context.String()) | ||||
| 		internalLog(" %v", value) | ||||
| 	} | ||||
|  | ||||
| 	stringValue := value.(string) | ||||
|  | ||||
| 	// minLength & maxLength: | ||||
| 	if currentSubSchema.minLength != nil { | ||||
| 		if utf8.RuneCount([]byte(stringValue)) < int(*currentSubSchema.minLength) { | ||||
| 			result.addError( | ||||
| 				new(StringLengthGTEError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{"min": *currentSubSchema.minLength}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
| 	if currentSubSchema.maxLength != nil { | ||||
| 		if utf8.RuneCount([]byte(stringValue)) > int(*currentSubSchema.maxLength) { | ||||
| 			result.addError( | ||||
| 				new(StringLengthLTEError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{"max": *currentSubSchema.maxLength}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// pattern: | ||||
| 	if currentSubSchema.pattern != nil { | ||||
| 		if !currentSubSchema.pattern.MatchString(stringValue) { | ||||
| 			result.addError( | ||||
| 				new(DoesNotMatchPatternError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{"pattern": currentSubSchema.pattern}, | ||||
| 			) | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// format | ||||
| 	if currentSubSchema.format != "" { | ||||
| 		if !FormatCheckers.IsFormat(currentSubSchema.format, stringValue) { | ||||
| 			result.addError( | ||||
| 				new(DoesNotMatchFormatError), | ||||
| 				context, | ||||
| 				value, | ||||
| 				ErrorDetails{"format": currentSubSchema.format}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	result.incrementScore() | ||||
| } | ||||
|  | ||||
| func (v *subSchema) validateNumber(currentSubSchema *subSchema, value interface{}, result *Result, context *jsonContext) { | ||||
|  | ||||
| 	// Ignore non numbers | ||||
| 	if !isJsonNumber(value) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if internalLogEnabled { | ||||
| 		internalLog("validateNumber %s", context.String()) | ||||
| 		internalLog(" %v", value) | ||||
| 	} | ||||
|  | ||||
| 	number := value.(json.Number) | ||||
| 	float64Value, _ := number.Float64() | ||||
|  | ||||
| 	// multipleOf: | ||||
| 	if currentSubSchema.multipleOf != nil { | ||||
|  | ||||
| 		if !isFloat64AnInteger(float64Value / *currentSubSchema.multipleOf) { | ||||
| 			result.addError( | ||||
| 				new(MultipleOfError), | ||||
| 				context, | ||||
| 				resultErrorFormatJsonNumber(number), | ||||
| 				ErrorDetails{"multiple": *currentSubSchema.multipleOf}, | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	//maximum & exclusiveMaximum: | ||||
| 	if currentSubSchema.maximum != nil { | ||||
| 		if currentSubSchema.exclusiveMaximum { | ||||
| 			if float64Value >= *currentSubSchema.maximum { | ||||
| 				result.addError( | ||||
| 					new(NumberLTError), | ||||
| 					context, | ||||
| 					resultErrorFormatJsonNumber(number), | ||||
| 					ErrorDetails{ | ||||
| 						"max": resultErrorFormatNumber(*currentSubSchema.maximum), | ||||
| 					}, | ||||
| 				) | ||||
| 			} | ||||
| 		} else { | ||||
| 			if float64Value > *currentSubSchema.maximum { | ||||
| 				result.addError( | ||||
| 					new(NumberLTEError), | ||||
| 					context, | ||||
| 					resultErrorFormatJsonNumber(number), | ||||
| 					ErrorDetails{ | ||||
| 						"max": resultErrorFormatNumber(*currentSubSchema.maximum), | ||||
| 					}, | ||||
| 				) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	//minimum & exclusiveMinimum: | ||||
| 	if currentSubSchema.minimum != nil { | ||||
| 		if currentSubSchema.exclusiveMinimum { | ||||
| 			if float64Value <= *currentSubSchema.minimum { | ||||
| 				result.addError( | ||||
| 					new(NumberGTError), | ||||
| 					context, | ||||
| 					resultErrorFormatJsonNumber(number), | ||||
| 					ErrorDetails{ | ||||
| 						"min": resultErrorFormatNumber(*currentSubSchema.minimum), | ||||
| 					}, | ||||
| 				) | ||||
| 			} | ||||
| 		} else { | ||||
| 			if float64Value < *currentSubSchema.minimum { | ||||
| 				result.addError( | ||||
| 					new(NumberGTEError), | ||||
| 					context, | ||||
| 					resultErrorFormatJsonNumber(number), | ||||
| 					ErrorDetails{ | ||||
| 						"min": resultErrorFormatNumber(*currentSubSchema.minimum), | ||||
| 					}, | ||||
| 				) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	result.incrementScore() | ||||
| } | ||||
		Reference in New Issue
	
	Block a user