1 package com.sun.syndication.io.impl; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.net.URL; 6 import java.util.*; 7 8 /*** 9 * Properties loader that aggregates a master properties file and several extra properties files, 10 * all from the current classpath. 11 * <P> 12 * The master properties file has to be in a distinct location than the extra properties files. 13 * First the master properties file is loaded, then all the extra properties files in their order 14 * of appearance in the classpath. 15 * <P> 16 * Current use cases (plugin manager for parsers/converters/generators for feeds and modules 17 * and date formats) assume properties are list of tokens, that why the only method to get 18 * property values is the getTokenizedProperty(). 19 * <p> 20 * 21 * @author Alejandro Abdelnur 22 * 23 */ 24 public class PropertiesLoader { 25 26 private static final String MASTER_PLUGIN_FILE = "com/sun/syndication/rome.properties"; 27 private static final String EXTRA_PLUGIN_FILE = "rome.properties"; 28 29 30 private static Map clMap = 31 new WeakHashMap(); 32 33 34 /*** 35 * Returns the PropertiesLoader singleton used by ROME to load plugin components. 36 * 37 * @return PropertiesLoader singleton. 38 * 39 */ 40 public static PropertiesLoader getPropertiesLoader() { 41 synchronized(PropertiesLoader.class) { 42 PropertiesLoader loader = (PropertiesLoader) 43 clMap.get(Thread.currentThread().getContextClassLoader()); 44 if (loader == null) { 45 try { 46 loader = new PropertiesLoader(MASTER_PLUGIN_FILE, EXTRA_PLUGIN_FILE); 47 clMap.put(Thread.currentThread().getContextClassLoader(), loader); 48 } 49 catch (IOException ex) { 50 throw new RuntimeException(ex); 51 } 52 } 53 return loader; 54 } 55 } 56 57 private Properties[] _properties; 58 59 /*** 60 * Creates a PropertiesLoader. 61 * <p> 62 * @param masterFileLocation master file location, there must be only one. 63 * @param extraFileLocation extra file location, there may be many. 64 * @throws IOException thrown if one of the properties file could not be read. 65 * 66 */ 67 private PropertiesLoader(String masterFileLocation,String extraFileLocation) throws IOException { 68 List propertiesList = new ArrayList(); 69 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 70 71 try { 72 InputStream is = classLoader.getResourceAsStream(masterFileLocation); 73 Properties p = new Properties(); 74 p.load(is); 75 is.close(); 76 propertiesList.add(p); 77 } 78 catch (IOException ioex) { 79 IOException ex = new IOException("could not load ROME master plugins file ["+masterFileLocation+"], "+ 80 ioex.getMessage()); 81 ex.setStackTrace(ioex.getStackTrace()); 82 throw ex; 83 } 84 85 Enumeration urls = classLoader.getResources(extraFileLocation); 86 while (urls.hasMoreElements()) { 87 URL url = (URL) urls.nextElement(); 88 Properties p = new Properties(); 89 try { 90 InputStream is = url.openStream(); 91 p.load(is); 92 is.close(); 93 } 94 catch (IOException ioex) { 95 IOException ex = new IOException("could not load ROME extensions plugins file ["+url.toString()+"], "+ 96 ioex.getMessage()); 97 ex.setStackTrace(ioex.getStackTrace()); 98 throw ex; 99 } 100 propertiesList.add(p); 101 } 102 103 _properties = new Properties[propertiesList.size()]; 104 propertiesList.toArray(_properties); 105 } 106 107 /*** 108 * Returns an array of tokenized values stored under a property key in all properties files. 109 * If the master file has this property its tokens will be the first ones in the array. 110 * <p> 111 * @param key property key to retrieve values 112 * @param separator String with all separator characters to tokenize from the values in all 113 * properties files. 114 * @return all the tokens for the given property key from all the properties files. 115 * 116 */ 117 public String[] getTokenizedProperty(String key,String separator) { 118 List entriesList = new ArrayList(); 119 for (int i=0;i<_properties.length;i++) { 120 String values = _properties[i].getProperty(key); 121 if (values!=null) { 122 StringTokenizer st = new StringTokenizer(values,separator); 123 while (st.hasMoreTokens()) { 124 String token = st.nextToken(); 125 entriesList.add(token); 126 } 127 } 128 } 129 String[] entries = new String[entriesList.size()]; 130 entriesList.toArray(entries); 131 return entries; 132 } 133 134 /*** 135 * Returns an array of values stored under a property key in all properties files. 136 * If the master file has this property it will be the first ones in the array. 137 * <p> 138 * @param key property key to retrieve values 139 * @return all the values for the given property key from all the properties files. 140 * 141 */ 142 public String[] getProperty(String key) { 143 List entriesList = new ArrayList(); 144 for (int i=0;i<_properties.length;i++) { 145 String values = _properties[i].getProperty(key); 146 if (values!=null) { 147 entriesList.add(values); 148 } 149 } 150 String[] entries = new String[entriesList.size()]; 151 entriesList.toArray(entries); 152 return entries; 153 } 154 155 }