You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
4.3 KiB

  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. package spec
  15. import (
  16. "encoding/json"
  17. "strings"
  18. "github.com/go-openapi/jsonpointer"
  19. "github.com/go-openapi/swag"
  20. )
  21. // Extensions vendor specific extensions
  22. type Extensions map[string]interface{}
  23. // Add adds a value to these extensions
  24. func (e Extensions) Add(key string, value interface{}) {
  25. realKey := strings.ToLower(key)
  26. e[realKey] = value
  27. }
  28. // GetString gets a string value from the extensions
  29. func (e Extensions) GetString(key string) (string, bool) {
  30. if v, ok := e[strings.ToLower(key)]; ok {
  31. str, ok := v.(string)
  32. return str, ok
  33. }
  34. return "", false
  35. }
  36. // GetBool gets a string value from the extensions
  37. func (e Extensions) GetBool(key string) (bool, bool) {
  38. if v, ok := e[strings.ToLower(key)]; ok {
  39. str, ok := v.(bool)
  40. return str, ok
  41. }
  42. return false, false
  43. }
  44. // GetStringSlice gets a string value from the extensions
  45. func (e Extensions) GetStringSlice(key string) ([]string, bool) {
  46. if v, ok := e[strings.ToLower(key)]; ok {
  47. arr, isSlice := v.([]interface{})
  48. if !isSlice {
  49. return nil, false
  50. }
  51. var strs []string
  52. for _, iface := range arr {
  53. str, isString := iface.(string)
  54. if !isString {
  55. return nil, false
  56. }
  57. strs = append(strs, str)
  58. }
  59. return strs, ok
  60. }
  61. return nil, false
  62. }
  63. // VendorExtensible composition block.
  64. type VendorExtensible struct {
  65. Extensions Extensions
  66. }
  67. // AddExtension adds an extension to this extensible object
  68. func (v *VendorExtensible) AddExtension(key string, value interface{}) {
  69. if value == nil {
  70. return
  71. }
  72. if v.Extensions == nil {
  73. v.Extensions = make(map[string]interface{})
  74. }
  75. v.Extensions.Add(key, value)
  76. }
  77. // MarshalJSON marshals the extensions to json
  78. func (v VendorExtensible) MarshalJSON() ([]byte, error) {
  79. toser := make(map[string]interface{})
  80. for k, v := range v.Extensions {
  81. lk := strings.ToLower(k)
  82. if strings.HasPrefix(lk, "x-") {
  83. toser[k] = v
  84. }
  85. }
  86. return json.Marshal(toser)
  87. }
  88. // UnmarshalJSON for this extensible object
  89. func (v *VendorExtensible) UnmarshalJSON(data []byte) error {
  90. var d map[string]interface{}
  91. if err := json.Unmarshal(data, &d); err != nil {
  92. return err
  93. }
  94. for k, vv := range d {
  95. lk := strings.ToLower(k)
  96. if strings.HasPrefix(lk, "x-") {
  97. if v.Extensions == nil {
  98. v.Extensions = map[string]interface{}{}
  99. }
  100. v.Extensions[k] = vv
  101. }
  102. }
  103. return nil
  104. }
  105. // InfoProps the properties for an info definition
  106. type InfoProps struct {
  107. Description string `json:"description,omitempty"`
  108. Title string `json:"title,omitempty"`
  109. TermsOfService string `json:"termsOfService,omitempty"`
  110. Contact *ContactInfo `json:"contact,omitempty"`
  111. License *License `json:"license,omitempty"`
  112. Version string `json:"version,omitempty"`
  113. }
  114. // Info object provides metadata about the API.
  115. // The metadata can be used by the clients if needed, and can be presented in the Swagger-UI for convenience.
  116. //
  117. // For more information: http://goo.gl/8us55a#infoObject
  118. type Info struct {
  119. VendorExtensible
  120. InfoProps
  121. }
  122. // JSONLookup look up a value by the json property name
  123. func (i Info) JSONLookup(token string) (interface{}, error) {
  124. if ex, ok := i.Extensions[token]; ok {
  125. return &ex, nil
  126. }
  127. r, _, err := jsonpointer.GetForToken(i.InfoProps, token)
  128. return r, err
  129. }
  130. // MarshalJSON marshal this to JSON
  131. func (i Info) MarshalJSON() ([]byte, error) {
  132. b1, err := json.Marshal(i.InfoProps)
  133. if err != nil {
  134. return nil, err
  135. }
  136. b2, err := json.Marshal(i.VendorExtensible)
  137. if err != nil {
  138. return nil, err
  139. }
  140. return swag.ConcatJSON(b1, b2), nil
  141. }
  142. // UnmarshalJSON marshal this from JSON
  143. func (i *Info) UnmarshalJSON(data []byte) error {
  144. if err := json.Unmarshal(data, &i.InfoProps); err != nil {
  145. return err
  146. }
  147. return json.Unmarshal(data, &i.VendorExtensible)
  148. }