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