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 |