1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.text.style;
18 
19 import android.os.Parcel;
20 import android.os.PersistableBundle;
21 import android.text.ParcelableSpan;
22 import android.text.TextUtils;
23 
24 import java.text.NumberFormat;
25 import java.util.Locale;
26 
27 /**
28  * A span that supplies additional meta-data for the associated text intended
29  * for text-to-speech engines. If the text is being processed by a
30  * text-to-speech engine, the engine may use the data in this span in addition
31  * to or instead of its associated text.
32  *
33  * Each instance of a TtsSpan has a type, for example {@link #TYPE_DATE}
34  * or {@link #TYPE_MEASURE}. And a list of arguments, provided as
35  * key-value pairs in a bundle.
36  *
37  * The inner classes are there for convenience and provide builders for each
38  * TtsSpan type.
39  */
40 public class TtsSpan implements ParcelableSpan {
41     private final String mType;
42     private final PersistableBundle mArgs;
43 
44     /**
45      * This span type can be used to add morphosyntactic features to the text it
46      * spans over, or synthesize a something else than the spanned text. Use
47      * the argument {@link #ARG_TEXT} to set a different text.
48      * Accepts the arguments {@link #ARG_GENDER},
49      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
50      * {@link #ARG_CASE}.
51      */
52     public static final String TYPE_TEXT = "android.type.text";
53 
54     /**
55      * The text associated with this span is a cardinal. Must include the
56      * number to be synthesized with {@link #ARG_NUMBER}.
57      * Also accepts the arguments {@link #ARG_GENDER},
58      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
59      * {@link #ARG_CASE}.
60      */
61     public static final String TYPE_CARDINAL = "android.type.cardinal";
62 
63     /**
64      * The text associated with this span is an ordinal. Must include the
65      * number to be synthesized with {@link #ARG_NUMBER}.
66      * Also accepts the arguments {@link #ARG_GENDER},
67      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
68      * {@link #ARG_CASE}.
69      */
70     public static final String TYPE_ORDINAL = "android.type.ordinal";
71 
72     /**
73      * The text associated with this span is a decimal number. Must include the
74      * number to be synthesized with {@link #ARG_INTEGER_PART} and
75      * {@link #ARG_FRACTIONAL_PART}.
76      * Also accepts the arguments {@link #ARG_GENDER},
77      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
78      * {@link #ARG_CASE}.
79      */
80     public static final String TYPE_DECIMAL = "android.type.decimal";
81 
82     /**
83      * The text associated with this span is a fractional number. Must include
84      * the number to be synthesized with {@link #ARG_NUMERATOR} and
85      * {@link #ARG_DENOMINATOR}. {@link #ARG_INTEGER_PART} is optional
86      * Also accepts the arguments {@link #ARG_GENDER},
87      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
88      * {@link #ARG_CASE}.
89      */
90     public static final String TYPE_FRACTION = "android.type.fraction";
91 
92     /**
93      * The text associated with this span is a measure, consisting of a number
94      * and a unit. The number can be a cardinal, decimal or a fraction. Set the
95      * number with the same arguments as {@link #TYPE_CARDINAL},
96      * {@link #TYPE_DECIMAL} or {@link #TYPE_FRACTION}. The unit can be
97      * specified with {@link #ARG_UNIT}.
98      * Also accepts the arguments {@link #ARG_GENDER},
99      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
100      * {@link #ARG_CASE}.
101      */
102     public static final String TYPE_MEASURE = "android.type.measure";
103 
104     /**
105      * The text associated with this span is a time, consisting of a number of
106      * hours and minutes, specified with {@link #ARG_HOURS} and
107      * {@link #ARG_MINUTES}.
108      * Also accepts the arguments {@link #ARG_GENDER},
109      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
110      * {@link #ARG_CASE}.
111      */
112     public static final String TYPE_TIME = "android.type.time";
113 
114     /**
115      * The text associated with this span is a date. At least one of the
116      * arguments {@link #ARG_MONTH} and {@link #ARG_YEAR} has to be provided.
117      * The argument {@link #ARG_DAY} is optional if {@link #ARG_MONTH} is set.
118      * The argument {@link #ARG_WEEKDAY} is optional if {@link #ARG_DAY} is set.
119      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
120      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
121      */
122     public static final String TYPE_DATE = "android.type.date";
123 
124     /**
125      * The text associated with this span is a telephone number. The argument
126      * {@link #ARG_NUMBER_PARTS} is required. {@link #ARG_COUNTRY_CODE} and
127      * {@link #ARG_EXTENSION} are optional.
128      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
129      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
130      */
131     public static final String TYPE_TELEPHONE = "android.type.telephone";
132 
133     /**
134      * The text associated with this span is a URI (can be used for URLs and
135      * email addresses). The full schema for URLs, which email addresses can
136      * effectively be seen as a subset of, is:
137      * protocol://username:password@domain:port/path?query_string#fragment_id
138      * Hence populating just username and domain will read as an email address.
139      * All arguments are optional, but at least one has to be provided:
140      * {@link #ARG_PROTOCOL}, {@link #ARG_USERNAME}, {@link #ARG_PASSWORD},
141      * {@link #ARG_DOMAIN}, {@link #ARG_PORT}, {@link #ARG_PATH},
142      * {@link #ARG_QUERY_STRING} and {@link #ARG_FRAGMENT_ID}.
143      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
144      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
145      */
146     public static final String TYPE_ELECTRONIC = "android.type.electronic";
147 
148     /**
149      * The text associated with this span is an amount of money. Set the amount
150      * with the same arguments as {@link #TYPE_DECIMAL}.
151      * {@link #ARG_CURRENCY} is used to set the currency. {@link #ARG_QUANTITY}
152      * is optional.
153      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
154      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
155      */
156     public static final String TYPE_MONEY = "android.type.money";
157 
158     /**
159      * The text associated with this span is a series of digits that have to be
160      * read sequentially. The digits can be set with {@link #ARG_DIGITS}.
161      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
162      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
163      */
164     public static final String TYPE_DIGITS = "android.type.digits";
165 
166     /**
167      * The text associated with this span is a series of characters that have to
168      * be read verbatim. The engine will attempt to read out any character like
169      * punctuation but excluding whitespace. {@link #ARG_VERBATIM} is required.
170      * Also accepts the arguments {@link #ARG_GENDER},
171      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
172      */
173     public static final String TYPE_VERBATIM = "android.type.verbatim";
174 
175     /**
176      * String argument supplying gender information. Can be any of
177      * {@link #GENDER_NEUTRAL}, {@link #GENDER_MALE} and
178      * {@link #GENDER_FEMALE}.
179      */
180     public static final String ARG_GENDER = "android.arg.gender";
181 
182     public static final String GENDER_NEUTRAL = "android.neutral";
183     public static final String GENDER_MALE = "android.male";
184     public static final String GENDER_FEMALE = "android.female";
185 
186     /**
187      * String argument supplying animacy information. Can be
188      * {@link #ANIMACY_ANIMATE} or
189      * {@link #ANIMACY_INANIMATE}
190      */
191     public static final String ARG_ANIMACY = "android.arg.animacy";
192 
193     public static final String ANIMACY_ANIMATE = "android.animate";
194     public static final String ANIMACY_INANIMATE = "android.inanimate";
195 
196     /**
197      * String argument supplying multiplicity information. Can be any of
198      * {@link #MULTIPLICITY_SINGLE}, {@link #MULTIPLICITY_DUAL} and
199      * {@link #MULTIPLICITY_PLURAL}
200      */
201     public static final String ARG_MULTIPLICITY = "android.arg.multiplicity";
202 
203     public static final String MULTIPLICITY_SINGLE = "android.single";
204     public static final String MULTIPLICITY_DUAL = "android.dual";
205     public static final String MULTIPLICITY_PLURAL = "android.plural";
206 
207     /**
208      * String argument supplying case information. Can be any of
209      * {@link #CASE_NOMINATIVE}, {@link #CASE_ACCUSATIVE}, {@link #CASE_DATIVE},
210      * {@link #CASE_ABLATIVE}, {@link #CASE_GENITIVE}, {@link #CASE_VOCATIVE},
211      * {@link #CASE_LOCATIVE} and {@link #CASE_INSTRUMENTAL}
212      */
213     public static final String ARG_CASE = "android.arg.case";
214 
215     public static final String CASE_NOMINATIVE = "android.nominative";
216     public static final String CASE_ACCUSATIVE = "android.accusative";
217     public static final String CASE_DATIVE = "android.dative";
218     public static final String CASE_ABLATIVE = "android.ablative";
219     public static final String CASE_GENITIVE = "android.genitive";
220     public static final String CASE_VOCATIVE = "android.vocative";
221     public static final String CASE_LOCATIVE = "android.locative";
222     public static final String CASE_INSTRUMENTAL = "android.instrumental";
223 
224     /**
225      * String supplying the text to be synthesized. The synthesizer is free
226      * to decide how to interpret the text.
227      * Can be used with {@link #TYPE_TEXT}.
228      */
229     public static final String ARG_TEXT = "android.arg.text";
230 
231     /**
232      * Argument used to specify a whole number. The value can be a string of
233      * digits of any size optionally prefixed with a - or +.
234      * Can be used with {@link #TYPE_CARDINAL} and {@link #TYPE_ORDINAL}.
235      */
236     public static final String ARG_NUMBER = "android.arg.number";
237 
238     /**
239      * Argument used to specify the integer part of a decimal or fraction. The
240      * value can be a string of digits of any size optionally prefixed with
241      * a - or +.
242      * Can be used with {@link #TYPE_DECIMAL} and {@link #TYPE_FRACTION}.
243      */
244     public static final String ARG_INTEGER_PART = "android.arg.integer_part";
245 
246     /**
247      * Argument used to specify the fractional part of a decimal. The value can
248      * be a string of digits of any size.
249      * Can be used with {@link #TYPE_DECIMAL}.
250      */
251     public static final String ARG_FRACTIONAL_PART =
252         "android.arg.fractional_part";
253 
254     /**
255      * Argument used to choose the suffix (thousand, million, etc) that is used
256      * to pronounce large amounts of money. For example it can be used to
257      * disambiguate between "two thousand five hundred dollars" and
258      * "two point five thousand dollars".
259      * If implemented, engines should support at least "1000", "1000000",
260      * "1000000000" and "1000000000000".
261      * Example: if the {@link #ARG_INTEGER_PART} argument is "10", the
262      * {@link #ARG_FRACTIONAL_PART} argument is "4", the {@link #ARG_QUANTITY}
263      * argument is "1000" and the {@link #ARG_CURRENCY} argument is "usd", the
264      * TTS engine may pronounce the span as "ten point four thousand dollars".
265      * With the same example but with the quantity set as "1000000" the TTS
266      * engine may pronounce the span as "ten point four million dollars".
267      * Can be used with {@link #TYPE_MONEY}.
268      */
269     public static final String ARG_QUANTITY =
270             "android.arg.quantity";
271 
272     /**
273      * Argument used to specify the numerator of a fraction. The value can be a
274      * string of digits of any size optionally prefixed with a - or +.
275      * Can be used with {@link #TYPE_FRACTION}.
276      */
277     public static final String ARG_NUMERATOR = "android.arg.numerator";
278 
279     /**
280      * Argument used to specify the denominator of a fraction. The value can be
281      * a string of digits of any size optionally prefixed with a + or -.
282      * Can be used with {@link #TYPE_FRACTION}.
283      */
284     public static final String ARG_DENOMINATOR = "android.arg.denominator";
285 
286     /**
287      * Argument used to specify the unit of a measure. The unit should always be
288      * specified in English singular form. Prefixes may be used. Engines will do
289      * their best to pronounce them correctly in the language used. Engines are
290      * expected to at least support the most common ones like "meter", "second",
291      * "degree celsius" and "degree fahrenheit" with some common prefixes like
292      * "milli" and "kilo".
293      * Can be used with {@link #TYPE_MEASURE}.
294      */
295     public static final String ARG_UNIT = "android.arg.unit";
296 
297     /**
298      * Argument used to specify the hours of a time. The hours should be
299      * provided as an integer in the range from 0 up to and including 24.
300      * Can be used with {@link #TYPE_TIME}.
301      */
302     public static final String ARG_HOURS = "android.arg.hours";
303 
304     /**
305      * Argument used to specify the minutes of a time. The hours should be
306      * provided as an integer in the range from 0 up to and including 59.
307      * Can be used with {@link #TYPE_TIME}.
308      */
309     public static final String ARG_MINUTES = "android.arg.minutes";
310 
311     /**
312      * Argument used to specify the weekday of a date. The value should be
313      * provided as an integer and can be any of {@link #WEEKDAY_SUNDAY},
314      * {@link #WEEKDAY_MONDAY}, {@link #WEEKDAY_TUESDAY},
315      * {@link #WEEKDAY_WEDNESDAY}, {@link #WEEKDAY_THURSDAY},
316      * {@link #WEEKDAY_FRIDAY} and {@link #WEEKDAY_SATURDAY}.
317      * Can be used with {@link #TYPE_DATE}.
318      */
319     public static final String ARG_WEEKDAY = "android.arg.weekday";
320 
321     public static final int WEEKDAY_SUNDAY = 1;
322     public static final int WEEKDAY_MONDAY = 2;
323     public static final int WEEKDAY_TUESDAY = 3;
324     public static final int WEEKDAY_WEDNESDAY = 4;
325     public static final int WEEKDAY_THURSDAY = 5;
326     public static final int WEEKDAY_FRIDAY = 6;
327     public static final int WEEKDAY_SATURDAY = 7;
328 
329     /**
330      * Argument used to specify the day of the month of a date. The value should
331      * be provided as an integer in the range from 1 up to and including 31.
332      * Can be used with {@link #TYPE_DATE}.
333      */
334     public static final String ARG_DAY = "android.arg.day";
335 
336     /**
337      * Argument used to specify the month of a date. The value should be
338      * provided as an integer and can be any of {@link #MONTH_JANUARY},
339      * {@link #MONTH_FEBRUARY},  {@link #MONTH_MARCH}, {@link #MONTH_APRIL},
340      * {@link #MONTH_MAY}, {@link #MONTH_JUNE}, {@link #MONTH_JULY},
341      * {@link #MONTH_AUGUST}, {@link #MONTH_SEPTEMBER}, {@link #MONTH_OCTOBER},
342      * {@link #MONTH_NOVEMBER} and {@link #MONTH_DECEMBER}.
343      * Can be used with {@link #TYPE_DATE}.
344      */
345     public static final String ARG_MONTH = "android.arg.month";
346 
347     public static final int MONTH_JANUARY = 0;
348     public static final int MONTH_FEBRUARY = 1;
349     public static final int MONTH_MARCH = 2;
350     public static final int MONTH_APRIL = 3;
351     public static final int MONTH_MAY = 4;
352     public static final int MONTH_JUNE = 5;
353     public static final int MONTH_JULY = 6;
354     public static final int MONTH_AUGUST = 7;
355     public static final int MONTH_SEPTEMBER = 8;
356     public static final int MONTH_OCTOBER = 9;
357     public static final int MONTH_NOVEMBER = 10;
358     public static final int MONTH_DECEMBER = 11;
359 
360     /**
361      * Argument used to specify the year of a date. The value should be provided
362      * as a positive integer.
363      * Can be used with {@link #TYPE_DATE}.
364      */
365     public static final String ARG_YEAR = "android.arg.year";
366 
367     /**
368      * Argument used to specify the country code of a telephone number. Can be
369      * a string of digits optionally prefixed with a "+".
370      * Can be used with {@link #TYPE_TELEPHONE}.
371      */
372     public static final String ARG_COUNTRY_CODE = "android.arg.country_code";
373 
374     /**
375      * Argument used to specify the main number part of a telephone number. Can
376      * be a string of digits where the different parts of the telephone number
377      * can be separated with a space, '-', '/' or '.'.
378      * Can be used with {@link #TYPE_TELEPHONE}.
379      */
380     public static final String ARG_NUMBER_PARTS = "android.arg.number_parts";
381 
382     /**
383      * Argument used to specify the extension part of a telephone number. Can be
384      * a string of digits.
385      * Can be used with {@link #TYPE_TELEPHONE}.
386      */
387     public static final String ARG_EXTENSION = "android.arg.extension";
388 
389     /**
390      * Argument used to specify the protocol of a URI. Examples are "http" and
391      * "ftp".
392      * Can be used with {@link #TYPE_ELECTRONIC}.
393      */
394     public static final String ARG_PROTOCOL = "android.arg.protocol";
395 
396     /**
397      * Argument used to specify the username part of a URI. Should be set as a
398      * string.
399      * Can be used with {@link #TYPE_ELECTRONIC}.
400      */
401     public static final String ARG_USERNAME = "android.arg.username";
402 
403     /**
404      * Argument used to specify the password part of a URI. Should be set as a
405      * string.
406      * Can be used with {@link #TYPE_ELECTRONIC}.
407      */
408     public static final String ARG_PASSWORD = "android.arg.password";
409 
410     /**
411      * Argument used to specify the domain part of a URI. For example
412      * "source.android.com".
413      * Can be used with {@link #TYPE_ELECTRONIC}.
414      */
415     public static final String ARG_DOMAIN = "android.arg.domain";
416 
417     /**
418      * Argument used to specify the port number of a URI. Should be specified as
419      * an integer.
420      * Can be used with {@link #TYPE_ELECTRONIC}.
421      */
422     public static final String ARG_PORT = "android.arg.port";
423 
424     /**
425      * Argument used to specify the path part of a URI. For example
426      * "source/index.html".
427      * Can be used with {@link #TYPE_ELECTRONIC}.
428      */
429     public static final String ARG_PATH = "android.arg.path";
430 
431     /**
432      * Argument used to specify the query string of a URI. For example
433      * "arg=value&argtwo=value".
434      * Can be used with {@link #TYPE_ELECTRONIC}.
435      */
436     public static final String ARG_QUERY_STRING = "android.arg.query_string";
437 
438     /**
439      * Argument used to specify the fragment id of a URI. Should be specified as
440      * a string.
441      * Can be used with {@link #TYPE_ELECTRONIC}.
442      */
443     public static final String ARG_FRAGMENT_ID = "android.arg.fragment_id";
444 
445     /**
446      * Argument used to specify the currency. Should be a ISO4217 currency code,
447      * e.g. "USD".
448      * Can be used with {@link #TYPE_MONEY}.
449      */
450     public static final String ARG_CURRENCY = "android.arg.money";
451 
452     /**
453      * Argument used to specify a string of digits.
454      * Can be used with {@link #TYPE_DIGITS}.
455      */
456     public static final String ARG_DIGITS = "android.arg.digits";
457 
458     /**
459      * Argument used to specify a string where the characters are read verbatim,
460      * except whitespace.
461      * Can be used with {@link #TYPE_VERBATIM}.
462      */
463     public static final String ARG_VERBATIM = "android.arg.verbatim";
464 
TtsSpan(String type, PersistableBundle args)465     public TtsSpan(String type, PersistableBundle args) {
466         mType = type;
467         mArgs = args;
468     }
469 
TtsSpan(Parcel src)470     public TtsSpan(Parcel src) {
471         mType = src.readString();
472         mArgs = src.readPersistableBundle();
473     }
474 
475     /**
476      * Returns the type.
477      * @return The type of this instance.
478      */
getType()479     public String getType() {
480         return mType;
481     }
482 
483     /**
484      * Returns a bundle of the arguments set.
485      * @return The bundle of the arguments set.
486      */
getArgs()487     public PersistableBundle getArgs() {
488         return mArgs;
489     }
490 
491     @Override
describeContents()492     public int describeContents() {
493         return 0;
494     }
495 
496     @Override
writeToParcel(Parcel dest, int flags)497     public void writeToParcel(Parcel dest, int flags) {
498         writeToParcelInternal(dest, flags);
499     }
500 
501     /** @hide */
writeToParcelInternal(Parcel dest, int flags)502     public void writeToParcelInternal(Parcel dest, int flags) {
503         dest.writeString(mType);
504         dest.writePersistableBundle(mArgs);
505     }
506 
507     @Override
getSpanTypeId()508     public int getSpanTypeId() {
509         return getSpanTypeIdInternal();
510     }
511 
512     /** @hide */
getSpanTypeIdInternal()513     public int getSpanTypeIdInternal() {
514         return TextUtils.TTS_SPAN;
515     }
516 
517     /**
518      * A simple builder for TtsSpans.
519      * This builder can be used directly, but the more specific subclasses of
520      * this builder like {@link TtsSpan.TextBuilder} and
521      * {@link TtsSpan.CardinalBuilder} are likely more useful.
522      *
523      * This class uses generics so methods from this class can return instances
524      * of its child classes, resulting in a fluent API (CRTP pattern).
525      */
526     public static class Builder<C extends Builder<?>> {
527         // Holds the type of this class.
528         private final String mType;
529 
530         // Holds the arguments of this class. It only stores objects of type
531         // String, Integer and Long.
532         private PersistableBundle mArgs = new PersistableBundle();
533 
Builder(String type)534         public Builder(String type) {
535             mType = type;
536         }
537 
538         /**
539          * Returns a TtsSpan built from the parameters set by the setter
540          * methods.
541          * @return A TtsSpan built with parameters of this builder.
542          */
build()543         public TtsSpan build() {
544             return new TtsSpan(mType, mArgs);
545         }
546 
547         /**
548          * Sets an argument to a string value.
549          * @param arg The argument name.
550          * @param value The value the argument should be set to.
551          * @return This instance.
552          */
553         @SuppressWarnings("unchecked")
setStringArgument(String arg, String value)554         public C setStringArgument(String arg, String value) {
555             mArgs.putString(arg, value);
556             return (C) this;
557         }
558 
559         /**
560          * Sets an argument to an int value.
561          * @param arg The argument name.
562          * @param value The value the argument should be set to.
563          */
564         @SuppressWarnings("unchecked")
setIntArgument(String arg, int value)565         public C setIntArgument(String arg, int value) {
566             mArgs.putInt(arg, value);
567             return (C) this;
568         }
569 
570         /**
571          * Sets an argument to a long value.
572          * @param arg The argument name.
573          * @param value The value the argument should be set to.
574          */
575         @SuppressWarnings("unchecked")
setLongArgument(String arg, long value)576         public C setLongArgument(String arg, long value) {
577             mArgs.putLong(arg, value);
578             return (C) this;
579         }
580     }
581 
582     /**
583      * A builder for TtsSpans, has setters for morphosyntactic features.
584      * This builder can be used directly, but the more specific subclasses of
585      * this builder like {@link TtsSpan.TextBuilder} and
586      * {@link TtsSpan.CardinalBuilder} are likely more useful.
587      */
588     public static class SemioticClassBuilder<C extends SemioticClassBuilder<?>>
589             extends Builder<C> {
590 
SemioticClassBuilder(String type)591         public SemioticClassBuilder(String type) {
592             super(type);
593         }
594 
595         /**
596          * Sets the gender information for this instance.
597          * @param gender Can any of {@link #GENDER_NEUTRAL},
598          *     {@link #GENDER_MALE} and {@link #GENDER_FEMALE}.
599          * @return This instance.
600          */
setGender(String gender)601         public C setGender(String gender) {
602             return setStringArgument(TtsSpan.ARG_GENDER, gender);
603         }
604 
605         /**
606          * Sets the animacy information for this instance.
607          * @param animacy Can be any of {@link #ANIMACY_ANIMATE} and
608          *     {@link #ANIMACY_INANIMATE}.
609          * @return This instance.
610          */
setAnimacy(String animacy)611         public C setAnimacy(String animacy) {
612             return setStringArgument(TtsSpan.ARG_ANIMACY, animacy);
613         }
614 
615         /**
616          * Sets the multiplicity information for this instance.
617          * @param multiplicity Can be any of
618          *     {@link #MULTIPLICITY_SINGLE}, {@link #MULTIPLICITY_DUAL} and
619          *     {@link #MULTIPLICITY_PLURAL}.
620          * @return This instance.
621          */
setMultiplicity(String multiplicity)622         public C setMultiplicity(String multiplicity) {
623             return setStringArgument(TtsSpan.ARG_MULTIPLICITY, multiplicity);
624         }
625 
626         /**
627          * Sets the grammatical case information for this instance.
628          * @param grammaticalCase Can be any of {@link #CASE_NOMINATIVE},
629          *     {@link #CASE_ACCUSATIVE}, {@link #CASE_DATIVE},
630          *     {@link #CASE_ABLATIVE}, {@link #CASE_GENITIVE},
631          *     {@link #CASE_VOCATIVE}, {@link #CASE_LOCATIVE} and
632          *     {@link #CASE_INSTRUMENTAL}.
633          * @return This instance.
634          */
setCase(String grammaticalCase)635         public C setCase(String grammaticalCase) {
636             return setStringArgument(TtsSpan.ARG_CASE, grammaticalCase);
637         }
638     }
639 
640     /**
641      * A builder for TtsSpans of type {@link #TYPE_TEXT}.
642      */
643     public static class TextBuilder extends SemioticClassBuilder<TextBuilder> {
644 
645         /**
646          * Creates a builder for a TtsSpan of type {@link #TYPE_TEXT}.
647          */
TextBuilder()648         public TextBuilder() {
649             super(TtsSpan.TYPE_TEXT);
650         }
651 
652         /**
653          * Creates a TtsSpan of type {@link #TYPE_TEXT} and sets the
654          * {@link #ARG_TEXT} argument.
655          * @param text The text to be synthesized.
656          * @see #setText(String)
657          */
TextBuilder(String text)658         public TextBuilder(String text) {
659             this();
660             setText(text);
661         }
662 
663         /**
664          * Sets the {@link #ARG_TEXT} argument, the text to be synthesized.
665          * @param text The string that will be synthesized.
666          * @return This instance.
667          */
setText(String text)668         public TextBuilder setText(String text) {
669             return setStringArgument(TtsSpan.ARG_TEXT, text);
670         }
671     }
672 
673     /**
674      * A builder for TtsSpans of type {@link #TYPE_CARDINAL}.
675      */
676     public static class CardinalBuilder
677             extends SemioticClassBuilder<CardinalBuilder> {
678 
679         /**
680          * Creates a builder for a TtsSpan of type {@link #TYPE_CARDINAL}.
681          */
CardinalBuilder()682         public CardinalBuilder() {
683             super(TtsSpan.TYPE_CARDINAL);
684         }
685 
686         /**
687          * Creates a TtsSpan of type {@link #TYPE_CARDINAL} and sets the
688          * {@link #ARG_NUMBER} argument.
689          * @param number The number to synthesize.
690          * @see #setNumber(long)
691          */
CardinalBuilder(long number)692         public CardinalBuilder(long number) {
693             this();
694             setNumber(number);
695         }
696 
697         /**
698          * Creates a TtsSpan of type {@link #TYPE_CARDINAL} and sets the
699          * {@link #ARG_NUMBER} argument.
700          * @param number The number to synthesize.
701          * @see #setNumber(String)
702          */
CardinalBuilder(String number)703         public CardinalBuilder(String number) {
704             this();
705             setNumber(number);
706         }
707 
708         /**
709          * Convenience method that converts the number to a String and set it to
710          * the value for {@link #ARG_NUMBER}.
711          * @param number The number that will be synthesized.
712          * @return This instance.
713          */
setNumber(long number)714         public CardinalBuilder setNumber(long number) {
715             return setNumber(String.valueOf(number));
716         }
717 
718         /**
719          * Sets the {@link #ARG_NUMBER} argument.
720          * @param number A non-empty string of digits with an optional
721          *     leading + or -.
722          * @return This instance.
723          */
setNumber(String number)724         public CardinalBuilder setNumber(String number) {
725             return setStringArgument(TtsSpan.ARG_NUMBER, number);
726         }
727     }
728 
729     /**
730      * A builder for TtsSpans of type {@link #TYPE_ORDINAL}.
731      */
732     public static class OrdinalBuilder
733             extends SemioticClassBuilder<OrdinalBuilder> {
734 
735         /**
736          * Creates a builder for a TtsSpan of type {@link #TYPE_ORDINAL}.
737          */
OrdinalBuilder()738         public OrdinalBuilder() {
739             super(TtsSpan.TYPE_ORDINAL);
740         }
741 
742         /**
743          * Creates a TtsSpan of type {@link #TYPE_ORDINAL} and sets the
744          * {@link #ARG_NUMBER} argument.
745          * @param number The ordinal number to synthesize.
746          * @see #setNumber(long)
747          */
OrdinalBuilder(long number)748         public OrdinalBuilder(long number) {
749             this();
750             setNumber(number);
751         }
752 
753         /**
754          * Creates a TtsSpan of type {@link #TYPE_ORDINAL} and sets the
755          * {@link #ARG_NUMBER} argument.
756          * @param number The number to synthesize.
757          * @see #setNumber(String)
758          */
OrdinalBuilder(String number)759         public OrdinalBuilder(String number) {
760             this();
761             setNumber(number);
762         }
763 
764         /**
765          * Convenience method that converts the number to a String and sets it
766          * to the value for {@link #ARG_NUMBER}.
767          * @param number The ordinal number that will be synthesized.
768          * @return This instance.
769          */
setNumber(long number)770         public OrdinalBuilder setNumber(long number) {
771             return setNumber(String.valueOf(number));
772         }
773 
774         /**
775          * Sets the {@link #ARG_NUMBER} argument.
776          * @param number A non-empty string of digits with an optional
777          *     leading + or -.
778          * @return This instance.
779          */
setNumber(String number)780         public OrdinalBuilder setNumber(String number) {
781             return setStringArgument(TtsSpan.ARG_NUMBER, number);
782         }
783     }
784 
785     /**
786      * A builder for TtsSpans of type {@link #TYPE_DECIMAL}.
787      */
788     public static class DecimalBuilder
789             extends SemioticClassBuilder<DecimalBuilder> {
790 
791         /**
792          * Creates a builder for a TtsSpan of type {@link #TYPE_DECIMAL}.
793          */
DecimalBuilder()794         public DecimalBuilder() {
795             super(TtsSpan.TYPE_DECIMAL);
796         }
797 
798         /**
799          * Creates a TtsSpan of type {@link #TYPE_DECIMAL} and sets the
800          * {@link #ARG_INTEGER_PART} and {@link #ARG_FRACTIONAL_PART} arguments.
801          * @see #setArgumentsFromDouble(double, int, int)
802          */
DecimalBuilder(double number, int minimumFractionDigits, int maximumFractionDigits)803         public DecimalBuilder(double number,
804                               int minimumFractionDigits,
805                               int maximumFractionDigits) {
806             this();
807             setArgumentsFromDouble(number,
808                                    minimumFractionDigits,
809                                    maximumFractionDigits);
810         }
811 
812         /**
813          * Creates a TtsSpan of type {@link #TYPE_DECIMAL} and sets the
814          * {@link #ARG_INTEGER_PART} and {@link #ARG_FRACTIONAL_PART} arguments.
815          */
DecimalBuilder(String integerPart, String fractionalPart)816         public DecimalBuilder(String integerPart, String fractionalPart) {
817             this();
818             setIntegerPart(integerPart);
819             setFractionalPart(fractionalPart);
820         }
821 
822         /**
823          * Convenience method takes a double and a maximum number of fractional
824          * digits, it sets the {@link #ARG_INTEGER_PART} and
825          * {@link #ARG_FRACTIONAL_PART} arguments.
826          * @param number The number to be synthesized.
827          * @param minimumFractionDigits The minimum number of fraction digits
828          *     that are pronounced.
829          * @param maximumFractionDigits The maximum number of fraction digits
830          *     that are pronounced. If maximumFractionDigits <
831          *     minimumFractionDigits then minimumFractionDigits will be assumed
832          *     to be equal to maximumFractionDigits.
833          * @return This instance.
834          */
setArgumentsFromDouble( double number, int minimumFractionDigits, int maximumFractionDigits)835         public DecimalBuilder setArgumentsFromDouble(
836                 double number,
837                 int minimumFractionDigits,
838                 int maximumFractionDigits) {
839             // Format double.
840             NumberFormat formatter = NumberFormat.getInstance(Locale.US);
841             formatter.setMinimumFractionDigits(maximumFractionDigits);
842             formatter.setMaximumFractionDigits(maximumFractionDigits);
843             formatter.setGroupingUsed(false);
844             String str = formatter.format(number);
845 
846             // Split at decimal point.
847             int i = str.indexOf('.');
848             if (i >= 0) {
849                 setIntegerPart(str.substring(0, i));
850                 setFractionalPart(str.substring(i + 1));
851             } else {
852                 setIntegerPart(str);
853             }
854             return this;
855         }
856 
857         /**
858          * Convenience method that converts the number to a String and sets it
859          * to the value for {@link #ARG_INTEGER_PART}.
860          * @param integerPart The integer part of the decimal.
861          * @return This instance.
862          */
setIntegerPart(long integerPart)863         public DecimalBuilder setIntegerPart(long integerPart) {
864             return setIntegerPart(String.valueOf(integerPart));
865         }
866 
867         /**
868          * Sets the {@link #ARG_INTEGER_PART} argument.
869          * @param integerPart A non-empty string of digits with an optional
870          *     leading + or -.
871          * @return This instance.
872          */
setIntegerPart(String integerPart)873         public DecimalBuilder setIntegerPart(String integerPart) {
874             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
875         }
876 
877         /**
878          * Sets the {@link #ARG_FRACTIONAL_PART} argument.
879          * @param fractionalPart A non-empty string of digits.
880          * @return This instance.
881          */
setFractionalPart(String fractionalPart)882         public DecimalBuilder setFractionalPart(String fractionalPart) {
883             return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART,
884                                      fractionalPart);
885         }
886     }
887 
888     /**
889      * A builder for TtsSpans of type {@link #TYPE_FRACTION}.
890      */
891     public static class FractionBuilder
892             extends SemioticClassBuilder<FractionBuilder> {
893 
894         /**
895          * Creates a builder for a TtsSpan of type {@link #TYPE_FRACTION}.
896          */
FractionBuilder()897         public FractionBuilder() {
898             super(TtsSpan.TYPE_FRACTION);
899         }
900 
901         /**
902          * Creates a TtsSpan of type {@link #TYPE_FRACTION} and sets the
903          * {@link #ARG_INTEGER_PART}, {@link #ARG_NUMERATOR}, and
904          * {@link #ARG_DENOMINATOR} arguments.
905          */
FractionBuilder(long integerPart, long numerator, long denominator)906         public FractionBuilder(long integerPart,
907                                long numerator,
908                                long denominator) {
909             this();
910             setIntegerPart(integerPart);
911             setNumerator(numerator);
912             setDenominator(denominator);
913         }
914 
915         /**
916          * Convenience method that converts the integer to a String and sets the
917          * argument {@link #ARG_NUMBER}.
918          * @param integerPart The integer part.
919          * @return This instance.
920          */
setIntegerPart(long integerPart)921         public FractionBuilder setIntegerPart(long integerPart) {
922             return setIntegerPart(String.valueOf(integerPart));
923         }
924 
925         /**
926          * Sets the {@link #ARG_INTEGER_PART} argument.
927          * @param integerPart A non-empty string of digits with an optional
928          *     leading + or -.
929          * @return This instance.
930          */
setIntegerPart(String integerPart)931         public FractionBuilder setIntegerPart(String integerPart) {
932             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
933         }
934 
935         /**
936          * Convenience method that converts the numerator to a String and sets
937          * the argument {@link #ARG_NUMERATOR}.
938          * @param numerator The numerator.
939          * @return This instance.
940          */
setNumerator(long numerator)941         public FractionBuilder setNumerator(long numerator) {
942             return setNumerator(String.valueOf(numerator));
943         }
944 
945         /**
946          * Sets the {@link #ARG_NUMERATOR} argument.
947          * @param numerator A non-empty string of digits with an optional
948          *     leading + or -.
949          * @return This instance.
950          */
setNumerator(String numerator)951         public FractionBuilder setNumerator(String numerator) {
952             return setStringArgument(TtsSpan.ARG_NUMERATOR, numerator);
953         }
954 
955         /**
956          * Convenience method that converts the denominator to a String and sets
957          * the argument {@link #ARG_DENOMINATOR}.
958          * @param denominator The denominator.
959          * @return This instance.
960          */
setDenominator(long denominator)961         public FractionBuilder setDenominator(long denominator) {
962             return setDenominator(String.valueOf(denominator));
963         }
964 
965         /**
966          * Sets the {@link #ARG_DENOMINATOR} argument.
967          * @param denominator A non-empty string of digits with an optional
968          *     leading + or -.
969          * @return This instance.
970          */
setDenominator(String denominator)971         public FractionBuilder setDenominator(String denominator) {
972             return setStringArgument(TtsSpan.ARG_DENOMINATOR, denominator);
973         }
974     }
975 
976     /**
977      * A builder for TtsSpans of type {@link #TYPE_MEASURE}.
978      */
979     public static class MeasureBuilder
980             extends SemioticClassBuilder<MeasureBuilder> {
981 
982         /**
983          * Creates a builder for a TtsSpan of type {@link #TYPE_MEASURE}.
984          */
MeasureBuilder()985         public MeasureBuilder() {
986             super(TtsSpan.TYPE_MEASURE);
987         }
988 
989         /**
990          * Convenience method that converts the number to a String and set it to
991          * the value for {@link #ARG_NUMBER}.
992          * @param number The amount of the measure.
993          * @return This instance.
994          */
setNumber(long number)995         public MeasureBuilder setNumber(long number) {
996             return setNumber(String.valueOf(number));
997         }
998 
999         /**
1000          * Sets the {@link #ARG_NUMBER} argument.
1001          * @param number A non-empty string of digits with an optional
1002          *     leading + or -.
1003          * @return This instance.
1004          */
setNumber(String number)1005         public MeasureBuilder setNumber(String number) {
1006             return setStringArgument(TtsSpan.ARG_NUMBER, number);
1007         }
1008 
1009         /**
1010          * Convenience method that converts the integer part to a String and set
1011          * it to the value for {@link #ARG_INTEGER_PART}.
1012          * @param integerPart The integer part of a decimal or fraction.
1013          * @return This instance.
1014          */
setIntegerPart(long integerPart)1015         public MeasureBuilder setIntegerPart(long integerPart) {
1016             return setIntegerPart(String.valueOf(integerPart));
1017         }
1018 
1019         /**
1020          * Sets the {@link #ARG_INTEGER_PART} argument.
1021          * @param integerPart The integer part of a decimal or fraction; a
1022          * non-empty string of digits with an optional
1023          *     leading + or -.
1024          * @return This instance.
1025          */
setIntegerPart(String integerPart)1026         public MeasureBuilder setIntegerPart(String integerPart) {
1027             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
1028         }
1029 
1030         /**
1031          * Sets the {@link #ARG_FRACTIONAL_PART} argument.
1032          * @param fractionalPart The fractional part of a decimal; a non-empty
1033          *     string of digits with an optional leading + or -.
1034          * @return This instance.
1035          */
setFractionalPart(String fractionalPart)1036         public MeasureBuilder setFractionalPart(String fractionalPart) {
1037             return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART,
1038                                      fractionalPart);
1039         }
1040 
1041         /**
1042          * Convenience method that converts the numerator to a String and set it
1043          * to the value for {@link #ARG_NUMERATOR}.
1044          * @param numerator The numerator of a fraction.
1045          * @return This instance.
1046          */
setNumerator(long numerator)1047         public MeasureBuilder setNumerator(long numerator) {
1048             return setNumerator(String.valueOf(numerator));
1049         }
1050 
1051         /**
1052          * Sets the {@link #ARG_NUMERATOR} argument.
1053          * @param numerator The numerator of a fraction; a non-empty string of
1054          *     digits with an optional leading + or -.
1055          * @return This instance.
1056          */
setNumerator(String numerator)1057         public MeasureBuilder setNumerator(String numerator) {
1058             return setStringArgument(TtsSpan.ARG_NUMERATOR, numerator);
1059         }
1060 
1061         /**
1062          * Convenience method that converts the denominator to a String and set
1063          * it to the value for {@link #ARG_DENOMINATOR}.
1064          * @param denominator The denominator of a fraction.
1065          * @return This instance.
1066          */
setDenominator(long denominator)1067         public MeasureBuilder setDenominator(long denominator) {
1068             return setDenominator(String.valueOf(denominator));
1069         }
1070 
1071         /**
1072          * Sets the {@link #ARG_DENOMINATOR} argument.
1073          * @param denominator The denominator of a fraction; a non-empty string
1074          *     of digits with an optional leading + or -.
1075          * @return This instance.
1076          */
setDenominator(String denominator)1077         public MeasureBuilder setDenominator(String denominator) {
1078             return setStringArgument(TtsSpan.ARG_DENOMINATOR, denominator);
1079         }
1080 
1081         /**
1082          * Sets the {@link #ARG_UNIT} argument.
1083          * @param unit The unit of the measure.
1084          * @return This instance.
1085          * @see TtsSpan#ARG_UNIT
1086          */
setUnit(String unit)1087         public MeasureBuilder setUnit(String unit) {
1088             return setStringArgument(TtsSpan.ARG_UNIT, unit);
1089         }
1090     }
1091 
1092     /**
1093      * A builder for TtsSpans of type {@link #TYPE_TIME}.
1094      */
1095     public static class TimeBuilder
1096             extends SemioticClassBuilder<TimeBuilder> {
1097 
1098         /**
1099          * Creates a builder for a TtsSpan of type {@link #TYPE_TIME}.
1100          */
TimeBuilder()1101         public TimeBuilder() {
1102             super(TtsSpan.TYPE_TIME);
1103         }
1104 
1105         /**
1106          * Creates a builder for a TtsSpan of type {@link #TYPE_TIME} and
1107          * sets the {@link #ARG_HOURS} and {@link #ARG_MINUTES} arguments.
1108          */
TimeBuilder(int hours, int minutes)1109         public TimeBuilder(int hours, int minutes) {
1110             this();
1111             setHours(hours);
1112             setMinutes(minutes);
1113         }
1114 
1115         /**
1116          * Sets the {@link #ARG_HOURS} argument.
1117          * @param hours The value to be set for hours. See {@link #ARG_HOURS}.
1118          * @return This instance.
1119          * @see #ARG_HOURS
1120          */
setHours(int hours)1121         public TimeBuilder setHours(int hours) {
1122             return setIntArgument(TtsSpan.ARG_HOURS, hours);
1123         }
1124 
1125         /**
1126          * Sets the {@link #ARG_MINUTES} argument.
1127          * @param minutes The value to be set for minutes. See
1128          *     {@link #ARG_MINUTES}.
1129          * @return This instance.
1130          * @see #ARG_MINUTES
1131          */
setMinutes(int minutes)1132         public TimeBuilder setMinutes(int minutes) {
1133             return setIntArgument(TtsSpan.ARG_MINUTES, minutes);
1134         }
1135     }
1136 
1137     /**
1138      * A builder for TtsSpans of type {@link #TYPE_DATE}.
1139      */
1140     public static class DateBuilder
1141             extends SemioticClassBuilder<DateBuilder> {
1142 
1143         /**
1144          * Creates a builder for a TtsSpan of type {@link #TYPE_DATE}.
1145          */
DateBuilder()1146         public DateBuilder() {
1147             super(TtsSpan.TYPE_DATE);
1148         }
1149 
1150         /**
1151          * Creates a builder for a TtsSpan of type {@link #TYPE_TIME} and
1152          * possibly sets the {@link #ARG_WEEKDAY}, {@link #ARG_DAY},
1153          * {@link #ARG_MONTH} and {@link #ARG_YEAR} arguments. Pass null to any
1154          * argument to leave it unset.
1155          */
DateBuilder(Integer weekday, Integer day, Integer month, Integer year)1156         public DateBuilder(Integer weekday,
1157                            Integer day,
1158                            Integer month,
1159                            Integer year) {
1160             this();
1161             if (weekday != null) {
1162                 setWeekday(weekday);
1163             }
1164             if (day != null) {
1165                 setDay(day);
1166             }
1167             if (month != null) {
1168                 setMonth(month);
1169             }
1170             if (year != null) {
1171                 setYear(year);
1172             }
1173         }
1174 
1175         /**
1176          * Sets the {@link #ARG_WEEKDAY} argument.
1177          * @param weekday The value to be set for weekday. See
1178          *     {@link #ARG_WEEKDAY}.
1179          * @return This instance.
1180          * @see #ARG_WEEKDAY
1181          */
setWeekday(int weekday)1182         public DateBuilder setWeekday(int weekday) {
1183             return setIntArgument(TtsSpan.ARG_WEEKDAY, weekday);
1184         }
1185 
1186         /**
1187          * Sets the {@link #ARG_DAY} argument.
1188          * @param day The value to be set for day. See {@link #ARG_DAY}.
1189          * @return This instance.
1190          * @see #ARG_DAY
1191          */
setDay(int day)1192         public DateBuilder setDay(int day) {
1193             return setIntArgument(TtsSpan.ARG_DAY, day);
1194         }
1195 
1196         /**
1197          * Sets the {@link #ARG_MONTH} argument.
1198          * @param month The value to be set for month. See {@link #ARG_MONTH}.
1199          * @return This instance.
1200          * @see #ARG_MONTH
1201          */
setMonth(int month)1202         public DateBuilder setMonth(int month) {
1203             return setIntArgument(TtsSpan.ARG_MONTH, month);
1204         }
1205 
1206         /**
1207          * Sets the {@link #ARG_YEAR} argument.
1208          * @param year The value to be set for year. See {@link #ARG_YEAR}.
1209          * @return This instance.
1210          * @see #ARG_YEAR
1211          */
setYear(int year)1212         public DateBuilder setYear(int year) {
1213             return setIntArgument(TtsSpan.ARG_YEAR, year);
1214         }
1215     }
1216 
1217     /**
1218      * A builder for TtsSpans of type {@link #TYPE_MONEY}.
1219      */
1220     public static class MoneyBuilder
1221             extends SemioticClassBuilder<MoneyBuilder> {
1222 
1223         /**
1224          * Creates a TtsSpan of type {@link #TYPE_MONEY}.
1225          */
MoneyBuilder()1226         public MoneyBuilder() {
1227             super(TtsSpan.TYPE_MONEY);
1228         }
1229 
1230         /**
1231          * Convenience method that converts the number to a String and set it to
1232          * the value for {@link #ARG_INTEGER_PART}.
1233          * @param integerPart The integer part of the amount.
1234          * @return This instance.
1235          */
setIntegerPart(long integerPart)1236         public MoneyBuilder setIntegerPart(long integerPart) {
1237             return setIntegerPart(String.valueOf(integerPart));
1238         }
1239 
1240         /**
1241          * Sets the {@link #ARG_INTEGER_PART} argument.
1242          * @param integerPart A non-empty string of digits with an optional
1243          *     leading + or -.
1244          * @return This instance.
1245          */
setIntegerPart(String integerPart)1246         public MoneyBuilder setIntegerPart(String integerPart) {
1247             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
1248         }
1249 
1250         /**
1251          * Sets the {@link #ARG_FRACTIONAL_PART} argument.
1252          * @param fractionalPart Can be a string of digits of any size.
1253          * @return This instance.
1254          */
setFractionalPart(String fractionalPart)1255         public MoneyBuilder setFractionalPart(String fractionalPart) {
1256             return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART, fractionalPart);
1257         }
1258 
1259         /**
1260          * Sets the {@link #ARG_CURRENCY} argument.
1261          * @param currency Should be a ISO4217 currency code, e.g. "USD".
1262          * @return This instance.
1263          */
setCurrency(String currency)1264         public MoneyBuilder setCurrency(String currency) {
1265             return setStringArgument(TtsSpan.ARG_CURRENCY, currency);
1266         }
1267 
1268         /**
1269          * Sets the {@link #ARG_QUANTITY} argument.
1270          * @param quantity
1271          * @return This instance.
1272          */
setQuantity(String quantity)1273         public MoneyBuilder setQuantity(String quantity) {
1274             return setStringArgument(TtsSpan.ARG_QUANTITY, quantity);
1275         }
1276     }
1277 
1278     /**
1279      * A builder for TtsSpans of type {@link #TYPE_TELEPHONE}.
1280      */
1281     public static class TelephoneBuilder
1282             extends SemioticClassBuilder<TelephoneBuilder> {
1283 
1284         /**
1285          * Creates a TtsSpan of type {@link #TYPE_TELEPHONE}.
1286          */
TelephoneBuilder()1287         public TelephoneBuilder() {
1288             super(TtsSpan.TYPE_TELEPHONE);
1289         }
1290 
1291         /**
1292          * Creates a TtsSpan of type {@link #TYPE_TELEPHONE} and sets the
1293          * {@link #ARG_NUMBER_PARTS} argument.
1294          */
TelephoneBuilder(String numberParts)1295         public TelephoneBuilder(String numberParts) {
1296             this();
1297             setNumberParts(numberParts);
1298         }
1299 
1300         /**
1301          * Sets the {@link #ARG_COUNTRY_CODE} argument.
1302          * @param countryCode The country code can be a series of digits
1303          * optionally prefixed with a "+".
1304          * @return This instance.
1305          */
setCountryCode(String countryCode)1306         public TelephoneBuilder setCountryCode(String countryCode) {
1307             return setStringArgument(TtsSpan.ARG_COUNTRY_CODE, countryCode);
1308         }
1309 
1310         /**
1311          * Sets the {@link #ARG_NUMBER_PARTS} argument.
1312          * @param numberParts The main telephone number. Can be a series of
1313          *     digits and letters separated by spaces, "/", "-" or ".".
1314          * @return This instance.
1315          */
setNumberParts(String numberParts)1316         public TelephoneBuilder setNumberParts(String numberParts) {
1317             return setStringArgument(TtsSpan.ARG_NUMBER_PARTS, numberParts);
1318         }
1319 
1320         /**
1321          * Sets the {@link #ARG_EXTENSION} argument.
1322          * @param extension The extension can be a series of digits.
1323          * @return This instance.
1324          */
setExtension(String extension)1325         public TelephoneBuilder setExtension(String extension) {
1326             return setStringArgument(TtsSpan.ARG_EXTENSION, extension);
1327         }
1328     }
1329 
1330     /**
1331      * A builder for TtsSpans of type {@link #TYPE_ELECTRONIC}.
1332      */
1333     public static class ElectronicBuilder
1334             extends SemioticClassBuilder<ElectronicBuilder> {
1335 
1336         /**
1337          * Creates a TtsSpan of type {@link #TYPE_ELECTRONIC}.
1338          */
ElectronicBuilder()1339         public ElectronicBuilder() {
1340             super(TtsSpan.TYPE_ELECTRONIC);
1341         }
1342 
1343         /**
1344          * Sets the {@link #ARG_USERNAME} and {@link #ARG_DOMAIN}
1345          *     arguments, representing an email address.
1346          * @param username The part before the @ in the email address.
1347          * @param domain The part after the @ in the email address.
1348          * @return This instance.
1349          */
setEmailArguments(String username, String domain)1350         public ElectronicBuilder setEmailArguments(String username,
1351                                                    String domain) {
1352             return setDomain(domain).setUsername(username);
1353         }
1354 
1355         /**
1356          * Sets the {@link #ARG_PROTOCOL} argument.
1357          * @param protocol The protocol of the URI. Examples are "http" and
1358          *     "ftp".
1359          * @return This instance.
1360          */
setProtocol(String protocol)1361         public ElectronicBuilder setProtocol(String protocol) {
1362             return setStringArgument(TtsSpan.ARG_PROTOCOL, protocol);
1363         }
1364 
1365         /**
1366          * Sets the {@link #ARG_USERNAME} argument.
1367          * @return This instance.
1368          */
setUsername(String username)1369         public ElectronicBuilder setUsername(String username) {
1370             return setStringArgument(TtsSpan.ARG_USERNAME, username);
1371         }
1372 
1373         /**
1374          * Sets the {@link #ARG_PASSWORD} argument.
1375          * @return This instance.
1376          */
setPassword(String password)1377         public ElectronicBuilder setPassword(String password) {
1378             return setStringArgument(TtsSpan.ARG_PASSWORD, password);
1379         }
1380 
1381         /**
1382          * Sets the {@link #ARG_DOMAIN} argument.
1383          * @param domain The domain, for example "source.android.com".
1384          * @return This instance.
1385          */
setDomain(String domain)1386         public ElectronicBuilder setDomain(String domain) {
1387             return setStringArgument(TtsSpan.ARG_DOMAIN, domain);
1388         }
1389 
1390         /**
1391          * Sets the {@link #ARG_PORT} argument.
1392          * @return This instance.
1393          */
setPort(int port)1394         public ElectronicBuilder setPort(int port) {
1395             return setIntArgument(TtsSpan.ARG_PORT, port);
1396         }
1397 
1398         /**
1399          * Sets the {@link #ARG_PATH} argument.
1400          * @param path For example "source/index.html".
1401          * @return This instance.
1402          */
setPath(String path)1403         public ElectronicBuilder setPath(String path) {
1404             return setStringArgument(TtsSpan.ARG_PATH, path);
1405         }
1406 
1407         /**
1408          * Sets the {@link #ARG_QUERY_STRING} argument.
1409          * @param queryString For example "arg=value&argtwo=value".
1410          * @return This instance.
1411          */
setQueryString(String queryString)1412         public ElectronicBuilder setQueryString(String queryString) {
1413             return setStringArgument(TtsSpan.ARG_QUERY_STRING, queryString);
1414         }
1415 
1416         /**
1417          * Sets the {@link #ARG_FRAGMENT_ID} argument.
1418          * @return This instance.
1419          */
setFragmentId(String fragmentId)1420         public ElectronicBuilder setFragmentId(String fragmentId) {
1421             return setStringArgument(TtsSpan.ARG_FRAGMENT_ID, fragmentId);
1422         }
1423     }
1424 
1425     /**
1426      * A builder for TtsSpans of type {@link #TYPE_DIGITS}.
1427      */
1428     public static class DigitsBuilder
1429             extends SemioticClassBuilder<DigitsBuilder> {
1430 
1431         /**
1432          * Creates a builder for a TtsSpan of type {@link #TYPE_DIGITS}.
1433          */
DigitsBuilder()1434         public DigitsBuilder() {
1435             super(TtsSpan.TYPE_DIGITS);
1436         }
1437 
1438         /**
1439          * Creates a builder for a TtsSpan of type {@link #TYPE_DIGITS}
1440          * and sets the {@link #ARG_DIGITS} argument.
1441          */
DigitsBuilder(String digits)1442         public DigitsBuilder(String digits) {
1443             this();
1444             setDigits(digits);
1445         }
1446 
1447         /**
1448          * Sets the {@link #ARG_DIGITS} argument.
1449          * @param digits A string of digits.
1450          * @return This instance.
1451          */
setDigits(String digits)1452         public DigitsBuilder setDigits(String digits) {
1453             return setStringArgument(TtsSpan.ARG_DIGITS, digits);
1454         }
1455     }
1456 
1457     /**
1458      * A builder for TtsSpans of type {@link #TYPE_VERBATIM}.
1459      */
1460     public static class VerbatimBuilder
1461             extends SemioticClassBuilder<VerbatimBuilder> {
1462 
1463         /**
1464          * Creates a builder for a TtsSpan of type {@link #TYPE_VERBATIM}.
1465          */
VerbatimBuilder()1466         public VerbatimBuilder() {
1467             super(TtsSpan.TYPE_VERBATIM);
1468         }
1469 
1470         /**
1471          * Creates a builder for a TtsSpan of type {@link #TYPE_VERBATIM}
1472          * and sets the {@link #ARG_VERBATIM} argument.
1473          */
VerbatimBuilder(String verbatim)1474         public VerbatimBuilder(String verbatim) {
1475             this();
1476             setVerbatim(verbatim);
1477         }
1478 
1479         /**
1480          * Sets the {@link #ARG_VERBATIM} argument.
1481          * @param verbatim A string of characters that will be read verbatim,
1482          *     except whitespace.
1483          * @return This instance.
1484          */
setVerbatim(String verbatim)1485         public VerbatimBuilder setVerbatim(String verbatim) {
1486             return setStringArgument(TtsSpan.ARG_VERBATIM, verbatim);
1487         }
1488     }
1489 }
1490