Package org.gudy.azureus2.core3.internat

Source Code of org.gudy.azureus2.core3.internat.IntegratedResourceBundle

/*
* Created on 29.11.2003
* Copyright (C) 2003, 2004, 2005, 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package org.gudy.azureus2.core3.internat;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.*;

import org.gudy.azureus2.core3.util.AETemporaryFileHandler;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.LightHashMap;
import org.gudy.azureus2.core3.util.SimpleTimer;
import org.gudy.azureus2.core3.util.TimerEvent;
import org.gudy.azureus2.core3.util.TimerEventPerformer;
import org.gudy.azureus2.core3.util.TimerEventPeriodic;

/**
* @author Rene Leonhardt
*/
public class
IntegratedResourceBundle
  extends ResourceBundle
{
  private static final boolean DEBUG = false;

  private static final Object  NULL_OBJECT = new Object();
 
  private static final Map  bundle_map = new WeakHashMap();

  private static TimerEventPeriodic  compact_timer;   

  protected static void
  resetCompactTimer()
  {
    synchronized( bundle_map ){

      if ( compact_timer == null && System.getProperty("transitory.startup", "0").equals("0")){
               
        compact_timer = SimpleTimer.addPeriodicEvent(
          "IRB:compactor",
          60*1000,
          new TimerEventPerformer()
          {
            public void
            perform(
              TimerEvent event )
            { 
              synchronized( bundle_map ){
         
                Iterator it = bundle_map.keySet().iterator();
         
                boolean  did_something = false;
         
                while( it.hasNext()){
         
                  IntegratedResourceBundle  rb = (IntegratedResourceBundle)it.next();
         
                  if (DEBUG) {
                    System.out.println("Compact RB " + rb.getString());
                  }

                  if ( rb.compact()){
         
                    did_something  = true;
                  }
                  if (DEBUG) {
                    System.out.println("        to " + rb.getString());
                  }
                }
         
                if ( !did_something ){
         
                  compact_timer.cancel();
       
                  compact_timer  = null;
                }
              }
            }
          });
      }
    }
  }
 
  private Locale  locale;

  private Map  messages;
  private Map  used_messages;
  private List null_values;
 
  private boolean    messages_dirty;
  private int      clean_count  = 0;
  private boolean    one_off_discard_done;
 
  private File    scratch_file_name;
  private InputStream  scratch_file_is;

  private final int initCapacity;
 
  private Map<String,String>  added_strings;
 
  public
  IntegratedResourceBundle(
    ResourceBundle     main,
    Map         localizationPaths)
  {
    this( main, localizationPaths, null, 10 );
  }

  public
  IntegratedResourceBundle(
    ResourceBundle     main,
    Map         localizationPaths,
    int          initCapacity)
  {
    this( main, localizationPaths, null, initCapacity );
  }

  public
  IntegratedResourceBundle(
    ResourceBundle     main,
    Map         localizationPaths,
    Collection       resource_bundles,
    int          initCapacity
  {
    this.initCapacity = initCapacity;
    messages = new LightHashMap(initCapacity);

    locale = main.getLocale();

      // use a somewhat decent initial capacity, proper calculation would require java 1.6
   
    addResourceMessages( main );
   
    synchronized (localizationPaths)
    {
      for (Iterator iter = localizationPaths.keySet().iterator(); iter.hasNext();){
        String localizationPath = (String) iter.next();
        ClassLoader classLoader = (ClassLoader) localizationPaths.get(localizationPath);

        addPluginBundle(localizationPath, classLoader);
      }
    }

    if (resource_bundles != null) {
      synchronized (resource_bundles)
      {
        for (Iterator itr = resource_bundles.iterator(); itr.hasNext();) {
          addResourceMessages((ResourceBundle)itr.next());
        }
      }

    }
   
    used_messages = new LightHashMap( messages.size());
   
    synchronized( bundle_map ){
     
      bundle_map.put( this, NULL_OBJECT );
     
      resetCompactTimer();
    }
    //System.out.println("IRB Size = " + messages.size() + "/cap=" + initCapacity + ";" + Debug.getCompressedStackTrace());
  }

  public Locale getLocale()
  {
    return locale;
  }

  private Map
  getMessages()
  {
    return( loadMessages());
  }
 
  public Enumeration
  getKeys()
  {
    new Exception("Don't call me, call getKeysLight").printStackTrace();
   
    Map m = loadMessages();
   
    return( new Vector( m.keySet()).elements());
  }
 
  protected Iterator
  getKeysLight()
  {
    Map m = new LightHashMap(loadMessages());
   
    return( m.keySet().iterator());
  }

  /**
   * Gets a string, using default if key doesn't exist.  Skips
   * throwing MissingResourceException when key doesn't exist, which saves
   * some CPU cycles
   *
   * @param key
   * @param def
   * @return
   *
   * @since 3.1.1.1
   */
  public String getString(String key, String def) {
    String s = (String) handleGetObject(key);
    if (s == null) {
      if (parent != null) {
        s = parent.getString(key);
      }
      if (s == null) {
        return def;
      }
    }
    return s;
  }

 
  protected Object
  handleGetObject(
    String key )
  {
    Object  res;
   
    synchronized( bundle_map ){
   
      res = used_messages.get( key );
    }
   
    Integer keyHash = null;
    if (null_values != null) {
      keyHash = new Integer(key.hashCode());
      int index = Collections.binarySearch(null_values, keyHash);
      if (index >= 0) {
        return null;
      }
    }
   
    if ( res == NULL_OBJECT ){
     
      return( null );
    }
   
    if ( res == null ){
     
      synchronized( bundle_map ){

        loadMessages();
     
        if ( messages != null ){
         
          res = messages.get( key );
        }

        if (res == null && null_values != null) {

          int index = Collections.binarySearch(null_values, keyHash);
          if (index < 0) {
            index = -1 * index - 1; // best guess
          }

          if (index > null_values.size()) {
            index = null_values.size();
          }
         
          null_values.add(index, keyHash);
         
        } else {

          used_messages.put( key, res==null?NULL_OBJECT:res );
        }
         
        clean_count  = 0;
       
        resetCompactTimer();
      }
    }
   
    return( res );
  }
 
  public void addPluginBundle(String localizationPath, ClassLoader classLoader)
  {
    ResourceBundle newResourceBundle = null;
    try {
      if(classLoader != null)
        newResourceBundle = ResourceBundle.getBundle(localizationPath, locale ,classLoader);
      else
        newResourceBundle = ResourceBundle.getBundle(localizationPath, locale,IntegratedResourceBundle.class.getClassLoader());
    } catch (Exception e) {
      //        System.out.println(localizationPath+": no resource bundle for " +
      // main.getLocale());
      try {
        if(classLoader != null)
          newResourceBundle = ResourceBundle.getBundle(localizationPath, MessageText.LOCALE_DEFAULT,classLoader);
        else
          newResourceBundle = ResourceBundle.getBundle(localizationPath, MessageText.LOCALE_DEFAULT,IntegratedResourceBundle.class.getClassLoader());
      } catch (Exception e2) {
        System.out.println(localizationPath + ": no default resource bundle");
        return;
      }
    }
       
    addResourceMessages(newResourceBundle);

   
  }
 
  public void
  addResourceMessages(
    ResourceBundle bundle )
  {
    synchronized (bundle_map)
    {
      loadMessages();
     
      if ( bundle != null ){
       
        messages_dirty = true;
       
        if ( bundle instanceof IntegratedResourceBundle ){
         
          messages.putAll(((IntegratedResourceBundle)bundle).getMessages());
         
        }else{
         
          for (Enumeration enumeration = bundle.getKeys(); enumeration.hasMoreElements();) {
           
            String key = (String) enumeration.nextElement();
           
            messages.put(key, bundle.getObject(key));
          }
        }
      }     
    }
//    System.out.println("after addrb; IRB Size = " + messages.size() + "/cap=" + initCapacity + ";" + Debug.getCompressedStackTrace());
  }
 
  protected boolean
  compact()
  {
    // System.out.println("compact " + getString() + ": cc=" + clean_count );
   
    clean_count++;
   
    if ( clean_count == 1 ){
         
      return( true );
    }
   
    if ( scratch_file_is == null || messages_dirty ){
     
      File temp_file = null;
     
      FileOutputStream  fos = null;
     
        // we have a previous cache, discard
     
      if ( scratch_file_is != null ){
       
          // System.out.println( "discard cache file " + scratch_file_name + " for " + this );
       
        try{
          scratch_file_is.close();
                   
        }catch( Throwable e ){ 
         
          scratch_file_name = null;
         
        }finally{
         
          scratch_file_is = null;
        }
      }
     
      try{
        Properties props = new Properties();
       
        props.putAll( messages );
       
        if ( scratch_file_name == null ){
       
          temp_file = AETemporaryFileHandler.createTempFile();
         
        }else{
         
          temp_file = scratch_file_name;
        }
       
        fos = new FileOutputStream( temp_file );
       
        props.store( fos, "message cache" );
       
        fos.close();
       
        fos = null;
       
          // System.out.println( "wrote cache file " + temp_file + " for " + this );
       
        scratch_file_name  = temp_file;
        scratch_file_is   = new FileInputStream( temp_file );
       
        messages_dirty    = false;
       
      }catch( Throwable e ){
       
        if ( fos != null ){
         
          try{
            fos.close();
           
          }catch( Throwable f ){
           
          }
        }
       
        if  ( temp_file != null ){
       
          temp_file.delete();
        }
      }
    }
   
    if ( scratch_file_is != null ){
     
      if ( clean_count >= 2 ){
   
        /*
        if ( messages != null ){
       
          System.out.println( "messages discarded  " + scratch_file_name + " for " + this );
        }
        */
       
          // throw away full message map after 2 ticks
     
        messages = null;
      }
   
      if ( clean_count == 5 && !one_off_discard_done){

          // System.out.println( "used discard " + scratch_file_name + " for " + this );
       
        one_off_discard_done = true;
       
          // one off discard of used_messages to clear out any that were
          // accessed once and never again
     
        used_messages.clear();
      }
    }
   
    if ( clean_count > 5 ){
   
      Map  compact_um = new LightHashMap( used_messages.size() + 16 );
     
      compact_um.putAll( used_messages );
     
      used_messages = compact_um;
     
      return( false );
     
    }else{
   
      return( true );
    }
  }
 
  protected Map
  loadMessages()
  {
    synchronized( bundle_map ){
     
      if ( messages != null ){
       
        return( messages );
      }
     
      Map  result;
     
      if ( scratch_file_is == null ){
       
        result = new LightHashMap();
       
      }else{
     
          // System.out.println( "read cache file " + scratch_file_name + " for " + this );

       
        Properties p = new Properties();
       
        InputStream  fis = scratch_file_is;
       
        try{
                 
          p.load( fis );
         
          fis.close();
         
          scratch_file_is = new FileInputStream( scratch_file_name );
         
          messages = new LightHashMap();
         
          messages.putAll( p );
         
          result = messages;
         
        }catch( Throwable e ){
         
          if ( fis != null ){
           
            try{
              fis.close();
             
            }catch( Throwable f ){
            }
          }
         
          Debug.out( "Failed to load message bundle scratch file", e );
         
          scratch_file_name.delete();
         
          scratch_file_is = null;
         
          result = new LightHashMap();
        }
      }
     
      if ( added_strings != null ){
       
        result.putAll( added_strings );
      }
     
      return( result );
    }
  }
 
  protected String
  getString()
  {
    return( locale + ": use=" + used_messages.size() + ",map=" + (messages==null?"":String.valueOf(messages.size()))
        + (null_values == null ? "" : ",null=" + null_values.size()) + ",added=" + (added_strings==null?"":added_strings.size()));
  }
 
  public void
  addString(String key, String value) {
    synchronized( bundle_map ){
      if ( added_strings == null ){
       
        added_strings = new HashMap<String, String>();
      }
     
      added_strings.put( key, value );
     
      if ( messages != null ){
       
        messages.put( key, value );
      }
    }
  }

  public boolean getUseNullList() {
    return null_values != null;
  }

  public void setUseNullList(boolean useNullList) {
    if (useNullList && null_values == null) {
      null_values = new ArrayList(0);
    } else if (!useNullList && null_values != null) {
      null_values = null;
    }
  }
 
  public void clearUsedMessagesMap(int initialCapacity) {
    used_messages = new LightHashMap(initialCapacity);
    if (null_values != null) {
      null_values = new ArrayList(0);
    }
  }
}
TOP

Related Classes of org.gudy.azureus2.core3.internat.IntegratedResourceBundle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.