podman

Форк
0
266 строк · 6.2 Кб
1
// Copyright 2015 go-swagger maintainers
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//    http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package loads
16

17
import (
18
	"bytes"
19
	"encoding/gob"
20
	"encoding/json"
21
	"fmt"
22

23
	"github.com/go-openapi/analysis"
24
	"github.com/go-openapi/spec"
25
	"github.com/go-openapi/swag"
26
)
27

28
func init() {
29
	gob.Register(map[string]interface{}{})
30
	gob.Register([]interface{}{})
31
}
32

33
// Document represents a swagger spec document
34
type Document struct {
35
	// specAnalyzer
36
	Analyzer     *analysis.Spec
37
	spec         *spec.Swagger
38
	specFilePath string
39
	origSpec     *spec.Swagger
40
	schema       *spec.Schema
41
	raw          json.RawMessage
42
	pathLoader   *loader
43
}
44

45
// JSONSpec loads a spec from a json document
46
func JSONSpec(path string, options ...LoaderOption) (*Document, error) {
47
	data, err := JSONDoc(path)
48
	if err != nil {
49
		return nil, err
50
	}
51
	// convert to json
52
	return Analyzed(data, "", options...)
53
}
54

55
// Embedded returns a Document based on embedded specs. No analysis is required
56
func Embedded(orig, flat json.RawMessage, options ...LoaderOption) (*Document, error) {
57
	var origSpec, flatSpec spec.Swagger
58
	if err := json.Unmarshal(orig, &origSpec); err != nil {
59
		return nil, err
60
	}
61
	if err := json.Unmarshal(flat, &flatSpec); err != nil {
62
		return nil, err
63
	}
64
	return &Document{
65
		raw:        orig,
66
		origSpec:   &origSpec,
67
		spec:       &flatSpec,
68
		pathLoader: loaderFromOptions(options),
69
	}, nil
70
}
71

72
// Spec loads a new spec document from a local or remote path
73
func Spec(path string, options ...LoaderOption) (*Document, error) {
74

75
	ldr := loaderFromOptions(options)
76

77
	b, err := ldr.Load(path)
78
	if err != nil {
79
		return nil, err
80
	}
81

82
	document, err := Analyzed(b, "", options...)
83
	if err != nil {
84
		return nil, err
85
	}
86

87
	if document != nil {
88
		document.specFilePath = path
89
		document.pathLoader = ldr
90
	}
91

92
	return document, err
93
}
94

95
// Analyzed creates a new analyzed spec document for a root json.RawMessage.
96
func Analyzed(data json.RawMessage, version string, options ...LoaderOption) (*Document, error) {
97
	if version == "" {
98
		version = "2.0"
99
	}
100
	if version != "2.0" {
101
		return nil, fmt.Errorf("spec version %q is not supported", version)
102
	}
103

104
	raw, err := trimData(data) // trim blanks, then convert yaml docs into json
105
	if err != nil {
106
		return nil, err
107
	}
108

109
	swspec := new(spec.Swagger)
110
	if err = json.Unmarshal(raw, swspec); err != nil {
111
		return nil, err
112
	}
113

114
	origsqspec, err := cloneSpec(swspec)
115
	if err != nil {
116
		return nil, err
117
	}
118

119
	d := &Document{
120
		Analyzer:   analysis.New(swspec),
121
		schema:     spec.MustLoadSwagger20Schema(),
122
		spec:       swspec,
123
		raw:        raw,
124
		origSpec:   origsqspec,
125
		pathLoader: loaderFromOptions(options),
126
	}
127

128
	return d, nil
129
}
130

