Author: jdonnerstag Date: Thu Jul 7 19:09:09 2011 New Revision: 1143981 URL: http://svn.apache.org/viewvc?rev=1143981&view=rev Log: fixed: When base markup file has been removed from the cache, the the derived markup should be removed as well Issue: WICKET-3878
Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupCache.java Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupCache.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupCache.java?rev=1143981&r1=1143980&r2=1143981&view=diff ============================================================================== --- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupCache.java (original) +++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupCache.java Thu Jul 7 19:09:09 2011 @@ -124,67 +124,52 @@ public class MarkupCache implements IMar if (log.isDebugEnabled()) { - log.debug("Remove from cache: cacheKey=" + cacheKey); + log.debug("Remove from cache: " + cacheKey); } // Remove the markup from the cache String locationString = markupKeyCache.get(cacheKey); IMarkupFragment markup = (locationString != null ? markupCache.get(locationString) : null); - if (markup != null) + if (markup == null) { - // Found an entry: actual markup or Markup.NO_MARKUP. Null values are not possible - // because of ConcurrentHashMap. - markupCache.remove(locationString); - - // If a base markup file has been removed from the cache, than - // the derived markup should be removed as well. - - // Repeat until all dependent resources have been removed (count == 0) - int count = 1; - while (count > 0) - { - // Reset prior to next round - count = 0; - - // Iterate though all entries of the cache - Iterator<String> iter = markupCache.getKeys().iterator(); - while (iter.hasNext()) - { - String key = iter.next(); + return null; + } - // Check if the markup associated with key has a base markup. And if yes, test - // if that is cached. - if (isBaseMarkupCached(key)) - { - if (log.isDebugEnabled()) - { - log.debug("Remove from cache: cacheKey=" + key); - } + // Found an entry: actual markup or Markup.NO_MARKUP. Null values are not possible + // because of ConcurrentHashMap. + markupCache.remove(locationString); - iter.remove(); - count++; - } - } - } + if (log.isDebugEnabled()) + { + log.debug("Removed from cache: " + locationString); + } - // And now remove all watcher entries associated with markup - // resources no longer in the cache. Note that you can not use - // Application.get() since removeMarkup() will be called from a - // ModificationWatcher thread which has no associated Application. + // If a base markup file has been removed from the cache, than + // the derived markup should be removed as well. + removeMarkupWhereBaseMarkupIsNoLongerInTheCache(); - IModificationWatcher watcher = application.getResourceSettings().getResourceWatcher( - false); - if (watcher != null) + // And now remove all watcher entries associated with markup + // resources no longer in the cache. + + // Note that you can not use Application.get() since removeMarkup() will be called from a + // ModificationWatcher thread which has no associated Application. + + IModificationWatcher watcher = application.getResourceSettings().getResourceWatcher(false); + if (watcher != null) + { + Iterator<IModifiable> iter = watcher.getEntries().iterator(); + while (iter.hasNext()) { - Iterator<IModifiable> iter = watcher.getEntries().iterator(); - while (iter.hasNext()) + IModifiable modifiable = iter.next(); + if (modifiable instanceof MarkupResourceStream) { - IModifiable modifiable = iter.next(); - if (modifiable instanceof MarkupResourceStream) + if (!isMarkupCached((MarkupResourceStream)modifiable)) { - if (isMarkupCached((MarkupResourceStream)modifiable)) + iter.remove(); + + if (log.isDebugEnabled()) { - iter.remove(); + log.debug("Removed from watcher: " + modifiable); } } } @@ -194,32 +179,42 @@ public class MarkupCache implements IMar return markup; } - /** - * @param key - * @return True, if base markup for entry with cache 'key' is available in the cache as well. - */ - private boolean isBaseMarkupCached(final String key) + private void removeMarkupWhereBaseMarkupIsNoLongerInTheCache() { - // Get the markup associated with key. Null in case the key has no associated value. A null - // value is not possible because of ConcurrentHashMap. - Markup markup = markupCache.get(key); - if (markup == null) + // Repeat until all dependent resources have been removed (count == 0) + int count = 1; + while (count > 0) { - return false; - } + // Reset prior to next round + count = 0; - // NO_MARKUP does not have an associated resource stream - if (markup == Markup.NO_MARKUP) - { - return false; - } + // Iterate though all entries of the cache + Iterator<Markup> iter = markupCache.getValues().iterator(); + while (iter.hasNext()) + { + Markup markup = iter.next(); + + // Check if the markup associated with key has a base markup. And if yes, test + // if that is cached. If the base markup has been removed, than remove the derived + // markup as well. + + MarkupResourceStream resourceStream = markup.getMarkupResourceStream() + .getBaseMarkupResourceStream(); - // Get the base markup resource stream from the markup - MarkupResourceStream resourceStream = markup.getMarkupResourceStream() - .getBaseMarkupResourceStream(); + // Is the base markup available in the cache? + if ((resourceStream != null) && !isMarkupCached(resourceStream)) + { + iter.remove(); + count++; - // Is the base markup available in the cache? - return isMarkupCached(resourceStream); + if (log.isDebugEnabled()) + { + log.debug("Removed derived markup from cache: " + + markup.getMarkupResourceStream()); + } + } + } + } } /** @@ -514,7 +509,7 @@ public class MarkupCache implements IMar { if (log.isDebugEnabled()) { - log.debug("Remove markup from cache: " + markupResourceStream); + log.debug("Remove markup from watcher: " + markupResourceStream); } // Remove the markup from the cache. It will be reloaded @@ -607,6 +602,13 @@ public class MarkupCache implements IMar Collection<K> getKeys(); /** + * Get all the values referencing cache entries + * + * @return collection of cached keys + */ + Collection<V> getValues(); + + /** * Check if key is in the cache * * @param key @@ -681,6 +683,11 @@ public class MarkupCache implements IMar return cache.keySet(); } + public Collection<V> getValues() + { + return cache.values(); + } + public void put(K key, V value) { // Note that neither key nor value are allowed to be null with ConcurrentHashMap