Add initial convert (exp is broken at this commit)

Still need to flesh out the types for conversion. Also still need to add
the serialize and deserialize calls for individual types. Finally, will
need to put the finishing touches on writing the output files in the
desired directories. Then the experimental tool will be ready for end to
end testing.
このコミットが含まれているのは:
Cory Slep 2018-12-08 23:05:02 +01:00
コミット 069b8de820
8個のファイルの変更237行の追加27行の削除

209
tools/exp/convert/convert.go ノーマルファイル
ファイルの表示

@ -0,0 +1,209 @@
package convert
import (
"fmt"
"github.com/cjslep/activity/tools/exp/props"
"github.com/cjslep/activity/tools/exp/rdf"
"github.com/cjslep/activity/tools/exp/types"
"strings"
)
type vocabulary struct {
Kinds map[string]*props.Kind
FProps map[string]*props.FunctionalPropertyGenerator
NFProps map[string]*props.NonFunctionalPropertyGenerator
Types map[string]*types.TypeGenerator
}
func newVocabulary() vocabulary {
return vocabulary{
Kinds: make(map[string]*props.Kind, 0),
FProps: make(map[string]*props.FunctionalPropertyGenerator, 0),
NFProps: make(map[string]*props.NonFunctionalPropertyGenerator, 0),
Types: make(map[string]*types.TypeGenerator, 0),
}
}
type PropertyPackagePolicy int
const (
FlatUnderRoot PropertyPackagePolicy = iota
IndividualUnderRoot
)
type Converter struct {
Registry *rdf.RDFRegistry
VocabularyRoot string
PropertyPackagePolicy PropertyPackagePolicy
PropertyPackageRoot string
}
func (c Converter) convert(p *rdf.ParsedVocabulary) (v vocabulary, e error) {
v = newVocabulary()
for k, val := range p.Vocab.Values {
v.Kinds[k] = c.convertValue(val)
}
for k, prop := range p.Vocab.Properties {
if prop.Functional {
v.FProps[k], e = c.convertFunctionalProperty(prop, v.Kinds, p.Vocab, p.References)
} else {
v.NFProps[k], e = c.convertNonFunctionalProperty(prop, v.Kinds, p.Vocab, p.References)
}
if e != nil {
return
}
}
// TODO: Types in dependency order.
return
}
func (c Converter) convertFunctionalProperty(p rdf.VocabularyProperty,
kinds map[string]*props.Kind,
v rdf.Vocabulary,
refs map[string]*rdf.Vocabulary) (fp *props.FunctionalPropertyGenerator, e error) {
var k []props.Kind
k, e = c.propertyKinds(p, kinds, v, refs)
if e != nil {
return
}
var pkg string
pkg, e = c.propertyPackageName(p)
if e != nil {
return
}
fp = props.NewFunctionalPropertyGenerator(
pkg,
c.toIdentifier(p),
k,
p.NaturalLanguageMap)
return
}
func (c Converter) convertNonFunctionalProperty(p rdf.VocabularyProperty,
kinds map[string]*props.Kind,
v rdf.Vocabulary,
refs map[string]*rdf.Vocabulary) (nfp *props.NonFunctionalPropertyGenerator, e error) {
var k []props.Kind
k, e = c.propertyKinds(p, kinds, v, refs)
if e != nil {
return
}
var pkg string
pkg, e = c.propertyPackageName(p)
if e != nil {
return
}
nfp = props.NewNonFunctionalPropertyGenerator(
pkg,
c.toIdentifier(p),
k,
p.NaturalLanguageMap)
return
}
func (c Converter) convertValue(v rdf.VocabularyValue) (k *props.Kind) {
k = &props.Kind{
Name: c.toIdentifier(v),
ConcreteKind: v.DefinitionType,
Nilable: c.isNilable(v.DefinitionType),
SerializeFn: v.SerializeFn,
DeserializeFn: v.DeserializeFn,
LessFn: v.LessFn,
}
return
}
func (c Converter) convertTypeToKind(v rdf.VocabularyType) (k *props.Kind) {
k = &props.Kind{
Name: c.toIdentifier(v),
ConcreteKind: strings.Title(v.Name),
Nilable: true,
// TODO
SerializeFn: types.SerializeFn,
DeserializeFn: types.DeserializeFn,
LessFn: types.LessFn,
}
return
}
func (c Converter) propertyKinds(v rdf.VocabularyProperty,
kinds map[string]*props.Kind,
vocab rdf.Vocabulary,
refs map[string]*rdf.Vocabulary) (k []props.Kind, e error) {
for _, r := range v.Range {
if len(r.Vocab) == 0 {
if kind, ok := kinds[r.Name]; !ok {
// It is a Type of the vocabulary
if t, ok := vocab.Types[r.Name]; !ok {
e = fmt.Errorf("cannot find own kind with name %q", r.Name)
return
} else {
k = append(k, *c.convertTypeToKind(t))
}
} else {
// It is a Value of the vocabulary
k = append(k, *kind)
}
} else {
var url string
url, e = c.Registry.ResolveAlias(r.Vocab)
if e != nil {
return
}
refVocab, ok := refs[url]
if !ok {
e = fmt.Errorf("references do not contain %s", url)
return
}
if val, ok := refVocab.Values[r.Name]; !ok {
// It is a Type of the vocabulary instead
if t, ok := refVocab.Types[r.Name]; !ok {
e = fmt.Errorf("cannot find kind with name %q in %s", r.Name, url)
return
} else {
k = append(k, *c.convertTypeToKind(t))
}
} else {
// It is a Value of the vocabulary
k = append(k, *c.convertValue(val))
}
}
}
return
}
func (c Converter) propertyPackageName(v rdf.VocabularyProperty) (pkg string, e error) {
switch c.PropertyPackagePolicy {
case FlatUnderRoot:
pkg = c.PropertyPackageRoot
case IndividualUnderRoot:
pkg = v.Name
default:
e = fmt.Errorf("unrecognized PropertyPackagePolicy: %v", c.PropertyPackagePolicy)
}
return
}
// TODO: Use this?
func (c Converter) propertyPackageFile(v rdf.VocabularyProperty) (pkg string, e error) {
switch c.PropertyPackagePolicy {
case FlatUnderRoot:
pkg = fmt.Sprintf("%s/%s", c.VocabularyRoot, c.PropertyPackageRoot)
case IndividualUnderRoot:
pkg = fmt.Sprintf("%s/%s/%s", c.VocabularyRoot, c.PropertyPackageRoot, v.Name)
default:
e = fmt.Errorf("unrecognized PropertyPackagePolicy: %v", c.PropertyPackagePolicy)
}
return
}
func (c Converter) toIdentifier(n rdf.NameGetter) props.Identifier {
return props.Identifier{
LowerName: n.GetName(),
CamelName: strings.Title(n.GetName()),
}
}
func (c Converter) isNilable(goType string) bool {
return goType[0] == '*'
}