131
func trimData(in json.RawMessage) (json.RawMessage, error) {
132
	trimmed := bytes.TrimSpace(in)
133
	if len(trimmed) == 0 {
134
		return in, nil
135
	}
136

137
	if trimmed[0] == '{' || trimmed[0] == '[' {
138
		return trimmed, nil
139
	}
140

141
	// assume yaml doc: convert it to json
142
	yml, err := swag.BytesToYAMLDoc(trimmed)
143
	if err != nil {
144
		return nil, fmt.Errorf("analyzed: %v", err)
145
	}
146

147
	d, err := swag.YAMLToJSON(yml)
148
	if err != nil {
149
		return nil, fmt.Errorf("analyzed: %v", err)
150
	}
151

152
	return d, nil
153
}
154

155
// Expanded expands the ref fields in the spec document and returns a new spec document
156
func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
157

158
	swspec := new(spec.Swagger)
159
	if err := json.Unmarshal(d.raw, swspec); err != nil {
160
		return nil, err
161
	}
162

163
	var expandOptions *spec.ExpandOptions
164
	if len(options) > 0 {
165
		expandOptions = options[0]
166
	} else {
167
		expandOptions = &spec.ExpandOptions{
168
			RelativeBase: d.specFilePath,
169
		}
170
	}
171

172
	if expandOptions.PathLoader == nil {
173
		if d.pathLoader != nil {
174
			// use loader from Document options
175
			expandOptions.PathLoader = d.pathLoader.Load
176
		} else {
177
			// use package level loader
178
			expandOptions.PathLoader = loaders.Load
179
		}
180
	}
181

182
	if err := spec.ExpandSpec(swspec, expandOptions); err != nil {
183
		return nil, err
184
	}
185

186
	dd := &Document{
187
		Analyzer:     analysis.New(swspec),
188
		spec:         swspec,
189
		specFilePath: d.specFilePath,
190
		schema:       spec.MustLoadSwagger20Schema(),
191
		raw:          d.raw,
192
		origSpec:     d.origSpec,
193
	}
194
	return dd, nil
195
}
196

197
// BasePath the base path for this spec
198
func (d *Document) BasePath() string {
199
	return d.spec.BasePath
200
}
201

202
// Version returns the version of this spec
203
func (d *Document) Version() string {
204
	return d.spec.Swagger
205
}
206

207
// Schema returns the swagger 2.0 schema
208
func (d *Document) Schema() *spec.Schema {
209
	return d.schema
210
}
211

212
// Spec returns the swagger spec object model
213
func (d *Document) Spec() *spec.Swagger {
214
	return d.spec
215
}
216

217
// Host returns the host for the API
218
func (d *Document) Host() string {
219
	return d.spec.Host
220
}
221

222
// Raw returns the raw swagger spec as json bytes
223
func (d *Document) Raw() json.RawMessage {
224
	return d.raw
225
}
226

227
// OrigSpec yields the original spec
228
func (d *Document) OrigSpec() *spec.Swagger {
229
	return d.origSpec
230
}
231

232
// ResetDefinitions gives a shallow copy with the models reset to the original spec
233
func (d *Document) ResetDefinitions() *Document {
234
	defs := make(map[string]spec.Schema, len(d.origSpec.Definitions))
235
	for k, v := range d.origSpec.Definitions {
236
		defs[k] = v
237
	}
238

239
	d.spec.Definitions = defs
240
	return d
241
}
242

243
// Pristine creates a new pristine document instance based on the input data
244
func (d *Document) Pristine() *Document {
245
	dd, _ := Analyzed(d.Raw(), d.Version())
246
	dd.pathLoader = d.pathLoader
247
	return dd
248
}
249

250
// SpecFilePath returns the file path of the spec if one is defined
251
func (d *Document) SpecFilePath() string {
252
	return d.specFilePath
253
}
254

255
func cloneSpec(src *spec.Swagger) (*spec.Swagger, error) {
256
	var b bytes.Buffer
257
	if err := gob.NewEncoder(&b).Encode(src); err != nil {
258
		return nil, err
259
	}
260

261
	var dst spec.Swagger
262
	if err := gob.NewDecoder(&b).Decode(&dst); err != nil {
263
		return nil, err
264
	}
265
	return &dst, nil
266
}
267

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.