// Copyright 2024 Matthew Rich . 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) }