| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * This defines a class for loading locale data incrementally from | |
| 7 * an external source as JSON. The external sources expected are either | |
| 8 * local files or via HTTP request. | |
| 9 */ | |
| 10 | |
| 11 library lazy_locale_data; | |
| 12 | |
| 13 import 'dart:async'; | |
| 14 import 'dart:convert'; | |
| 15 import 'intl_helpers.dart'; | |
| 16 | |
| 17 /** | |
| 18 * This implements the very basic map-type operations which are used | |
| 19 * in locale lookup, and looks them up based on a URL that defines | |
| 20 * the external source. | |
| 21 */ | |
| 22 class LazyLocaleData { | |
| 23 /// This holds the data we have loaded. | |
| 24 Map map; | |
| 25 | |
| 26 /// The object that actually does the data reading. | |
| 27 LocaleDataReader _reader; | |
| 28 | |
| 29 /** | |
| 30 * In order to avoid a potentially remote call to see if a locale | |
| 31 * is available, we hold a complete list of all the available | |
| 32 * locales. | |
| 33 */ | |
| 34 List availableLocales; | |
| 35 | |
| 36 /** | |
| 37 * Given a piece of remote data, apply [_creationFunction] to it to | |
| 38 * convert it into the right form. Typically this means converting it | |
| 39 * from a Map into an object form. | |
| 40 */ | |
| 41 Function _creationFunction; | |
| 42 | |
| 43 /** | |
| 44 * The set of available locales. | |
| 45 */ | |
| 46 Set availableLocaleSet; | |
| 47 | |
| 48 /** | |
| 49 * The constructor. The [_reader] specifies where the data comes | |
| 50 * from. The [_creationFunction] creates the appropriate data type | |
| 51 * from the remote data (which typically comes in as a Map). The | |
| 52 * [keys] lists the set of remotely available locale names so we know which | |
| 53 * things can be fetched without having to check remotely. | |
| 54 */ | |
| 55 LazyLocaleData(this._reader, this._creationFunction, List keys) { | |
| 56 map = new Map(); | |
| 57 availableLocales = keys; | |
| 58 availableLocaleSet = new Set.from(availableLocales); | |
| 59 } | |
| 60 | |
| 61 /** | |
| 62 * Tests if we have data for the locale available. Note that this returns | |
| 63 * true even if the data is known to be available remotely but not yet loaded. | |
| 64 */ | |
| 65 bool containsKey(String locale) => availableLocaleSet.contains(locale); | |
| 66 | |
| 67 /** Returns the list of keys/locale names. */ | |
| 68 List get keys => availableLocales; | |
| 69 | |
| 70 /** | |
| 71 * Returns the data stored for [localeName]. If no data has been loaded | |
| 72 * for [localeName], throws an exception. If no data is available for | |
| 73 * [localeName] then throw an exception with a different message. | |
| 74 */ | |
| 75 operator [](String localeName) { | |
| 76 if (containsKey(localeName)) { | |
| 77 var data = map[localeName]; | |
| 78 if (data == null) { | |
| 79 throw new LocaleDataException( | |
| 80 "Locale $localeName has not been initialized." | |
| 81 " Call initializeDateFormatting($localeName, <data url>) first"); | |
| 82 } else { | |
| 83 return data; | |
| 84 } | |
| 85 } else { | |
| 86 unsupportedLocale(localeName); | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 /** | |
| 91 * Throw an exception indicating that the locale has no data available, | |
| 92 * either locally or remotely. | |
| 93 */ | |
| 94 unsupportedLocale(localeName) { | |
| 95 throw new LocaleDataException('Locale $localeName has no data available'); | |
| 96 } | |
| 97 | |
| 98 /** | |
| 99 * Initialize for locale. Internal use only. As a user, call | |
| 100 * initializeDateFormatting instead. | |
| 101 */ | |
| 102 Future initLocale(String localeName) { | |
| 103 var data = _reader.read(localeName); | |
| 104 return jsonData(data).then((input) { | |
| 105 map[localeName] = _creationFunction(input); | |
| 106 }); | |
| 107 } | |
| 108 | |
| 109 /** | |
| 110 * Given a Future [input] whose value is expected to be a string in JSON form, | |
| 111 * return another future that parses the JSON into a usable format. | |
| 112 */ | |
| 113 Future jsonData(Future input) { | |
| 114 return input.then((response) => JSON.decode(response)); | |
| 115 } | |
| 116 } | |
| OLD | NEW |