* 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:
hns 2006-05-26 14:41:50 +00:00
parent f122e203b3
commit cab28b406a

View file

@ -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();