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