Revision 2bbb310544293fd977c454eaf0ce48c995bcc095 authored by Denys Smirnov on 08 February 2019, 22:09:34 UTC, committed by Denys Smirnov on 08 February 2019, 22:09:34 UTC
1 parent 807b7b8
voc.go
// Package voc implements an RDF namespace (vocabulary) registry.
package voc
import (
"strings"
"sync"
)
// Namespace is a RDF namespace (vocabulary).
type Namespace struct {
Full string
Prefix string
}
type ByFullName []Namespace
func (o ByFullName) Len() int { return len(o) }
func (o ByFullName) Less(i, j int) bool { return o[i].Full < o[j].Full }
func (o ByFullName) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
// Namespaces is a set of registered namespaces.
type Namespaces struct {
Safe bool // if set, assume no locking is required
mu sync.RWMutex
prefixes map[string]string
}
// Register adds namespace to registered list.
func (p *Namespaces) Register(ns Namespace) {
if !p.Safe {
p.mu.Lock()
defer p.mu.Unlock()
}
if p.prefixes == nil {
p.prefixes = make(map[string]string)
}
p.prefixes[ns.Prefix] = ns.Full
}
// ShortIRI replaces a base IRI of a known vocabulary with it's prefix.
//
// ShortIRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type") // returns "rdf:type"
func (p *Namespaces) ShortIRI(iri string) string {
if !p.Safe {
p.mu.RLock()
defer p.mu.RUnlock()
}
for pref, ns := range p.prefixes {
if strings.HasPrefix(iri, ns) {
return pref + iri[len(ns):]
}
}
return iri
}
// FullIRI replaces known prefix in IRI with it's full vocabulary IRI.
//
// FullIRI("rdf:type") // returns "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
func (p *Namespaces) FullIRI(iri string) string {
if !p.Safe {
p.mu.RLock()
defer p.mu.RUnlock()
}
for pref, ns := range p.prefixes {
if strings.HasPrefix(iri, pref) {
return ns + iri[len(pref):]
}
}
return iri
}
// List enumerates all registered namespace pairs.
func (p *Namespaces) List() (out []Namespace) {
if !p.Safe {
p.mu.RLock()
defer p.mu.RUnlock()
}
out = make([]Namespace, 0, len(p.prefixes))
for pref, ns := range p.prefixes {
out = append(out, Namespace{Prefix: pref, Full: ns})
}
return
}
// Clone makes a copy of namespaces list.
func (p *Namespaces) Clone() *Namespaces {
if !p.Safe {
p.mu.RLock()
defer p.mu.RUnlock()
}
p2 := Namespaces{
prefixes: make(map[string]string, len(p.prefixes)),
}
for pref, ns := range p.prefixes {
p2.prefixes[pref] = ns
}
return &p2
}
// CloneTo adds registered namespaces to a given list.
func (p *Namespaces) CloneTo(p2 *Namespaces) {
if p == p2 {
return
}
if !p.Safe {
p.mu.RLock()
defer p.mu.RUnlock()
}
if !p2.Safe {
p2.mu.Lock()
defer p2.mu.Unlock()
}
if p2.prefixes == nil {
p2.prefixes = make(map[string]string, len(p.prefixes))
}
for pref, ns := range p.prefixes {
p2.prefixes[pref] = ns
}
}
var global Namespaces
// Register adds namespace to a global registered list.
func Register(ns Namespace) {
global.Register(ns)
}
// RegisterPrefix globally associates a given prefix with a base vocabulary IRI.
func RegisterPrefix(pref string, ns string) {
Register(Namespace{Prefix: pref, Full: ns})
}
// ShortIRI replaces a base IRI of a known vocabulary with it's prefix.
//
// ShortIRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type") // returns "rdf:type"
func ShortIRI(iri string) string {
return global.ShortIRI(iri)
}
// FullIRI replaces known prefix in IRI with it's full vocabulary IRI.
//
// FullIRI("rdf:type") // returns "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
func FullIRI(iri string) string {
return global.FullIRI(iri)
}
// List enumerates all registered namespace pairs.
func List() []Namespace {
return global.List()
}
// Clone makes a copy of global namespaces list.
func Clone() *Namespaces {
return global.Clone()
}
// CloneTo adds all global namespaces to a given list.
func CloneTo(p *Namespaces) {
global.CloneTo(p)
}
Computing file changes ...