* Fold default properties checksum calculation into getChecksum() so changes in
default properties will get picked up even if they were already consumed by other child properties. * Reimplement update algorithm using a temporary ResourceProperties object to avoid getting into unconsistent state by invoking clear(). * Use uppercase name for final CACHE_TIME field. * Make update() synchronized as concurrent invocation could be absolutely harmful.
This commit is contained in:
parent
f122e203b3
commit
cab28b406a
1 changed files with 45 additions and 37 deletions
|
@ -28,7 +28,7 @@ import helma.framework.repository.Repository;
|
||||||
public class ResourceProperties extends Properties {
|
public class ResourceProperties extends Properties {
|
||||||
|
|
||||||
// Delay between checks
|
// Delay between checks
|
||||||
private final long cacheTime = 1500L;
|
private final long CACHE_TIME = 1500L;
|
||||||
|
|
||||||
// Default properties. Note that in contrast to java.util.Properties,
|
// Default properties. Note that in contrast to java.util.Properties,
|
||||||
// defaultProperties are copied statically to ourselves in update(), so
|
// defaultProperties are copied statically to ourselves in update(), so
|
||||||
|
@ -169,30 +169,27 @@ public class ResourceProperties extends Properties {
|
||||||
return resources.iterator();
|
return resources.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks wether the properties need to be updated
|
|
||||||
* @return true if the properties need tu be updated
|
|
||||||
*/
|
|
||||||
public boolean needsUpdate() {
|
|
||||||
lastCheck = System.currentTimeMillis();
|
|
||||||
return (getChecksum() != lastChecksum);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates all properties if there is a need to update
|
* Updates all properties if there is a need to update
|
||||||
*/
|
*/
|
||||||
public void update() {
|
public synchronized void update() {
|
||||||
if (needsUpdate() || (defaultProperties != null && defaultProperties.needsUpdate())) {
|
// set lastCheck first to reduce risk of recursive calls
|
||||||
clear();
|
lastCheck = System.currentTimeMillis();
|
||||||
|
if (getChecksum() != lastChecksum) {
|
||||||
|
// First collect properties into a temporary collection,
|
||||||
|
// in a second step copy over new properties,
|
||||||
|
// and in the final step delete properties which have gone.
|
||||||
|
ResourceProperties temp = new ResourceProperties();
|
||||||
|
temp.setIgnoreCase(ignoreCase);
|
||||||
|
|
||||||
// first of all, properties are load from default properties
|
// first of all, properties are load from default properties
|
||||||
if (defaultProperties != null) {
|
if (defaultProperties != null) {
|
||||||
defaultProperties.update();
|
defaultProperties.update();
|
||||||
this.putAll(defaultProperties);
|
temp.putAll(defaultProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* next we try to load properties from the application's
|
// next we try to load properties from the application's
|
||||||
repositories, if we blong to any application */
|
// repositories, if we belong to any application
|
||||||
if (resourceName != null) {
|
if (resourceName != null) {
|
||||||
Iterator iterator = app.getRepositories().iterator();
|
Iterator iterator = app.getRepositories().iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
|
@ -200,7 +197,7 @@ public class ResourceProperties extends Properties {
|
||||||
Repository repository = (Repository) iterator.next();
|
Repository repository = (Repository) iterator.next();
|
||||||
Resource res = repository.getResource(resourceName);
|
Resource res = repository.getResource(resourceName);
|
||||||
if (res != null && res.exists()) {
|
if (res != null && res.exists()) {
|
||||||
load(res.getInputStream());
|
temp.load(res.getInputStream());
|
||||||
}
|
}
|
||||||
} catch (IOException iox) {
|
} catch (IOException iox) {
|
||||||
iox.printStackTrace();
|
iox.printStackTrace();
|
||||||
|
@ -215,7 +212,7 @@ public class ResourceProperties extends Properties {
|
||||||
try {
|
try {
|
||||||
Resource res = (Resource) iterator.next();
|
Resource res = (Resource) iterator.next();
|
||||||
if (res.exists()) {
|
if (res.exists()) {
|
||||||
load(res.getInputStream());
|
temp.load(res.getInputStream());
|
||||||
}
|
}
|
||||||
} catch (IOException iox) {
|
} catch (IOException iox) {
|
||||||
iox.printStackTrace();
|
iox.printStackTrace();
|
||||||
|
@ -223,6 +220,16 @@ public class ResourceProperties extends Properties {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy over new properties ...
|
||||||
|
putAll(temp);
|
||||||
|
// ... and remove properties which have been removed.
|
||||||
|
Iterator it = super.keySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
if (!temp.containsKey(it.next())) {
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lastChecksum = getChecksum();
|
lastChecksum = getChecksum();
|
||||||
lastCheck = lastModified = System.currentTimeMillis();
|
lastCheck = lastModified = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
@ -239,7 +246,7 @@ public class ResourceProperties extends Properties {
|
||||||
public ResourceProperties getSubProperties(String prefix) {
|
public ResourceProperties getSubProperties(String prefix) {
|
||||||
if (prefix == null)
|
if (prefix == null)
|
||||||
throw new NullPointerException("prefix");
|
throw new NullPointerException("prefix");
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
ResourceProperties subprops = new ResourceProperties();
|
ResourceProperties subprops = new ResourceProperties();
|
||||||
|
@ -262,7 +269,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return true if the value is found in the value list
|
* @return true if the value is found in the value list
|
||||||
*/
|
*/
|
||||||
public boolean contains(Object value) {
|
public boolean contains(Object value) {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return super.contains(value.toString());
|
return super.contains(value.toString());
|
||||||
|
@ -274,7 +281,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return true if the key is found in the key list
|
* @return true if the key is found in the key list
|
||||||
*/
|
*/
|
||||||
public boolean containsKey(Object key) {
|
public boolean containsKey(Object key) {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return super.containsKey(key.toString());
|
return super.containsKey(key.toString());
|
||||||
|
@ -285,7 +292,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return values enumeration
|
* @return values enumeration
|
||||||
*/
|
*/
|
||||||
public Enumeration elements() {
|
public Enumeration elements() {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return super.elements();
|
return super.elements();
|
||||||
|
@ -297,7 +304,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return value belonging to the given key
|
* @return value belonging to the given key
|
||||||
*/
|
*/
|
||||||
public Object get(Object key) {
|
public Object get(Object key) {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return (String) super.get(ignoreCase ? key.toString().toLowerCase() : key.toString());
|
return (String) super.get(ignoreCase ? key.toString().toLowerCase() : key.toString());
|
||||||
|
@ -308,7 +315,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return last modified date
|
* @return last modified date
|
||||||
*/
|
*/
|
||||||
public long lastModified() {
|
public long lastModified() {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return lastModified;
|
return lastModified;
|
||||||
|
@ -324,13 +331,10 @@ public class ResourceProperties extends Properties {
|
||||||
if (resourceName != null) {
|
if (resourceName != null) {
|
||||||
Iterator iterator = app.getRepositories().iterator();
|
Iterator iterator = app.getRepositories().iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
try {
|
Repository repository = (Repository) iterator.next();
|
||||||
Repository repository = (Repository) iterator.next();
|
Resource resource = repository.getResource(resourceName);
|
||||||
Resource resource = repository.getResource(resourceName);
|
if (resource != null) {
|
||||||
checksum += resource != null ?
|
checksum += resource.lastModified();
|
||||||
resource.lastModified() : repository.lastModified();
|
|
||||||
} catch (IOException iox) {
|
|
||||||
iox.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,6 +346,10 @@ public class ResourceProperties extends Properties {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (defaultProperties != null) {
|
||||||
|
checksum += defaultProperties.getChecksum();
|
||||||
|
}
|
||||||
|
|
||||||
return checksum;
|
return checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +361,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return spiecific value or default value if not found
|
* @return spiecific value or default value if not found
|
||||||
*/
|
*/
|
||||||
public String getProperty(String key, String defaultValue) {
|
public String getProperty(String key, String defaultValue) {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return super.getProperty(ignoreCase ? key.toLowerCase() : key, defaultValue);
|
return super.getProperty(ignoreCase ? key.toLowerCase() : key, defaultValue);
|
||||||
|
@ -365,7 +373,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return value belonging to the given key
|
* @return value belonging to the given key
|
||||||
*/
|
*/
|
||||||
public String getProperty(String key) {
|
public String getProperty(String key) {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return super.getProperty(ignoreCase ? key.toLowerCase() : key);
|
return super.getProperty(ignoreCase ? key.toLowerCase() : key);
|
||||||
|
@ -376,7 +384,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return true if the properties list is empty
|
* @return true if the properties list is empty
|
||||||
*/
|
*/
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return super.isEmpty();
|
return super.isEmpty();
|
||||||
|
@ -395,7 +403,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return keys enumeration
|
* @return keys enumeration
|
||||||
*/
|
*/
|
||||||
public Enumeration keys() {
|
public Enumeration keys() {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return super.keys();
|
return super.keys();
|
||||||
|
@ -406,7 +414,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return keys set
|
* @return keys set
|
||||||
*/
|
*/
|
||||||
public Set keySet() {
|
public Set keySet() {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return super.keySet();
|
return super.keySet();
|
||||||
|
@ -450,7 +458,7 @@ public class ResourceProperties extends Properties {
|
||||||
* @return number of properties
|
* @return number of properties
|
||||||
*/
|
*/
|
||||||
public int size() {
|
public int size() {
|
||||||
if ((System.currentTimeMillis() - lastCheck) > cacheTime) {
|
if ((System.currentTimeMillis() - lastCheck) > CACHE_TIME) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return super.size();
|
return super.size();
|
||||||
|
|
Loading…
Add table
Reference in a new issue