https://github.com/google/cayley
Raw File
Tip revision: 1bd4885c3ca568d580b73046a34bcb43add524e5 authored by sah607 on 21 September 2017, 21:04:29 UTC
Merge branch 'master' of https://github.com/michaelqiu94/cayley
Tip revision: 1bd4885
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)
}
back to top