1 package org.apache.slide.projector.i18n; 2 3 import java.io.InputStream ; 4 import java.text.MessageFormat ; 5 import java.util.Collection ; 6 import java.util.HashMap ; 7 import java.util.Iterator ; 8 import java.util.Locale ; 9 import java.util.Map ; 10 import java.util.logging.Level ; 11 import java.util.logging.Logger ; 12 13 import org.apache.slide.projector.Projector; 14 import org.apache.slide.projector.URI; 15 import org.apache.slide.projector.application.Application; 16 import org.apache.slide.projector.application.ApplicationListener; 17 import org.apache.slide.projector.value.StreamableValue; 18 import org.apache.slide.projector.value.URIValue; 19 import org.apache.webdav.lib.Subscriber; 20 import org.xml.sax.InputSource ; 21 import org.xml.sax.helpers.AttributesImpl ; 22 23 import de.zeigermann.xml.simpleImporter.DefaultSimpleImportHandler; 24 import de.zeigermann.xml.simpleImporter.SimpleImporter; 25 import de.zeigermann.xml.simpleImporter.SimplePath; 26 27 public class MessageManager implements ApplicationListener, Subscriber { 28 private static Logger logger = Logger.getLogger(MessageManager.class.getName()); 29 30 private final static String MESSAGES_CONFIG = "messages.xml"; 31 32 private final static String MESSAGES_NOT_FOUND_ID = "messageNotFound"; 33 34 private Map installedMessages = new HashMap (); 35 private Map messages = new HashMap (); 36 private static MessageManager messageManager = new MessageManager(); 37 38 private MessageManager() { 39 } 40 41 public static MessageManager getInstance() { 42 return messageManager; 43 } 44 45 public static String getText(String id, String entry, Object [] arguments, Locale locale, String defaultText) { 46 Message message = messageManager.findMessage(id, locale); 47 if (message != null) return messageManager.format(message.getEntry(entry), arguments); 48 return defaultText; 49 } 50 51 public static String getText(String id, String entry, Object [] arguments, Locale locale) throws MessageNotFoundException { 52 Message message = messageManager.findMessage(id, locale); 53 if (message != null) return messageManager.format(message.getEntry(entry), arguments); 54 throw new MessageNotFoundException(new ErrorMessage(MESSAGES_NOT_FOUND_ID, new String [] { id })); 55 } 56 57 public static Map getEntries(String id, Locale locale) throws MessageNotFoundException { 58 Message message = messageManager.findMessage(id, locale); 59 if ( message == null ) throw new MessageNotFoundException(new ErrorMessage(MESSAGES_NOT_FOUND_ID, new String [] { id })); 60 return message.getEntries(); 61 } 62 63 public void install(String type, URI applicationUri, URI configurationUri) { 64 if ( type == Application.MESSAGES ) { 65 install(configurationUri); 66 } 67 } 68 69 public void uninstall(String type, URI applicationUri, URI configurationUri) { 70 if ( type == Application.MESSAGES ) { 71 uninstall(configurationUri); 72 } 73 } 74 75 public void update(String type, URI applicationUri, URI configurationUri) { 76 if ( type == Application.MESSAGES ) { 77 update(configurationUri); 78 } 79 } 80 81 public void install(URI messagesUri) { 82 logger.log(Level.FINE, "Installing messages '"+messagesUri+"'"); 83 try { 84 Map applicationMessages = new HashMap (); 85 StreamableValue messagesResource = (StreamableValue)Projector.getRepository().getResource(messagesUri, Projector.getCredentials()); 86 if ( messagesResource != null ) { 87 InputStream inputStream = messagesResource.getInputStream(); 88 SimpleImporter importer = new SimpleImporter(); 89 importer.setIncludeLeadingCDataIntoStartElementCallback(true); 90 ConfigurationHandler handler = new ConfigurationHandler(); 91 importer.addSimpleImportHandler(handler); 92 importer.parse(new InputSource (inputStream)); 93 Map parsedMessages = handler.getMessages(); 94 applicationMessages.putAll(parsedMessages); 95 Projector.getRepository().subscribe("Update", messagesUri, 0, this, Projector.getCredentials()); 96 } else { 97 logger.log(Level.FINE, "Configured messages resource '"+messagesUri+"' not found!"); 98 } 99 messages.putAll(applicationMessages); 100 installedMessages.put(messagesUri, applicationMessages.keySet()); 101 } catch (Exception exception) { 102 logger.log(Level.SEVERE, "Error while parsing messages", exception); 103 } 104 } 105 106 public void uninstall(URI messageUri) { 107 logger.log(Level.FINE, "Uninstalling messages '"+messageUri+"'"); 108 Collection messageKeys = (Collection )installedMessages.get(messageUri); 109 for ( Iterator i = messageKeys.iterator(); i.hasNext(); ) { 110 String messageKey = (String )i.next(); 111 messages.remove(messageKey); 112 logger.log(Level.FINE, "Removing message with key '"+messageKey+"'"); 113 } 114 installedMessages.remove(messageUri); 115 Projector.getRepository().unsubscribe(messageUri, this, Projector.getCredentials()); 116 } 117 118 public void update(URI messagesUri) { 119 uninstall(messagesUri); 120 install(messagesUri); 121 } 122 123 public void notify(String uri, Map information) { 124 URI messageUri = new URIValue(uri); 125 uninstall(messageUri); 126 install(messageUri); 127 } 128 129 private String format(String formatString, Object [] arguments) { 130 if (formatString == null) return null; 131 return MessageFormat.format(formatString, arguments); 132 } 133 134 private Message findMessage(String id, Locale locale) { 135 Message message = lookupMessage(id, locale); 136 if (message == null) { 137 message = lookupMessage(id, Locale.getDefault()); 138 } 139 if (message == null) { 140 logger.severe("No message found for id=" + id + " locale=" + locale); 141 } 142 return message; 143 } 144 145 private Message lookupMessage(String id, Locale locale) { 146 StringBuffer keyBuffer = new StringBuffer (64); 147 keyBuffer.append(id); 148 if (locale.getLanguage() != null) keyBuffer.append("_" + locale.getLanguage()); 149 if (locale.getCountry() != null) keyBuffer.append("_" + locale.getCountry()); 150 if (locale.getVariant() != null) keyBuffer.append("_" + locale.getVariant()); 151 String key = keyBuffer.toString(); 152 if (messages.containsKey(key)) return (Message)messages.get(key); 153 while (key.lastIndexOf('_') > 0) { 154 key = key.substring(0, key.lastIndexOf('_')); 155 if (messages.containsKey(key)) return (Message)messages.get(key); 156 } 157 return null; 158 } 159 160 class ConfigurationHandler extends DefaultSimpleImportHandler { 161 private Map messages = new HashMap (); 162 private String id; 163 private Message message; 164 165 public void startElement(SimplePath path, String name, AttributesImpl attributes, String leadingCDdata) { 166 if (path.matches("message")) { 167 id = attributes.getValue("id"); 168 } else if (path.matches("message/locale")) { 169 message = new Message(id); 170 message.setLanguage(attributes.getValue("language")); 171 message.setCountry(attributes.getValue("country")); 172 message.setVariant(attributes.getValue("variant")); 173 } else if (path.matches("message/locale/entry")) { 174 String key = attributes.getValue("key"); 175 message.addEntry(key, leadingCDdata); 176 } 177 } 178 179 public void endElement(SimplePath path, String name) { 180 if (path.matches("message/locale")) { 181 messages.put(message.getKey(), message); 182 } 183 } 184 185 Map getMessages() { 186 return messages; 187 } 188 } 189 190 static class Message { 191 private String id, language, country, variant; 192 private Map entries = new HashMap (); 193 194 public Message(String id) { 195 this.id = id; 196 } 197 198 public void addEntry(String key, String value) { 199 entries.put(key, value); 200 } 201 202 public String getEntry(String key) { 203 return (String )entries.get(key); 204 } 205 206 public Map getEntries() { 207 return entries; 208 } 209 210 public void setLanguage(String language) { 211 this.language = language; 212 } 213 214 public void setCountry(String country) { 215 this.country = country; 216 } 217 218 public void setVariant(String variant) { 219 this.variant = variant; 220 } 221 222 public String getKey() { 223 StringBuffer key = new StringBuffer (64); 224 key.append(id); 225 if (language != null) key.append("_" + language); 226 if (country != null) key.append("_" + country); 227 if (variant != null) key.append("_" + variant); 228 return key.toString(); 229 } 230 } 231 } | Popular Tags |