-
-
Notifications
You must be signed in to change notification settings - Fork 815
ICU-22124 Adding a tech preview implementation of MessageFormat v2 #2170
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
icu4j/main/classes/core/src/com/ibm/icu/message2/DateTimeFormatterFactory.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// © 2022 and later: Unicode, Inc. and others. | ||
// License & terms of use: http://www.unicode.org/copyright.html | ||
|
||
package com.ibm.icu.message2; | ||
|
||
import java.util.Locale; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
import com.ibm.icu.impl.locale.AsciiUtil; | ||
import com.ibm.icu.text.DateFormat; | ||
import com.ibm.icu.text.SimpleDateFormat; | ||
|
||
/** | ||
* Creates a {@link Formatter} doing formatting of date / time, similar to | ||
* <code>{exp, date}</code> and <code>{exp, time}</code> in {@link com.ibm.icu.text.MessageFormat}. | ||
*/ | ||
class DateTimeFormatterFactory implements FormatterFactory { | ||
|
||
private static int stringToStyle(String option) { | ||
switch (AsciiUtil.toUpperString(option)) { | ||
case "FULL": return DateFormat.FULL; | ||
case "LONG": return DateFormat.LONG; | ||
case "MEDIUM": return DateFormat.MEDIUM; | ||
case "SHORT": return DateFormat.SHORT; | ||
case "": // intentional fall-through | ||
case "DEFAULT": return DateFormat.DEFAULT; | ||
default: throw new IllegalArgumentException("Invalid datetime style: " + option); | ||
} | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* | ||
* @throws IllegalArgumentException when something goes wrong | ||
* (for example conflicting options, invalid option values, etc.) | ||
*/ | ||
@Override | ||
public Formatter createFormatter(Locale locale, Map<String, Object> fixedOptions) { | ||
DateFormat df; | ||
|
||
// TODO: how to handle conflicts. What if we have both skeleton and style, or pattern? | ||
Object opt = fixedOptions.get("skeleton"); | ||
if (opt != null) { | ||
String skeleton = Objects.toString(opt); | ||
df = DateFormat.getInstanceForSkeleton(skeleton, locale); | ||
return new DateTimeFormatter(df); | ||
} | ||
|
||
opt = fixedOptions.get("pattern"); | ||
if (opt != null) { | ||
String pattern = Objects.toString(opt); | ||
SimpleDateFormat sf = new SimpleDateFormat(pattern, locale); | ||
return new DateTimeFormatter(sf); | ||
} | ||
|
||
int dateStyle = DateFormat.NONE; | ||
opt = fixedOptions.get("datestyle"); | ||
if (opt != null) { | ||
dateStyle = stringToStyle(Objects.toString(opt, "")); | ||
} | ||
|
||
int timeStyle = DateFormat.NONE; | ||
opt = fixedOptions.get("timestyle"); | ||
if (opt != null) { | ||
timeStyle = stringToStyle(Objects.toString(opt, "")); | ||
} | ||
|
||
if (dateStyle == DateFormat.NONE && timeStyle == DateFormat.NONE) { | ||
// Match the MessageFormat behavior | ||
dateStyle = DateFormat.SHORT; | ||
timeStyle = DateFormat.SHORT; | ||
} | ||
df = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale); | ||
|
||
return new DateTimeFormatter(df); | ||
} | ||
|
||
private static class DateTimeFormatter implements Formatter { | ||
private final DateFormat icuFormatter; | ||
|
||
private DateTimeFormatter(DateFormat df) { | ||
this.icuFormatter = df; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public FormattedPlaceholder format(Object toFormat, Map<String, Object> variableOptions) { | ||
// TODO: use a special type to indicate function without input argument. | ||
if (toFormat == null) { | ||
throw new IllegalArgumentException("The date to format can't be null"); | ||
} | ||
String result = icuFormatter.format(toFormat); | ||
return new FormattedPlaceholder(toFormat, new PlainStringFormattedValue(result)); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public String formatToString(Object toFormat, Map<String, Object> variableOptions) { | ||
return format(toFormat, variableOptions).toString(); | ||
} | ||
} | ||
} |
120 changes: 120 additions & 0 deletions
120
icu4j/main/classes/core/src/com/ibm/icu/message2/FormattedMessage.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// © 2022 and later: Unicode, Inc. and others. | ||
// License & terms of use: http://www.unicode.org/copyright.html | ||
|
||
package com.ibm.icu.message2; | ||
|
||
import java.text.AttributedCharacterIterator; | ||
|
||
import com.ibm.icu.text.ConstrainedFieldPosition; | ||
import com.ibm.icu.text.FormattedValue; | ||
|
||
/** | ||
* Not yet implemented: The result of a message formatting operation. | ||
* | ||
* <p>This contains information about where the various fields and placeholders | ||
* ended up in the final result.</p> | ||
* <p>This class allows the result to be exported in several data types, | ||
* including a {@link String}, {@link AttributedCharacterIterator}, more (TBD).</p> | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
public class FormattedMessage implements FormattedValue { | ||
|
||
/** | ||
* Not yet implemented. | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
public FormattedMessage() { | ||
throw new RuntimeException("Not yet implemented."); | ||
} | ||
|
||
/** | ||
* Not yet implemented. | ||
* | ||
* {@inheritDoc} | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
@Override | ||
public int length() { | ||
throw new RuntimeException("Not yet implemented."); | ||
} | ||
|
||
/** | ||
* Not yet implemented. | ||
* | ||
* {@inheritDoc} | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
@Override | ||
public char charAt(int index) { | ||
throw new RuntimeException("Not yet implemented."); | ||
} | ||
|
||
/** | ||
* Not yet implemented. | ||
* | ||
* {@inheritDoc} | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
@Override | ||
public CharSequence subSequence(int start, int end) { | ||
throw new RuntimeException("Not yet implemented."); | ||
} | ||
|
||
/** | ||
* Not yet implemented. | ||
* | ||
* {@inheritDoc} | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
@Override | ||
public <A extends Appendable> A appendTo(A appendable) { | ||
throw new RuntimeException("Not yet implemented."); | ||
} | ||
|
||
/** | ||
* Not yet implemented. | ||
* | ||
* {@inheritDoc} | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
@Override | ||
public boolean nextPosition(ConstrainedFieldPosition cfpos) { | ||
throw new RuntimeException("Not yet implemented."); | ||
} | ||
|
||
/** | ||
* Not yet implemented. | ||
* | ||
* {@inheritDoc} | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
@Override | ||
public AttributedCharacterIterator toCharacterIterator() { | ||
throw new RuntimeException("Not yet implemented."); | ||
} | ||
|
||
} |
79 changes: 79 additions & 0 deletions
79
icu4j/main/classes/core/src/com/ibm/icu/message2/FormattedPlaceholder.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// © 2022 and later: Unicode, Inc. and others. | ||
// License & terms of use: http://www.unicode.org/copyright.html | ||
|
||
package com.ibm.icu.message2; | ||
|
||
import com.ibm.icu.text.FormattedValue; | ||
|
||
/** | ||
* An immutable, richer formatting result, encapsulating a {@link FormattedValue}, | ||
* the original value to format, and we are considering adding some more info. | ||
* Very preliminary. | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
public class FormattedPlaceholder { | ||
private final FormattedValue formattedValue; | ||
private final Object inputValue; | ||
|
||
/** | ||
* Constructor creating the {@code FormattedPlaceholder}. | ||
* | ||
* @param inputValue the original value to be formatted. | ||
* @param formattedValue the result of formatting the placeholder. | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
public FormattedPlaceholder(Object inputValue, FormattedValue formattedValue) { | ||
if (formattedValue == null) { | ||
throw new IllegalAccessError("Should not try to wrap a null formatted value"); | ||
} | ||
this.inputValue = inputValue; | ||
this.formattedValue = formattedValue; | ||
} | ||
|
||
/** | ||
* Retrieve the original input value that was formatted. | ||
* | ||
* @return the original value to be formatted. | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
public Object getInput() { | ||
return inputValue; | ||
} | ||
|
||
/** | ||
* Retrieve the formatted value. | ||
* | ||
* @return the result of formatting the placeholder. | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
public FormattedValue getFormattedValue() { | ||
return formattedValue; | ||
} | ||
|
||
/** | ||
* Returns a string representation of the object. | ||
* It can be null, which is unusual, and we plan to change that. | ||
* | ||
* @return a string representation of the object. | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
@Override | ||
public String toString() { | ||
return formattedValue.toString(); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
icu4j/main/classes/core/src/com/ibm/icu/message2/Formatter.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// © 2022 and later: Unicode, Inc. and others. | ||
// License & terms of use: http://www.unicode.org/copyright.html | ||
|
||
package com.ibm.icu.message2; | ||
|
||
import java.util.Map; | ||
|
||
/** | ||
* The interface that must be implemented by all formatters | ||
* that can be used from {@link MessageFormatter}. | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
public interface Formatter { | ||
/** | ||
* A method that takes the object to format and returns | ||
* the i18n-aware string representation. | ||
* | ||
* @param toFormat the object to format. | ||
* @param variableOptions options that are not know at build time. | ||
* @return the formatted string. | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
String formatToString(Object toFormat, Map<String, Object> variableOptions); | ||
|
||
/** | ||
* A method that takes the object to format and returns | ||
* the i18n-aware formatted placeholder. | ||
* | ||
* @param toFormat the object to format. | ||
* @param variableOptions options that are not know at build time. | ||
* @return the formatted placeholder. | ||
* | ||
* @internal ICU 72 technology preview | ||
* @deprecated This API is for ICU internal use only. | ||
*/ | ||
@Deprecated | ||
FormattedPlaceholder format(Object toFormat, Map<String, Object> variableOptions); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.