ファイルの表示

@ -2,8 +2,8 @@ package props
import ( import (
"fmt" "fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"github.com/dave/jennifer/jen" "github.com/dave/jennifer/jen"
"github.com/go-fed/activity/tools/exp/codegen"
"sync" "sync"
) )

ファイルの表示

@ -2,8 +2,8 @@ package props
import ( import (
"fmt" "fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"github.com/dave/jennifer/jen" "github.com/dave/jennifer/jen"
"github.com/go-fed/activity/tools/exp/codegen"
"sync" "sync"
) )

ファイルの表示

@ -2,8 +2,8 @@ package props
import ( import (
"fmt" "fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"github.com/dave/jennifer/jen" "github.com/dave/jennifer/jen"
"github.com/go-fed/activity/tools/exp/codegen"
) )
const ( const (
@ -62,7 +62,6 @@ type Kind struct {
Name Identifier Name Identifier
ConcreteKind string ConcreteKind string
Nilable bool Nilable bool
HasNaturalLanguageMap bool
SerializeFn codegen.Function SerializeFn codegen.Function
DeserializeFn codegen.Function DeserializeFn codegen.Function
LessFn codegen.Function LessFn codegen.Function

ファイルの表示

@ -3,6 +3,7 @@ package rdf
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"net/url" "net/url"
) )
@ -99,6 +100,9 @@ type VocabularyValue struct {
URI *url.URL URI *url.URL
DefinitionType string DefinitionType string
Zero string Zero string
SerializeFn codegen.Function
DeserializeFn codegen.Function
LessFn codegen.Function
} }
func (v VocabularyValue) String() string { func (v VocabularyValue) String() string {
@ -109,7 +113,7 @@ func (v *VocabularyValue) SetName(s string) {
v.Name = s v.Name = s
} }
func (v *VocabularyValue) GetName() string { func (v VocabularyValue) GetName() string {
return v.Name return v.Name
} }
@ -121,7 +125,7 @@ func (v *VocabularyValue) SetURI(s string) error {
var ( var (
_ NameSetter = &VocabularyValue{} _ NameSetter = &VocabularyValue{}
_ nameGetter = &VocabularyValue{} _ NameGetter = &VocabularyValue{}
_ URISetter = &VocabularyValue{} _ URISetter = &VocabularyValue{}
) )
@ -143,7 +147,7 @@ func (v *VocabularyType) SetName(s string) {
v.Name = s v.Name = s
} }
func (v *VocabularyType) GetName() string { func (v VocabularyType) GetName() string {
return v.Name return v.Name
} }
@ -163,7 +167,7 @@ func (v *VocabularyType) AddExample(e *VocabularyExample) {
var ( var (
_ NameSetter = &VocabularyType{} _ NameSetter = &VocabularyType{}
_ nameGetter = &VocabularyType{} _ NameGetter = &VocabularyType{}
_ URISetter = &VocabularyType{} _ URISetter = &VocabularyType{}
_ NotesSetter = &VocabularyType{} _ NotesSetter = &VocabularyType{}
_ ExampleAdder = &VocabularyType{} _ ExampleAdder = &VocabularyType{}
@ -193,7 +197,7 @@ func (v *VocabularyProperty) SetName(s string) {
v.Name = s v.Name = s
} }
func (v *VocabularyProperty) GetName() string { func (v VocabularyProperty) GetName() string {
return v.Name return v.Name
} }
@ -213,7 +217,7 @@ func (v *VocabularyProperty) AddExample(e *VocabularyExample) {
var ( var (
_ NameSetter = &VocabularyProperty{} _ NameSetter = &VocabularyProperty{}
_ nameGetter = &VocabularyProperty{} _ NameGetter = &VocabularyProperty{}
_ URISetter = &VocabularyProperty{} _ URISetter = &VocabularyProperty{}
_ NotesSetter = &VocabularyProperty{} _ NotesSetter = &VocabularyProperty{}
_ ExampleAdder = &VocabularyProperty{} _ ExampleAdder = &VocabularyProperty{}
@ -235,7 +239,7 @@ func (v *VocabularyExample) SetName(s string) {
v.Name = s v.Name = s
} }
func (v *VocabularyExample) GetName() string { func (v VocabularyExample) GetName() string {
return v.Name return v.Name
} }
@ -247,7 +251,7 @@ func (v *VocabularyExample) SetURI(s string) error {
var ( var (
_ NameSetter = &VocabularyExample{} _ NameSetter = &VocabularyExample{}
_ nameGetter = &VocabularyExample{} _ NameGetter = &VocabularyExample{}
_ URISetter = &VocabularyExample{} _ URISetter = &VocabularyExample{}
) )
@ -268,7 +272,7 @@ func (v *VocabularyReference) SetName(s string) {
v.Name = s v.Name = s
} }
func (v *VocabularyReference) GetName() string { func (v VocabularyReference) GetName() string {
return v.Name return v.Name
} }
@ -280,6 +284,6 @@ func (v *VocabularyReference) SetURI(s string) error {
var ( var (
_ NameSetter = &VocabularyReference{} _ NameSetter = &VocabularyReference{}
_ nameGetter = &VocabularyReference{} _ NameGetter = &VocabularyReference{}
_ URISetter = &VocabularyReference{} _ URISetter = &VocabularyReference{}
) )

ファイルの表示

@ -73,7 +73,7 @@ func (p *ParsingContext) Push() {
func (p *ParsingContext) Pop() { func (p *ParsingContext) Pop() {
p.Current = p.Stack[0] p.Current = p.Stack[0]
p.Stack = p.Stack[1:] p.Stack = p.Stack[1:]
if ng, ok := p.Current.(nameGetter); ok { if ng, ok := p.Current.(NameGetter); ok {
p.Name = ng.GetName() p.Name = ng.GetName()
} }
} }
@ -92,7 +92,7 @@ type NameSetter interface {
SetName(string) SetName(string)
} }
type nameGetter interface { type NameGetter interface {
GetName() string GetName() string
} }
@ -194,7 +194,7 @@ func resolveReference(reference VocabularyReference, registry *RDFRegistry, ctx
vocab := &ctx.Result.Vocab vocab := &ctx.Result.Vocab
if len(reference.Vocab) > 0 { if len(reference.Vocab) > 0 {
name = joinAlias(reference.Vocab, reference.Name) name = joinAlias(reference.Vocab, reference.Name)
url, e := registry.resolveAlias(reference.Vocab) url, e := registry.ResolveAlias(reference.Vocab)
if e != nil { if e != nil {
return e return e
} }

ファイルの表示

@ -262,9 +262,7 @@ func (r *RDFRegistry) getNode(s string) (n RDFNode, e error) {
} }
// resolveAlias turns an alias into its full qualifier for the ontology. // resolveAlias turns an alias into its full qualifier for the ontology.
// func (r *RDFRegistry) ResolveAlias(alias string) (url string, e error) {
// Package public.
func (r *RDFRegistry) resolveAlias(alias string) (url string, e error) {
var ok bool var ok bool
if url, ok = r.aliases[alias]; !ok { if url, ok = r.aliases[alias]; !ok {
e = fmt.Errorf("registry cannot resolve alias %q", alias) e = fmt.Errorf("registry cannot resolve alias %q", alias)

ファイルの表示

@ -2,8 +2,8 @@ package types
import ( import (
"fmt" "fmt"
"github.com/cjslep/activity/tools/exp/codegen"
"github.com/dave/jennifer/jen" "github.com/dave/jennifer/jen"
"github.com/go-fed/activity/tools/exp/codegen"
"sync" "sync"
) )