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.model.w3.rdf;
019
020import com.google.errorprone.annotations.CanIgnoreReturnValue;
021
022import dev.enola.model.w3.rdfs.Class;
023import dev.enola.model.w3.rdfs.Resource;
024import dev.enola.thing.HasPredicateIRI;
025import dev.enola.thing.KIRI;
026import dev.enola.thing.Link;
027import dev.enola.thing.impl.ImmutableThing;
028import dev.enola.thing.java.ProxyTBF;
029import dev.enola.thing.java.RdfClass;
030
031import java.util.Optional;
032
033@RdfClass(iri = KIRI.RDFS.CLASS)
034// Nota bene: The rdf:class (@type) of a Property is Class, not Property!!
035public interface Property extends Resource, HasPredicateIRI {
036
037    default Optional<Property> subPropertyOf() {
038        return getThing(
039                "http://www.w3.org/2000/01/rdf-schema#subPropertyOf",
040                Property.class,
041                Property.Builder.class);
042    }
043
044    /**
045     * <a href="https://www.w3.org/TR/rdf12-schema/#ch_domain">Domains</a> of this property.
046     *
047     * <p>Beware that, if more than one, then this means intersection, not union; see <a
048     * href="https://g.co/gemini/share/1ec30662b500">this explanation</a>.
049     */
050    default Iterable<Class> domains() {
051        return getThings(KIRI.RDFS.DOMAIN, Class.class, Class.Builder.class);
052    }
053
054    /**
055     * <a href="https://www.w3.org/TR/rdf12-schema/#ch_range">Domains</a> of this property.
056     *
057     * <p>Beware that, if more than one, then this means intersection, not union; see <a
058     * href="https://g.co/gemini/share/1ec30662b500">this explanation</a>.
059     */
060    default Iterable<Class> ranges() {
061        return getThings(KIRI.RDFS.RANGE, Class.class, Class.Builder.class);
062    }
063
064    @Override
065    Builder<? extends Property> copy();
066
067    // skipcq: JAVA-E0169
068    interface Builder<B extends Property> extends Resource.Builder<B> {
069
070        @CanIgnoreReturnValue
071        default Builder<B> domain(String iri) {
072            set(KIRI.RDFS.DOMAIN, new Link(iri));
073            return this;
074        }
075
076        @CanIgnoreReturnValue
077        default Builder<B> range(String iri) {
078            set(KIRI.RDFS.RANGE, new Link(iri));
079            return this;
080        }
081
082        @Override
083        @CanIgnoreReturnValue
084        Builder<B> iri(String iri);
085    }
086
087    @SuppressWarnings("unchecked")
088    static Property.Builder<Property> builder() {
089        return new ProxyTBF(ImmutableThing.FACTORY).create(Builder.class, Property.class);
090    }
091}