1 11 package org.eclipse.osgi.framework.internal.core; 12 13 import java.io.IOException ; 14 import java.io.InputStream ; 15 import java.lang.reflect.Field ; 16 import java.lang.reflect.Modifier ; 17 import java.security.AccessController ; 18 import java.security.PrivilegedAction ; 19 import java.util.*; 20 import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor; 21 import org.eclipse.osgi.framework.debug.Debug; 22 import org.eclipse.osgi.framework.log.FrameworkLogEntry; 23 24 29 public class MessageResourceBundle { 30 36 private static class MessagesProperties extends Properties { 37 38 private static final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC; 39 private static final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL; 40 private static final long serialVersionUID = 1L; 41 42 private final String bundleName; 43 private final Map fields; 44 private final boolean isAccessible; 45 46 public MessagesProperties(Map fieldMap, String bundleName, boolean isAccessible) { 47 super(); 48 this.fields = fieldMap; 49 this.bundleName = bundleName; 50 this.isAccessible = isAccessible; 51 } 52 53 56 public synchronized Object put(Object key, Object value) { 57 Object fieldObject = fields.put(key, ASSIGNED); 58 if (fieldObject == ASSIGNED) 60 return null; 61 if (fieldObject == null) { 62 final String msg = "NLS unused message: " + key + " in: " + bundleName; if (Debug.DEBUG_MESSAGE_BUNDLES) 64 System.out.println(msg); 65 log(SEVERITY_WARNING, msg, null); 66 return null; 67 } 68 final Field field = (Field ) fieldObject; 69 if ((field.getModifiers() & MOD_MASK) != MOD_EXPECTED) 71 return null; 72 try { 73 if (!isAccessible) 77 makeAccessible(field); 78 field.set(null, value); 83 } catch (Exception e) { 84 log(SEVERITY_ERROR, "Exception setting field value.", e); } 86 return null; 87 } 88 } 89 90 private static FrameworkAdaptor adaptor; 91 95 static final Object ASSIGNED = new Object (); 96 97 private static final String EXTENSION = ".properties"; 99 private static String [] nlSuffixes; 100 101 static int SEVERITY_ERROR = 0x04; 102 103 static int SEVERITY_WARNING = 0x02; 104 105 111 private static String [] buildVariants(String root) { 112 if (nlSuffixes == null) { 113 String nl = Locale.getDefault().toString(); 115 ArrayList result = new ArrayList(4); 116 int lastSeparator; 117 while (true) { 118 result.add('_' + nl + EXTENSION); 119 lastSeparator = nl.lastIndexOf('_'); 120 if (lastSeparator == -1) 121 break; 122 nl = nl.substring(0, lastSeparator); 123 } 124 result.add(EXTENSION); 126 nlSuffixes = (String []) result.toArray(new String [result.size()]); 127 } 128 root = root.replace('.', '/'); 129 String [] variants = new String [nlSuffixes.length]; 130 for (int i = 0; i < variants.length; i++) 131 variants[i] = root + nlSuffixes[i]; 132 return variants; 133 } 134 135 139 static void makeAccessible(final Field field) { 140 if (System.getSecurityManager() == null) { 141 field.setAccessible(true); 142 } else { 143 AccessController.doPrivileged(new PrivilegedAction () { 144 public Object run() { 145 field.setAccessible(true); 146 return null; 147 } 148 }); 149 } 150 } 151 152 private static void computeMissingMessages(String bundleName, Class clazz, Map fieldMap, Field [] fieldArray, boolean isAccessible) { 153 final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC; 155 final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL; 156 final int numFields = fieldArray.length; 157 for (int i = 0; i < numFields; i++) { 158 Field field = fieldArray[i]; 159 if ((field.getModifiers() & MOD_MASK) != MOD_EXPECTED) 160 continue; 161 if (fieldMap.get(field.getName()) == ASSIGNED) 163 continue; 164 try { 165 String value = "NLS missing message: " + field.getName() + " in: " + bundleName; if (Debug.DEBUG_MESSAGE_BUNDLES) 171 System.out.println(value); 172 log(SEVERITY_WARNING, value, null); 173 if (!isAccessible) 174 makeAccessible(field); 175 field.set(null, value); 176 } catch (Exception e) { 177 log(SEVERITY_ERROR, "Error setting the missing message value for: " + field.getName(), e); } 179 } 180 } 181 182 185 public static void load(final String bundleName, Class clazz) { 186 long start = System.currentTimeMillis(); 187 final Field [] fieldArray = clazz.getDeclaredFields(); 188 ClassLoader loader = clazz.getClassLoader(); 189 190 boolean isAccessible = (clazz.getModifiers() & Modifier.PUBLIC) != 0; 191 192 final int len = fieldArray.length; 194 Map fields = new HashMap(len * 2); 195 for (int i = 0; i < len; i++) 196 fields.put(fieldArray[i].getName(), fieldArray[i]); 197 198 final String [] variants = buildVariants(bundleName); 202 for (int i = 0; i < variants.length; i++) { 203 final InputStream input = loader==null ? ClassLoader.getSystemResourceAsStream(variants[i]) : loader.getResourceAsStream(variants[i]); 205 if (input == null) 206 continue; 207 try { 208 final MessagesProperties properties = new MessagesProperties(fields, bundleName, isAccessible); 209 properties.load(input); 210 } catch (IOException e) { 211 log(SEVERITY_ERROR, "Error loading " + variants[i], e); } finally { 213 if (input != null) 214 try { 215 input.close(); 216 } catch (IOException e) { 217 } 219 } 220 } 221 computeMissingMessages(bundleName, clazz, fields, fieldArray, isAccessible); 222 if (Debug.DEBUG_MESSAGE_BUNDLES) 223 System.out.println("Time to load message bundle: " + bundleName + " was " + (System.currentTimeMillis() - start) + "ms."); } 225 226 static void log(int severity, String msg, Exception e) { 227 if (adaptor != null) 228 adaptor.getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + ' ' + severity + ' ' + 1, msg, 0, e, null)); 229 else { 230 System.out.println(msg); 231 if (e != null) 232 e.printStackTrace(); 233 } 234 } 235 236 static void setAdaptor(FrameworkAdaptor adaptor) { 237 MessageResourceBundle.adaptor = adaptor; 238 } 239 } | Popular Tags |