コード例 #1
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
 /**
  * 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;
 }
コード例 #2
0
 @Override
 public boolean flushEntry(IFileSpec entry) {
   boolean result = _cache.flushEntry(entry);
   int key = _cache.getCacheKey(entry).getKey();
   if (result) {
     log(String.format("Flushed %s: %d", entry.getPreferredPathString(), key));
   } else {
     log(String.format("Could not flush %s: %d", entry.getPreferredPathString(), key));
   }
   return result;
 }
コード例 #3
0
 @Override
 public IFileSpec putEntry(IFileSpec entry) {
   IFileSpec result = _cache.putEntry(entry);
   int key = _cache.getCacheKey(entry).getKey();
   if (null != result) {
     log(String.format("Cached existing %s: %d", entry.getPreferredPathString(), key));
   } else {
     log(String.format("Cached new entry for %s: %d", entry.getPreferredPathString(), key));
   }
   return result;
 }
コード例 #4
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
 /**
  * @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;
 }
コード例 #5
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
  /**
   * 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;
  }
コード例 #6
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
  /**
   * 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);
  }
コード例 #7
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
  /**
   * Loads markup from a resource stream.
   *
   * @param container The original requesting markup container
   * @param markupResourceStream The markup resource stream to load
   * @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. Markup.NO_MARKUP, if not found.
   */
  private final Markup loadMarkup(
      final MarkupContainer container,
      final MarkupResourceStream markupResourceStream,
      final boolean enforceReload) {
    String cacheKey = markupResourceStream.getCacheKey();
    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 = MarkupFactory.get().loadMarkup(container, markupResourceStream, enforceReload);
    if (markup != null) {
      if (cacheKey != null) {
        String temp = markup.locationAsString();
        if (temp != null) {
          locationString = temp;
        }

        // add the markup to the cache.
        markupKeyCache.put(cacheKey, locationString);
        return putIntoCache(locationString, container, markup);
      }
      return markup;
    }

    // In case the markup could not be loaded (without exception) then ..
    if (cacheKey != null) {
      removeMarkup(cacheKey);
    }

    return Markup.NO_MARKUP;
  }
コード例 #8
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
  private void removeMarkupWhereBaseMarkupIsNoLongerInTheCache() {
    // 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<Markup> iter = markupCache.getValues().iterator();
      while (iter.hasNext()) {
        Markup markup = iter.next();

        if ((markup != null) && (markup != Markup.NO_MARKUP)) {
          // 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();
          if (resourceStream != null) {
            resourceStream = resourceStream.getBaseMarkupResourceStream();
          }

          // Is the base markup available in the cache?
          if ((resourceStream != null) && !isMarkupCached(resourceStream)) {
            iter.remove();
            count++;

            if (log.isDebugEnabled()) {
              log.debug("Removed derived markup from cache: " + markup.getMarkupResourceStream());
            }
          }
        }
      }
    }
  }
コード例 #9
0
 @Override
 public IFileSpec getEntry(ICacheKey<IFileSpec> key) {
   IFileSpec result = _cache.getEntry(key);
   if (null == result) {
     log(String.format("Cache miss for %d", key.getKey()));
   } else {
     log(String.format("Cache hit for %s: %d", result.getPreferredPathString(), key.getKey()));
   }
   return result;
 }
コード例 #10
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
  /**
   * 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;
  }
コード例 #11
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
  /**
   * Will be called if the markup was not in the cache yet and could not be found either.
   *
   * <p>Subclasses may change the default implementation. E.g. they might choose not to update the
   * cache to enforce reloading of any markup not found. This might be useful in very dynamic
   * environments. Additionally a non-caching IResourceStreamLocator should be used.
   *
   * @param cacheKey
   * @param container
   * @param markup Markup.NO_MARKUP
   * @return Same as parameter "markup"
   * @see
   *     org.apache.wicket.settings.def.ResourceSettings#setResourceStreamLocator(org.apache.wicket.core.util.resource.locator.IResourceStreamLocator)
   */
  protected Markup onMarkupNotFound(
      final String cacheKey, final MarkupContainer container, final Markup markup) {
    if (log.isDebugEnabled()) {
      log.debug("Markup not found: " + cacheKey);
    }

    // If cacheKey == null then caching is disabled for the component
    if (cacheKey != null) {
      // flag markup as non-existent
      markupKeyCache.put(cacheKey, cacheKey);
      putIntoCache(cacheKey, container, markup);
    }

    return markup;
  }
コード例 #12
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
 @Override
 public final int size() {
   return markupCache.size();
 }
コード例 #13
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
 @Override
 public void shutdown() {
   markupCache.shutdown();
   markupKeyCache.shutdown();
 }
コード例 #14
0
 private void log(String message) {
   _logger.log(String.format("[%s]: %s", _cache.getCacheName(), message));
 }
コード例 #15
0
 @Override
 public ICacheKey<IFileSpec> getCacheKey(IFileSpec entry) {
   return _cache.getCacheKey(entry);
 }
コード例 #16
0
 @Override
 public void flush() {
   _cache.flush();
   log(String.format("Flushed"));
 }
コード例 #17
0
ファイル: MarkupCache.java プロジェクト: jmireles/wicket
 @Override
 public void clear() {
   markupCache.clear();
   markupKeyCache.clear();
 }
コード例 #18
0
 @Override
 public String getCacheName() {
   return _cache.getCacheName();
 }