package pt.estgp.estgweb.domain.utils;
import org.apache.log4j.Logger;
import org.apache.struts.util.PropertyMessageResources;
import pt.estgp.estgweb.web.filters.UserRoleProxy;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
/**
* Automatisch neu ladbare MessageResources.
*
* @author boeckmic
* @since Mar 26, 2008
*/
public class ReloadablePropertyMessageResources
extends PropertyMessageResources
{
private static final long serialVersionUID = 4344652868862075298L
;
private final 1.5.0/docs/api/java/util/logging/Logger.html">Logger logger =
1.5.0/docs/api/java/util/logging/Logger.html">Logger.
getLogger(ReloadablePropertyMessageResources.
class);
/** The last time the file was checked for changes. */
protected long lastChecked
;
/** The minimum delay in milliseconds between checks. */
protected long refreshDelay = DEFAULT_REFRESH_DELAY
;
/** Constant for the default refresh delay. */
private static final int DEFAULT_REFRESH_DELAY =
5000;
private final ConcurrentHashMap
<String, File
> fileMap =
new ConcurrentHashMap
<String, File
>();
private final ConcurrentHashMap
<File, Long
> timestampMap =
new ConcurrentHashMap
<File, Long
>();
/**
* Konstruktor aus Superklasse.
*
* @param factory Factory
* @param config Name der Konfigurationsdatei
*/
public ReloadablePropertyMessageResources
(
final ReloadablePropertyMessageResourcesFactory factory,
final 1.5.0/docs/api/java/lang/String.html">String config
) {
super(factory, config
);
}
/**
* Konstruktor aus Superklasse.
*
* @param factory Factory
* @param config Name der Konfigurationsdatei
* @param returnNull Fehler werfen bei nicht vorhandenem Key?
*/
public ReloadablePropertyMessageResources
(
final ReloadablePropertyMessageResourcesFactory factory,
final 1.5.0/docs/api/java/lang/String.html">String config,
final boolean returnNull
) {
super(factory, config, returnNull
);
}
/**
* Pr�ft ob ein Reload der Properties notwendig ist.
*
* {@inheritDoc}
*
* @see org.apache.struts.util.PropertyMessageResources#getMessage(java.util.Locale,
* java.lang.String)
*/
@
1.5.0/docs/api/java/lang/Override.html">Override
public 1.5.0/docs/api/java/lang/String.html">String getMessage
(final 1.5.0/docs/api/java/util/Locale.html">Locale locale,
final 1.5.0/docs/api/java/lang/String.html">String key
) {
reload
(locale
);
if(key ==
null || key.
length() == 0
)
{
return "CHAVE MSG EM FALTA";
}
else if(key.
startsWith("user.role."))
{
logger.
debug("BACO ROLES:Getting role from UserRoleProxy" + key
);
1.5.0/docs/api/java/lang/String.html">String msg = UserRoleProxy.
getMessage(key.
substring("user.role.".
length()),locale
);
if(msg ==
null)
return key
;
return msg
;
}
return super.
getMessage(locale, key
);
}
/**
* Pr�ft ob ein Reload der Properties notwendig ist.
*
* {@inheritDoc}
*
* @see org.apache.struts.util.MessageResources#getMessage(java.util.Locale, java.lang.String,
* java.lang.Object[])
*/
@
1.5.0/docs/api/java/lang/Override.html">Override
public 1.5.0/docs/api/java/lang/String.html">String getMessage
(final 1.5.0/docs/api/java/util/Locale.html">Locale locale,
final 1.5.0/docs/api/java/lang/String.html">String key,
final 5+0%2Fdocs%2Fapi+Object">Object[] args
) {
reload
(locale
);
if(key ==
null || key.
length() == 0
)
{
return "CHAVE MSG EM FALTA";
}
else if(key.
startsWith("user.role."))
{
logger.
debug("BACO ROLES:Getting role from UserRoleProxy" + key
);
1.5.0/docs/api/java/lang/String.html">String msg = UserRoleProxy.
getMessage(key.
substring("user.role.".
length()),locale
);
if(msg ==
null)
return key
;
return msg
;
}
return super.
getMessage(locale, key, args
);
}
/**
* Das Resetten der Maps f�hrt zum reload der Properties.
*
* @param locale Locale
*/
public synchronized void reload
(final 1.5.0/docs/api/java/util/Locale.html">Locale locale
) {
if (reloadingRequired
(locale
)) {
logger.
info("Reloading resources " + getFilename
(locale
));
locales.
clear();
messages.
clear();
formats.
clear();
}
}
/**
* Pr�ft ob es notwendig ist die Properties neu zu laden. Pr�ft nur nach Ablauf des
* {@link #refreshDelay}, um eine �berm��ige Beanspruchung des Dateisystems zu vermeiden.
*
* @param locale Locale
* @return <code>true</code> falls neu geladen werden muss
*/
public boolean reloadingRequired
(final 1.5.0/docs/api/java/util/Locale.html">Locale locale
) {
boolean reloading =
false;
long now =
1.5.0/docs/api/java/lang/System.html">System.
currentTimeMillis();
if (now
> lastChecked + refreshDelay
) {
lastChecked = now
;
if (hasChanged
(locale
)) {
reloading =
true;
}
}
return reloading
;
}
/**
* Pr�ft ob sich die Konfiguration seit dem letzten Aufruf ge�ndert hat.
*
* @param locale Locale
* @return <code>true</code> falls sich die Datei ge�ndert hat
*/
protected boolean hasChanged
(final 1.5.0/docs/api/java/util/Locale.html">Locale locale
) {
1.5.0/docs/api/java/io/File.html">File file = getFile
(locale
);
if (file ==
null ||
!file.
exists()) {
return false;
}
1.5.0/docs/api/java/lang/Long.html">Long timestamp = timestampMap.
get(file
);
if (timestamp ==
null) {
timestampMap.
putIfAbsent(file,
1.5.0/docs/api/java/lang/Long.html">Long.
valueOf(file.
lastModified()));
return false;
}
if (file.
lastModified() > timestamp.
longValue()) {
timestampMap.
put(file,
1.5.0/docs/api/java/lang/Long.html">Long.
valueOf(file.
lastModified()));
return true;
}
return false;
}
/**
* Gibt die Datei zur Locale zur�ck.
*
* @param locale Locale
* @return (gecachte) File
*/
private 1.5.0/docs/api/java/io/File.html">File getFile
(final 1.5.0/docs/api/java/util/Locale.html">Locale locale
) {
1.5.0/docs/api/java/lang/String.html">String filename = getFilename
(locale
);
1.5.0/docs/api/java/io/File.html">File f = fileMap.
get(filename
);
if (f ==
null) {
1.5.0/docs/api/java/lang/ClassLoader.html">ClassLoader classLoader =
1.5.0/docs/api/java/lang/Thread.html">Thread.
currentThread().
getContextClassLoader();
if (classLoader ==
null) {
classLoader = getClass
().
getClassLoader();
}
1.5.0/docs/api/java/net/URL.html">URL fileUrl = classLoader.
getResource(filename
);
// no bundle for this locale found, so try default bundle
if (fileUrl ==
null) {
fileUrl = classLoader.
getResource(getFilename
(null));
}
try {
try {
f =
new 1.5.0/docs/api/java/io/File.html">File(fileUrl.
toURI());
} catch (1.5.0/docs/api/java/net/URISyntaxException.html">URISyntaxException ex
) {
logger.
error(ex,ex
);
} catch (1.5.0/docs/api/java/lang/IllegalArgumentException.html">IllegalArgumentException ex
) {
try {
1.5.0/docs/api/java/lang/System.html">System.
out.
println("Decoding from fileUrl.getFile");
f =
new 1.5.0/docs/api/java/io/File.html">File(1.5.0/docs/api/java/net/URLDecoder.html">URLDecoder.
decode(fileUrl.
getFile(),
"UTF-8"));
1.5.0/docs/api/java/lang/System.html">System.
out.
println(f.
getAbsolutePath());
} catch (1.5.0/docs/api/java/lang/Exception.html">Exception ex2
) {
logger.
error(ex2,ex2
);
}
}
}catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e
) {
throw new 1.5.0/docs/api/java/lang/IllegalArgumentException.html">IllegalArgumentException("The properties file "
+ fileUrl.
toExternalForm() +
" could not be loaded.", e
);
}
fileMap.
putIfAbsent(filename, f
);
}
return f
;
}
/**
* Berechnet den Dateinamen f�r die Locale.
*
* @param locale Locale
* @return Dateinamen
*/
private 1.5.0/docs/api/java/lang/String.html">String getFilename
(final 1.5.0/docs/api/java/util/Locale.html">Locale locale
) {
1.5.0/docs/api/java/lang/String.html">String name = config.
replace('.',
'/');
1.5.0/docs/api/java/lang/String.html">String localeKey =
"";
if (locale
!=
null) {
localeKey = locale.
toString();
int underscore = localeKey.
lastIndexOf("_");
if (underscore
> 0
) {
localeKey = localeKey.
substring(0, underscore
);
}
}
if (localeKey.
length() > 0) {
name = name +
"_" + localeKey
;
}
return name +
".properties";
}
}