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.impl;
019
020import com.google.common.collect.ImmutableMap;
021import com.google.common.collect.ImmutableSet;
022import com.google.errorprone.annotations.Immutable;
023import com.google.errorprone.annotations.ThreadSafe;
024
025import dev.enola.thing.PredicatesObjects;
026
027import org.jspecify.annotations.Nullable;
028
029@Immutable
030@ThreadSafe
031// TODO Make ImmutablePredicatesObjects package private, and let users create them via the TBF (?)
032public class ImmutablePredicatesObjects implements IImmutablePredicatesObjects {
033
034    @SuppressWarnings("Immutable")
035    // Immutability of Objects is guaranteed by @ImmutableTypeParameter in PredicatesObjects.Builder
036    protected final ImmutableMap<String, Object> properties;
037
038    protected final ImmutableMap<String, String> datatypes;
039
040    protected ImmutablePredicatesObjects(
041            ImmutableMap<String, Object> properties, ImmutableMap<String, String> datatypes) {
042        this.properties = properties;
043        this.datatypes = datatypes;
044    }
045
046    public static <T extends IImmutablePredicatesObjects>
047            IImmutablePredicatesObjects.Builder<T> builder() {
048        return new MutablePredicatesObjectsBuilder<>();
049    }
050
051    public static PredicatesObjects.Builder<? extends IImmutablePredicatesObjects>
052            builderWithExpectedSize(int expectedSize) {
053        return new MutablePredicatesObjectsBuilder<>(expectedSize);
054    }
055
056    @Override
057    public ImmutableMap<String, Object> properties() {
058        return properties;
059    }
060
061    @Override
062    public ImmutableSet<String> predicateIRIs() {
063        return properties.keySet();
064    }
065
066    @Override
067    @SuppressWarnings("unchecked")
068    public <T> @Nullable T get(String predicateIRI) {
069        return (T) properties.get(predicateIRI);
070    }
071
072    @Override
073    public ImmutableMap<String, String> datatypes() {
074        return datatypes;
075    }
076
077    @Override
078    public @Nullable String datatype(String predicateIRI) {
079        return datatypes.get(predicateIRI);
080    }
081
082    @Override
083    public boolean equals(Object obj) {
084        return ThingHashCodeEqualsToString.equals(this, obj);
085    }
086
087    @Override
088    public int hashCode() {
089        return ThingHashCodeEqualsToString.hashCode(this);
090    }
091
092    @Override
093    public String toString() {
094        return ThingHashCodeEqualsToString.toString(this, properties, datatypes);
095    }
096
097    @Override
098    public PredicatesObjects.Builder<? extends IImmutablePredicatesObjects> copy() {
099        return new MutablePredicatesObjectsBuilder<>(properties(), datatypes());
100    }
101}