proposal: ICU4J and JDK1.5 API 'reconciliation'
Doug Felt <[email protected]> Mon, 17 Jan 2005 19:35:21 -0800 (PST)
| Newsgroups | gmane.comp.lib.icu.general |
|---|---|
| Message-ID | <[email protected]> |
Please respond by the end of January.
Proposal to synch ICU4J APIs up to JDK 1.5
Many classes in ICU4J are intended to be 'drop in'
replacements for their Java counterparts. This is still
not true, for various reasons. This proposal is to
modify ICU4J to add 'covering' APIs for JDK 1.5 APIs
where possible, and to document deviations from
compatibility where necessary. 'Covering' is defined
as providing APIs whose arguments and return types
promote from/to Java's, or are icu counterparts of
Java's. For example, an API that took or returned
a ULocale would be considered to cover Java apis that
took a Locale, even though Locale is not a superclass
of ULocale.
The deviations are primarily in the following places:
1) icu.lang.UCharacter's 'char wrapper' APIs. Java's Character class,
while primarily providing access to character property information,
also serves as a wrapper class for the 'char' primitive type.
ICU's UCharacter cannot in general serve as a wrapper class, so we
have not implemented APIs related to this function (primarily
non-static methods).
2) Calendar subclass APIs. We restructured Calendar to make it
possible to subclass, and so the subclass APIs are different. In
particular, we have final methods where Java has abstract ones.
3) Format subclassing APIs. Our formatting and parsing code vectors
through different core apis. The situation is similar to
Calendar.
Following is a list of currently known deviations between ICU4J
and JDK 1.5, and my proposals for either changing ICU or accepting
(and documenting) the deviation.
------
API in java.util.Calendar missing from com.ibm.icu.util.Calendar
METHODS
compareTo // has no override
public int (java.lang.Object)
public int (java.util.Calendar)
--- I propose making ibm.icu.util.Calendar implement Comparable and
implementing these.
get
public int (int) /* not handled by public final int (int) */
getGreatestMinimum
public abstract int (int) /* not handled by public final int (int) */
getLeastMaximum
public abstract int (int) /* not handled by public final int (int) */
getMaximum
public abstract int (int) /* not handled by public final int (int) */
getMinimum
public abstract int (int) /* not handled by public final int (int) */
roll
public abstract void (int, boolean) /* not handled by public final void
(int, boolean) */
set
public void (int, int) /* not handled by public final void (int, int) */
FIELDS
FIELD_COUNT // has no override
public static final int
--- Our Calendars are designed to be subclassed differently from
java.util.Calendar. A number of APIs in java.util.Calendar which
are abstract for subclasses to implement, we make final. We
assume no one is subclassing our calendars, and that we do not
need to be compatible with other people's subclasses of
java.util.Calendar. FIELD_COUNT is also not fixed in our
Calendar. I propose this be a deviation from Java compatibility.
============
API in java.text.Collator missing from com.ibm.icu.text.Collator
METHODS
equals
public boolean (java.lang.Object) /* not handled by public abstract boolean
(java.lang.Object) */
--- Our equals(Object) and hashCode() APIs are both abstract, while
only Java's hashCode() API is abstract. Arguably, it makes more
sense for both to default or both to be abstract, but this is a
fine point. On the other hand, we might argue that Collator is
not truly subclassable, so this could be considered a deviation.
I propose that we not define these equals or hashCode APIs at all
and let them default to the Object implementation.
FIELDS
FULL_DECOMPOSITION // has no override
public static final int
--- We do not support this since it does not exist in UCA collation.
We could define it but it would do nothing. I propose adding
this constant for compatibility, but documenting that it should
not be used.
============
API in java.util.Currency missing from com.ibm.icu.util.Currency
METHODS
getSymbol // has no override
public java.lang.String (java.util.Locale)
public java.lang.String ()
--- We provide a more complex getName api that returns two kinds of
names, which might be choice format strings instead of static
strings. I recommend we provide these APIs, as convenience
versions of getName.
============
API in java.text.DateFormat missing from com.ibm.icu.text.DateFormat
METHODS
format
public abstract java.lang.StringBuffer (java.util.Date,
java.lang.StringBuffer, java.text.FieldPosition) /* not handled by public
final java.lang.StringBuffer (java.util.Date, java.lang.StringBuffer,
java.text.FieldPosition) */
parse
public abstract java.util.Date (java.lang.String, java.text.ParsePosition)
/* not handled by public final java.util.Date (java.lang.String,
java.text.ParsePosition) */
--- Our subclass API is different. Our core format and parse methods
use a Calendar, and so we delegate our implementation to those new
abstract methods instead of leaving the originals abstract. Since
we add abstract API, we cannot be compatible with
java.text.DateFormat (we'd have to implement the new abstract
API). So I propose this be deviation from Java compatibility.
============
API in java.text.DecimalFormat missing from com.ibm.icu.text.DecimalFormat
METHODS
isParseBigDecimal // has no override
public boolean ()
setParseBigDecimal // has no override
public void (boolean)
--- I propose we add this API (and implement it, which will take some work).
============
API in java.text.DecimalFormatSymbols missing from
com.ibm.icu.text.DecimalFormatSymbols
METHODS
getCurrency // has no override
public java.util.Currency ()
setCurrency // has no override
public void (java.util.Currency)
--- We don't put currency in DFS any more (see comments in code) but
it seems we could support these for backwards compatibility (with
appropriate comments not to use it). I propose adding this.
============
API in java.util.GregorianCalendar missing from
com.ibm.icu.util.GregorianCalendar
METHODS
compareTo // has no override
public int (java.lang.Object)
public int (java.util.Calendar)
--- See comments for com.ibm.icu.util.Calendar, which would fix this.
get
public int (int) /* not handled by public final int (int) */
getGreatestMinimum
public int (int) /* not handled by public final int (int) */
getLeastMaximum
public int (int) /* not handled by public final int (int) */
getMaximum
public int (int) /* not handled by public final int (int) */
getMinimum
public int (int) /* not handled by public final int (int) */
roll
public void (int, boolean) /* not handled by {
public void (int, int)
public final void (int, boolean)
} */
set
public void (int, int) /* not handled by {
public final void (int, int, int)
public final void (int, int)
public final void (int, int, int, int, int)
public final void (int, int, int, int, int, int)
} */
FIELDS
FIELD_COUNT // has no override
public static final int
--- Leave as is (deviation), see comments for com.ibm.icu.util.Calendar.
============
API in java.text.NumberFormat missing from com.ibm.icu.text.NumberFormat
CONSTRUCTORS
<init> // has no override
public void ()
--- We provide a protected method only, since this class is abstract.
Java generates a default public constructor. Our API is present
only because javadoc complains about the public API having no ICU
release tag, so it might be possible to remove this completely.
I propose making the constructor public as the simplest solution.
METHODS
format
public java.lang.StringBuffer (java.lang.Object, java.lang.StringBuffer,
java.text.FieldPosition) /* not handled by public final java.lang.StringBuffer
(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) */
--- Our format method is final and doesn't need to be. Note that our
parse method is not. I propose removing 'final'.
============
API in java.text.SimpleDateFormat missing from
com.ibm.icu.text.SimpleDateFormat
METHODS
format
public java.lang.StringBuffer (java.util.Date, java.lang.StringBuffer,
java.text.FieldPosition) /* not handled by public final java.lang.StringBuffer
(java.util.Date, java.lang.StringBuffer, java.text.FieldPosition) */
parse
public java.util.Date (java.lang.String, java.text.ParsePosition) /* not
handled by public final java.util.Date (java.lang.String,
java.text.ParsePosition) */
--- These apis are abstract in java's base class
java.text.NumberFormat, but not in our version, and we instead
override our own abstract APIs that take a Calendar. I propose
this be a deviation from Java compatibility.
============
API in java.util.SimpleTimeZone missing from com.ibm.icu.util.SimpleTimeZone
CONSTRUCTORS
<init>
public void (int, java.lang.String, int, int, int, int, int, int, int, int,
int, int, int) /* not handled by {
public void (int, java.lang.String, int, int, int, int, int, int, int, int)
public void (int, java.lang.String, int, int, int, int, int, int, int, int,
int)
public void (java.util.SimpleTimeZone)
public void (int, java.lang.String)
} */
FIELDS
STANDARD_TIME // has no override
public static final int
UTC_TIME // has no override
public static final int
WALL_TIME // has no override
public static final int
--- These are odd. In 1.3 there was state and code added to
SimpleTimeZone to stream in/out timeModes for the start and end
times of DST. In 1.4 this new constrctor was added. The current
code seems in error since endTimeMode is never used--
startTimeMode is used to compute the 'real' endTime when matching
times against transitions. This all seems unnecessary.
Nevertheless, we could add these and use the modes to immediately
modify the times to the representation we use, and ignore streaming.
Not sure what to propose here. I propose doing this, as a straw
man. Any objections?
============
API in java.lang.Character missing from com.ibm.icu.lang.UCharacter
CONSTRUCTORS
<init> // has no override
public void (char)
--- We're not a full replacement for Character; since it's used as a
wrapper for the primitive 'char' it's best to let java's Character
continue to fulfill that role. I propose this be a deviation from
Java compatibility. Also see additional methods below.
METHODS
charValue // has no override
public char ()
compareTo // has no override
public int (java.lang.Character)
public int (java.lang.Object)
--- Deviation, we don't implement 'char wrapper' API.
isJavaIdentifierPart // has no override
public static final boolean (char)
public static final boolean (int)
isJavaIdentifierStart // has no override
public static final boolean (char)
public static final boolean (int)
isJavaLetter // has no override
public static final boolean (char)
isJavaLetterOrDigit // has no override
public static final boolean (char)
--- I propose adding appropriate versions, as calls through to the
JDK. There's no reason not to do so.
isSpace // has no override
public static final boolean (char)
--- This is deprecated in the JDK. I propose implementing this and making
it permanently deprecated, for compatibility.
reverseBytes // has no override
public static final char (char)
--- Deviation, we don't implement 'char wrapper' API. This is related
to Character being a primitive wrapper (Integer, Long also have
this API). Who knows why it is needed.
toLowerCase
public static final char (char) /* not handled by public static final int
(int) */
toTitleCase
public static final char (char) /* not handled by public static final int
(int) */
toUpperCase
public static final char (char) /* not handled by public static final int
(int) */
--- We return an int for toLowerCase, toTitleCase, and toUpperCase,
since that's required for case conversion of all unicode
values. I propose this be a deviation from Java compatibility.
valueOf // has no override
public static final java.lang.Character (char)
--- Deviation, we don't implement 'char wrapper' API.
FIELDS
COMBINING_SPACING_MARK
public static final byte /* not handled by public static final int */
CONNECTOR_PUNCTUATION
public static final byte /* not handled by public static final int */
CONTROL
public static final byte /* not handled by public static final int */
CURRENCY_SYMBOL
public static final byte /* not handled by public static final int */
DASH_PUNCTUATION
public static final byte /* not handled by public static final int */
DECIMAL_DIGIT_NUMBER
public static final byte /* not handled by public static final int */
DIRECTIONALITY_NONSPACING_MARK // has no override
public static final byte
ENCLOSING_MARK
public static final byte /* not handled by public static final int */
END_PUNCTUATION
public static final byte /* not handled by public static final int */
FINAL_QUOTE_PUNCTUATION
public static final byte /* not handled by public static final int */
FORMAT
public static final byte /* not handled by public static final int */
INITIAL_QUOTE_PUNCTUATION
public static final byte /* not handled by public static final int */
LETTER_NUMBER
public static final byte /* not handled by public static final int */
LINE_SEPARATOR
public static final byte /* not handled by public static final int */
LOWERCASE_LETTER
public static final byte /* not handled by public static final int */
MATH_SYMBOL
public static final byte /* not handled by public static final int */
MAX_RADIX // has no override
public static final int
MAX_VALUE
public static final char /* not handled by public static final int */
MIN_RADIX // has no override
public static final int
MIN_VALUE
public static final char /* not handled by public static final int */
MODIFIER_LETTER
public static final byte /* not handled by public static final int */
MODIFIER_SYMBOL
public static final byte /* not handled by public static final int */
NON_SPACING_MARK
public static final byte /* not handled by public static final int */
OTHER_LETTER
public static final byte /* not handled by public static final int */
OTHER_NUMBER
public static final byte /* not handled by public static final int */
OTHER_PUNCTUATION
public static final byte /* not handled by public static final int */
OTHER_SYMBOL
public static final byte /* not handled by public static final int */
PARAGRAPH_SEPARATOR
public static final byte /* not handled by public static final int */
PRIVATE_USE
public static final byte /* not handled by public static final int */
SIZE // has no override
public static final int
SPACE_SEPARATOR
public static final byte /* not handled by public static final int */
START_PUNCTUATION
public static final byte /* not handled by public static final int */
SURROGATE
public static final byte /* not handled by public static final int */
TITLECASE_LETTER
public static final byte /* not handled by public static final int */
TYPE // has no override
public static final java.lang.Class
UNASSIGNED
public static final byte /* not handled by public static final int */
UPPERCASE_LETTER
public static final byte /* not handled by public static final int */
--- I propose adding MIN_RADIX and MAX_RADIX (equal to Character's
values).
--- SIZE, TYPE are related to 'char' wrapper aspect, I propose this be
a deviation from Java compatibility.
--- DIRECTIONALITY_NONSPACING_MARK is an oversight, our (draft)
version has a hyphen in 'NON_SPACING'. I propose this be changed.
--- All others are int but could be byte, I propose we change for
compatibility. This shouldn't break our clients as these are
final.
============
API in java.lang.Character$UnicodeBlock missing from
com.ibm.icu.lang.UCharacter$UnicodeBlock
FIELDS
SURROGATES_AREA // has no override
public static final java.lang.Character$UnicodeBlock
--- This is deprecated in 1.5, and we have no analogous block for it.
I propose this be a Java compatibility deviation.
============
API in java.util.Locale missing from com.ibm.icu.util.ULocale
CONSTRUCTORS
<init>
public void (java.lang.String, java.lang.String) /* not handled by {
public void (java.lang.String, java.lang.String, java.lang.String)
public void (java.lang.String)
} */
--- I propose we add this constructor. Our semantic is to just
concatenate, while Java's is that the second argument is language,
but the effect is compatible. If you pass a script as the second
argument to ours we'll accept it, but java says nothing about
scripts. We also don't map 'he' to 'iw' either...
============
API in java.util.ResourceBundle missing from com.ibm.icu.util.UResourceBundle
CONSTRUCTORS
<init> // has no override
public void ()
--- Default constructor for abstract class, ours is protected. Same
issue as with NumberFormat, see that discussion. I propose our
protected constructor be made public.
__________________________________
Do you Yahoo!?
Yahoo! Mail - Helps protect you from nasty viruses.
http://promotions.yahoo.com/new_mail