1
0
mirror of https://github.com/rancher/norman.git synced 2025-06-04 04:59:25 +00:00
norman/types/schemas.go

215 lines
4.3 KiB
Go
Raw Normal View History

2017-11-11 04:44:02 +00:00
package types
import (
"bytes"
"fmt"
"strings"
"github.com/rancher/norman/name"
"github.com/rancher/norman/types/convert"
)
type SchemaCollection struct {
Data []Schema
}
2017-11-15 04:33:57 +00:00
type SchemaInitFunc func(*Schemas) *Schemas
2017-11-29 21:27:02 +00:00
type MappersFactory func() []Mapper
2017-11-11 04:44:02 +00:00
type Schemas struct {
2017-11-21 20:46:30 +00:00
schemasByPath map[string]map[string]*Schema
schemasBySubContext map[string]*Schema
mappers map[string]map[string][]Mapper
2017-11-29 21:27:02 +00:00
DefaultMappers MappersFactory
DefaultPostMappers MappersFactory
2017-11-21 20:46:30 +00:00
versions []APIVersion
schemas []*Schema
errors []error
2017-11-11 04:44:02 +00:00
}
func NewSchemas() *Schemas {
return &Schemas{
2017-11-21 20:46:30 +00:00
schemasByPath: map[string]map[string]*Schema{},
schemasBySubContext: map[string]*Schema{},
mappers: map[string]map[string][]Mapper{},
2017-11-11 04:44:02 +00:00
}
}
2017-11-15 04:33:57 +00:00
func (s *Schemas) Init(initFunc SchemaInitFunc) *Schemas {
return initFunc(s)
}
2017-11-11 04:44:02 +00:00
func (s *Schemas) Err() error {
return NewErrors(s.errors)
}
2017-11-21 20:46:30 +00:00
func (s *Schemas) SubContext(subContext string) *Schema {
return s.schemasBySubContext[subContext]
}
func (s *Schemas) SubContextSchemas() map[string]*Schema {
return s.schemasBySubContext
}
2017-11-12 00:07:09 +00:00
func (s *Schemas) AddSchemas(schema *Schemas) *Schemas {
for _, schema := range schema.Schemas() {
2017-12-12 03:58:43 +00:00
s.AddSchema(*schema)
2017-11-12 00:07:09 +00:00
}
return s
}
2017-12-12 03:58:43 +00:00
func (s *Schemas) AddSchema(schema Schema) *Schemas {
2017-12-05 16:21:12 +00:00
schema.Type = "/meta/schemas/schema"
2017-11-11 04:44:02 +00:00
if schema.ID == "" {
s.errors = append(s.errors, fmt.Errorf("ID is not set on schema: %v", schema))
return s
}
2017-11-28 21:28:25 +00:00
if schema.Version.Path == "" || schema.Version.Version == "" {
2017-11-11 04:44:02 +00:00
s.errors = append(s.errors, fmt.Errorf("version is not set on schema: %s", schema.ID))
return s
}
if schema.PluralName == "" {
schema.PluralName = name.GuessPluralName(schema.ID)
}
if schema.CodeName == "" {
schema.CodeName = convert.Capitalize(schema.ID)
}
2017-11-13 19:50:25 +00:00
if schema.CodeNamePlural == "" {
schema.CodeNamePlural = name.GuessPluralName(schema.CodeName)
}
2017-11-21 20:46:30 +00:00
if schema.BaseType == "" {
schema.BaseType = schema.ID
}
2017-11-11 04:44:02 +00:00
schemas, ok := s.schemasByPath[schema.Version.Path]
if !ok {
schemas = map[string]*Schema{}
s.schemasByPath[schema.Version.Path] = schemas
s.versions = append(s.versions, schema.Version)
}
if _, ok := schemas[schema.ID]; !ok {
2017-12-12 03:58:43 +00:00
schemas[schema.ID] = &schema
s.schemas = append(s.schemas, &schema)
2017-11-11 04:44:02 +00:00
}
2017-11-21 20:46:30 +00:00
if schema.SubContext != "" {
2017-12-12 03:58:43 +00:00
s.schemasBySubContext[schema.SubContext] = &schema
2017-11-21 20:46:30 +00:00
}
2017-11-11 04:44:02 +00:00
return s
}
func (s *Schemas) AddMapper(version *APIVersion, schemaID string, mapper Mapper) *Schemas {
mappers, ok := s.mappers[version.Path]
if !ok {
2017-11-21 20:46:30 +00:00
mappers = map[string][]Mapper{}
2017-11-11 04:44:02 +00:00
s.mappers[version.Path] = mappers
}
2017-11-21 20:46:30 +00:00
mappers[schemaID] = append(mappers[schemaID], mapper)
2017-11-11 04:44:02 +00:00
return s
}
func (s *Schemas) SchemasForVersion(version APIVersion) map[string]*Schema {
return s.schemasByPath[version.Path]
}
func (s *Schemas) Versions() []APIVersion {
return s.versions
}
func (s *Schemas) Schemas() []*Schema {
return s.schemas
}
2017-11-21 20:46:30 +00:00
func (s *Schemas) mapper(version *APIVersion, name string) []Mapper {
2017-11-11 04:44:02 +00:00
var (
path string
)
if strings.Contains(name, "/") {
idx := strings.LastIndex(name, "/")
path = name[0:idx]
name = name[idx+1:]
} else if version != nil {
path = version.Path
} else {
path = "core"
}
mappers, ok := s.mappers[path]
if !ok {
return nil
}
mapper := mappers[name]
if mapper != nil {
return mapper
}
return nil
}
func (s *Schemas) Schema(version *APIVersion, name string) *Schema {
var (
path string
)
2017-11-21 20:46:30 +00:00
if strings.Contains(name, "/schemas/") {
parts := strings.SplitN(name, "/schemas/", 2)
path = parts[0]
name = parts[1]
2017-11-11 04:44:02 +00:00
} else if version != nil {
path = version.Path
} else {
path = "core"
}
schemas, ok := s.schemasByPath[path]
if !ok {
return nil
}
schema := schemas[name]
if schema != nil {
return schema
}
for _, check := range schemas {
if strings.EqualFold(check.ID, name) || strings.EqualFold(check.PluralName, name) {
return check
}
}
return nil
}
type multiErrors struct {
errors []error
}
func NewErrors(errors []error) error {
if len(errors) == 0 {
return nil
} else if len(errors) == 1 {
return errors[0]
}
return &multiErrors{
errors: errors,
}
}
func (m *multiErrors) Error() string {
buf := bytes.NewBuffer(nil)
for _, err := range m.errors {
if buf.Len() > 0 {
buf.WriteString(", ")
}
buf.WriteString(err.Error())
}
return buf.String()
}