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;
019
020import dev.enola.common.string2long.StringToLongBiMap;
021import dev.enola.thing.proto.Value.Literal;
022
023/**
024 * Java constants for some "well-known" IRIs used in Enola's code. This is NOT a list of all
025 * possible such IRIs, because that's by definition an open set. This is merely for convenient use
026 * in code.
027 */
028public final class KIRI {
029    // TODO Use HasPredicateIRI enums instead, see dev.enola.model.w3.rdfs.IRI
030    // TODO This class should eventually disappear from package dev.enola.thing,
031    //   because it will #later be generated from RDFS into dev.enola.models.*
032
033    // The JavaDoc of this class must currently be manually kept in sync with
034    // the same content that's also in the //models/enola.dev/properties.ttl file.
035    // (We could theoretically build something like https://github.com/ansell/rdf4j-schema-generator
036    // into Enola to automate that; but it's probably not really worth it.)
037
038    // TODO Make all of these actually resolvable in Enola! (Just for documentation look-up.)
039    // by (built-in?!) loading //models/enola.dev/properties.ttl from classpath at start-up
040
041    // TODO LDP? https://rdf4j.org/javadoc/latest/org/eclipse/rdf4j/model/vocabulary/LDP.html
042
043    /** Enola.dev's very own! */
044    // NB: Should the constant values ever change, update //models/enola.dev/properties.ttl
045    public static final class E {
046        private static final String NS = "https://enola.dev/";
047
048        // TODO Change to e.g. https://enola.dev/ql/all?inline=true&limit=7
049        // TODO "enola:/?inline" would be nicer than "enola:/inline" but fails to match
050        public static final String LIST_THINGS = "enola:/inline";
051        public static final String LIST_IRIS = "enola:/";
052
053        // https://docs.enola.dev/concepts/metadata/
054        public static final String LABEL = NS + "label";
055        public static final String DESCRIPTION = NS + "description";
056
057        /**
058         * Emoji 😃 of a Thing, from Unicode or <a href="https://www.nerdfonts.com">Nerdfonts</a>.
059         *
060         * <p>Often used as an alternative to {@link KIRI.SCHEMA#IMG}, and (either) is often shown
061         * as prefix to the label in UIs.
062         */
063        public static final String EMOJI = NS + "emoji";
064
065        public static final String MEDIA_TYPE = NS + "mediaType";
066
067        /**
068         * URI of what something is 'based on', e.g. where it 'comes from' (source), such as where
069         * e.g. a Thing was originally "loaded" from. This may be a list.
070         *
071         * <p>TODO: Is there some existing standard vocabulary for this?
072         * https://www.w3.org/TR/prov-overview/, perhaps? Seems complicated.
073         */
074        public static final String ORIGIN = NS + "origin";
075
076        public static final String PARENT = NS + "parent";
077
078        /** Name (not URL/URI/IRI) of something. */
079        public static final String NAME = NS + "name";
080
081        public static final String IRI_TEMPLATE_PROPERTY = NS + "iriTemplate";
082        public static final String IRI_TEMPLATE_DATATYPE = NS + "IRITemplate";
083        public static final String LABEL_PROPERTY = NS + "labelProperty";
084
085        // Special
086        public static final String UNKNOWN_CLASS = NS + "UnknownClass"; // TODO UnknownClass.IRI
087
088        // Style-related stuff...
089        public static final String COLOR = NS + "color";
090        public static final String TEXT_COLOR = NS + "text-color";
091
092        // TODO Add meta.ttl to document https://enola.dev/meta/...
093        public static final class META {
094            private static final String NS = "https://enola.dev/meta/";
095
096            public static final String ID = NS + "id";
097            public static final String XSD = NS + "xsd";
098            public static final String JAVA = NS + "java";
099            public static final String PROTO = NS + "proto";
100            public static final String SCHEMA = NS + "schema";
101            public static final String SCHEMA_PROPERTIES = NS + "schemaProperties";
102            public static final String SCHEMA_CLASSES = NS + "schemaClasses";
103            public static final String PARENTS = NS + "parents";
104            public static final String DATATYPE = NS + "datatype";
105            public static final String DATATYPES = NS + "datatypes";
106            public static final String CLASS_PROPERTIES = NS + "classProperties";
107            public static final String CLASS_ID_PROPERTIES = NS + "classIdProperties";
108            public static final String IRI_TEMPLATE = NS + "iriTemplate";
109            // TODO public static final String MULTIPLICITY = NS + "multiplicity";
110        }
111
112        // See binary.ttl & https://github.com/multiformats/multibase/issues/133
113        public static final String BINARY = "https://multiformats.io/multibaseBinary";
114    }
115
116    /** Schema.org Properties. */
117    public static final class SCHEMA {
118        private static final String NS = "https://schema.org/";
119
120        /**
121         * IRI which identifies 🆔 a Thing, see https://schema.org/identifier. This is a "logical"
122         * identity, and may or may not be an URL.
123         */
124        // TODO This is technically not always an IRI... so make it E.GUN, instead!
125        public static final String ID = NS + "identifier";
126
127        /**
128         * Text with human-readable name (AKA "label" 🏷️) of a Thing, see https://schema.org/name.
129         */
130        public static final String NAME = NS + "name";
131
132        /**
133         * Text with human-readable 📜 description of a Thing, see https://schema.org/description.
134         *
135         * <p>Typically length is a sentence or single paragraph.
136         */
137        public static final String DESC = NS + "description";
138
139        /** An abstract is a short description that summarizes a CreativeWork. */
140        public static final String ABSTRACT = NS + "abstract";
141
142        /**
143         * URL of an 🖼️ image of the Thing, see https://schema.org/image.
144         *
145         * <p>Perhaps e.g. a logo or favicon or something like that. Alternatively use {@link
146         * KIRI.E#EMOJI}.
147         */
148        public static final String IMG = NS + "image";
149
150        public static final String THUMBNAIL_URL = NS + "thumbnailUrl";
151
152        public static final String LOGO = NS + "logo";
153
154        /**
155         * IRI of Property for URL 🔗 of the Thing, see https://schema.org/url. You *CAN* always
156         * http GET an URL. This is NOT the same as a logical URI/IRI, and thus not be to confused
157         * with the {@link #ID}. One example of this could be e.g. its use in Thing "metadata" about
158         * a file: URL; this would point to the actual file itself.
159         */
160        public static final String URL = NS + "url";
161
162        /** IRI of URL Datatype. Used to mark properties which are links to webpages. */
163        public static final String URL_DATATYPE = NS + "URL";
164
165        /**
166         * IRI of a Thing which is "the 🪞 same as this one", see https://schema.org/sameAs. For
167         * example, the URL of a Wikipedia article about it.
168         */
169        public static final String SAMEAS = NS + "sameAs";
170
171        private SCHEMA() {}
172    }
173
174    /** Dublin Core */
175    public static final class DC {
176        private static final String NS = "http://purl.org/dc/elements/1.1/";
177
178        public static final String TITLE = NS + "title";
179        public static final String DESCRIPTION = NS + "description";
180
181        public static final String CREATOR = NS + "creator";
182        public static final String LANGUAGE = NS + "language";
183
184        private DC() {}
185    }
186
187    public static final class RDF {
188        private static final String NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
189
190        /**
191         * IRI of the Type :information_source: 🛈 of a Thing; see
192         * https://www.w3.org/TR/rdf-schema/#ch_type.
193         */
194        public static final String TYPE = NS + "type";
195
196        public static final String PROPERTY = NS + "Property";
197
198        public static final String LANGSTRING = NS + "langString";
199        public static final String LANGUAGE = NS + "language";
200        public static final String DIRECTION = NS + "direction";
201
202        /** 📃 */
203        public static final String HTML = NS + "HTML";
204
205        public static final String JSON = NS + "JSON";
206
207        private RDF() {}
208    }
209
210    public static final class RDFS {
211        private static final String NS = "http://www.w3.org/2000/01/rdf-schema#";
212
213        /** https://www.w3.org/TR/rdf-schema/#ch_class */
214        public static final String CLASS = NS + "Class";
215
216        /** https://www.w3.org/TR/rdf-schema/#ch_label */
217        public static final String LABEL = NS + "label";
218
219        /** https://www.w3.org/TR/rdf-schema/#ch_comment */
220        public static final String COMMENT = NS + "comment";
221
222        /** https://www.w3.org/TR/rdf-schema/#ch_domain */
223        public static final String DOMAIN = NS + "domain";
224
225        /** https://www.w3.org/TR/rdf-schema/#ch_range */
226        public static final String RANGE = NS + "range";
227
228        private RDFS() {}
229    }
230
231    /**
232     * XML Schema's built-in datatypes. These are used as Things' Literal's Datatypes in {@link
233     * Literal#getDatatype()}. See <a href="https://www.w3.org/TR/rdf11-concepts/#xsd-datatypes">RDF
234     * 1.1 Concepts XSD datatypes</a>, based (of course) on the <a
235     * href="https://www.w3.org/TR/xmlschema11-2/">XML Schema 1.1 datatypes</a>.
236     */
237    public static final class XSD {
238        private static final String NS = "http://www.w3.org/2001/XMLSchema#";
239
240        public static final String STRING = NS + "string";
241        public static final String IRI = NS + "anyURI";
242        public static final String BOOL = NS + "boolean";
243
244        public static final String DOUBLE = NS + "double";
245        public static final String FLOAT = NS + "float";
246
247        public static final String INT32 = NS + "int";
248        public static final String INT64 = NS + "long";
249        public static final String UINT64 = NS + "unsignedLong";
250        public static final String UINT32 = NS + "unsignedInt";
251
252        public static final String BIN64 = NS + "base64Binary";
253
254        public static final String TS = NS + "dateTime";
255
256        private XSD() {}
257    }
258
259    // TODO Move this to somewhere else...
260    public void initialize(StringToLongBiMap.Builder iriToLongBiMap) {
261        iriToLongBiMap.put(""); // 0
262        iriToLongBiMap.put(RDF.TYPE); // 1
263        iriToLongBiMap.put(RDF.LANGSTRING);
264        iriToLongBiMap.put(RDF.JSON);
265        iriToLongBiMap.put(RDF.HTML);
266        iriToLongBiMap.put(RDF.PROPERTY);
267        iriToLongBiMap.put(RDFS.CLASS);
268        iriToLongBiMap.put(RDFS.DOMAIN);
269        iriToLongBiMap.put(RDFS.RANGE);
270        iriToLongBiMap.put(RDFS.LABEL);
271        iriToLongBiMap.put(RDFS.COMMENT);
272        iriToLongBiMap.put(XSD.STRING);
273        iriToLongBiMap.put(XSD.BOOL);
274        iriToLongBiMap.put(XSD.INT32);
275        iriToLongBiMap.put(XSD.UINT32);
276        iriToLongBiMap.put(XSD.INT64);
277        iriToLongBiMap.put(XSD.UINT64);
278        iriToLongBiMap.put(XSD.DOUBLE);
279        iriToLongBiMap.put(XSD.FLOAT);
280        iriToLongBiMap.put(XSD.TS);
281        iriToLongBiMap.put(XSD.IRI);
282        iriToLongBiMap.put(XSD.BIN64);
283        iriToLongBiMap.put(E.EMOJI);
284        iriToLongBiMap.put(E.LABEL);
285        iriToLongBiMap.put(E.DESCRIPTION);
286        iriToLongBiMap.put(E.ORIGIN);
287        iriToLongBiMap.put(E.COLOR);
288        iriToLongBiMap.put(E.TEXT_COLOR);
289        iriToLongBiMap.put(E.LABEL_PROPERTY);
290        iriToLongBiMap.put(E.IRI_TEMPLATE_PROPERTY);
291        iriToLongBiMap.put(E.IRI_TEMPLATE_DATATYPE);
292        iriToLongBiMap.put(E.UNKNOWN_CLASS);
293    }
294
295    private KIRI() {}
296}