1 16 package org.outerj.daisy.frontend.admin; 17 18 import org.apache.excalibur.source.SourceResolver; 19 import org.apache.excalibur.source.Source; 20 import org.apache.excalibur.source.impl.FileSource; 21 import org.apache.avalon.framework.thread.ThreadSafe; 22 import org.apache.avalon.framework.service.Serviceable; 23 import org.apache.avalon.framework.service.ServiceManager; 24 import org.apache.avalon.framework.service.ServiceException; 25 import org.apache.avalon.framework.activity.Initializable; 26 import org.apache.avalon.framework.activity.Disposable; 27 import org.apache.avalon.framework.logger.AbstractLogEnabled; 28 import org.apache.avalon.framework.configuration.Configurable; 29 import org.apache.avalon.framework.configuration.Configuration; 30 import org.apache.avalon.framework.configuration.ConfigurationException; 31 import org.apache.avalon.excalibur.monitor.ActiveMonitor; 32 import org.apache.avalon.excalibur.monitor.FileResource; 33 import org.outerj.daisy.repository.LocaleHelper; 34 35 import java.io.*; 36 import java.util.ArrayList ; 37 import java.util.Locale ; 38 import java.beans.PropertyChangeListener ; 39 import java.beans.PropertyChangeEvent ; 40 41 public class AdminLocalesImpl extends AbstractLogEnabled implements AdminLocales, ThreadSafe, Configurable, Serviceable, Initializable, Disposable { 42 private Locales locales; 43 private ServiceManager serviceManager; 44 private ActiveMonitor monitor; 45 private String localesURI; 46 private File localesFile; 47 private FileResource monitoredResource; 48 49 public void service(ServiceManager serviceManager) throws ServiceException { 50 this.serviceManager = serviceManager; 51 monitor = (ActiveMonitor)serviceManager.lookup(ActiveMonitor.ROLE); 52 } 53 54 public void configure(Configuration configuration) throws ConfigurationException { 55 localesURI = configuration.getChild("localesSource").getValue(); 56 } 57 58 public void initialize() throws Exception { 59 SourceResolver sourceResolver = null; 60 Source localesSource = null; 61 try { 62 sourceResolver = (SourceResolver)serviceManager.lookup(SourceResolver.ROLE); 63 localesSource = sourceResolver.resolveURI(localesURI); 64 if (localesSource instanceof FileSource) { 65 localesFile = ((FileSource)localesSource).getFile(); 66 monitoredResource = new FileResource(localesFile); 67 monitoredResource.addPropertyChangeListener(new ResourceListener()); 68 monitor.addResource(monitoredResource); 69 } else { 70 throw new Exception ("Source for the list of admin locales must be a file, not: " + localesURI); 71 } 72 } finally { 73 if (localesSource != null) 74 sourceResolver.release(localesSource); 75 if (sourceResolver != null) 76 serviceManager.release(sourceResolver); 77 } 78 reloadLocales(); 79 } 80 81 private synchronized void reloadLocales() { 82 ArrayList locales = new ArrayList (); 83 InputStream is = null; 84 85 try { 86 is = new FileInputStream(localesFile); 87 BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 88 String line = reader.readLine(); 89 while (line != null) { 90 if (line.equals("empty")) { 91 locales.add(""); 92 } else if (line.length() > 0 && line.charAt(0) != '#') { 93 locales.add(line.trim()); 94 } 95 line = reader.readLine(); 96 } 97 } catch (Exception e) { 98 getLogger().error("Error reading locales.", e); 99 } finally { 100 try { 101 if (is != null) 102 is.close(); 103 } catch (Exception e) { 104 getLogger().error("Error closing input stream of locales file.", e); 105 } 106 } 107 108 String [] localeStrings = (String [])locales.toArray(new String [locales.size()]); 109 Locale [] localeObjects = new Locale [localeStrings.length]; 110 for (int i = 0; i < localeStrings.length; i++) { 111 localeObjects[i] = LocaleHelper.parseLocale(localeStrings[i]); 112 } 113 this.locales = new LocalesImpl(localeStrings, localeObjects); 114 } 115 116 public Locales getLocales() { 117 return locales; 118 } 119 120 public void dispose() { 121 monitor.removeResource(monitoredResource); 122 serviceManager.release(monitor); 123 } 124 125 class ResourceListener implements PropertyChangeListener { 126 public void propertyChange(PropertyChangeEvent evt) { 127 if (evt.getPropertyName().equals("last-modified")) { 128 reloadLocales(); 129 } 130 } 131 } 132 133 static class LocalesImpl implements Locales { 134 private String [] localeStrings; 135 private Locale [] localeObjects; 136 137 public LocalesImpl(String [] localeStrings, Locale [] localeObjects) { 138 this.localeStrings = localeStrings; 139 this.localeObjects = localeObjects; 140 } 141 142 public String [] getAsStrings() { 143 return localeStrings; 144 } 145 146 public Locale [] getAsObjects() { 147 return localeObjects; 148 } 149 } 150 } 151 | Popular Tags |