Fix bugs for handling aliased nodes and containers

Implemented the beginning of the container and index handling, but have
not yet completed it.
このコミットが含まれているのは:
Cory Slep 2018-12-02 13:55:29 +01:00
コミット 90b12d43aa
5個のファイルの変更220行の追加13行の削除

145
tools/exp/rdf/jsonld.go ノーマルファイル
ファイルの表示

@ -0,0 +1,145 @@
package rdf
import (
"fmt"
)
const (
typeSpec = "@type"
typeActivityStreamsSpec = "type"
IdSpec = "@id"
IdActivityStreamsSpec = "id"
ContainerSpec = "@container"
IndexSpec = "@index"
)
// jsonLDNodes contains the well-known set of nodes as defined by the JSON-LD
// specification.
var jsonLDNodes []RDFNode
func init() {
// Order matters -- we want to be able to distinguish the types of
// things first, for example, to be able to have the parsing context
// applied correctly.
jsonLDNodes = []RDFNode{
&AliasedDelegate{
Spec: "",
Alias: "",
Name: typeSpec,
Delegate: &typeLD{},
},
&AliasedDelegate{
Spec: "",
Alias: "",
Name: typeActivityStreamsSpec,
Delegate: &typeLD{},
},
&AliasedDelegate{
Spec: "",
Alias: "",
Name: IdSpec,
Delegate: &idLD{},
},
&AliasedDelegate{
Spec: "",
Alias: "",
Name: IdActivityStreamsSpec,
Delegate: &idLD{},
},
&AliasedDelegate{
Spec: "",
Alias: "",
Name: ContainerSpec,
Delegate: &ContainerLD{},
},
&AliasedDelegate{
Spec: "",
Alias: "",
Name: IndexSpec,
Delegate: &IndexLD{},
},
}
}
var _ RDFNode = &idLD{}
type idLD struct{}
func (i *idLD) Enter(key string, ctx *ParsingContext) (bool, error) {
return true, fmt.Errorf("id cannot be entered")
}
func (i *idLD) Exit(key string, ctx *ParsingContext) (bool, error) {
return true, fmt.Errorf("id cannot be exited")
}
func (i *idLD) Apply(key string, value interface{}, ctx *ParsingContext) (bool, error) {
if ctx.Current == nil {
return true, fmt.Errorf("id apply called with nil Current")
} else if ider, ok := ctx.Current.(URISetter); !ok {
return true, fmt.Errorf("id apply called with non-URISetter")
} else if str, ok := value.(string); !ok {
return true, fmt.Errorf("id apply called with non-string value")
} else {
return true, ider.SetURI(str)
}
}
var _ RDFNode = &typeLD{}
type typeLD struct{}
func (t *typeLD) Enter(key string, ctx *ParsingContext) (bool, error) {
// TODO
return true, nil
}
func (t *typeLD) Exit(key string, ctx *ParsingContext) (bool, error) {
// TODO
return true, nil
}
func (t *typeLD) Apply(key string, value interface{}, ctx *ParsingContext) (bool, error) {
// TODO
return true, nil
}
var _ RDFNode = &ContainerLD{}
type ContainerLD struct {
ContainsNode RDFNode
}
func (c *ContainerLD) Enter(key string, ctx *ParsingContext) (bool, error) {
// TODO
return true, nil
}
func (c *ContainerLD) Exit(key string, ctx *ParsingContext) (bool, error) {
// TODO
return true, nil
}
func (c *ContainerLD) Apply(key string, value interface{}, ctx *ParsingContext) (bool, error) {
// TODO
return true, nil
}
var _ RDFNode = &IndexLD{}
type IndexLD struct{}
func (i *IndexLD) Enter(key string, ctx *ParsingContext) (bool, error) {
// TODO
return true, nil
}
func (i *IndexLD) Exit(key string, ctx *ParsingContext) (bool, error) {
// TODO
return true, nil
}
func (i *IndexLD) Apply(key string, value interface{}, ctx *ParsingContext) (bool, error) {
// TODO
return true, nil
}

ファイルの表示

@ -61,6 +61,7 @@ func (l *langstring) Exit(key string, ctx *ParsingContext) (bool, error) {
}
func (l *langstring) Apply(key string, value interface{}, ctx *ParsingContext) (bool, error) {
// TODO: Act as value
return true, fmt.Errorf("rdf langstring cannot be applied")
}
@ -77,6 +78,7 @@ func (p *property) Exit(key string, ctx *ParsingContext) (bool, error) {
}
func (p *property) Apply(key string, value interface{}, ctx *ParsingContext) (bool, error) {
// TODO: Act as value
return true, fmt.Errorf("rdf property cannot be applied")
}
@ -93,5 +95,6 @@ func (v *value) Exit(key string, ctx *ParsingContext) (bool, error) {
}
func (v *value) Apply(key string, value interface{}, ctx *ParsingContext) (bool, error) {
// TODO: Act as value
return true, fmt.Errorf("rdf value cannot be applied")
}

ファイルの表示

