⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 markupcache.java

📁 Wicket一个开发Java Web应用程序框架。它使得开发web应用程序变得容易而轻松。 Wicket利用一个POJO data beans组件使得它可以与任何持久层技术相结合。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.wicket.markup;import java.io.IOException;import java.util.Collection;import java.util.Iterator;import org.apache.wicket.Application;import org.apache.wicket.MarkupContainer;import org.apache.wicket.WicketRuntimeException;import org.apache.wicket.markup.loader.DefaultMarkupLoader;import org.apache.wicket.markup.loader.IMarkupLoader;import org.apache.wicket.settings.IMarkupSettings;import org.apache.wicket.util.concurrent.ConcurrentHashMap;import org.apache.wicket.util.listener.IChangeListener;import org.apache.wicket.util.resource.IResourceStream;import org.apache.wicket.util.resource.ResourceStreamNotFoundException;import org.apache.wicket.util.watch.IModifiable;import org.apache.wicket.util.watch.ModificationWatcher;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * This is Wicket's default IMarkupCache implementation. It will load the markup and cache it for * fast retrieval. * <p> * If the application is in development mode and a markup file changes, it'll automatically be * removed from the cache and reloaded when needed. * <p> * MarkupCache is registered with {@link IMarkupSettings} and thus can be replaced with a subclassed * version. *  * @see IMarkupSettings *  * @author Jonathan Locke * @author Juergen Donnerstag */public class MarkupCache implements IMarkupCache{	/** Log for reporting. */	private static final Logger log = LoggerFactory.getLogger(MarkupCache.class);	/** Map of markup tags by class (exactly what is in the file). */	private final ICache markupCache;	/** The markup cache key provider used by MarkupCache */	private IMarkupCacheKeyProvider markupCacheKeyProvider;	/** The markup resource stream provider used by MarkupCache */	private IMarkupResourceStreamProvider markupResourceStreamProvider;	/** The markup loader used by MarkupCache */	private IMarkupLoader markupLoader;	/** The application object */	private final Application application;	/**	 * Constructor.	 * 	 * @param application	 */	public MarkupCache(Application application)	{		this.application = application;		markupCache = newCacheImplementation();		if (markupCache == null)		{			throw new WicketRuntimeException("The map used to cache markup must not be null");		}	}	/**	 * @see org.apache.wicket.markup.IMarkupCache#clear()	 */	public final void clear()	{		markupCache.clear();	}	/**	 * 	 * @see org.apache.wicket.markup.IMarkupCache#shutdown()	 */	public void shutdown()	{		markupCache.shutdown();	}	/**	 * @see org.apache.wicket.markup.IMarkupCache#removeMarkup(java.lang.String)	 */	public final Markup removeMarkup(final String cacheKey)	{		if (cacheKey == null)		{			throw new IllegalArgumentException("Parameter 'cacheKey' must not be null");		}		if (log.isDebugEnabled())		{			log.debug("Remove from cache: cacheKey=" + cacheKey);		}		// Remove the markup and any other markup which depends on it		// (inheritance)		Markup markup = (Markup)markupCache.get(cacheKey);		if (markup != null)		{			markupCache.remove(cacheKey);			// In practice markup inheritance has probably not more than 3 or 4			// levels. And since markup reloading is only enabled in development			// mode, this max 4 iterations of the outer loop shouldn't be a			// problem.			int count;			do			{				count = 0;				// If a base markup file has been removed from the cache, than				// the derived markup should be removed as well.				Iterator iter = markupCache.getKeys().iterator();				while (iter.hasNext())				{					Markup cacheMarkup = (Markup)markupCache.get(iter.next());					MarkupResourceData resourceData = cacheMarkup.getMarkupResourceData()						.getBaseMarkupResourceData();					if (resourceData != null)					{						String baseCacheKey = resourceData.getResource().getCacheKey();						if (markupCache.get(baseCacheKey) == null)						{							if (log.isDebugEnabled())							{								log.debug("Remove from cache: cacheKey=" +									cacheMarkup.getMarkupResourceData().getResource().getCacheKey());							}							iter.remove();							count++;						}					}				}			}			while (count > 0);			// 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 call from a			// ModificationWatcher thread which has no associated Application.			final ModificationWatcher watcher = application.getResourceSettings()				.getResourceWatcher(true);			if (watcher != null)			{				Iterator iter = watcher.getEntries().iterator();				while (iter.hasNext())				{					IModifiable modifiable = (IModifiable)iter.next();					if (modifiable instanceof MarkupResourceStream)					{						MarkupResourceStream resourceStream = (MarkupResourceStream)modifiable;						String resourceCacheKey = resourceStream.getCacheKey();						if (markupCache.containsKey(resourceCacheKey) == false)						{							iter.remove();						}					}				}			}		}		return markup;	}	/**	 * @see org.apache.wicket.markup.IMarkupCache#getMarkupStream(org.apache.wicket.MarkupContainer,	 *      boolean, boolean)	 */	public final MarkupStream getMarkupStream(final MarkupContainer container,		final boolean enforceReload, final boolean throwException)	{		if (container == null)		{			throw new IllegalArgumentException("Parameter 'container' must not be 'null'.");		}		// Look for associated markup		final Markup markup = getMarkup(container, container.getClass(), enforceReload);		// If we found markup for this container		if (markup != Markup.NO_MARKUP)		{			return new MarkupStream(markup);		}		if (throwException == true)		{			// throw exception since there is no associated markup			throw new MarkupNotFoundException("Markup not found. Component class: " +				container.getClass().getName() +				" Enable debug messages for org.apache.wicket.util.resource to get a list of all filenames tried");		}		return null;	}	/**	 * @see org.apache.wicket.markup.IMarkupCache#hasAssociatedMarkup(org.apache.wicket.MarkupContainer)	 */	public final boolean hasAssociatedMarkup(final MarkupContainer container)	{		return getMarkup(container, container.getClass(), false) != Markup.NO_MARKUP;	}	/**	 * @see org.apache.wicket.markup.IMarkupCache#size()	 */	public final int size()	{		return markupCache.size();	}	/**	 * Get a unmodifiable map which contains the cached data. The map key is of type String and the	 * value is of type Markup.	 * 	 * @return	 */	protected final ICache getMarkupCache()	{		return markupCache;	}	/**	 * THIS IS NOT PART OF WICKET'S PUBLIC API. DO NOT USE IT.	 * 	 * I still don't like this method being part of the API but I didn't find a suitable other	 * solution.	 * 	 * @see org.apache.wicket.markup.IMarkupCache#getMarkup(org.apache.wicket.MarkupContainer,	 *      java.lang.Class, boolean)	 */	public final Markup getMarkup(final MarkupContainer container, final Class clazz,		final boolean enforceReload)	{		Class containerClass = clazz;		if (clazz == null)		{			containerClass = container.getClass();		}		else if (!clazz.isAssignableFrom(container.getClass()))		{			throw new WicketRuntimeException("Parameter clazz must be an instance of " +				container.getClass().getName() + ", but is a " + clazz.getName());		}		// Get the cache key to be associated with the markup resource stream		final String cacheKey = getMarkupCacheKeyProvider(container).getCacheKey(container,			containerClass);		// Is the markup already in the cache?		Markup markup = (enforceReload == false ? getMarkupFromCache(cacheKey, container) : null);		if (markup == null)		{			if (log.isDebugEnabled())			{				log.debug("Load markup: cacheKey=" + cacheKey);			}			// Who is going to provide the markup resource stream?			// And ask the provider to locate the markup resource stream			final IResourceStream resourceStream = getMarkupResourceStreamProvider(container).getMarkupResourceStream(				container, containerClass);			// Found markup?			if (resourceStream != null)			{				final MarkupResourceStream markupResourceStream;				if (resourceStream instanceof MarkupResourceStream)				{					markupResourceStream = (MarkupResourceStream)resourceStream;				}				else				{					markupResourceStream = new MarkupResourceStream(resourceStream,						new ContainerInfo(container), containerClass);				}				markupResourceStream.setCacheKey(cacheKey);				// load the markup and watch for changes				markup = loadMarkupAndWatchForChanges(container, markupResourceStream,					enforceReload);			}			else			{				markup = onMarkupNotFound(cacheKey, container);			}		}		return markup;	}	/**	 * Will be called if the markup was not in the cache yet but could not be found either.	 * <p>	 * Subclasses may change the default implementation. E.g. they might choose not update the cache	 * to enforce reloading of any markup not found. This might be useful in very dynamic	 * environments.	 * 	 * @param cacheKey	 * @param container	 * @return Markup.NO_MARKUP	 */	protected Markup onMarkupNotFound(final String cacheKey, final MarkupContainer container)	{		if (log.isDebugEnabled())		{			log.debug("Markup not found: " + cacheKey);		}		// flag markup as non-existent		return putIntoCache(cacheKey, Markup.NO_MARKUP);	}	/**	 * 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.	 * 	 * @param cacheKey	 *            If null, than ignore the cache	 * @param markup	 * @return markup The markup provided, except if the cacheKey already existed in the cache, than	 *         the markup from the cache is provided.	 */	protected Markup putIntoCache(final String cacheKey, Markup markup)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -