Bug fixes and ontology improvements.
- Fixed the way indexing nodes were being applied - Implemented property types in ontologies - Improved class types in ontologies - Lots of other stuff
このコミットが含まれているのは:
コミット
0f98307f07
|
@ -31,7 +31,7 @@ func (v *Vocabulary) SetType(name string, a *VocabularyType) error {
|
|||
v.Types = make(map[string]VocabularyType, 1)
|
||||
}
|
||||
if _, has := v.Types[name]; has {
|
||||
return fmt.Errorf("name already exists for vocabulary Types")
|
||||
return fmt.Errorf("name %q already exists for vocabulary Types", name)
|
||||
}
|
||||
v.Types[name] = *a
|
||||
return nil
|
||||
|
@ -71,6 +71,10 @@ func (v *VocabularyValue) SetName(s string) {
|
|||
v.Name = s
|
||||
}
|
||||
|
||||
func (v *VocabularyValue) GetName() string {
|
||||
return v.Name
|
||||
}
|
||||
|
||||
func (v *VocabularyValue) SetURI(s string) error {
|
||||
var e error
|
||||
v.URI, e = url.Parse(s)
|
||||
|
@ -79,6 +83,7 @@ func (v *VocabularyValue) SetURI(s string) error {
|
|||
|
||||
var (
|
||||
_ NameSetter = &VocabularyValue{}
|
||||
_ nameGetter = &VocabularyValue{}
|
||||
_ URISetter = &VocabularyValue{}
|
||||
)
|
||||
|
||||
|
@ -98,6 +103,10 @@ func (v *VocabularyType) SetName(s string) {
|
|||
v.Name = s
|
||||
}
|
||||
|
||||
func (v *VocabularyType) GetName() string {
|
||||
return v.Name
|
||||
}
|
||||
|
||||
func (v *VocabularyType) SetURI(s string) error {
|
||||
var e error
|
||||
v.URI, e = url.Parse(s)
|
||||
|
@ -114,6 +123,7 @@ func (v *VocabularyType) AddExample(e *VocabularyExample) {
|
|||
|
||||
var (
|
||||
_ NameSetter = &VocabularyType{}
|
||||
_ nameGetter = &VocabularyType{}
|
||||
_ URISetter = &VocabularyType{}
|
||||
_ NotesSetter = &VocabularyType{}
|
||||
_ ExampleAdder = &VocabularyType{}
|
||||
|
@ -138,6 +148,10 @@ func (v *VocabularyProperty) SetName(s string) {
|
|||
v.Name = s
|
||||
}
|
||||
|
||||
func (v *VocabularyProperty) GetName() string {
|
||||
return v.Name
|
||||
}
|
||||
|
||||
func (v *VocabularyProperty) SetURI(s string) error {
|
||||
var e error
|
||||
v.URI, e = url.Parse(s)
|
||||
|
@ -154,6 +168,7 @@ func (v *VocabularyProperty) AddExample(e *VocabularyExample) {
|
|||
|
||||
var (
|
||||
_ NameSetter = &VocabularyProperty{}
|
||||
_ nameGetter = &VocabularyProperty{}
|
||||
_ URISetter = &VocabularyProperty{}
|
||||
_ NotesSetter = &VocabularyProperty{}
|
||||
_ ExampleAdder = &VocabularyProperty{}
|
||||
|
@ -171,6 +186,10 @@ func (v *VocabularyExample) SetName(s string) {
|
|||
v.Name = s
|
||||
}
|
||||
|
||||
func (v *VocabularyExample) GetName() string {
|
||||
return v.Name
|
||||
}
|
||||
|
||||
func (v *VocabularyExample) SetURI(s string) error {
|
||||
var e error
|
||||
v.URI, e = url.Parse(s)
|
||||
|
@ -179,6 +198,7 @@ func (v *VocabularyExample) SetURI(s string) error {
|
|||
|
||||
var (
|
||||
_ NameSetter = &VocabularyExample{}
|
||||
_ nameGetter = &VocabularyExample{}
|
||||
_ URISetter = &VocabularyExample{}
|
||||
)
|
||||
|
||||
|
@ -195,6 +215,10 @@ func (v *VocabularyReference) SetName(s string) {
|
|||
v.Name = s
|
||||
}
|
||||
|
||||
func (v *VocabularyReference) GetName() string {
|
||||
return v.Name
|
||||
}
|
||||
|
||||
func (v *VocabularyReference) SetURI(s string) error {
|
||||
var e error
|
||||
v.URI, e = url.Parse(s)
|
||||
|
@ -203,5 +227,6 @@ func (v *VocabularyReference) SetURI(s string) error {
|
|||
|
||||
var (
|
||||
_ NameSetter = &VocabularyReference{}
|
||||
_ nameGetter = &VocabularyReference{}
|
||||
_ URISetter = &VocabularyReference{}
|
||||
)
|
||||
|
|
|
@ -17,8 +17,7 @@ const (
|
|||
// specification.
|
||||
func jsonLDNodes(r *RDFRegistry) []RDFNode {
|
||||
// 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.
|
||||
// things without other nodes hijacking the flow.
|
||||
return []RDFNode{
|
||||
&AliasedDelegate{
|
||||
Spec: "",
|
||||
|
@ -117,6 +116,7 @@ type ContainerLD struct {
|
|||
}
|
||||
|
||||
func (c *ContainerLD) Enter(key string, ctx *ParsingContext) (bool, error) {
|
||||
fmt.Println("===container enter")
|
||||
if ctx.OnlyApplyThisNodeNextLevel != nil {
|
||||
return true, fmt.Errorf("@container parsing context exit already has non-nil node")
|
||||
}
|
||||
|
@ -125,6 +125,7 @@ func (c *ContainerLD) Enter(key string, ctx *ParsingContext) (bool, error) {
|
|||
}
|
||||
|
||||
func (c *ContainerLD) Exit(key string, ctx *ParsingContext) (bool, error) {
|
||||
fmt.Println("===container exit")
|
||||
if ctx.OnlyApplyThisNodeNextLevel == nil {
|
||||
return true, fmt.Errorf("@container parsing context exit already has nil node")
|
||||
}
|
||||
|
@ -141,10 +142,12 @@ var _ RDFNode = &IndexLD{}
|
|||
type IndexLD struct{}
|
||||
|
||||
func (i *IndexLD) Enter(key string, ctx *ParsingContext) (bool, error) {
|
||||
fmt.Println(">>> enter index")
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (i *IndexLD) Exit(key string, ctx *ParsingContext) (bool, error) {
|
||||
fmt.Println(">>> exit index")
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,12 @@ func (o *RDFOntology) LoadElement(name string, payload map[string]interface{}) (
|
|||
func (o *RDFOntology) GetByName(name string) (RDFNode, error) {
|
||||
name = strings.TrimPrefix(name, o.SpecURI())
|
||||
switch name {
|
||||
case langstringSpec:
|
||||
return &langstring{}, nil
|
||||
case propertySpec:
|
||||
return &property{}, nil
|
||||
case valueSpec:
|
||||
return &value{}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("rdf ontology could not find node for name %s", name)
|
||||
}
|
||||
|
@ -119,8 +125,15 @@ 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")
|
||||
// Prepare a new VocabularyProperty in the context. If one already
|
||||
// exists, skip.
|
||||
if _, ok := ctx.Current.(*VocabularyProperty); ok {
|
||||
return true, nil
|
||||
} else if !ctx.IsReset() {
|
||||
return true, fmt.Errorf("rdf property applied with non-reset ParsingContext")
|
||||
}
|
||||
ctx.Current = &VocabularyProperty{}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var _ RDFNode = &value{}
|
||||
|
|
|
@ -216,7 +216,22 @@ func (o *OWLOntology) LoadElement(name string, payload map[string]interface{}) (
|
|||
func (o *OWLOntology) GetByName(name string) (rdf.RDFNode, error) {
|
||||
name = strings.TrimPrefix(name, o.SpecURI())
|
||||
switch name {
|
||||
// TODO
|
||||
case membersSpec:
|
||||
return &members{}, nil
|
||||
case disjointWithSpec:
|
||||
return &disjointWith{}, nil
|
||||
case unionOfSpec:
|
||||
return &unionOf{}, nil
|
||||
case importsSpec:
|
||||
return &imports{}, nil
|
||||
case ontologySpec:
|
||||
return &ontology{}, nil
|
||||
case classSpec:
|
||||
return &class{}, nil
|
||||
case objectPropertySpec:
|
||||
return &objectProperty{}, nil
|
||||
case functionalPropertySpec:
|
||||
return &functionalProperty{}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("owl ontology could not find node for name %s", name)
|
||||
}
|
||||
|
@ -301,18 +316,50 @@ var _ rdf.RDFNode = &unionOf{}
|
|||
type unionOf struct{}
|
||||
|
||||
func (u *unionOf) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
ctx.Push()
|
||||
ctx.Current = &rdf.VocabularyReference{}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (u *unionOf) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
if ctx.Current == nil {
|
||||
return true, fmt.Errorf("owl unionOf exit given nil Current")
|
||||
}
|
||||
i := ctx.Current
|
||||
ctx.Pop()
|
||||
ref, ok := i.(*rdf.VocabularyReference)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("owl unionOf exit not given *rdf.VocabularyReference")
|
||||
}
|
||||
arr, ok := ctx.Current.([]rdf.VocabularyReference)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("owl unionOf exit's previous Current not given []rdf.VocabularyReference")
|
||||
}
|
||||
ctx.Current = append(arr, *ref)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (u *unionOf) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("owl unionOf apply given non-string value")
|
||||
}
|
||||
strs := rdf.SplitAlias(s)
|
||||
ref := &rdf.VocabularyReference{}
|
||||
if len(strs) == 1 {
|
||||
ref.Name = strs[0]
|
||||
} else if len(strs) == 2 {
|
||||
ref.Name = strs[1]
|
||||
ref.Vocab = strs[0]
|
||||
} else {
|
||||
return true, fmt.Errorf("owl unionOf apply bad SplitAlias")
|
||||
}
|
||||
arr, ok := ctx.Current.([]rdf.VocabularyReference)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("owl unionOf apply's Current not given []rdf.VocabularyReference")
|
||||
}
|
||||
ctx.Current = append(arr, *ref)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &imports{}
|
||||
|
@ -320,18 +367,15 @@ var _ rdf.RDFNode = &imports{}
|
|||
type imports struct{}
|
||||
|
||||
func (i *imports) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
return true, fmt.Errorf("owl imports cannot be entered")
|
||||
}
|
||||
|
||||
func (i *imports) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
return true, fmt.Errorf("owl imports cannot be entered")
|
||||
}
|
||||
|
||||
func (i *imports) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
return true, fmt.Errorf("owl imports cannot be entered")
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &ontology{}
|
||||
|
@ -339,18 +383,16 @@ var _ rdf.RDFNode = &ontology{}
|
|||
type ontology struct{}
|
||||
|
||||
func (o *ontology) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
return true, fmt.Errorf("owl ontology cannot be entered")
|
||||
}
|
||||
|
||||
func (o *ontology) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
return true, fmt.Errorf("owl ontology cannot be exited")
|
||||
}
|
||||
|
||||
func (o *ontology) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
// Do nothing
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &class{}
|
||||
|
@ -366,11 +408,15 @@ func (c *class) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
|||
}
|
||||
|
||||
func (c *class) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// Prepare a new VocabularyType in the context
|
||||
if !ctx.IsReset() {
|
||||
return true, fmt.Errorf("owl class applied with non-reset ParsingContext")
|
||||
// Prepare a new VocabularyType in the context, unless it is a
|
||||
// reference already prepared.
|
||||
if ctx.IsReset() {
|
||||
ctx.Current = &rdf.VocabularyType{}
|
||||
} else if _, ok := ctx.Current.(*rdf.VocabularyReference); ok {
|
||||
return true, nil
|
||||
} else {
|
||||
return true, fmt.Errorf("owl class applied with non-reset ctx and not a vocab reference: %T", ctx.Current)
|
||||
}
|
||||
ctx.Current = &rdf.VocabularyType{}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
@ -387,8 +433,11 @@ func (o *objectProperty) Exit(key string, ctx *rdf.ParsingContext) (bool, error)
|
|||
}
|
||||
|
||||
func (o *objectProperty) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// Prepare a new VocabularyProperty in the context
|
||||
if !ctx.IsReset() {
|
||||
// Prepare a new VocabularyProperty in the context. If one already
|
||||
// exists, skip.
|
||||
if _, ok := ctx.Current.(*rdf.VocabularyProperty); ok {
|
||||
return true, nil
|
||||
} else if !ctx.IsReset() {
|
||||
return true, fmt.Errorf("owl objectProperty applied with non-reset ParsingContext")
|
||||
}
|
||||
ctx.Current = &rdf.VocabularyProperty{}
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
|
||||
const (
|
||||
JSON_LD_CONTEXT = "@context"
|
||||
JSON_LD_TYPE = "@type"
|
||||
JSON_LD_TYPE_AS = "type"
|
||||
)
|
||||
|
||||
// JSONLD is an alias for the generic map of keys to interfaces, presumably
|
||||
|
@ -45,14 +47,16 @@ func (p *ParsingContext) SetOnlyApplyThisNodeNextLevel(n RDFNode) {
|
|||
p.OnlyApplied = false
|
||||
}
|
||||
|
||||
func (p *ParsingContext) GetNextNodes(n []RDFNode) []RDFNode {
|
||||
func (p *ParsingContext) GetNextNodes(n []RDFNode) (r []RDFNode, clearFn func()) {
|
||||
if p.OnlyApplyThisNodeNextLevel == nil {
|
||||
return n
|
||||
return n, func () {}
|
||||
} else if p.OnlyApplied {
|
||||
return n
|
||||
return n, func () {}
|
||||
} else {
|
||||
p.OnlyApplied = true
|
||||
return []RDFNode{p.OnlyApplyThisNodeNextLevel}
|
||||
return []RDFNode{p.OnlyApplyThisNodeNextLevel}, func () {
|
||||
p.OnlyApplied = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,11 +67,15 @@ func (p *ParsingContext) ResetOnlyAppliedThisNodeNextLevel() {
|
|||
|
||||
func (p *ParsingContext) Push() {
|
||||
p.Stack = append([]interface{}{p.Current}, p.Stack...)
|
||||
p.Current = nil
|
||||
}
|
||||
|
||||
func (p *ParsingContext) Pop() {
|
||||
p.Current = p.Stack[0]
|
||||
p.Stack = p.Stack[1:]
|
||||
if ng, ok := p.Current.(nameGetter); ok {
|
||||
p.Name = ng.GetName()
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ParsingContext) IsReset() bool {
|
||||
|
@ -84,6 +92,10 @@ type NameSetter interface {
|
|||
SetName(string)
|
||||
}
|
||||
|
||||
type nameGetter interface {
|
||||
GetName() string
|
||||
}
|
||||
|
||||
type URISetter interface {
|
||||
SetURI(string) error
|
||||
}
|
||||
|
@ -118,8 +130,8 @@ func ParseVocabulary(registry *RDFRegistry, input JSONLD) (vocabulary *ParsedVoc
|
|||
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.
|
||||
// parser can understand things like types so that other nodes do not
|
||||
// hijack processing.
|
||||
nodes = append(jsonLDNodes(registry), nodes...)
|
||||
err = apply(nodes, input, ctx)
|
||||
return
|
||||
|
@ -136,53 +148,79 @@ func apply(nodes []RDFNode, input JSONLD, ctx *ParsingContext) error {
|
|||
} else {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// Special processing: '@type' or 'type' if they are present
|
||||
if v, ok := input[JSON_LD_TYPE]; ok {
|
||||
if err := doApply(nodes, JSON_LD_TYPE, v, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if v, ok := input[JSON_LD_TYPE_AS]; ok {
|
||||
if err := doApply(nodes, JSON_LD_TYPE_AS, v, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Normal recursive processing
|
||||
for k, v := range input {
|
||||
// Skip the context as it has already been parsed to create the
|
||||
// nodes.
|
||||
fmt.Println(k)
|
||||
// Skip things we have already processed: context and type
|
||||
if k == JSON_LD_CONTEXT {
|
||||
continue
|
||||
} else if k == JSON_LD_TYPE {
|
||||
continue
|
||||
} else if k == JSON_LD_TYPE_AS {
|
||||
continue
|
||||
}
|
||||
// Hijacked processing: Only use the ParsingContext's node to
|
||||
// handle all elements.
|
||||
recurNodes := nodes
|
||||
enterApplyExitNodes := ctx.GetNextNodes(nodes)
|
||||
// Normal recursive processing
|
||||
if mapValue, ok := v.(map[string]interface{}); ok {
|
||||
if err := enterFirstNode(enterApplyExitNodes, k, ctx); err != nil {
|
||||
return err
|
||||
} else if err = apply(recurNodes, mapValue, ctx); err != nil {
|
||||
return err
|
||||
} else if err = exitFirstNode(enterApplyExitNodes, k, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if arrValue, ok := v.([]interface{}); ok {
|
||||
for _, val := range arrValue {
|
||||
// First, enter for this key
|
||||
if err := enterFirstNode(enterApplyExitNodes, k, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
// Recur or handle the value as necessary.
|
||||
if mapValue, ok := val.(map[string]interface{}); ok {
|
||||
if err := apply(recurNodes, mapValue, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := applyFirstNode(enterApplyExitNodes, k, val, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
// Finally, exit for this key
|
||||
if err := exitFirstNode(enterApplyExitNodes, k, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if err := applyFirstNode(enterApplyExitNodes, k, v, ctx); err != nil {
|
||||
if err := doApply(nodes, k, v, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// doApply actually does the application logic for the apply function.
|
||||
func doApply(nodes []RDFNode,
|
||||
k string, v interface{},
|
||||
ctx *ParsingContext) error {
|
||||
// Hijacked processing: Only use the ParsingContext's node to
|
||||
// handle all elements.
|
||||
recurNodes := nodes
|
||||
enterApplyExitNodes, clearFn := ctx.GetNextNodes(nodes)
|
||||
defer clearFn()
|
||||
// Normal recursive processing
|
||||
if mapValue, ok := v.(map[string]interface{}); ok {
|
||||
if err := enterFirstNode(enterApplyExitNodes, k, ctx); err != nil {
|
||||
return err
|
||||
} else if err = apply(recurNodes, mapValue, ctx); err != nil {
|
||||
return err
|
||||
} else if err = exitFirstNode(enterApplyExitNodes, k, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if arrValue, ok := v.([]interface{}); ok {
|
||||
for _, val := range arrValue {
|
||||
// First, enter for this key
|
||||
if err := enterFirstNode(enterApplyExitNodes, k, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
// Recur or handle the value as necessary.
|
||||
if mapValue, ok := val.(map[string]interface{}); ok {
|
||||
if err := apply(recurNodes, mapValue, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := applyFirstNode(enterApplyExitNodes, k, val, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
// Finally, exit for this key
|
||||
if err := exitFirstNode(enterApplyExitNodes, k, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if err := applyFirstNode(enterApplyExitNodes, k, v, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// enterFirstNode will Enter the first RDFNode that returns true or an error.
|
||||
func enterFirstNode(nodes []RDFNode, key string, ctx *ParsingContext) error {
|
||||
for _, node := range nodes {
|
||||
|
|
|
@ -28,9 +28,9 @@ func IsKeyApplicable(key, spec, alias, name string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// splitAlias splits a possibly-aliased string, without splitting on the colon
|
||||
// SplitAlias splits a possibly-aliased string, without splitting on the colon
|
||||
// if it is part of the http or https spec.
|
||||
func splitAlias(s string) []string {
|
||||
func SplitAlias(s string) []string {
|
||||
strs := strings.Split(s, ALIAS_DELIMITER)
|
||||
if len(strs) == 1 {
|
||||
return strs
|
||||
|
@ -46,6 +46,7 @@ func splitAlias(s string) []string {
|
|||
// for this ontology.
|
||||
type Ontology interface {
|
||||
// SpecURI refers to the URI location of this ontology.
|
||||
// TODO: Handle both http and https.
|
||||
SpecURI() string
|
||||
|
||||
// The Load methods deal with determining how best to apply an ontology
|
||||
|
@ -171,7 +172,7 @@ func (r *RDFRegistry) getForAliased(alias, s string) (n []RDFNode, e error) {
|
|||
//
|
||||
// Package public.
|
||||
func (r *RDFRegistry) getAliased(alias, s string) (n []RDFNode, e error) {
|
||||
strs := splitAlias(s)
|
||||
strs := SplitAlias(s)
|
||||
if len(strs) == 1 {
|
||||
if e = r.setAlias(alias, s); e != nil {
|
||||
return
|
||||
|
@ -205,7 +206,7 @@ func (r *RDFRegistry) getAliasedObject(alias string, object map[string]interface
|
|||
e = fmt.Errorf("element in getAliasedObject must be a string")
|
||||
return
|
||||
} else {
|
||||
strs := splitAlias(element)
|
||||
strs := SplitAlias(element)
|
||||
if len(strs) == 1 {
|
||||
n, e = r.getFor(strs[0])
|
||||
} else if len(strs) == 2 {
|
||||
|
@ -228,7 +229,7 @@ func (r *RDFRegistry) getAliasedObject(alias string, object map[string]interface
|
|||
//
|
||||
// Package public.
|
||||
func (r *RDFRegistry) getNode(s string) (n RDFNode, e error) {
|
||||
strs := splitAlias(s)
|
||||
strs := SplitAlias(s)
|
||||
if len(strs) == 2 {
|
||||
if ontName, ok := r.aliases[strs[0]]; !ok {
|
||||
e = fmt.Errorf("no alias to ontology for %s", strs[0])
|
||||
|
|
|
@ -6,22 +6,95 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
rdfsSpecURI = "http://www.w3.org/2000/01/rdf-schema#"
|
||||
commentSpec = "comment"
|
||||
domainSpec = "domain"
|
||||
isDefinedBySpec = "isDefinedBy"
|
||||
rangeSpec = "range"
|
||||
subClassOfSpec = "subClassOf"
|
||||
subPropertyOfSpec = "subPropertyOf"
|
||||
)
|
||||
|
||||
type RDFSchemaOntology struct{}
|
||||
|
||||
func (o *RDFSchemaOntology) SpecURI() string {
|
||||
return "http://www.w3.org/2000/01/rdf-schema#"
|
||||
return rdfsSpecURI
|
||||
}
|
||||
|
||||
func (o *RDFSchemaOntology) Load() ([]rdf.RDFNode, error) {
|
||||
return nil, nil
|
||||
return o.LoadAsAlias("")
|
||||
}
|
||||
|
||||
func (o *RDFSchemaOntology) LoadAsAlias(s string) ([]rdf.RDFNode, error) {
|
||||
return nil, nil
|
||||
return []rdf.RDFNode{
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: rdfsSpecURI,
|
||||
Alias: s,
|
||||
Name: commentSpec,
|
||||
Delegate: &comment{},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (o *RDFSchemaOntology) LoadSpecificAsAlias(alias, name string) ([]rdf.RDFNode, error) {
|
||||
return nil, nil
|
||||
switch name {
|
||||
case commentSpec:
|
||||
return []rdf.RDFNode{
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: "",
|
||||
Alias: "",
|
||||
Name: alias,
|
||||
Delegate: &comment{},
|
||||
},
|
||||
}, nil
|
||||
case domainSpec:
|
||||
return []rdf.RDFNode{
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: "",
|
||||
Alias: "",
|
||||
Name: alias,
|
||||
Delegate: &domain{},
|
||||
},
|
||||
}, nil
|
||||
case isDefinedBySpec:
|
||||
return []rdf.RDFNode{
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: "",
|
||||
Alias: "",
|
||||
Name: alias,
|
||||
Delegate: &isDefinedBy{},
|
||||
},
|
||||
}, nil
|
||||
case rangeSpec:
|
||||
return []rdf.RDFNode{
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: "",
|
||||
Alias: "",
|
||||
Name: alias,
|
||||
Delegate: &ranges{},
|
||||
},
|
||||
}, nil
|
||||
case subClassOfSpec:
|
||||
return []rdf.RDFNode{
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: "",
|
||||
Alias: "",
|
||||
Name: alias,
|
||||
Delegate: &subClassOf{},
|
||||
},
|
||||
}, nil
|
||||
case subPropertyOfSpec:
|
||||
return []rdf.RDFNode{
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: "",
|
||||
Alias: "",
|
||||
Name: alias,
|
||||
Delegate: &comment{},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("rdfs ontology cannot find %q to alias to %q", name, alias)
|
||||
}
|
||||
|
||||
func (o *RDFSchemaOntology) LoadElement(name string, payload map[string]interface{}) ([]rdf.RDFNode, error) {
|
||||
|
@ -31,7 +104,151 @@ func (o *RDFSchemaOntology) LoadElement(name string, payload map[string]interfac
|
|||
func (o *RDFSchemaOntology) GetByName(name string) (rdf.RDFNode, error) {
|
||||
name = strings.TrimPrefix(name, o.SpecURI())
|
||||
switch name {
|
||||
// TODO
|
||||
case commentSpec:
|
||||
return &comment{}, nil
|
||||
case domainSpec:
|
||||
return &domain{}, nil
|
||||
case isDefinedBySpec:
|
||||
return &isDefinedBy{}, nil
|
||||
case rangeSpec:
|
||||
return &ranges{}, nil
|
||||
case subClassOfSpec:
|
||||
return &subClassOf{}, nil
|
||||
case subPropertyOfSpec:
|
||||
return &subPropertyOf{}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("rdfs ontology could not find node for name %s", name)
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &comment{}
|
||||
|
||||
type comment struct{}
|
||||
|
||||
func (n *comment) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("rdfs comment cannot be entered")
|
||||
}
|
||||
|
||||
func (n *comment) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("rdfs comment cannot be exited")
|
||||
}
|
||||
|
||||
func (n *comment) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
note, ok := value.(string)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("rdf comment not given string value")
|
||||
}
|
||||
if ctx.Current == nil {
|
||||
return true, fmt.Errorf("rdf comment given nil Current")
|
||||
}
|
||||
noteSetter, ok := ctx.Current.(rdf.NotesSetter)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("rdf comment not given NotesSetter")
|
||||
}
|
||||
noteSetter.SetNotes(note)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &domain{}
|
||||
|
||||
type domain struct{}
|
||||
|
||||
func (d *domain) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (d *domain) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (d *domain) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &isDefinedBy{}
|
||||
|
||||
type isDefinedBy struct{}
|
||||
|
||||
func (i *isDefinedBy) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (i *isDefinedBy) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (i *isDefinedBy) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &ranges{}
|
||||
|
||||
type ranges struct{}
|
||||
|
||||
func (r *ranges) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (r *ranges) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (r *ranges) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &subClassOf{}
|
||||
|
||||
type subClassOf struct{}
|
||||
|
||||
func (s *subClassOf) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
ctx.Push()
|
||||
ctx.Current = &rdf.VocabularyReference{}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *subClassOf) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
i := ctx.Current
|
||||
ctx.Pop()
|
||||
vr, ok := i.(*rdf.VocabularyReference)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("rdfs subclassof exit did not get *rdf.VocabularyReference")
|
||||
}
|
||||
vt, ok := ctx.Current.(*rdf.VocabularyType)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("rdf subclassof exit Current is not *rdf.VocabularyType")
|
||||
}
|
||||
vt.Extends = append(vt.Extends, *vr)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *subClassOf) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("rdfs subclassof cannot be applied")
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &subPropertyOf{}
|
||||
|
||||
type subPropertyOf struct{}
|
||||
|
||||
func (s *subPropertyOf) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *subPropertyOf) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *subPropertyOf) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -7,11 +7,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
schemaSpec = "http://schema.org/"
|
||||
exampleSpec = "workExample"
|
||||
mainEntitySpec = "mainEntity"
|
||||
urlSpec = "URL"
|
||||
nameSpec = "name"
|
||||
schemaSpec = "http://schema.org/"
|
||||
exampleSpec = "workExample"
|
||||
mainEntitySpec = "mainEntity"
|
||||
urlSpec = "URL"
|
||||
nameSpec = "name"
|
||||
creativeWorkSpec = "CreativeWork"
|
||||
)
|
||||
|
||||
type SchemaOntology struct{}
|
||||
|
@ -50,6 +51,12 @@ func (o *SchemaOntology) LoadAsAlias(s string) ([]rdf.RDFNode, error) {
|
|||
Name: nameSpec,
|
||||
Delegate: &name{},
|
||||
},
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: schemaSpec,
|
||||
Alias: s,
|
||||
Name: creativeWorkSpec,
|
||||
Delegate: &creativeWork{},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -91,6 +98,15 @@ func (o *SchemaOntology) LoadSpecificAsAlias(alias, n string) ([]rdf.RDFNode, er
|
|||
Delegate: &name{},
|
||||
},
|
||||
}, nil
|
||||
case creativeWorkSpec:
|
||||
return []rdf.RDFNode{
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: "",
|
||||
Alias: "",
|
||||
Name: alias,
|
||||
Delegate: &creativeWork{},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("schema ontology cannot find %q to alias to %q", n, alias)
|
||||
}
|
||||
|
@ -99,12 +115,21 @@ func (o *SchemaOntology) LoadElement(name string, payload map[string]interface{}
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (o *SchemaOntology) GetByName(name string) (rdf.RDFNode, error) {
|
||||
name = strings.TrimPrefix(name, o.SpecURI())
|
||||
switch name {
|
||||
// TODO
|
||||
func (o *SchemaOntology) GetByName(n string) (rdf.RDFNode, error) {
|
||||
n = strings.TrimPrefix(n, o.SpecURI())
|
||||
switch n {
|
||||
case exampleSpec:
|
||||
return &example{}, nil
|
||||
case mainEntitySpec:
|
||||
return &mainEntity{}, nil
|
||||
case urlSpec:
|
||||
return &url{}, nil
|
||||
case nameSpec:
|
||||
return &name{}, nil
|
||||
case creativeWorkSpec:
|
||||
return &creativeWork{}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("schema ontology could not find node for name %s", name)
|
||||
return nil, fmt.Errorf("schema ontology could not find node for name %s", n)
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &example{}
|
||||
|
@ -205,6 +230,24 @@ func (n *name) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bo
|
|||
return true, fmt.Errorf("schema name not given NameSetter in context")
|
||||
} else {
|
||||
ns.SetName(s)
|
||||
ctx.Name = s
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &creativeWork{}
|
||||
|
||||
type creativeWork struct{}
|
||||
|
||||
func (c *creativeWork) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("schema creative work cannot be entered")
|
||||
}
|
||||
|
||||
func (c *creativeWork) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("schema creative work cannot be exited")
|
||||
}
|
||||
|
||||
func (c *creativeWork) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// Do nothing -- should already be an example.
|
||||
return true, nil
|
||||
}
|
||||
|
|
読み込み中…
新しいイシューから参照