@ -17,7 +17,9 @@ const (
functionalPropertySpec = "FunctionalProperty"
)
type OWLOntology struct{}
type OWLOntology struct {
alias string
}
func (o *OWLOntology) SpecURI() string {
return owlSpec
@ -28,6 +30,7 @@ func (o *OWLOntology) Load() ([]rdf.RDFNode, error) {
}
func (o *OWLOntology) LoadAsAlias(s string) ([]rdf.RDFNode, error) {
o.alias = s
return []rdf.RDFNode{
&rdf.AliasedDelegate{
Spec: owlSpec,
@ -81,8 +84,54 @@ func (o *OWLOntology) LoadAsAlias(s string) ([]rdf.RDFNode, error) {
}
func (o *OWLOntology) LoadElement(name string, payload map[string]interface{}) ([]rdf.RDFNode, error) {
// TODO: Imports
return nil, nil
// First, detect if an idValue exists
var idValue interface{}
var ok bool
idValue, ok = payload[rdf.IdSpec]
if !ok {
idValue, ok = payload[rdf.IdActivityStreamsSpec]
}
if !ok {
return nil, nil
}
vStr, ok := idValue.(string)
if !ok {
return nil, nil
}
// Now that we have a string idValue, handle the import use case
if !rdf.IsKeyApplicable(vStr, owlSpec, o.alias, importsSpec) {
return nil, nil
}
node := &rdf.AliasedDelegate{
Spec: "",
Alias: "",
Name: name,
// Need to set Delegate, based on below logic
}
for k, v := range payload {
if k == rdf.IdSpec || k == rdf.IdActivityStreamsSpec {
continue
}
switch k {
case rdf.ContainerSpec:
container := &rdf.ContainerLD{}
node.Delegate = container
// Ugly, maybe move out to its own function when needed
if cValStr, ok := v.(string); !ok {
return nil, fmt.Errorf("unhandled owl import @container to non-string type: %T", v)
} else {
switch cValStr {
case rdf.IndexSpec:
container.ContainsNode = &rdf.IndexLD{}
default:
return nil, fmt.Errorf("unhandled owl import @container to string type %s", cValStr)
}
}
default:
return nil, fmt.Errorf("unhandled owl import use case: %s", k)
}
}
return []rdf.RDFNode{node}, nil
}
var _ rdf.RDFNode = &members{}

ファイルの表示

@ -73,6 +73,10 @@ func ParseVocabulary(registry *RDFRegistry, input JSONLD) (vocabulary *ParsedVoc
ctx := &ParsingContext{
Result: vocabulary,
}
// Prepend well-known JSON LD parsing nodes. Order matters, so that the
// parser can understand things like types first, and populate it with
// data afterwards.
nodes = append(jsonLDNodes, nodes...)
err = apply(nodes, input, ctx)
return
}

ファイルの表示

@ -139,7 +139,7 @@ func (r *RDFRegistry) AddOntology(o Ontology) error {
return nil
}
// getFor gets RDFKeyers and RDFValuers based on a context's string.
// getFor gets RDFKeyers based on a context's string.
func (r *RDFRegistry) getFor(s string) (n []RDFNode, e error) {
ontology, ok := r.ontologies[s]
if !ok {
@ -149,7 +149,17 @@ func (r *RDFRegistry) getFor(s string) (n []RDFNode, e error) {
return ontology.Load()
}
// getAliased gets RDFKeyers and RDFValuers based on a context string and its
// getForAliased gets RDFKeyers based on a context's string.
func (r *RDFRegistry) getForAliased(alias, s string) (n []RDFNode, e error) {
ontology, ok := r.ontologies[s]
if !ok {
e = fmt.Errorf("no ontology for %s", s)
return
}
return ontology.LoadAsAlias(alias)
}
// getAliased gets RDFKeyers based on a context string and its
// alias.
func (r *RDFRegistry) getAliased(alias, s string) (n []RDFNode, e error) {
strs := splitAlias(s)
@ -157,7 +167,7 @@ func (r *RDFRegistry) getAliased(alias, s string) (n []RDFNode, e error) {
if e = r.setAlias(alias, s); e != nil {
return
}
return r.getFor(s)
return r.getForAliased(alias, s)
} else if len(strs) == 2 {
var o Ontology
o, e = r.getOntology(strs[0])
@ -172,7 +182,7 @@ func (r *RDFRegistry) getAliased(alias, s string) (n []RDFNode, e error) {
}
}
// getAliasedObject gets RDFKeyers and RDFValuers based on a context object and
// getAliasedObject gets RDFKeyers based on a context object and
// its alias and definition.
func (r *RDFRegistry) getAliasedObject(alias string, object map[string]interface{}) (n []RDFNode, e error) {
raw, ok := object[ID]
@ -184,7 +194,6 @@ func (r *RDFRegistry) getAliasedObject(alias string, object map[string]interface
e = fmt.Errorf("element in getAliasedObject must be a string")
return
} else {
var nodes []RDFNode
strs := splitAlias(element)
if len(strs) == 1 {
n, e = r.getFor(strs[0])
@ -194,15 +203,12 @@ func (r *RDFRegistry) getAliasedObject(alias string, object map[string]interface
if e != nil {
return
}
n, e = o.LoadElement(strs[1], object)
return
n, e = o.LoadElement(alias, object)
}
if e != nil {
return
}
if e = r.setAliasedNode(alias, nodes); e != nil {
return
}
e = r.setAliasedNode(alias, n)
return
}
}