/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2004-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * This package contains documentation from OpenGIS specifications. * OpenGIS consortium's work is fully acknowledged here. */ package org.geotools.util; import java.util.Locale; import org.opengis.util.InternationalString; import org.geotools.resources.i18n.Errors; import org.geotools.resources.i18n.ErrorKeys; /** * A {@linkplain String string} that has been internationalized into several * {@linkplain Locale locales}. This class is used as a replacement for the * {@link String} type whenever an attribute needs to be internationalization * capable. The default value (as returned by {@link #toString()} and other * {@link CharSequence} methods} is the string in the current {@linkplain * Locale#getDefault system default}. * <P> * The {@linkplain Comparable natural ordering} is defined by the string in * {@linkplain Locale#getDefault default locale}, as returned by {@link #toString()}. * This string also defines the {@linkplain CharSequence character sequence}. * * @since 2.1 * * @source $URL$ * @version $Id$ * @author Martin Desruisseaux (IRD) */ public abstract class AbstractInternationalString implements InternationalString { /** * The string in the {@linkplain Locale#getDefault system default} locale, or {@code null} * if this string has not yet been determined. This is the default string returned by * {@link #toString()} and others methods from the {@link CharSequence} interface. * <P> * This field is not serialized because serialization is often used for data transmission * between a server and a client, and the client may not use the same locale than the server. * We want the locale to be examined again on the client side. * <P> * This field is read and write by {@link SimpleInternationalString}. */ transient String defaultValue; /** * Constructs an international string. */ public AbstractInternationalString() { } /** * Makes sure an argument is non-null. * * @param name Argument name. * @param object User argument. * @throws IllegalArgumentException if {@code object} is null. */ static void ensureNonNull(final String name, final Object object) throws IllegalArgumentException { if (object == null) { throw new IllegalArgumentException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, name)); } } /** * Returns the length of the string in the {@linkplain Locale#getDefault default locale}. * This is the length of the string returned by {@link #toString()}. */ public int length() { if (defaultValue == null) { defaultValue = toString(); if (defaultValue == null) { return 0; } } return defaultValue.length(); } /** * Returns the character of the string in the {@linkplain Locale#getDefault default locale} * at the specified index. This is the character of the string returned by {@link #toString()}. * * @param index The index of the character. * @return The character at the specified index. * @throws IndexOutOfBoundsException if the specified index is out of bounds. */ public char charAt(final int index) throws IndexOutOfBoundsException { if (defaultValue == null) { defaultValue = toString(); if (defaultValue == null) { throw new IndexOutOfBoundsException(String.valueOf(index)); } } return defaultValue.charAt(index); } /** * Returns a subsequence of the string in the {@linkplain Locale#getDefault default locale}. * The subsequence is a {@link String} object starting with the character value at the specified * index and ending with the character value at index {@code end - 1}. * * @param start The start index, inclusive. * @param end The end index, exclusive. * @return The specified subsequence. * @throws IndexOutOfBoundsException if {@code start} or {@code end} is out of range. */ public CharSequence subSequence(final int start, final int end) { if (defaultValue == null) { defaultValue = toString(); if (defaultValue == null) { throw new IndexOutOfBoundsException(String.valueOf(start)); } } return defaultValue.substring(start, end); } /** * Returns this string in the given locale. If no string is available in the given locale, * then some default locale is used. The default locale is implementation-dependent. It * may or may not be the {@linkplain Locale#getDefault() system default}). * * @param locale The desired locale for the string to be returned, or {@code null} * for a string in the implementation default locale. * @return The string in the given locale if available, or in the default locale otherwise. */ public abstract String toString(final Locale locale); /** * Returns this string in the default locale. Invoking this method is equivalent to invoking * <code>{@linkplain #toString(Locale) toString}({@linkplain Locale#getDefault})</code>. All * methods from {@link CharSequence} operate on this string. This string is also used as the * criterion for {@linkplain Comparable natural ordering}. * * @return The string in the default locale. */ @Override public String toString() { if (defaultValue == null) { defaultValue = toString(Locale.getDefault()); if (defaultValue == null) { return ""; } } return defaultValue; } /** * Compares this string with the specified object for order. This method compare * the string in the {@linkplain Locale#getDefault default locale}, as returned * by {@link #toString()}. * * @param object The string to compare with this string. * @return A negative number if this string is before the given string, a positive * number if after, or 0 if equals. */ public int compareTo(final InternationalString object) { return toString().compareTo(object.toString()); } }