1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
package org.apache.commons.i18n; |
22 | |
|
23 | |
import java.io.InputStream; |
24 | |
import java.text.MessageFormat; |
25 | |
import java.util.HashMap; |
26 | |
import java.util.Locale; |
27 | |
import java.util.Map; |
28 | |
import java.util.logging.Level; |
29 | |
import java.util.logging.Logger; |
30 | |
|
31 | |
import javax.xml.parsers.SAXParser; |
32 | |
import javax.xml.parsers.SAXParserFactory; |
33 | |
|
34 | |
import org.xml.sax.Attributes; |
35 | |
import org.xml.sax.InputSource; |
36 | |
import org.xml.sax.helpers.DefaultHandler; |
37 | |
|
38 | |
|
39 | |
|
40 | |
|
41 | |
|
42 | 29 | public class XMLMessageProvider implements MessageProvider { |
43 | 2 | private static final Logger logger = Logger.getLogger(XMLMessageProvider.class.getName()); |
44 | |
|
45 | 1 | private static SAXParserFactory factory = SAXParserFactory.newInstance(); |
46 | |
|
47 | 5 | private Map messages = new HashMap(); |
48 | |
|
49 | 5 | public XMLMessageProvider(InputStream inputStream) { |
50 | |
try { |
51 | 5 | Map applicationMessages = new HashMap(); |
52 | 5 | SAXParser parser = factory.newSAXParser(); |
53 | 5 | ConfigurationHandler handler = new ConfigurationHandler(); |
54 | 5 | parser.parse(new InputSource(inputStream), handler); |
55 | 4 | Map parsedMessages = handler.getMessages(); |
56 | 4 | applicationMessages.putAll(parsedMessages); |
57 | 4 | messages.putAll(applicationMessages); |
58 | 1 | } catch (Exception exception) { |
59 | 1 | String msg = I18nUtils.INTERNAL_MESSAGES.getString(I18nUtils.MESSAGE_PARSING_ERROR); |
60 | 1 | logger.log(Level.SEVERE,msg,exception); |
61 | 1 | throw new RuntimeException(msg, exception); |
62 | 4 | } |
63 | 4 | } |
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
public String getText(String id, String entry, Locale locale) throws MessageNotFoundException { |
69 | 25 | Message message = findMessage(id, locale); |
70 | 24 | return message.getEntry(entry); |
71 | |
} |
72 | |
|
73 | |
|
74 | |
|
75 | |
|
76 | |
public Map getEntries(String id, Locale locale) throws MessageNotFoundException { |
77 | 7 | Message message = findMessage(id, locale); |
78 | 6 | return message.getEntries(); |
79 | |
} |
80 | |
|
81 | |
private Message findMessage(String id, Locale locale) { |
82 | 32 | Message message = lookupMessage(id, locale); |
83 | 32 | if (message == null) { |
84 | 5 | message = lookupMessage(id, Locale.getDefault()); |
85 | |
} |
86 | 32 | if (message == null ) throw new MessageNotFoundException( |
87 | |
MessageFormat.format( |
88 | |
I18nUtils.INTERNAL_MESSAGES.getString(I18nUtils.NO_MESSAGE_ENTRIES_FOUND), |
89 | |
new String[] { id })); |
90 | 30 | return message; |
91 | |
} |
92 | |
|
93 | |
private Message lookupMessage(String id, Locale locale) { |
94 | 37 | String key = id + '_' + locale.toString(); |
95 | 37 | if (messages.containsKey(key)) return (Message)messages.get(key); |
96 | 22 | locale = I18nUtils.getParentLocale(locale); |
97 | 26 | while (locale != null) { |
98 | 19 | key = id + '_' + locale.toString(); |
99 | 19 | if (messages.containsKey(key)) return (Message)messages.get(key); |
100 | 4 | locale = I18nUtils.getParentLocale(locale); |
101 | 4 | } |
102 | 7 | return null; |
103 | |
} |
104 | |
|
105 | 5 | class ConfigurationHandler extends DefaultHandler { |
106 | |
private String id, key; |
107 | |
private Message message; |
108 | |
private StringBuffer cData; |
109 | |
|
110 | |
public void startElement(String namespaceUri, String localeName, String qName, Attributes attributes) { |
111 | 82 | if (qName.matches("message")) { |
112 | 4 | id = attributes.getValue("id"); |
113 | 4 | } else if (qName.matches("locale")) { |
114 | 25 | message = new Message(id); |
115 | 25 | message.setLanguage(attributes.getValue("language")); |
116 | 25 | message.setCountry(attributes.getValue("country")); |
117 | 25 | message.setVariant(attributes.getValue("variant")); |
118 | 25 | } else if (qName.matches("entry")) { |
119 | 49 | key = attributes.getValue("key"); |
120 | 49 | cData = new StringBuffer(); |
121 | |
} |
122 | 82 | } |
123 | |
public void characters(char[] ch, |
124 | |
int start, |
125 | |
int length) { |
126 | 206 | if ( message != null && key != null && length > 0 ) { |
127 | 49 | cData.append(ch, start, length); |
128 | |
} |
129 | 206 | } |
130 | |
|
131 | |
public void endElement(String namespaceUri, String localeName, String qName) { |
132 | 82 | if (qName.matches("locale")) { |
133 | 25 | messages.put(message.getKey(), message); |
134 | 25 | } else if (qName.matches("entry")) { |
135 | 49 | message.addEntry(key, cData.toString()); |
136 | 49 | key = null; |
137 | |
} |
138 | 82 | } |
139 | |
|
140 | |
Map getMessages() { |
141 | 4 | return messages; |
142 | |
} |
143 | |
} |
144 | |
|
145 | |
static class Message { |
146 | |
private final String id; |
147 | |
private String language, country, variant; |
148 | 25 | private Map entries = new HashMap(); |
149 | |
|
150 | 25 | public Message(String id) { |
151 | 25 | this.id = id; |
152 | 25 | } |
153 | |
|
154 | |
public void addEntry(String key, String value) { |
155 | 49 | entries.put(key, value); |
156 | 49 | } |
157 | |
|
158 | |
public String getEntry(String key) { |
159 | 24 | return (String)entries.get(key); |
160 | |
} |
161 | |
|
162 | |
public Map getEntries() { |
163 | 6 | return entries; |
164 | |
} |
165 | |
|
166 | |
public void setLanguage(String language) { |
167 | 25 | this.language = language; |
168 | 25 | } |
169 | |
|
170 | |
public void setCountry(String country) { |
171 | 25 | this.country = country; |
172 | 25 | } |
173 | |
|
174 | |
public void setVariant(String variant) { |
175 | 25 | this.variant = variant; |
176 | 25 | } |
177 | |
|
178 | |
public String getKey() { |
179 | 25 | return id + '_' + new Locale((language != null) ? language : "", |
180 | |
(country != null) ? country : "", |
181 | |
(variant != null) ? variant : "").toString(); |
182 | |
} |
183 | |
} |
184 | |
} |