123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /*
- Copyright 2017 The Kubernetes Authors.
- 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.
- */
- package aggregator
- import (
- "strings"
- "github.com/go-openapi/spec"
- )
- const (
- definitionPrefix = "#/definitions/"
- )
- // Run a readonlyReferenceWalker method on all references of an OpenAPI spec
- type readonlyReferenceWalker struct {
- // walkRefCallback will be called on each reference. The input will never be nil.
- walkRefCallback func(ref *spec.Ref)
- // The spec to walk through.
- root *spec.Swagger
- }
- // walkOnAllReferences recursively walks on all references, while following references into definitions.
- // it calls walkRef on each found reference.
- func walkOnAllReferences(walkRef func(ref *spec.Ref), root *spec.Swagger) {
- alreadyVisited := map[string]bool{}
- walker := &readonlyReferenceWalker{
- root: root,
- }
- walker.walkRefCallback = func(ref *spec.Ref) {
- walkRef(ref)
- refStr := ref.String()
- if refStr == "" || !strings.HasPrefix(refStr, definitionPrefix) {
- return
- }
- defName := refStr[len(definitionPrefix):]
- if _, found := root.Definitions[defName]; found && !alreadyVisited[refStr] {
- alreadyVisited[refStr] = true
- def := root.Definitions[defName]
- walker.walkSchema(&def)
- }
- }
- walker.Start()
- }
- func (s *readonlyReferenceWalker) walkSchema(schema *spec.Schema) {
- if schema == nil {
- return
- }
- s.walkRefCallback(&schema.Ref)
- var v *spec.Schema
- if len(schema.Definitions)+len(schema.Properties)+len(schema.PatternProperties) > 0 {
- v = &spec.Schema{}
- }
- for k := range schema.Definitions {
- *v = schema.Definitions[k]
- s.walkSchema(v)
- }
- for k := range schema.Properties {
- *v = schema.Properties[k]
- s.walkSchema(v)
- }
- for k := range schema.PatternProperties {
- *v = schema.PatternProperties[k]
- s.walkSchema(v)
- }
- for i := range schema.AllOf {
- s.walkSchema(&schema.AllOf[i])
- }
- for i := range schema.AnyOf {
- s.walkSchema(&schema.AnyOf[i])
- }
- for i := range schema.OneOf {
- s.walkSchema(&schema.OneOf[i])
- }
- if schema.Not != nil {
- s.walkSchema(schema.Not)
- }
- if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
- s.walkSchema(schema.AdditionalProperties.Schema)
- }
- if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
- s.walkSchema(schema.AdditionalItems.Schema)
- }
- if schema.Items != nil {
- if schema.Items.Schema != nil {
- s.walkSchema(schema.Items.Schema)
- }
- for i := range schema.Items.Schemas {
- s.walkSchema(&schema.Items.Schemas[i])
- }
- }
- }
- func (s *readonlyReferenceWalker) walkParams(params []spec.Parameter) {
- if params == nil {
- return
- }
- for _, param := range params {
- s.walkRefCallback(¶m.Ref)
- s.walkSchema(param.Schema)
- if param.Items != nil {
- s.walkRefCallback(¶m.Items.Ref)
- }
- }
- }
- func (s *readonlyReferenceWalker) walkResponse(resp *spec.Response) {
- if resp == nil {
- return
- }
- s.walkRefCallback(&resp.Ref)
- s.walkSchema(resp.Schema)
- }
- func (s *readonlyReferenceWalker) walkOperation(op *spec.Operation) {
- if op == nil {
- return
- }
- s.walkParams(op.Parameters)
- if op.Responses == nil {
- return
- }
- s.walkResponse(op.Responses.Default)
- for _, r := range op.Responses.StatusCodeResponses {
- s.walkResponse(&r)
- }
- }
- func (s *readonlyReferenceWalker) Start() {
- if s.root.Paths == nil {
- return
- }
- for _, pathItem := range s.root.Paths.Paths {
- s.walkParams(pathItem.Parameters)
- s.walkOperation(pathItem.Delete)
- s.walkOperation(pathItem.Get)
- s.walkOperation(pathItem.Head)
- s.walkOperation(pathItem.Options)
- s.walkOperation(pathItem.Patch)
- s.walkOperation(pathItem.Post)
- s.walkOperation(pathItem.Put)
- }
- }
|