forked from sakaiproject/sakai
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
KNL-1191 Make ResourceLoader more helpful in debugging and unit tests
git-svn-id: https://source.sakaiproject.org/svn/kernel/trunk@306722 66ffb92e-73f9-0310-93c1-f5514f145a0a
- Loading branch information
Aaron Zeckoski
committed
Mar 4, 2014
1 parent
7744a38
commit 9ab9a1f
Showing
1 changed file
with
76 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,17 +21,6 @@ | |
|
||
package org.sakaiproject.util; | ||
|
||
import java.text.MessageFormat; | ||
import java.util.Collection; | ||
import java.util.Date; | ||
import java.util.Enumeration; | ||
import java.util.Hashtable; | ||
import java.util.Locale; | ||
import java.util.Map; | ||
import java.util.MissingResourceException; | ||
import java.util.ResourceBundle; | ||
import java.util.Set; | ||
|
||
import org.apache.commons.lang.StringUtils; | ||
import org.apache.commons.logging.Log; | ||
import org.apache.commons.logging.LogFactory; | ||
|
@@ -41,10 +30,15 @@ | |
import org.sakaiproject.tool.api.SessionManager; | ||
import org.sakaiproject.user.api.PreferencesService; | ||
|
||
import java.text.MessageFormat; | ||
import java.util.*; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
/** | ||
* ResourceLoader provides an alternate implementation of org.util.ResourceBundle, dynamically selecting the prefered locale from either the user's session or from the user's sakai preferences | ||
* | ||
* @author Sugiura, Tatsuki (University of Nagoya) | ||
* @author Aaron Zeckoski (azeckoski @ unicon.net) | ||
*/ | ||
@SuppressWarnings("rawtypes") | ||
public class ResourceLoader extends DummyMap implements InternationalizedMessages | ||
|
@@ -53,28 +47,37 @@ public class ResourceLoader extends DummyMap implements InternationalizedMessage | |
|
||
// name of ResourceBundle | ||
protected String baseName = null; | ||
|
||
// Optional ClassLoader for ResourceBundle | ||
public String getBaseName() { | ||
return baseName; | ||
} | ||
|
||
// Optional ClassLoader for ResourceBundle | ||
protected ClassLoader classLoader = null; | ||
public ClassLoader getClassLoader() { | ||
return classLoader; | ||
} | ||
|
||
// cached set of ResourceBundle objects | ||
protected Hashtable<Locale, ResourceBundle> bundles = new Hashtable<Locale, ResourceBundle>(); | ||
// cached set of ResourceBundle objects | ||
protected ConcurrentHashMap<Locale, ResourceBundle> bundles = new ConcurrentHashMap<Locale, ResourceBundle>(); | ||
|
||
// cached set of last time bundle was loaded | ||
protected Hashtable<Locale, Date> bundlesTimestamp = new Hashtable<Locale, Date>(); | ||
protected ConcurrentHashMap<Locale, Date> bundlesTimestamp = new ConcurrentHashMap<Locale, Date>(); | ||
|
||
// current user id | ||
protected String userId = null; | ||
|
||
// session key string for determining validity of ResourceBundle cache | ||
protected String LOCALE_SESSION_KEY = "sakai.locale."; | ||
public String getUserId() { | ||
return userId; | ||
} | ||
|
||
// session key string for determining validity of ResourceBundle cache | ||
protected final String LOCALE_SESSION_KEY = "sakai.locale."; | ||
|
||
// Debugging variables for displaying ResourceBundle name & property | ||
protected String DEBUG_LOCALE = "en_US_DEBUG"; | ||
private String DBG_PREFIX = "** "; | ||
private String DBG_SUFFIX = " **"; | ||
protected final String DEBUG_LOCALE = "en_US_DEBUG"; | ||
private final String DBG_PREFIX = "** "; | ||
private final String DBG_SUFFIX = " **"; | ||
|
||
private static Object LOCK = new Object(); | ||
private final static Object LOCK = new Object(); | ||
|
||
private static SessionManager sessionManager; | ||
protected static SessionManager getSessionManager() { | ||
|
@@ -143,7 +146,8 @@ public ResourceLoader(String userId, String name) | |
/** | ||
** Return ResourceBundle properties as if Map.entrySet() | ||
**/ | ||
public Set entrySet() | ||
@Override | ||
public Set entrySet() | ||
{ | ||
return getBundleAsMap().entrySet(); | ||
} | ||
|
@@ -267,8 +271,8 @@ public String getLocaleDisplayName(Locale loc) { | |
** @author Steve Swinsburg ([email protected]) | ||
**/ | ||
public Locale getLocale() | ||
{ | ||
Locale loc = null; | ||
{ | ||
Locale loc; | ||
// check if locale is requested for specific user | ||
if ( this.userId != null ) { | ||
loc = getLocale( this.userId ); | ||
|
@@ -312,12 +316,7 @@ public Locale getLocale() | |
**/ | ||
protected String formatDebugPropertiesString( String key ) | ||
{ | ||
StringBuilder dbgPropertiesString = new StringBuilder(DBG_PREFIX); | ||
dbgPropertiesString.append( this.baseName ); | ||
dbgPropertiesString.append( " " ); | ||
dbgPropertiesString.append( key ); | ||
dbgPropertiesString.append( DBG_SUFFIX ); | ||
return dbgPropertiesString.toString(); | ||
return DBG_PREFIX + this.baseName + " " + key + DBG_SUFFIX; | ||
} | ||
|
||
/** | ||
|
@@ -429,7 +428,7 @@ else if (!Locale.getDefault().getLanguage().equals("en") && loc.getLanguage().eq | |
} //Ignore and continue | ||
|
||
|
||
return loc; | ||
return loc; | ||
} | ||
|
||
/** | ||
|
@@ -446,9 +445,17 @@ public boolean getIsValid( String key ) | |
{ | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
} | ||
|
||
@Override | ||
public boolean containsKey(Object key) { | ||
if (key == null || !(key instanceof String)) { | ||
return false; | ||
} | ||
return getIsValid((String)key); | ||
} | ||
|
||
/** | ||
* Return string value for specified property in current locale specific ResourceBundle | ||
* | ||
* @param key property key to look up in current ResourceBundle | ||
|
@@ -579,15 +586,15 @@ public String[] getStrings(String key) | |
**/ | ||
public Set keySet() | ||
{ | ||
return getBundleAsMap().keySet(); | ||
return getBundle().keySet(); | ||
} | ||
|
||
/** | ||
* * Clear bundles hashmap | ||
*/ | ||
public void purgeCache() | ||
{ | ||
this.bundles = new Hashtable<Locale, ResourceBundle>(); | ||
this.bundles = new ConcurrentHashMap<Locale, ResourceBundle>(); | ||
M_log.debug("purge bundle cache"); | ||
} | ||
|
||
|
@@ -613,7 +620,17 @@ public Collection values() | |
return getBundleAsMap().values(); | ||
} | ||
|
||
/** | ||
@Override | ||
public int size() { | ||
return getBundle().keySet().size(); | ||
} | ||
|
||
@Override | ||
public boolean isEmpty() { | ||
return getBundle().keySet().isEmpty(); | ||
} | ||
|
||
/** | ||
* Return ResourceBundle for user's preferred locale | ||
* | ||
* @return user's ResourceBundle object | ||
|
@@ -624,7 +641,7 @@ protected ResourceBundle getBundle() | |
return getBundleFromDb(); | ||
} | ||
Locale loc = getLocale(); | ||
ResourceBundle bundle = (ResourceBundle) this.bundles.get(loc); | ||
ResourceBundle bundle = this.bundles.get(loc); | ||
if (bundle == null) | ||
{ | ||
if (M_log.isDebugEnabled()) { | ||
|
@@ -643,8 +660,8 @@ protected ResourceBundle getBundleFromDb() | |
{ | ||
Locale loc = getLocale(); | ||
//TODO consider using a better caching method here | ||
ResourceBundle bundle = (ResourceBundle) this.bundles.get(loc); | ||
Date timeStamp = (Date) this.bundlesTimestamp.get(loc); | ||
ResourceBundle bundle = this.bundles.get(loc); | ||
Date timeStamp = this.bundlesTimestamp.get(loc); | ||
if ((timeStamp == null || timeStamp.getTime() + ServerConfigurationService.getInt("load.bundles.from.db.timeout", 30000) < new Date().getTime() ) ) | ||
{ | ||
M_log.debug("Load bundle name=" + this.baseName + ", locale=" + getLocale().toString()); | ||
|
@@ -658,7 +675,7 @@ protected ResourceBundle getBundleFromDb() | |
**/ | ||
protected Map<Object, Object> getBundleAsMap() | ||
{ | ||
Map<Object, Object> bundle = new Hashtable<Object, Object>(); | ||
Map<Object, Object> bundle = new ConcurrentHashMap<Object, Object>(); | ||
|
||
for (Enumeration e = getBundle().getKeys(); e.hasMoreElements();) | ||
{ | ||
|
@@ -685,19 +702,16 @@ protected ResourceBundle loadBundle(Locale loc) | |
ResourceBundle newBundle = null; | ||
try | ||
{ | ||
if ( this.classLoader == null ) | ||
if (this.classLoader == null) { | ||
newBundle = ResourceBundle.getBundle(this.baseName, loc); | ||
else | ||
} else { | ||
newBundle = ResourceBundle.getBundle(this.baseName, loc, this.classLoader); | ||
|
||
|
||
} | ||
} catch (NullPointerException e) { | ||
// IGNORE FAILURE | ||
} | ||
catch (NullPointerException e) | ||
{ | ||
} // ignore | ||
|
||
|
||
setBundle(loc, newBundle); | ||
setBundle(loc, newBundle); | ||
return newBundle; | ||
} | ||
|
||
|
@@ -713,7 +727,7 @@ protected ResourceBundle loadBundle(Locale loc) | |
*/ | ||
protected ResourceBundle loadBundleFromDb(Locale loc) | ||
{ | ||
ResourceBundle newBundle = null; | ||
ResourceBundle newBundle; | ||
try | ||
{ | ||
newBundle = DbResourceBundle.addResourceBundle(this.baseName, loc, this.classLoader); | ||
|
@@ -748,6 +762,15 @@ protected void setBundle(Locale loc, ResourceBundle bundle) | |
this.bundles.put(loc, bundle); | ||
this.bundlesTimestamp.put(loc, new Date()); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "ResourceLoader{" + | ||
"base='" + baseName + '\'' + | ||
", user='" + userId + '\'' + | ||
'}'; | ||
} | ||
|
||
} | ||
|
||
@SuppressWarnings({ "rawtypes" }) | ||
|