...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package schema
16
17 import (
18 "bytes"
19 "encoding/json"
20 "fmt"
21 "io"
22 "net/http"
23 "strings"
24
25 "github.com/xeipuuv/gojsonreference"
26 "github.com/xeipuuv/gojsonschema"
27 )
28
29
30 type fsLoaderFactory struct {
31 namespaces []string
32 fs http.FileSystem
33 }
34
35
36 func newFSLoaderFactory(namespaces []string, fs http.FileSystem) *fsLoaderFactory {
37 return &fsLoaderFactory{
38 namespaces: namespaces,
39 fs: fs,
40 }
41 }
42
43 func (factory *fsLoaderFactory) New(source string) gojsonschema.JSONLoader {
44 return &fsLoader{
45 factory: factory,
46 source: source,
47 }
48 }
49
50
51 func (factory *fsLoaderFactory) refContents(ref gojsonreference.JsonReference) ([]byte, error) {
52 refStr := ref.String()
53 path := ""
54 for _, ns := range factory.namespaces {
55 if strings.HasPrefix(refStr, ns) {
56 path = "/" + strings.TrimPrefix(refStr, ns)
57 break
58 }
59 }
60 if path == "" {
61 return nil, fmt.Errorf("schema reference %#v unexpectedly not available in fsLoaderFactory with namespaces %#v", path, factory.namespaces)
62 }
63
64 f, err := factory.fs.Open(path)
65 if err != nil {
66 return nil, err
67 }
68 defer f.Close()
69
70 return io.ReadAll(f)
71 }
72
73
74 type fsLoader struct {
75 factory *fsLoaderFactory
76 source string
77 }
78
79
80 func (l *fsLoader) JsonSource() interface{} {
81 return l.source
82 }
83
84 func (l *fsLoader) LoadJSON() (interface{}, error) {
85
86 reference, err := gojsonreference.NewJsonReference(l.source)
87 if err != nil {
88 return nil, err
89 }
90
91 refToURL := reference
92 refToURL.GetUrl().Fragment = ""
93
94 body, err := l.factory.refContents(refToURL)
95 if err != nil {
96 return nil, err
97 }
98
99 return decodeJSONUsingNumber(bytes.NewReader(body))
100 }
101
102
103 func decodeJSONUsingNumber(r io.Reader) (interface{}, error) {
104
105 var document interface{}
106
107 decoder := json.NewDecoder(r)
108 decoder.UseNumber()
109
110 err := decoder.Decode(&document)
111 if err != nil {
112 return nil, err
113 }
114
115 return document, nil
116 }
117
118
119 func (l *fsLoader) JsonReference() (gojsonreference.JsonReference, error) {
120 return gojsonreference.NewJsonReference(l.JsonSource().(string))
121 }
122
123 func (l *fsLoader) LoaderFactory() gojsonschema.JSONLoaderFactory {
124 return l.factory
125 }
126
View as plain text