151 lines
4.8 KiB
Go
151 lines
4.8 KiB
Go
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
|
|
|
package folio
|
|
|
|
import (
|
|
_ "errors"
|
|
_ "fmt"
|
|
"net/url"
|
|
_ "strings"
|
|
"decl/internal/types"
|
|
"decl/internal/data"
|
|
"decl/internal/mapper"
|
|
"io/fs"
|
|
"log/slog"
|
|
)
|
|
|
|
var (
|
|
)
|
|
|
|
type Registry struct {
|
|
Schemas mapper.Store[URI, fs.FS]
|
|
ConfigurationTypes *types.Types[data.Configuration] // Config Factory
|
|
ResourceTypes *types.Types[data.Resource] // Resource Factory
|
|
ConverterTypes *types.Types[data.Converter] // Converter Factory
|
|
Documents []*Document
|
|
UriMap mapper.Store[URI, *Document]
|
|
DeclarationMap mapper.Store[*Declaration, *Document]
|
|
ConfigNameMap mapper.Store[string, *Block]
|
|
ConfigurationMap mapper.Store[*Block, *Document]
|
|
DefaultSchema URI
|
|
}
|
|
|
|
func NewRegistry() *Registry {
|
|
r := &Registry{
|
|
ConfigurationTypes: types.New[data.Configuration](),
|
|
ResourceTypes: types.New[data.Resource](),
|
|
ConverterTypes: types.New[data.Converter](),
|
|
Documents: make([]*Document, 0, 10),
|
|
UriMap: mapper.New[URI, *Document](),
|
|
DeclarationMap: mapper.New[*Declaration, *Document](),
|
|
ConfigNameMap: mapper.New[string, *Block](),
|
|
ConfigurationMap: mapper.New[*Block, *Document](),
|
|
Schemas: mapper.New[URI, fs.FS](),
|
|
DefaultSchema: schemaFilesUri,
|
|
}
|
|
r.Schemas[schemaFilesUri] = schemaFiles
|
|
return r
|
|
}
|
|
|
|
func (r *Registry) Get(key *Declaration) (*Document, bool) {
|
|
return r.DeclarationMap.Get(key)
|
|
}
|
|
|
|
func (r *Registry) Has(key *Declaration) (bool) {
|
|
return r.DeclarationMap.Has(key)
|
|
}
|
|
|
|
func (r *Registry) HasDocument(key URI) bool {
|
|
return r.UriMap.Has(key)
|
|
}
|
|
|
|
func (r *Registry) GetDocument(key URI) (*Document, bool) {
|
|
return r.UriMap.Get(key)
|
|
}
|
|
|
|
func (r *Registry) SetDocument(key URI, value *Document) {
|
|
r.UriMap.Set(key, value)
|
|
}
|
|
|
|
func (r *Registry) NewDocument(uri URI) (doc *Document) {
|
|
doc = NewDocument(r)
|
|
doc.URI = uri
|
|
r.Documents = append(r.Documents, doc)
|
|
if uri != "" {
|
|
r.UriMap[uri] = doc
|
|
}
|
|
return
|
|
}
|
|
|
|
func (r *Registry) AppendParsedURI(uri *url.URL, documents []data.Document) (addedDocuments []data.Document, err error) {
|
|
var convertUri data.Converter
|
|
var sourceResource data.Resource
|
|
|
|
slog.Info("folio.Registry.AppendParsedURI()", "uri", uri, "converter", r.ConverterTypes)
|
|
if convertUri, err = r.ConverterTypes.NewFromParsedURI(uri); err == nil {
|
|
if sourceResource, err = NewResourceFromParsedURI(uri, nil); err == nil {
|
|
switch extractor := convertUri.(type) {
|
|
case data.ManyExtractor:
|
|
var docs []data.Document
|
|
docs, err = extractor.ExtractMany(sourceResource, nil)
|
|
slog.Info("folio.Registry.AppendParsedURI() - ExtractMany", "uri", uri, "source", sourceResource, "docs", docs, "error", err)
|
|
documents = append(documents, docs...)
|
|
case data.Extractor:
|
|
var singleDocument data.Document
|
|
singleDocument, err = extractor.Extract(sourceResource, nil)
|
|
slog.Info("folio.Registry.AppendParsedURI() - Extract", "uri", uri, "source", sourceResource, "doc", singleDocument, "error", err)
|
|
documents = append(documents, singleDocument)
|
|
}
|
|
}
|
|
}
|
|
slog.Info("folio.Registry.AppendParsedURI()", "uri", uri, "converter", r.ConverterTypes, "error", err)
|
|
addedDocuments = documents
|
|
return
|
|
}
|
|
|
|
func (r *Registry) Append(uri URI, documents []data.Document) (addedDocuments []data.Document, err error) {
|
|
var convertUri data.Converter
|
|
var sourceResource data.Resource
|
|
|
|
if fileResource, ok := sourceResource.(data.FileResource); ok {
|
|
fileResource.SetGzipContent(true)
|
|
}
|
|
|
|
slog.Info("folio.Registry.Append()", "uri", uri, "converter", r.ConverterTypes)
|
|
|
|
convertUri, err = uri.Converter()
|
|
if err == nil {
|
|
|
|
slog.Info("folio.Registry.Append() Converter", "uri", uri, "converter", convertUri, "type", convertUri.Type(), "error", err)
|
|
if sourceResource, err = uri.NewResource(nil); err == nil {
|
|
switch extractor := convertUri.(type) {
|
|
case data.ManyExtractor:
|
|
var docs []data.Document
|
|
docs, err = extractor.ExtractMany(sourceResource, nil)
|
|
slog.Info("folio.Registry.Append() - ExtractMany", "uri", uri, "source", sourceResource, "docs", docs, "error", err)
|
|
documents = append(documents, docs...)
|
|
case data.Extractor:
|
|
var singleDocument data.Document
|
|
singleDocument, err = extractor.Extract(sourceResource, nil)
|
|
slog.Info("folio.Registry.Append() - Extract", "uri", uri, "source", sourceResource, "doc", singleDocument, "error", err)
|
|
documents = append(documents, singleDocument)
|
|
}
|
|
} else {
|
|
slog.Warn("folio.Registry.Append(): failed loading extractor as resource")
|
|
}
|
|
}
|
|
slog.Info("folio.Registry.Append()", "uri", uri, "converter", r.ConverterTypes, "error", err)
|
|
addedDocuments = documents
|
|
return
|
|
}
|
|
|
|
func (r *Registry) Load(uri URI) (documents []data.Document, err error) {
|
|
documents = make([]data.Document, 0, 10)
|
|
return r.Append(uri, documents)
|
|
}
|
|
|
|
func (r *Registry) LoadFromURL(uri *url.URL) (documents []data.Document, err error) {
|
|
documents = make([]data.Document, 0, 10)
|
|
return r.AppendParsedURI(uri, documents)
|
|
}
|