use of org.apache.wicket.util.watch.IModifiable in project wicket by apache.
the class ReloadingClassLoader method watchForModifications.
/**
* Watch changes of a class file by locating it in the list of location URLs and adding the
* corresponding file to the ModificationWatcher
*
* @param clz
* the class to watch
*/
private void watchForModifications(final Class<?> clz) {
// Watch class in the future
Iterator<URL> locationsIterator = urls.iterator();
File clzFile = null;
while (locationsIterator.hasNext()) {
// FIXME only works for directories, but JARs etc could be checked
// as well
URL location = locationsIterator.next();
String clzLocation = location.getFile() + clz.getName().replaceAll("\\.", "/") + ".class";
log.debug("clzLocation=" + clzLocation);
clzFile = new File(clzLocation);
final File finalClzFile = clzFile;
if (clzFile.exists()) {
log.info("Watching changes of class " + clzFile);
watcher.add(clzFile, new IChangeListener<IModifiable>() {
@Override
public void onChange(IModifiable modifiable) {
log.info("Class file " + finalClzFile + " has changed, reloading");
try {
listener.onChange(clz);
} catch (Exception e) {
log.error("Could not notify listener", e);
// If an error occurs when the listener is notified,
// remove the watched object to avoid rethrowing the
// exception at next check
// FIXME check if class file has been deleted
watcher.remove(finalClzFile);
}
}
});
break;
} else {
log.debug("Class file does not exist: " + clzFile);
}
}
if (clzFile != null && !clzFile.exists()) {
log.debug("Could not locate class " + clz.getName());
}
}
use of org.apache.wicket.util.watch.IModifiable in project wicket by apache.
the class MarkupCache method loadMarkupAndWatchForChanges.
/**
* 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 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<IModifiable>() {
@Override
public void onChange(IModifiable modifiable) {
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);
}
use of org.apache.wicket.util.watch.IModifiable in project wicket by apache.
the class MarkupCache method removeMarkup.
/**
* 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;
}
Aggregations