This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 13847
Collapse All | Expand All

(-)openide/src/org/openide/util/NbBundle.java (+163 lines)
Lines 321-326 Link Here
321
        return getBundle(baseName, locale, getLoader());
321
        return getBundle(baseName, locale, getLoader());
322
    }
322
    }
323
323
324
    private static final boolean USE_FAST_PROPERTIES = Boolean.getBoolean("NbBundle.fast.properties");
325
    
324
    /** Get a resource bundle the hard way.
326
    /** Get a resource bundle the hard way.
325
    * @param baseName bundle basename
327
    * @param baseName bundle basename
326
    * @param locale the locale to use
328
    * @param locale the locale to use
Lines 331-336 Link Here
331
    public static final ResourceBundle getBundle(String baseName, Locale locale,
333
    public static final ResourceBundle getBundle(String baseName, Locale locale,
332
            ClassLoader loader) throws MissingResourceException {
334
            ClassLoader loader) throws MissingResourceException {
333
        if (USE_DEBUG_LOADER) loader = DebugLoader.get (loader);
335
        if (USE_DEBUG_LOADER) loader = DebugLoader.get (loader);
336
        if (USE_FAST_PROPERTIES) {
337
            ResourceBundle b = getBundleFast(baseName, locale, loader);
338
            if (b != null) {
339
                return b;
340
            } else {
341
                MissingResourceException e = new MissingResourceException("No such bundle " + baseName, baseName, null);
342
                if (Lookup.getDefault().lookup(ClassLoader.class) == null) {
343
                    ErrorManager.getDefault().annotate(e, ErrorManager.UNKNOWN, "Class loader not yet initialized in lookup", null, null, null); // NOI18N
344
                } else {
345
                    ErrorManager.getDefault().annotate(e, ErrorManager.UNKNOWN, "Offending classloader: " + loader, null, null, null); // NOI18N
346
                }
347
                throw e;
348
            }
349
        }
334
        String t;
350
        String t;
335
        if (brandingToken == null)
351
        if (brandingToken == null)
336
            t = ""; // NOI18N
352
            t = ""; // NOI18N
Lines 407-412 Link Here
407
        }
423
        }
408
    }
424
    }
409
425
426
    private static final Object MISSING = new String("MISSING"); // NOI18N
427
    private static final Map bundleCache = new WeakHashMap(); // Map<ClassLoader,Map<String,Reference<ResourceBundle>|MISSING>>
428
    private static ResourceBundle getBundleFast(String name, Locale locale, ClassLoader loader) {
429
        Map m;
430
        synchronized (bundleCache) {
431
            m = (Map)bundleCache.get(loader); // Map<String,Reference<ResourceBundle>|MISSING>
432
            if (m == null) {
433
                bundleCache.put(loader, m = new HashMap());
434
            }
435
        }
436
        String key = name + '/' + (brandingToken != null ? brandingToken : "-") + '/' + locale; // NOI18N
437
        synchronized (m) {
438
            Object o = m.get(key);
439
            if (o == MISSING) {
440
                return null;
441
            }
442
            ResourceBundle b = (o != null) ? (ResourceBundle)((Reference)o).get() : null;
443
            if (b != null) {
444
                return b;
445
            } else {
446
                b = loadBundle(name, locale, loader);
447
                m.put(key, (b != null) ? new TimedSoftReference(b, m, key) : MISSING);
448
                return b;
449
            }
450
        }
451
    }
452
    private static final class TimedSoftReference extends SoftReference implements Runnable {
453
        private static final int TIMEOUT = 30000; // 30sec
454
        private static final RequestProcessor RP = new RequestProcessor("TimedSoftReference"); // NOI18N
455
        private RequestProcessor.Task task;
456
        private Object o;
457
        private final Map m;
458
        private final Object k;
459
        public TimedSoftReference(Object o, Map m, Object k) {
460
            super(o, Utilities.activeReferenceQueue());
461
            this.o = o;
462
            this.m = m;
463
            this.k = k;
464
            task = RP.create(this);
465
            task.schedule(TIMEOUT);
466
        }
467
        public void run() {
468
            synchronized (m) {
469
                if (o != null) {
470
                    //System.err.println("Expire " + k);
471
                    o = null;
472
                } else {
473
                    // clean up map ref, we are dead
474
                    //System.err.println("Die " + k);
475
                    m.remove(k);
476
                }
477
            }
478
        }
479
        public Object get() {
480
            synchronized (m) {
481
                if (o == null) {
482
                    o = super.get();
483
                }
484
                if (o != null) {
485
                    // touch me
486
                    task.schedule(TIMEOUT);
487
                    //System.err.println("Touch " + k);
488
                    return o;
489
                } else {
490
                    return null;
491
                }
492
            }
493
        }
494
    }
495
    private static ResourceBundle loadBundle(String name, Locale locale, ClassLoader loader) {
496
        String sname = name.replace('.', '/');
497
        Iterator it = new LocaleIterator(locale);
498
        LinkedList l = new LinkedList();
499
        while (it.hasNext()) {
500
            l.addFirst(it.next());
501
        }
502
        it = l.iterator();
503
        Properties p = new Properties();
504
        boolean first = true;
505
        while (it.hasNext()) {
506
            String res = sname + (String)it.next() + ".properties";
507
            InputStream is = loader.getResourceAsStream(res);
508
            if (is != null) {
509
                //System.err.println("Loading " + res);
510
                try {
511
                    try {
512
                        p.load(is);
513
                    } finally {
514
                        is.close();
515
                    }
516
                } catch (IOException e) {
517
                    ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
518
                    return null;
519
                }
520
            } else if (first) {
521
                // No base *.properties. Try *.class.
522
                // Note that you may not mix *.properties w/ *.class this way.
523
                return loadBundleClass(name, sname, locale, l, loader);
524
            }
525
            first = false;
526
        }
527
        return new PBundle(p, locale);
528
    }
529
    private static final class PBundle extends ResourceBundle {
530
        private final Map m; // Map<String,String>
531
        private final Locale locale;
532
        public PBundle(Map m, Locale locale) {
533
            this.m = m;
534
            this.locale = locale;
535
        }
536
        public Enumeration getKeys() {
537
            return Collections.enumeration(m.keySet());
538
        }
539
        protected Object handleGetObject(String key) {
540
            return m.get(key);
541
        }
542
        public Locale getLocale() {
543
            return locale;
544
        }
545
    }
546
    private static ResourceBundle loadBundleClass(String name, String sname, Locale locale, List suffixes, ClassLoader l) {
547
        if (l.getResource(sname + ".class") == null) { // NOI18N
548
            // No chance - no base bundle. Don't waste time catching CNFE.
549
            return null;
550
        }
551
        ResourceBundle master = null;
552
        Iterator it = suffixes.iterator();
553
        while (it.hasNext()) {
554
            try {
555
                Class c = Class.forName(name + (String)it.next(), true, l);
556
                ResourceBundle b = (ResourceBundle)c.newInstance();
557
                if (master == null) {
558
                    master = b;
559
                } else {
560
                    master = new MergedBundle(locale, b, master);
561
                }
562
            } catch (ClassNotFoundException cnfe) {
563
                // fine - ignore
564
            } catch (Exception e) {
565
                ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
566
            } catch (LinkageError e) {
567
                ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
568
            }
569
        }
570
        return master;
571
    }
572
    
410
    //
573
    //
411
    // Helper methods to simplify localization of messages
574
    // Helper methods to simplify localization of messages
412
    //
575
    //

Return to bug 13847