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.
このコミットが含まれているのは:
コミット
069b8de820
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
読み込み中…
新しいイシューから参照