...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package spec
16
17 import (
18 "bytes"
19 "encoding/gob"
20 "encoding/json"
21 "net/http"
22 "os"
23 "path/filepath"
24
25 "github.com/go-openapi/jsonreference"
26 )
27
28
29 type Refable struct {
30 Ref Ref
31 }
32
33
34 func (r Refable) MarshalJSON() ([]byte, error) {
35 return r.Ref.MarshalJSON()
36 }
37
38
39 func (r *Refable) UnmarshalJSON(d []byte) error {
40 return json.Unmarshal(d, &r.Ref)
41 }
42
43
44 type Ref struct {
45 jsonreference.Ref
46 }
47
48
49 func (r *Ref) RemoteURI() string {
50 if r.String() == "" {
51 return ""
52 }
53
54 u := *r.GetURL()
55 u.Fragment = ""
56 return u.String()
57 }
58
59
60 func (r *Ref) IsValidURI(basepaths ...string) bool {
61 if r.String() == "" {
62 return true
63 }
64
65 v := r.RemoteURI()
66 if v == "" {
67 return true
68 }
69
70 if r.HasFullURL {
71
72 rr, err := http.Get(v)
73 if err != nil {
74 return false
75 }
76 defer rr.Body.Close()
77
78 return rr.StatusCode/100 == 2
79 }
80
81 if !(r.HasFileScheme || r.HasFullFilePath || r.HasURLPathOnly) {
82 return false
83 }
84
85
86 pth := v
87 if r.HasURLPathOnly {
88 base := "."
89 if len(basepaths) > 0 {
90 base = filepath.Dir(filepath.Join(basepaths...))
91 }
92 p, e := filepath.Abs(filepath.ToSlash(filepath.Join(base, pth)))
93 if e != nil {
94 return false
95 }
96 pth = p
97 }
98
99 fi, err := os.Stat(filepath.ToSlash(pth))
100 if err != nil {
101 return false
102 }
103
104 return !fi.IsDir()
105 }
106
107
108
109 func (r *Ref) Inherits(child Ref) (*Ref, error) {
110 ref, err := r.Ref.Inherits(child.Ref)
111 if err != nil {
112 return nil, err
113 }
114 return &Ref{Ref: *ref}, nil
115 }
116
117
118
119 func NewRef(refURI string) (Ref, error) {
120 ref, err := jsonreference.New(refURI)
121 if err != nil {
122 return Ref{}, err
123 }
124 return Ref{Ref: ref}, nil
125 }
126
127
128
129 func MustCreateRef(refURI string) Ref {
130 return Ref{Ref: jsonreference.MustCreateRef(refURI)}
131 }
132
133
134 func (r Ref) MarshalJSON() ([]byte, error) {
135 str := r.String()
136 if str == "" {
137 if r.IsRoot() {
138 return []byte(`{"$ref":""}`), nil
139 }
140 return []byte("{}"), nil
141 }
142 v := map[string]interface{}{"$ref": str}
143 return json.Marshal(v)
144 }
145
146
147 func (r *Ref) UnmarshalJSON(d []byte) error {
148 var v map[string]interface{}
149 if err := json.Unmarshal(d, &v); err != nil {
150 return err
151 }
152 return r.fromMap(v)
153 }
154
155
156 func (r Ref) GobEncode() ([]byte, error) {
157 var b bytes.Buffer
158 raw, err := r.MarshalJSON()
159 if err != nil {
160 return nil, err
161 }
162 err = gob.NewEncoder(&b).Encode(raw)
163 return b.Bytes(), err
164 }
165
166
167 func (r *Ref) GobDecode(b []byte) error {
168 var raw []byte
169 buf := bytes.NewBuffer(b)
170 err := gob.NewDecoder(buf).Decode(&raw)
171 if err != nil {
172 return err
173 }
174 return json.Unmarshal(raw, r)
175 }
176
177 func (r *Ref) fromMap(v map[string]interface{}) error {
178 if v == nil {
179 return nil
180 }
181
182 if vv, ok := v["$ref"]; ok {
183 if str, ok := vv.(string); ok {
184 ref, err := jsonreference.New(str)
185 if err != nil {
186 return err
187 }
188 *r = Ref{Ref: ref}
189 }
190 }
191
192 return nil
193 }
194
View as plain text