Exemple #1
0
 /**
  * Wicket's default implementation just uses the cacheKey to retrieve the markup from the cache.
  * More sophisticated implementations may call a container method to e.g. ignore the cached markup
  * under certain situations.
  *
  * @param cacheKey If null, than the cache will be ignored
  * @param container
  * @return null, if not found or to enforce reloading the markup
  */
 protected Markup getMarkupFromCache(final String cacheKey, final MarkupContainer container) {
   if (cacheKey != null) {
     String locationString = markupKeyCache.get(cacheKey);
     if (locationString != null) {
       return markupCache.get(locationString);
     }
   }
   return null;
 }
Exemple #2
0
 /**
  * @param resourceStream
  * @return True if the markup is cached
  */
 private boolean isMarkupCached(final MarkupResourceStream resourceStream) {
   if (resourceStream != null) {
     String key = resourceStream.getCacheKey();
     if (key != null) {
       String locationString = markupKeyCache.get(key);
       if ((locationString != null) && (markupCache.get(locationString) != null)) {
         return true;
       }
     }
   }
   return false;
 }
Exemple #3
0
  /**
   * Note that this method will be called from a "cleanup" thread which might not have a thread
   * local application.
   */
  @Override
  public final IMarkupFragment removeMarkup(final String cacheKey) {
    Args.notNull(cacheKey, "cacheKey");

    if (log.isDebugEnabled()) {
      log.debug("Removing 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) {
      return null;
    }

    // Found an entry: actual markup or Markup.NO_MARKUP. Null values are not possible
    // because of ConcurrentHashMap.
    markupCache.remove(locationString);

    if (log.isDebugEnabled()) {
      log.debug("Removed from cache: " + locationString);
    }

    // If a base markup file has been removed from the cache then
    // the derived markup should be removed as well.
    removeMarkupWhereBaseMarkupIsNoLongerInTheCache();

    // 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()) {
        IModifiable modifiable = iter.next();
        if (modifiable instanceof MarkupResourceStream) {
          if (!isMarkupCached((MarkupResourceStream) modifiable)) {
            iter.remove();

            if (log.isDebugEnabled()) {
              log.debug("Removed from watcher: " + modifiable);
            }
          }
        }
      }
    }

    return markup;
  }
Exemple #4
0
  /**
   * Load markup from an IResourceStream and add an {@link IChangeListener}to the {@link
   * ModificationWatcher} so that if the resource changes, we can remove it from the cache
   * automatically and subsequently reload when needed.
   *
   * @param container The original requesting markup container
   * @param markupResourceStream The markup stream to load and begin to watch
   * @param enforceReload The cache will be ignored and all, including inherited markup files, will
   *     be reloaded. Whatever is in the cache, it will be ignored
   * @return The markup in the stream
   */
  private final Markup loadMarkupAndWatchForChanges(
      final MarkupContainer container,
      final MarkupResourceStream markupResourceStream,
      final boolean enforceReload) {
    // @TODO the following code sequence looks very much like in loadMarkup. Can it be
    // optimized?
    final String cacheKey = markupResourceStream.getCacheKey();
    if (cacheKey != null) {
      if (enforceReload == false) {
        // get the location String
        String locationString = markupResourceStream.locationAsString();
        if (locationString == null) {
          // set the cache key as location string, because location string
          // couldn't be resolved.
          locationString = cacheKey;
        }
        Markup markup = markupCache.get(locationString);
        if (markup != null) {
          markupKeyCache.put(cacheKey, locationString);
          return markup;
        }
      }

      // Watch file in the future
      final IModificationWatcher watcher =
          application.getResourceSettings().getResourceWatcher(true);
      if (watcher != null) {
        watcher.add(
            markupResourceStream,
            new IChangeListener() {
              @Override
              public void onChange() {
                if (log.isDebugEnabled()) {
                  log.debug("Remove markup from watcher: " + markupResourceStream);
                }

                // Remove the markup from the cache. It will be reloaded
                // next time when the markup is requested.
                watcher.remove(markupResourceStream);
                removeMarkup(cacheKey);
              }
            });
      }
    }

    if (log.isDebugEnabled()) {
      log.debug("Loading markup from " + markupResourceStream);
    }
    return loadMarkup(container, markupResourceStream, enforceReload);
  }
Exemple #5
0
  /**
   * Put the markup into the cache if cacheKey is not null and the cache does not yet contain the
   * cacheKey. Return the markup stored in the cache if cacheKey is present already.
   *
   * <p>More sophisticated implementations may call a container method to e.g. cache it per
   * container instance.
   *
   * @param locationString If {@code null} then ignore the cache
   * @param container The container this markup is for.
   * @param markup
   * @return markup The markup provided, except if the cacheKey already existed in the cache, then
   *     the markup from the cache is provided.
   */
  protected Markup putIntoCache(
      final String locationString, final MarkupContainer container, Markup markup) {
    if (locationString != null) {
      if (markupCache.containsKey(locationString) == false) {
        // The default cache implementation is a ConcurrentHashMap. Thus neither the key nor
        // the value can be null.
        if (markup == null) {
          markup = Markup.NO_MARKUP;
        }

        markupCache.put(locationString, markup);
      } else {
        // We don't lock the cache while loading a markup. Thus it may
        // happen that the very same markup gets loaded twice (the first
        // markup being loaded, but not yet in the cache, and another
        // request requesting the very same markup). Since markup
        // loading in avg takes less than 100ms, it is not really an
        // issue. For consistency reasons however, we should always use
        // the markup loaded first which is why it gets returned.
        markup = markupCache.get(locationString);
      }
    }
    return markup;
  }