001/* 002 * SPDX-License-Identifier: Apache-2.0 003 * 004 * Copyright 2024-2026 The Enola <https://enola.dev> Authors 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package dev.enola.thing.namespace; 019 020import dev.enola.data.iri.namespace.repo.CachingNamespaceRepository; 021import dev.enola.data.iri.namespace.repo.ImmutableNamespace; 022import dev.enola.data.iri.namespace.repo.Namespace; 023import dev.enola.data.iri.namespace.repo.NamespaceRepository; 024import dev.enola.thing.PredicatesObjects; 025import dev.enola.thing.repo.ThingProvider; 026 027import org.jspecify.annotations.Nullable; 028 029import java.util.Collections; 030import java.util.Optional; 031 032/** 033 * {@link NamespaceRepository} based on reading {@link #ACTIVE_NAMESPACES_IRI} from a {@link 034 * ThingProvider}. 035 * 036 * <p>This is (much!) slower than the {@link 037 * dev.enola.data.iri.namespace.repo.NamespaceRepositoryEnolaDefaults#INSTANCE}, and should only 038 * ever be used indirectly through {@link CachingNamespaceRepository}. 039 * 040 * @param thingProvider the provider of things used to retrieve namespace information 041 */ 042public record ThingNamespaceRepository(ThingProvider thingProvider) implements NamespaceRepository { 043 044 public static final String ACTIVE_NAMESPACES_IRI = "https://enola.dev/namespaces"; 045 046 public ThingNamespaceRepository() { 047 this(ThingProvider.CTX); 048 } 049 050 @Override 051 public @Nullable Namespace get(String iri) { 052 return thingProvider 053 .getOptional(ACTIVE_NAMESPACES_IRI) 054 .flatMap( 055 ns -> 056 ns.getOptional(iri, String.class) 057 .map(prefix -> new ImmutableNamespace(prefix, iri))) 058 .orElse(null); 059 } 060 061 @Override 062 public Optional<String> getIRI(String prefix) { 063 var optNamespaces = thingProvider.getOptional(ACTIVE_NAMESPACES_IRI); 064 if (optNamespaces.isEmpty()) return Optional.empty(); 065 var namespaces = optNamespaces.get(); 066 // TODO Replace with ThingVisitor, when available. 067 for (var iri : namespaces.predicateIRIs()) { 068 var object = namespaces.get(iri); 069 if (prefix.equals(object)) return Optional.of(iri); 070 } 071 return Optional.empty(); 072 } 073 074 @Override 075 public Iterable<String> listIRI() { 076 return thingProvider 077 .getOptional(ACTIVE_NAMESPACES_IRI) 078 .map(PredicatesObjects::predicateIRIs) 079 .orElse(Collections.emptySet()); 080 } 081}