001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2005-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.Map;
021import java.util.Locale;
022import java.lang.reflect.Type;
023
024
025/**
026 * Factory for {@linkplain GenericName generic names} and
027 * {@linkplain InternationalString international strings}.
028 *
029 * <div class="note"><b>Note:</b>
030 * despite the "{@code create(…)}" method names, implementations may return cached instances.</div>
031 *
032 * @departure extension
033 *   Added in order to provide constructors for {@code GenericName} and related interfaces.
034 *
035 * @author  Jesse Crossley (SYS Technologies)
036 * @author  Martin Desruisseaux (Geomatys)
037 * @version 3.1
038 * @since   2.0
039 */
040public interface NameFactory extends Factory {
041    /**
042     * Creates an international string from a set of strings in different locales.
043     *
044     * @param  strings  string value for each locale key.
045     * @return the international string.
046     */
047    InternationalString createInternationalString(Map<Locale,String> strings);
048
049    /**
050     * Creates a namespace having the given name and separators. The {@code properties} argument
051     * is optional: if non-null, the given properties may be given to the namespace to be created.
052     * The properties can include for example the separator character to be used between the
053     * {@linkplain GenericName#getParsedNames() parsed names}.
054     *
055     * <p>Implementations are encouraged to recognize at least the properties listed in the following table.
056     * Additional implementation-specific properties can be added. Unknown properties shall be ignored.</p>
057     *
058     * <blockquote><table class="ogc">
059     *   <caption>Keys for additional standard properties</caption>
060     *   <tr>
061     *     <th>Property name</th>
062     *     <th>Purpose</th>
063     *   </tr><tr>
064     *     <td>{@code "separator"}</td>
065     *     <td>The separator to insert between {@linkplain GenericName#getParsedNames() parsed names}
066     *         in that namespace.</td>
067     *   </tr><tr>
068     *     <td>{@code "separator.head"}</td>
069     *     <td>The separator to insert between the namespace and the {@linkplain GenericName#head() head}.<br>
070     *         If omitted, then the default is the same value as {@code "separator"}.</td>
071     *   </tr>
072     * </table></blockquote>
073     *
074     * <div class="note"><b>Examples:</b>
075     * <ul>
076     *   <li>For URN namespace, {@code separator} = {@code ":"} is typically sufficient.</li>
077     *   <li>For HTTP namespace, {@code separator.head} = {@code "://"} and {@code separator} = {@code "."}.</li>
078     * </ul></div>
079     *
080     * @param   name       the name of the namespace to be returned. This argument can be created using
081     *                     <code>{@linkplain #createGenericName createGenericName}(null, namespace)</code>.
082     * @param  properties  an optional map of properties to be assigned to the namespace, or {@code null} if none.
083     * @return a namespace having the given name and separators.
084     */
085    NameSpace createNameSpace(GenericName name, Map<String,?> properties);
086
087    /**
088     * Creates a type name from the given character sequence and automatically inferred Java type.
089     * The character sequence shall complies to the same restriction as
090     * {@link #createLocalName createLocalName(…)}.
091     *
092     * @param  scope  the {@linkplain GenericName#scope() scope} of the type name to create,
093     *                or {@code null} for a global namespace.
094     * @param  name   the type name as a string or an international string.
095     * @return the type name for the given scope and character sequence.
096     */
097    TypeName createTypeName(NameSpace scope, CharSequence name);
098
099    /**
100     * Creates a type name from the given character sequence and explicit Java type.
101     * The {@code javaType} argument specifies the value to be returned by
102     * {@link TypeName#toJavaType()}, which may be absent.
103     *
104     * @param  scope     the {@linkplain GenericName#scope() scope} of the type name to create,
105     *                   or {@code null} for a global namespace.
106     * @param  name      the type name as a string or an international string.
107     * @param  javaType  the Java type represented by the name, or {@code null} if none.
108     * @return the type name for the given scope, character sequence and Java type.
109     *
110     * @see TypeName#toJavaType()
111     *
112     * @since 3.1
113     */
114    TypeName createTypeName(NameSpace scope, CharSequence name, Type javaType);
115
116    /**
117     * Creates a member name from the given character sequence and attribute type.
118     *
119     * @param  scope  the {@linkplain GenericName#scope() scope} of the member name to create,
120     *                or {@code null} for a global namespace.
121     * @param  name   the member name as a string or an international string.
122     * @param  attributeType  the type of the data associated with the record member.
123     * @return the member name for the given scope, character sequence and type name.
124     *
125     * @since 3.1
126     */
127    MemberName createMemberName(NameSpace scope, CharSequence name, TypeName attributeType);
128
129    /**
130     * Creates a local name from the given character sequence. The character sequence can be either
131     * a {@link String} or an {@link InternationalString} instance. In the latter case, implementations
132     * can use an arbitrary locale (typically {@link Locale#ROOT}) for the unlocalized string to be
133     * returned by {@link LocalName#toString()}.
134     *
135     * @param  scope  the {@linkplain GenericName#scope() scope} of the local name to create,
136     *                or {@code null} for a global namespace.
137     * @param  name   the local name as a string or an international string.
138     * @return the local name for the given scope and character sequence.
139     */
140    LocalName createLocalName(NameSpace scope, CharSequence name);
141
142    /**
143     * Creates a local or scoped name from an array of parsed names. The array elements can be either
144     * {@link String} or {@link InternationalString} instances. In the latter case, implementations
145     * can use an arbitrary locale (typically {@link Locale#ROOT}) for the unlocalized string to be
146     * returned by {@link LocalName#toString()}.
147     *
148     * <p>If the length of the {@code parsedNames} array is 1, then this method returns an instance
149     * of {@link LocalName}. If the length is 2 or more, then this method returns an instance of
150     * {@link ScopedName}.</p>
151     *
152     * @param  scope        the {@linkplain GenericName#scope() scope} of the generic name to create,
153     *                      or {@code null} for a global namespace.
154     * @param  parsedNames  the local names as an array of strings or international strings.
155     *                      This array must contains at least one element.
156     * @return the generic name for the given parsed names.
157     */
158    GenericName createGenericName(NameSpace scope, CharSequence... parsedNames);
159
160    /**
161     * Constructs a generic name from a qualified name. This method splits the given name around a
162     * separator inferred from the given scope, or an implementation-dependent default separator if
163     * the given scope is null.
164     *
165     * <p>For example, if the {@code scope} argument is the namespace {@code "urn:ogc:def"}
166     * with {@code ":"} as the separator, and if the {@code name} argument is the string
167     * {@code "crs:epsg:4326"}, then the result is a {@linkplain ScopedName scoped name}
168     * having a {@linkplain GenericName#depth depth} of 3, which is the length of the list
169     * of {@linkplain GenericName#getParsedNames parsed names} ({@code "crs"}, {@code "epsg"},
170     * {@code "4326"}).</p>
171     *
172     * @param  scope  the {@linkplain GenericName#scope() scope} of the generic name to create,
173     *                or {@code null} for a global namespace.
174     * @param  name   the qualified name, as a sequence of names separated by a scope-dependent separator.
175     * @return a name parsed from the given string.
176     */
177    GenericName parseGenericName(NameSpace scope, CharSequence name);
178}