func (m *MediaTypeDefinition) projectSingle(view, canonical string) (p *MediaTypeDefinition, links *UserTypeDefinition, err error) { v, ok := m.Views[view] if !ok { return nil, nil, fmt.Errorf("unknown view %#v", view) } viewObj := v.Type.ToObject() // Compute validations - view may not have all attributes var val *dslengine.ValidationDefinition if m.Validation != nil { names := m.Validation.Required var required []string for _, n := range names { if _, ok := viewObj[n]; ok { required = append(required, n) } } val = m.Validation.Dup() val.Required = required } // Compute description desc := m.Description if desc == "" { desc = m.TypeName + " media type" } desc += " (" + view + " view)" p = &MediaTypeDefinition{ Identifier: m.projectIdentifier(view), UserTypeDefinition: &UserTypeDefinition{ TypeName: m.projectTypeName(view), AttributeDefinition: &AttributeDefinition{ Description: desc, Type: Dup(v.Type), Validation: val, }, }, } p.Views = map[string]*ViewDefinition{"default": { Name: "default", AttributeDefinition: DupAtt(v.AttributeDefinition), Parent: p, }} ProjectedMediaTypes[canonical] = p projectedObj := p.Type.ToObject() mtObj := m.Type.ToObject() for n := range viewObj { if n == "links" { linkObj := make(Object) for n, link := range m.Links { linkView := link.View if linkView == "" { linkView = "link" } mtAtt, ok := mtObj[n] if !ok { return nil, nil, fmt.Errorf("unknown attribute %#v used in links", n) } mtt := mtAtt.Type.(*MediaTypeDefinition) vl, _, err := mtt.Project(linkView) if err != nil { return nil, nil, err } linkObj[n] = &AttributeDefinition{Type: vl, Validation: mtt.Validation, Metadata: mtAtt.Metadata} } lTypeName := fmt.Sprintf("%sLinks", m.TypeName) links = &UserTypeDefinition{ AttributeDefinition: &AttributeDefinition{ Description: fmt.Sprintf("%s contains links to related resources of %s.", lTypeName, m.TypeName), Type: linkObj, }, TypeName: lTypeName, } projectedObj[n] = &AttributeDefinition{Type: links, Description: "Links to related resources"} ProjectedMediaTypes[canonical+"; links"] = &MediaTypeDefinition{UserTypeDefinition: links} } else { if at := mtObj[n]; at != nil { at = DupAtt(at) if mt, ok := at.Type.(*MediaTypeDefinition); ok { vatt := viewObj[n] view := vatt.View if view == "" { view = at.View } if view == "" { view = DefaultView } pr, _, err := mt.Project(view) if err != nil { return nil, nil, fmt.Errorf("view %#v on field %#v cannot be computed: %s", view, n, err) } at.Type = pr } projectedObj[n] = at } } } return }
func (m *MediaTypeDefinition) projectSingle(view string) (p *MediaTypeDefinition, links *UserTypeDefinition, err error) { v := m.Views[view] canonical := CanonicalIdentifier(m.Identifier) typeName := m.TypeName if view != "default" { typeName += strings.Title(view) canonical += "; view=" + view } var ok bool if p, ok = GeneratedMediaTypes[canonical]; ok { mLinks := GeneratedMediaTypes[canonical+"; links"] if mLinks != nil { links = mLinks.UserTypeDefinition } return } // Compute validations - view may not have all attributes viewObj := v.Type.ToObject() var val *dslengine.ValidationDefinition if m.Validation != nil { names := m.Validation.Required var required []string for _, n := range names { if _, ok := viewObj[n]; ok { required = append(required, n) } } val = m.Validation.Dup() val.Required = required } p = &MediaTypeDefinition{ Identifier: m.Identifier, UserTypeDefinition: &UserTypeDefinition{ TypeName: typeName, AttributeDefinition: &AttributeDefinition{ Type: Dup(v.Type), Validation: val, }, }, } p.Views = map[string]*ViewDefinition{view: { Name: view, AttributeDefinition: v.AttributeDefinition, Parent: p, }} GeneratedMediaTypes[canonical] = p projectedObj := p.Type.ToObject() mtObj := m.Type.ToObject() for n := range viewObj { if n == "links" { linkObj := make(Object) for n, link := range m.Links { linkView := link.View if linkView == "" { linkView = "link" } mtAtt, ok := mtObj[n] if !ok { return nil, nil, fmt.Errorf("unknown attribute %#v used in links", n) } vl, _, err := mtAtt.Type.(*MediaTypeDefinition).Project(linkView) if err != nil { return nil, nil, err } linkObj[n] = &AttributeDefinition{Type: vl} } lTypeName := fmt.Sprintf("%sLinks", m.TypeName) links = &UserTypeDefinition{ AttributeDefinition: &AttributeDefinition{ Description: fmt.Sprintf("%s contains links to related resources of %s.", lTypeName, m.TypeName), Type: linkObj, }, TypeName: lTypeName, } projectedObj[n] = &AttributeDefinition{Type: links, Description: "Links to related resources"} GeneratedMediaTypes[canonical+"; links"] = &MediaTypeDefinition{UserTypeDefinition: links} } else { if at := mtObj[n]; at != nil { if m, ok := at.Type.(*MediaTypeDefinition); ok { view := at.View if view == "" { view = "default" } pr, _, err := m.Project(view) if err != nil { return nil, nil, fmt.Errorf("view %#v on field %#v cannot be computed: %s", view, n, err) } at = DupAtt(at) at.Type = pr } projectedObj[n] = at } } } return }
func (m *MediaTypeDefinition) projectSingle(view string) (p *MediaTypeDefinition, links *UserTypeDefinition, err error) { v := m.Views[view] var suffix string if view != "default" { suffix = strings.Title(view) } typeName := fmt.Sprintf("%s%s", m.TypeName, suffix) var ok bool if p, ok = GeneratedMediaTypes[typeName]; ok { mLinks := GeneratedMediaTypes[typeName+":Links"] if mLinks != nil { links = mLinks.UserTypeDefinition } return } // Compute validations - view may not have all attributes viewObj := v.Type.ToObject() var val *dslengine.ValidationDefinition if m.Validation != nil { names := m.Validation.Required var required []string for _, n := range names { if _, ok := viewObj[n]; ok { required = append(required, n) } } val = m.Validation.Dup() val.Required = required } description := m.Description if view != "default" { description += fmt.Sprintf(", %s view", view) } p = &MediaTypeDefinition{ Identifier: m.Identifier, UserTypeDefinition: &UserTypeDefinition{ TypeName: typeName, AttributeDefinition: &AttributeDefinition{ APIVersions: m.APIVersions, Description: description, Type: Dup(v.Type), Validation: val, }, }, } GeneratedMediaTypes[typeName] = p projectedObj := p.Type.ToObject() mtObj := m.Type.ToObject() for n := range viewObj { if n == "links" { linkObj := make(Object) for n, link := range m.Links { linkView := link.View if linkView == "" { linkView = "link" } mtAtt, ok := mtObj[n] if !ok { return nil, nil, fmt.Errorf("unknown attribute %#v used in links", n) } vl, _, err := mtAtt.Type.(*MediaTypeDefinition).Project(linkView) if err != nil { return nil, nil, err } linkObj[n] = &AttributeDefinition{Type: vl} } lTypeName := fmt.Sprintf("%sLinks", m.TypeName) links = &UserTypeDefinition{ AttributeDefinition: &AttributeDefinition{ APIVersions: m.APIVersions, Description: fmt.Sprintf("%s contains links to related resources of %s.", lTypeName, m.TypeName), Type: linkObj, }, TypeName: lTypeName, } projectedObj[n] = &AttributeDefinition{Type: links, Description: "Links to related resources"} GeneratedMediaTypes[m.TypeName+":Links"] = &MediaTypeDefinition{UserTypeDefinition: links} } else { if at := mtObj[n]; at != nil { if at.View != "" { m, ok := at.Type.(*MediaTypeDefinition) if !ok { return nil, nil, fmt.Errorf("View specified on non media type attribute %#v", n) } pr, _, err := m.Project(at.View) if err != nil { return nil, nil, fmt.Errorf("view %#v on field %#v cannot be computed: %s", at.View, n, err) } at.Type = pr } projectedObj[n] = at } } } return }