001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2014-2024 Open Geospatial Consortium, Inc.
004 *    http://www.geoapi.org
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 *        http://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 org.opengis.util;
019
020import java.util.Optional;
021
022
023/**
024 * Common interface of all {@linkplain Enum enumerations} and {@linkplain CodeList code lists} defined in GeoAPI.
025 * Enumerations are <em>closed</em> controlled vocabularies: it is not possible to add new members
026 * (except by releasing new versions of the library).
027 * By contrast, code lists are <em>open</em> vocabularies:
028 * they provide a basic set of members defined at compile-time,
029 * but users are free to add new members at runtime.
030 *
031 * @author  Martin Desruisseaux (Geomatys)
032 * @version 3.1
033 * @since   3.1
034 *
035 * @departure integration
036 *   Provided for allowing developers to handles {@code Enum} and {@code CodeList}
037 *   in the same way for some common tasks.
038 */
039public interface ControlledVocabulary {
040    /**
041     * Returns the name of this enumeration constant or code list value.
042     *
043     * @return the name of this enumeration constant or code list value.
044     */
045    String name();
046
047    /**
048     * Returns all the names of this constant. The returned array contains the
049     * following elements, with duplicated values and null values removed:
050     *
051     * <ul>
052     *   <li>The programmatic {@linkplain #name() name}</li>
053     *   <li>The UML {@linkplain #identifier() identifier}</li>
054     *   <li>Any other special case, if any. Examples:
055     *     <ul>
056     *       <li>The legacy name of {@link org.opengis.metadata.constraint.Restriction#LICENCE}.</li>
057     *       <li>American spelling such as "cell center" as an alternative to "cell centre".</li>
058     *     </ul>
059     *   </li>
060     * </ul>
061     *
062     * Those names are typically equal except for the case (programmatic names are upper case
063     * while UML names are lower case) and special characters like {@code '-'}.
064     *
065     * @return all names of this constant. This array is never null and never empty.
066     */
067    default String[] names() {
068        final String name = name();
069        final String id = identifier().orElse(null);
070        if (id != null && !id.equals(name)) {
071            return new String[] {name, id};
072        } else {
073            return new String[] {name};
074        }
075    }
076
077    /**
078     * Returns the identifier declared in the {@link org.opengis.annotation.UML} annotation.
079     * The UML identifier shall be the ISO or OGC name for this enumeration or code list constant.
080     *
081     * @return the ISO/OGC identifier for this constant.
082     */
083    default Optional<String> identifier() {
084        return Optional.empty();
085    }
086
087    /**
088     * Returns the ordinal of this constant. This is its position in its elements declaration,
089     * where the initial constant is assigned an ordinal of zero.
090     *
091     * @return the position of this constants in elements declaration.
092     */
093    int ordinal();
094
095    /**
096     * Returns the enumeration or list of codes of the same kind as this item.
097     * Invoking this method gives identical results than invoking the static {@code values()} methods
098     * provided in {@code Enum} and {@code CodeList} subclasses, except that {@code family()} does not
099     * require the class to be known at compile-time — provided that at leat one instance of the family
100     * is available.
101     *
102     * @return the enumeration or list of codes of the same kind as this item.
103     */
104    ControlledVocabulary[] family();
105}