You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2007/06/17 09:58:21 UTC
svn commit: r548018 - in
/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket: ./
markup/ markup/loader/ settings/ util/watch/
Author: jdonnerstag
Date: Sun Jun 17 00:58:20 2007
New Revision: 548018
URL: http://svn.apache.org/viewvc?view=rev&rev=548018
Log:
Backported IMarkupLoader
Added:
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCache.java (with props)
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java (with props)
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java (with props)
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java (with props)
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java (with props)
Removed:
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/watch/Watcher.java
Modified:
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Application.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/DefaultMarkupCacheKeyProvider.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCacheKeyProvider.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IMarkupSettings.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/watch/ModificationWatcher.java
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Application.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Application.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Application.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Application.java Sun Jun 17 00:58:20 2007
@@ -31,7 +31,7 @@
import org.apache.wicket.application.IComponentInstantiationListener;
import org.apache.wicket.application.IComponentOnAfterRenderListener;
import org.apache.wicket.application.IComponentOnBeforeRenderListener;
-import org.apache.wicket.markup.MarkupCache;
+import org.apache.wicket.markup.IMarkupCache;
import org.apache.wicket.markup.html.image.resource.DefaultButtonImageResourceFactory;
import org.apache.wicket.markup.parser.filter.RelativePathPrefixHandler;
import org.apache.wicket.markup.parser.filter.WicketMessageTagHandler;
@@ -221,9 +221,6 @@
/** list of initializers. */
private List initializers = new ArrayList();
- /** Markup cache for this application */
- private final MarkupCache markupCache;
-
/** Application level meta data. */
private MetaDataEntry[] metaData;
@@ -254,9 +251,6 @@
// Create name from subclass
this.name = Classes.simpleName(getClass());
- // Construct markup cache for this application
- this.markupCache = new MarkupCache(this);
-
// Create shared resources repository
this.sharedResources = new SharedResources(this);
@@ -441,10 +435,11 @@
* THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT.
*
* @return The markup cache associated with the application
+ * @deprecated please use {@link IMarkupSettings#getMarkupCache()} instead
*/
- public final MarkupCache getMarkupCache()
+ public final IMarkupCache getMarkupCache()
{
- return this.markupCache;
+ return getMarkupSettings().getMarkupCache();
}
/**
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java Sun Jun 17 00:58:20 2007
@@ -328,7 +328,7 @@
{
try
{
- return getApplication().getMarkupCache().getMarkupStream(this, throwException);
+ return getApplication().getMarkupSettings().getMarkupCache().getMarkupStream(this, false, throwException);
}
catch (MarkupException ex)
{
@@ -1479,6 +1479,6 @@
*/
final boolean hasAssociatedMarkup()
{
- return getApplication().getMarkupCache().hasAssociatedMarkup(this);
+ return getApplication().getMarkupSettings().getMarkupCache().hasAssociatedMarkup(this);
}
}
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/DefaultMarkupCacheKeyProvider.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/DefaultMarkupCacheKeyProvider.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/DefaultMarkupCacheKeyProvider.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/DefaultMarkupCacheKeyProvider.java Sun Jun 17 00:58:20 2007
@@ -48,14 +48,15 @@
* @return Key that uniquely identifies any markup that might be associated
* with this markup container.
*/
- public CharSequence getCacheKey(final MarkupContainer container, final Class clazz)
+ public String getCacheKey(final MarkupContainer container, final Class clazz)
{
final String classname = clazz.getName();
final Locale locale = container.getLocale();
+ // TODO until now getStyle() == style + variation
final String style = container.getStyle();
final String markupType = container.getMarkupType();
- final AppendingStringBuffer buffer = new AppendingStringBuffer(classname.length() + 32);
+ final AppendingStringBuffer buffer = new AppendingStringBuffer(classname.length() + 64);
buffer.append(classname);
if (locale != null)
@@ -81,6 +82,6 @@
}
buffer.append(markupType);
- return buffer;
+ return buffer.toString();
}
}
Added: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCache.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCache.java?view=auto&rev=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCache.java (added)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCache.java Sun Jun 17 00:58:20 2007
@@ -0,0 +1,96 @@
+/*
+ * 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 org.apache.wicket.MarkupContainer;
+import org.apache.wicket.settings.IMarkupSettings;
+
+/**
+ * Each Wicket application has a single IMarkupCache associated with it (see
+ * {@link IMarkupSettings}). The markup cache is used by every Component to get
+ * its associated markup stream. Note that it is the markup caches
+ * responsibility to load the markup, if not yet done.
+ *
+ * @author Juergen Donnerstag
+ */
+public interface IMarkupCache
+{
+ /**
+ * Clear markup cache and force reload of all markup data
+ */
+ void clear();
+
+ /**
+ * Gets any (immutable) markup resource for the container or any of its
+ * parent classes (markup inheritance)
+ *
+ * @param container
+ * The original requesting markup container
+ * @param clazz
+ * The class to get the associated markup for. If null, the
+ * container's class is used, but it can be a parent class of the
+ * container as well (markup inheritance)
+ * @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 Markup resource
+ */
+ Markup getMarkup(final MarkupContainer container, final Class clazz, final boolean enforceReload);
+
+ /**
+ * Gets a fresh markup stream that contains the (immutable) markup resource
+ * for this class.
+ *
+ * @param container
+ * The container the markup should be associated with
+ * @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
+ * @param throwException
+ * If true, throw an exception, if markup could not be found
+ * @return A stream of MarkupElement elements
+ */
+ MarkupStream getMarkupStream(final MarkupContainer container, final boolean enforceReload,
+ final boolean throwException);
+
+ /**
+ * Check if container has associated markup
+ *
+ * @param container
+ * The container the markup should be associated with
+ * @return True if this markup container has associated markup
+ */
+ boolean hasAssociatedMarkup(final MarkupContainer container);
+
+ /**
+ * Remove the markup associated with the cache key from the cache including
+ * all dependent markups (markup inheritance)
+ *
+ * @see MarkupResourceStream#getCacheKey()
+ *
+ * @param cacheKey
+ * @return The markup removed from the cache. Null, if nothing was found.
+ */
+ Markup removeMarkup(final String cacheKey);
+
+ /**
+ * @return the number of elements currently in the cache.
+ */
+ int size();
+}
\ No newline at end of file
Propchange: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCache.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCacheKeyProvider.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCacheKeyProvider.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCacheKeyProvider.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkupCacheKeyProvider.java Sun Jun 17 00:58:20 2007
@@ -39,5 +39,5 @@
* The container the markup should be associated with
* @return A IResourceStream if the resource was found
*/
- CharSequence getCacheKey(final MarkupContainer container, Class containerClass);
+ String getCacheKey(final MarkupContainer container, Class containerClass);
}
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java Sun Jun 17 00:58:20 2007
@@ -17,29 +17,40 @@
package org.apache.wicket.markup;
import java.io.IOException;
+import java.util.Iterator;
import java.util.Map;
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.apache.wicket.util.watch.Watcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
/**
- * Load markup and cache it for fast retrieval. If markup file changes, it'll be
- * removed and subsequently reloaded when needed.
+ * 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
+public class MarkupCache implements IMarkupCache
{
/** Log for reporting. */
private static final Logger log = LoggerFactory.getLogger(MarkupCache.class);
@@ -47,13 +58,16 @@
/** Map of markup tags by class (exactly what is in the file). */
private final Map markupCache = new ConcurrentHashMap();
- /**
- * Markup inheritance requires that merged markup gets re-merged either
- * AFTER the base markup or the derived markup has been reloaded.
- */
- private final Watcher afterLoadListeners = new Watcher();
+ /** 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 Wicket application */
+ /** The application object */
private final Application application;
/**
@@ -61,45 +75,109 @@
*
* @param application
*/
- public MarkupCache(final Application application)
+ public MarkupCache()
{
- this.application = application;
+ this.application = Application.get();
}
/**
- * Clear markup cache and force reload of all markup data
+ * @see org.apache.wicket.markup.IMarkupCache#clear()
*/
- public void clear()
+ public final void clear()
{
- this.afterLoadListeners.clear();
this.markupCache.clear();
}
/**
- * Gets a fresh markup stream that contains the (immutable) markup resource
- * for this class.
- *
- * @param container
- * The container the markup should be associated with
- * @return A stream of MarkupElement elements
+ * @see org.apache.wicket.markup.IMarkupCache#removeMarkup(java.lang.String)
*/
- public final MarkupStream getMarkupStream(final MarkupContainer container)
+ public final Markup removeMarkup(final String cacheKey)
{
- return getMarkupStream(container, true);
+ 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.remove(cacheKey);
+ if (markup != null)
+ {
+ // 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.values().iterator();
+ while (iter.hasNext())
+ {
+ Markup cacheMarkup = (Markup)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;
}
/**
- * Gets a fresh markup stream that contains the (immutable) markup resource
- * for this class.
- *
- * @param container
- * The container the markup should be associated with
- * @param throwException
- * If true, throw an exception, if markup could not be found
- * @return A stream of MarkupElement elements
+ * @see org.apache.wicket.markup.IMarkupCache#getMarkupStream(org.apache.wicket.MarkupContainer,
+ * boolean, boolean)
*/
public final MarkupStream getMarkupStream(final MarkupContainer container,
- final boolean throwException)
+ final boolean enforceReload, final boolean throwException)
{
if (container == null)
{
@@ -107,7 +185,7 @@
}
// Look for associated markup
- final Markup markup = getMarkup(container, container.getClass());
+ final Markup markup = getMarkup(container, container.getClass(), false);
// If we found markup for this container
if (markup != Markup.NO_MARKUP)
@@ -118,245 +196,201 @@
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");
+ 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;
}
/**
- * Check if container has associated markup
- *
- * @param container
- * The container the markup should be associated with
- * @return True if this markup container has associated markup
+ * @see org.apache.wicket.markup.IMarkupCache#hasAssociatedMarkup(org.apache.wicket.MarkupContainer)
*/
public final boolean hasAssociatedMarkup(final MarkupContainer container)
{
- return getMarkup(container, container.getClass()) != Markup.NO_MARKUP;
+ return getMarkup(container, container.getClass(), false) != Markup.NO_MARKUP;
}
/**
- * @return the number of elements currently in the cache.
+ * @see org.apache.wicket.markup.IMarkupCache#size()
*/
- public int size()
+ public final int size()
{
return markupCache.size();
}
/**
- * The markup has just been loaded and now we check if markup inheritance
- * applies, which is if <wicket:extend> is found in the markup. If yes, than
- * load the base markups and merge the markup elements to create an updated
- * (merged) list of markup elements.
+ * THIS IS NOT PART OF WICKET'S PUBLIC API. DO NOT USE IT.
*
- * @param container
- * The original requesting markup container
- * @param markup
- * The markup to checked for inheritance
- * @return A markup object with the the base markup elements resolved.
+ * 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)
*/
- private Markup checkForMarkupInheritance(final MarkupContainer container, final Markup markup)
+ public final Markup getMarkup(final MarkupContainer container, final Class clazz,
+ final boolean enforceReload)
{
- // Check if markup contains <wicket:extend> which tells us that
- // we need to read the inherited markup as well.
- int extendIndex = requiresBaseMarkup(markup);
- if (extendIndex == -1)
+ Class containerClass = clazz;
+ if (clazz == null)
{
- // return a MarkupStream for the markup
- return markup;
+ containerClass = container.getClass();
}
-
- // get the base markup
- final Markup baseMarkup = getMarkup(container, markup.getMarkupResourceData().getResource().getMarkupClass()
- .getSuperclass());
-
- if (baseMarkup == Markup.NO_MARKUP)
+ else
{
- throw new MarkupNotFoundException(
- "Parent markup of inherited markup not found. Component class: "
- + markup.getMarkupResourceData().getResource().getContainerInfo().getContainerClass().getName()
- + " Enable debug messages for org.apache.wicket.util.resource.Resource to get a list of all filenames tried.");
+ if (!clazz.isAssignableFrom(container.getClass()))
+ {
+ throw new WicketRuntimeException("Parameter clazz must be instance of container");
+ }
}
- final CharSequence key = markup.getMarkupResourceData().getResource().getCacheKey();
- if (key != null)
+ // Get the cache key to be associated with the markup resource stream
+ final String cacheKey = getMarkupCacheKeyProvider(container).getCacheKey(container, clazz);
+
+ // Is the markup already in the cache?
+ Markup markup = (enforceReload == false ? getMarkupFromCache(cacheKey, container) : null);
+ if (markup == null)
{
- // register an after-load listener for base markup. The listener
- // implementation will remove the derived markup which must be
- // merged with the base markup
- afterLoadListeners.add(baseMarkup.getMarkupResourceData().getResource(), new IChangeListener()
+ if (log.isDebugEnabled())
{
- /**
- * Make sure there is only one listener per derived markup
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- public boolean equals(Object obj)
- {
- return true;
- }
+ 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);
- /**
- * Make sure there is only one listener per derived markup
- *
- * @see java.lang.Object#hashCode()
- */
- public int hashCode()
+ // Found markup?
+ if (resourceStream != null)
+ {
+ final MarkupResourceStream markupResourceStream;
+ if (resourceStream instanceof MarkupResourceStream)
{
- return key.hashCode();
+ markupResourceStream = (MarkupResourceStream)resourceStream;
}
-
- public void onChange()
+ else
{
- if (log.isDebugEnabled())
- {
- log.debug("Remove derived markup from cache: " + markup.getMarkupResourceData().getResource());
- }
- removeMarkup(markup.getMarkupResourceData().getResource());
+ markupResourceStream = new MarkupResourceStream(resourceStream,
+ new ContainerInfo(container), containerClass);
}
- });
- }
- // Merge base and derived markup
- Markup mergedMarkup = new MergedMarkup(markup, baseMarkup, extendIndex);
- return mergedMarkup;
+ markupResourceStream.setCacheKey(cacheKey);
+
+ // load the markup and watch for changes
+ markup = loadMarkupAndWatchForChanges(container, markupResourceStream,
+ enforceReload);
+ }
+ else
+ {
+ markup = onMarkupNotFound(cacheKey, container);
+ }
+ }
+ return markup;
}
/**
- * Gets any (immutable) markup resource for the container or any of its
- * parent classes (markup inheritance)
+ * 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
- * The original requesting markup container
- * @param clazz
- * The class to get the associated markup for. If null, the
- * container's class is used, but it can be a parent class of the
- * container as well (markup inheritance)
- * @return Markup resource
+ * @return Markup.NO_MARKUP
*/
- private final Markup getMarkup(final MarkupContainer container, final Class clazz)
+ protected Markup onMarkupNotFound(final String cacheKey, final MarkupContainer container)
{
- Class containerClass = clazz;
- if (clazz == null)
- {
- containerClass = container.getClass();
- }
- else
+ if (log.isDebugEnabled())
{
- if (!clazz.isAssignableFrom(container.getClass()))
- {
- throw new WicketRuntimeException("Parameter clazz must be instance of container");
- }
+ log.debug("Markup not found: " + cacheKey);
}
- // Get the cache key to be associated with the markup resource stream
- final IMarkupCacheKeyProvider markupCacheKeyProvider = getMarkupCacheKeyProvider(container);
- final CharSequence cacheKey = markupCacheKeyProvider.getCacheKey(container, clazz);
+ // flag markup as non-existent
+ return putIntoCache(cacheKey, Markup.NO_MARKUP);
+ }
- // Markup already in the cache? If cacheKey == null, than don't cache
- // the markup resource stream
- Markup markup = null;
+ /**
+ * 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)
+ {
if (cacheKey != null)
{
- markup = (Markup)markupCache.get(cacheKey);
- }
-
- // Must Markup be loaded?
- if (markup == null)
- {
- synchronized (markupCache)
+ if (markupCache.containsKey(cacheKey) == false)
{
- if (cacheKey != null)
- {
- markup = (Markup)markupCache.get(cacheKey);
- }
-
- // Must Markup be loaded?
- if (markup == null)
- {
- // Who is going to provide the markup resource stream?
- final IMarkupResourceStreamProvider markupResourceStreamProvider = getMarkupResourceStreamProvider(container);
-
- // Ask the provider to locate the markup resource stream
- final IResourceStream resourceStream = markupResourceStreamProvider
- .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);
- }
- else
- {
- // flag markup as non-existent (as opposed to null,
- // which might mean that it's simply not loaded into
- // the cache)
- markup = Markup.NO_MARKUP;
-
- // Save any markup list (or absence of one) for next
- // time
- if (cacheKey != null)
- {
- markupCache.put(cacheKey, markup);
- }
- }
- }
+ markupCache.put(cacheKey, 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 = (Markup)markupCache.get(cacheKey);
}
}
return markup;
}
/**
+ * Wicket's default implementation just uses the cacheKey to retrieve the
+ * markup from the cache. More sofisticated 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 CharSequence cacheKey, final MarkupContainer container)
+ {
+ if (cacheKey != null)
+ {
+ return (Markup)markupCache.get(cacheKey);
+ }
+ return null;
+ }
+
+ /**
* 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
*/
private final Markup loadMarkup(final MarkupContainer container,
- final MarkupResourceStream markupResourceStream)
+ final MarkupResourceStream markupResourceStream, final boolean enforceReload)
{
- CharSequence cacheKey = markupResourceStream.getCacheKey();
+ String cacheKey = markupResourceStream.getCacheKey();
try
{
- // read and parse the markup
- Markup markup = application.getMarkupSettings().getMarkupParserFactory()
- .newMarkupParser(markupResourceStream).parse();
-
- // Check for markup inheritance. If it contains <wicket:extend>
- // the two markups get merged.
- markup = checkForMarkupInheritance(container, markup);
+ Markup markup = getMarkupLoader().loadMarkup(container, markupResourceStream, null,
+ enforceReload);
- // add the markup to the cache
- if (cacheKey != null)
- {
- markupCache.put(cacheKey, markup);
- }
-
- // trigger all listeners registered on the markup just loaded
- afterLoadListeners.notifyListeners(markupResourceStream);
-
- return markup;
+ // add the markup to the cache.
+ return putIntoCache(cacheKey, markup);
}
catch (ResourceStreamNotFoundException e)
{
@@ -368,13 +402,9 @@
}
// In case of an error, remove the cache entry
- synchronized (markupCache)
+ if (cacheKey != null)
{
- if (cacheKey != null)
- {
- markupCache.remove(cacheKey);
- afterLoadListeners.remove(markupResourceStream);
- }
+ removeMarkup(cacheKey);
}
return Markup.NO_MARKUP;
@@ -390,15 +420,20 @@
* 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 MarkupResourceStream markupResourceStream, final boolean enforceReload)
{
- if (markupResourceStream.getCacheKey() != null)
+ final String cacheKey = markupResourceStream.getCacheKey();
+ if (cacheKey != null)
{
// Watch file in the future
- final ModificationWatcher watcher = application.getResourceSettings()
+ final ModificationWatcher watcher = Application.get().getResourceSettings()
.getResourceWatcher(true);
if (watcher != null)
{
@@ -412,9 +447,9 @@
}
// Remove the markup from the cache. It will be reloaded
- // next time it the markup is requested.
- removeMarkup(markupResourceStream);
+ // next time when the markup is requested.
watcher.remove(markupResourceStream);
+ removeMarkup(cacheKey);
}
});
}
@@ -424,86 +459,63 @@
{
log.debug("Loading markup from " + markupResourceStream);
}
- return loadMarkup(container, markupResourceStream);
+ return loadMarkup(container, markupResourceStream, enforceReload);
}
/**
- * Remove the markup from the cache and trigger all associated listeners
+ * Get the markup cache key provider to be used
*
- * @param markupResourceStream
- * The resource stream
+ * @param container
+ * The MarkupContainer requesting the markup resource stream
+ * @return IMarkupResourceStreamProvider
*/
- private void removeMarkup(final MarkupResourceStream markupResourceStream)
+ public IMarkupCacheKeyProvider getMarkupCacheKeyProvider(final MarkupContainer container)
{
- CharSequence cacheKey = markupResourceStream.getCacheKey();
- if (cacheKey != null)
+ if (container instanceof IMarkupCacheKeyProvider)
{
- markupCache.remove(cacheKey);
- // trigger all listeners registered on the markup that is removed
- afterLoadListeners.notifyListeners(markupResourceStream);
- afterLoadListeners.remove(markupResourceStream);
+ return (IMarkupCacheKeyProvider)container;
}
- }
- /**
- * Check if markup contains <wicket:extend> which tells us that we
- * need to read the inherited markup as well. <wicket:extend> MUST BE
- * the first wicket tag in the markup. Skip raw markup
- *
- * @param markup
- * @return == 0, if no wicket:extend was found
- */
- private int requiresBaseMarkup(final Markup markup)
- {
- for (int i = 0; i < markup.size(); i++)
+ if (this.markupCacheKeyProvider == null)
{
- MarkupElement elem = (MarkupElement)markup.get(i);
- if (elem instanceof WicketTag)
- {
- WicketTag wtag = (WicketTag)elem;
- if (wtag.isExtendTag())
- {
- // Ok, inheritance is on and we must get the
- // inherited markup as well.
- return i;
- }
- }
+ this.markupCacheKeyProvider = new DefaultMarkupCacheKeyProvider();
}
- return -1;
+ return this.markupCacheKeyProvider;
}
/**
- * Determine the markup cache key provider to be used
+ * Get the markup resource stream provider to be used
*
* @param container
* The MarkupContainer requesting the markup resource stream
* @return IMarkupResourceStreamProvider
*/
- protected IMarkupCacheKeyProvider getMarkupCacheKeyProvider(final MarkupContainer container)
+ protected IMarkupResourceStreamProvider getMarkupResourceStreamProvider(
+ final MarkupContainer container)
{
- if (container instanceof IMarkupCacheKeyProvider)
+ if (container instanceof IMarkupResourceStreamProvider)
{
- return (IMarkupCacheKeyProvider)container;
+ return (IMarkupResourceStreamProvider)container;
}
- return new DefaultMarkupCacheKeyProvider();
+ if (this.markupResourceStreamProvider == null)
+ {
+ this.markupResourceStreamProvider = new DefaultMarkupResourceStreamProvider();
+ }
+ return this.markupResourceStreamProvider;
}
/**
- * Determine the markup resource stream provider to be used
+ * In case there is a need to extend the default chain of MarkupLoaders
*
- * @param container
- * The MarkupContainer requesting the markup resource stream
- * @return IMarkupResourceStreamProvider
+ * @return MarkupLoader
*/
- protected IMarkupResourceStreamProvider getMarkupResourceStreamProvider(
- final MarkupContainer container)
+ protected IMarkupLoader getMarkupLoader()
{
- if (container instanceof IMarkupResourceStreamProvider)
+ if (markupLoader == null)
{
- return (IMarkupResourceStreamProvider)container;
+ markupLoader = new DefaultMarkupLoader();
}
-
- return new DefaultMarkupResourceStreamProvider();
+ return markupLoader;
}
}
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java Sun Jun 17 00:58:20 2007
@@ -37,9 +37,12 @@
/** Placeholder that indicates no markup */
public static final MarkupResourceData NO_MARKUP_RESOURCE_DATA = new MarkupResourceData();
- /** The markup's resource stream for diagnostic purposes */
+ /** The markup's resource stream */
private MarkupResourceStream resource;
+ /** In case of the inherited markup, the base markup's resource stream */
+ private MarkupResourceData baseMarkupResourceData;
+
/** If found in the markup, the <?xml ...?> string */
private String xmlDeclaration;
@@ -80,7 +83,7 @@
*
* @return The resource where this markup came from
*/
- MarkupResourceStream getResource()
+ public MarkupResourceStream getResource()
{
return resource;
}
@@ -125,7 +128,7 @@
{
return wicketId;
}
-
+
/**
* Sets encoding.
*
@@ -175,5 +178,26 @@
final void setResource(final MarkupResourceStream resource)
{
this.resource = resource;
+ }
+
+ /**
+ * Get the resource stream containing the base markup (markup inheritance)
+ *
+ * @return baseMarkupResource Null, if not base markup
+ */
+ public MarkupResourceData getBaseMarkupResourceData()
+ {
+ return this.baseMarkupResourceData;
+ }
+
+ /**
+ * In case of markup inheritance, the base markup resource.
+ *
+ * @param baseMarkupResourceData
+ * The base markup resource
+ */
+ public void setBaseMarkupResourceData(MarkupResourceData baseMarkupResourceData)
+ {
+ this.baseMarkupResourceData = baseMarkupResourceData;
}
}
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceStream.java Sun Jun 17 00:58:20 2007
@@ -51,7 +51,7 @@
private final Class markupClass;
/** The key used to cache the markup resource stream */
- private CharSequence cacheKey;
+ private String cacheKey;
/**
* Construct.
@@ -178,7 +178,7 @@
* Gets cacheKey.
* @return cacheKey
*/
- public final CharSequence getCacheKey()
+ public final String getCacheKey()
{
return cacheKey;
}
@@ -187,7 +187,7 @@
* Set the cache key
* @param cacheKey
*/
- public final void setCacheKey(final CharSequence cacheKey)
+ public final void setCacheKey(final String cacheKey)
{
this.cacheKey = cacheKey;
}
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java Sun Jun 17 00:58:20 2007
@@ -74,15 +74,6 @@
}
/**
- * DO NOT YOU THIS CONSTRUCTOR. IT WILL MOST LIKELY BE REPLACED IN THE NEAR
- * FUTURE.
- */
- protected MarkupStream()
- {
- this.markup = null;
- }
-
- /**
* @return True if current markup element is a close tag
*/
public boolean atCloseTag()
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java Sun Jun 17 00:58:20 2007
@@ -35,13 +35,13 @@
* The markup resource file, which is associated with the markup, will be the
* resource of the requested markup file. The base markup resources are not.
* <p>
- * Base Markup must have a <wicket:hild/> tag which the position where the
- * derived markup is inserted. From the derived markup all tags in between
- * <wicket:extend> and </wicket:extend> will be inserted.
+ * Base Markup must have a <wicket:child/> tag at the position where the
+ * derived markup should be inserted. From the derived markup all tags in
+ * between <wicket:extend> and </wicket:extend> will be inserted.
* <p>
- * In addition, all <wicket:head> regions are copied as well as the body
- * onLoad attribute. This allows to develop completely self-contained plug &
- * play components including javascript etc.
+ * In addition, all <wicket:head> regions are copied as well. This allows to
+ * develop completely self-contained plug & play components including javascript
+ * etc.
*
* @author Juergen Donnerstag
*/
@@ -59,22 +59,27 @@
* @param extendIndex
* Index where <wicket:extend> has been found
*/
- MergedMarkup(final Markup markup, final Markup baseMarkup, int extendIndex)
+ public MergedMarkup(final Markup markup, final Markup baseMarkup, int extendIndex)
{
super(new MarkupResourceData());
-
+
// Copy settings from derived markup
getMarkupResourceData().setResource(markup.getMarkupResourceData().getResource());
- getMarkupResourceData().setXmlDeclaration(markup.getMarkupResourceData().getXmlDeclaration());
+ getMarkupResourceData().setXmlDeclaration(
+ markup.getMarkupResourceData().getXmlDeclaration());
getMarkupResourceData().setEncoding(markup.getMarkupResourceData().getEncoding());
- getMarkupResourceData().setWicketNamespace(markup.getMarkupResourceData().getWicketNamespace());
+ getMarkupResourceData().setWicketNamespace(
+ markup.getMarkupResourceData().getWicketNamespace());
+ getMarkupResourceData().setBaseMarkupResourceData(baseMarkup.getMarkupResourceData());
if (log.isDebugEnabled())
{
- String derivedResource = Strings.afterLast(markup.getMarkupResourceData().getResource().toString(), '/');
- String baseResource = Strings.afterLast(baseMarkup.getMarkupResourceData().getResource().toString(), '/');
- log.debug("Merge markup: derived markup: " + derivedResource + "; base markup: "
- + baseResource);
+ String derivedResource = Strings.afterLast(markup.getMarkupResourceData().getResource()
+ .toString(), '/');
+ String baseResource = Strings.afterLast(baseMarkup.getMarkupResourceData()
+ .getResource().toString(), '/');
+ log.debug("Merge markup: derived markup: " + derivedResource + "; base markup: " +
+ baseResource);
}
// Merge derived and base markup
@@ -123,20 +128,24 @@
// Make sure all tags of the base markup remember where they are
// from
- if ((baseMarkup.getMarkupResourceData().getResource() != null) && (tag.getMarkupClass() == null))
+ if ((baseMarkup.getMarkupResourceData().getResource() != null) &&
+ (tag.getMarkupClass() == null))
{
- tag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ tag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource()
+ .getMarkupClass());
}
if (element instanceof WicketTag)
{
WicketTag wtag = (WicketTag)element;
- // Found org.apache.wicket.child in base markup. In case of 3+ level
+ // Found org.apache.wicket.child in base markup. In case of 3+
+ // level
// inheritance make sure the child tag is not from one of the
// deeper levels
- if (wtag.isChildTag()
- && (tag.getMarkupClass() == baseMarkup.getMarkupResourceData().getResource().getMarkupClass()))
+ if (wtag.isChildTag() &&
+ (tag.getMarkupClass() == baseMarkup.getMarkupResourceData().getResource()
+ .getMarkupClass()))
{
if (wtag.isOpenClose())
{
@@ -144,7 +153,8 @@
childTag = wtag;
WicketTag childOpenTag = (WicketTag)wtag.mutable();
childOpenTag.getXmlTag().setType(XmlTag.OPEN);
- childOpenTag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ childOpenTag.setMarkupClass(baseMarkup.getMarkupResourceData()
+ .getResource().getMarkupClass());
addMarkupElement(childOpenTag);
break;
}
@@ -156,8 +166,8 @@
}
else
{
- throw new WicketRuntimeException("Did not expect a </wicket:child> tag in "
- + baseMarkup.toString());
+ throw new WicketRuntimeException(
+ "Did not expect a </wicket:child> tag in " + baseMarkup.toString());
}
}
@@ -195,8 +205,8 @@
if (wicketHeadProcessed == false)
{
// if <head> in base markup
- if ((tag.isClose() && TagUtils.isHeadTag(tag))
- || (tag.isOpen() && TagUtils.isBodyTag(tag)))
+ if ((tag.isClose() && TagUtils.isHeadTag(tag)) ||
+ (tag.isOpen() && TagUtils.isBodyTag(tag)))
{
wicketHeadProcessed = true;
@@ -211,8 +221,8 @@
if (baseIndex == baseMarkup.size())
{
- throw new WicketRuntimeException("Expected to find <wicket:child/> in base markup: "
- + baseMarkup.toString());
+ throw new WicketRuntimeException("Expected to find <wicket:child/> in base markup: " +
+ baseMarkup.toString());
}
// Now append all elements from the derived markup starting with
@@ -250,22 +260,23 @@
if (tag.isChildTag() && tag.isClose())
{
// Ok, skipped the childs content
- tag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ tag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource()
+ .getMarkupClass());
addMarkupElement(tag);
break;
}
else
{
throw new WicketRuntimeException(
- "Wicket tags like <wicket:xxx> are not allowed in between <wicket:child> and </wicket:child> tags: "
- + markup.toString());
+ "Wicket tags like <wicket:xxx> are not allowed in between <wicket:child> and </wicket:child> tags: " +
+ markup.toString());
}
}
else if (element instanceof ComponentTag)
{
throw new WicketRuntimeException(
- "Wicket tags identified by wicket:id are not allowed in between <wicket:child> and </wicket:child> tags: "
- + markup.toString());
+ "Wicket tags identified by wicket:id are not allowed in between <wicket:child> and </wicket:child> tags: " +
+ markup.toString());
}
}
@@ -282,10 +293,11 @@
// But first add </wicket:child>
WicketTag childCloseTag = (WicketTag)childTag.mutable();
childCloseTag.getXmlTag().setType(XmlTag.CLOSE);
- childCloseTag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ childCloseTag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource()
+ .getMarkupClass());
addMarkupElement(childCloseTag);
}
-
+
for (baseIndex++; baseIndex < baseMarkup.size(); baseIndex++)
{
MarkupElement element = baseMarkup.get(baseIndex);
@@ -293,10 +305,12 @@
// Make sure all tags of the base markup remember where they are
// from
- if ((element instanceof ComponentTag) && (baseMarkup.getMarkupResourceData().getResource() != null))
+ if ((element instanceof ComponentTag) &&
+ (baseMarkup.getMarkupResourceData().getResource() != null))
{
ComponentTag tag = (ComponentTag)element;
- tag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ tag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource()
+ .getMarkupClass());
}
}
@@ -304,7 +318,8 @@
// it must enclose ALL of the <wicket:head> tags.
// Note: HtmlHeaderSectionHandler does something similar, but because
// markup filters are not called for merged markup again, ...
- if (Page.class.isAssignableFrom(markup.getMarkupResourceData().getResource().getMarkupClass()))
+ if (Page.class.isAssignableFrom(markup.getMarkupResourceData().getResource()
+ .getMarkupClass()))
{
// Find the position inside the markup for first <wicket:head>,
// last </wicket:head> and <head>
@@ -315,18 +330,18 @@
{
MarkupElement element = get(i);
- if ((hasOpenWicketHead == -1) && (element instanceof WicketTag)
- && ((WicketTag)element).isHeadTag())
+ if ((hasOpenWicketHead == -1) && (element instanceof WicketTag) &&
+ ((WicketTag)element).isHeadTag())
{
hasOpenWicketHead = i;
}
- else if ((element instanceof WicketTag) && ((WicketTag)element).isHeadTag()
- && ((WicketTag)element).isClose())
+ else if ((element instanceof WicketTag) && ((WicketTag)element).isHeadTag() &&
+ ((WicketTag)element).isClose())
{
hasCloseWicketHead = i;
}
- else if ((hasHead == -1) && (element instanceof ComponentTag)
- && TagUtils.isHeadTag((ComponentTag)element))
+ else if ((hasHead == -1) && (element instanceof ComponentTag) &&
+ TagUtils.isHeadTag((ComponentTag)element))
{
hasHead = i;
}
Added: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java?view=auto&rev=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java (added)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java Sun Jun 17 00:58:20 2007
@@ -0,0 +1,59 @@
+/*
+ * 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.loader;
+
+import java.io.IOException;
+
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.Markup;
+import org.apache.wicket.markup.MarkupResourceStream;
+import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
+
+/**
+ * This is Wickets default markup loader. It uses the
+ * InheritedMarkupMarkupLoader and SimpleMarkupLoader to load the markup
+ * associated with a MarkupContainer.
+ *
+ * @see InheritedMarkupMarkupLoader
+ * @see SimpleMarkupLoader
+ *
+ * @author Juergen Donnerstag
+ */
+public class DefaultMarkupLoader implements IMarkupLoader
+{
+ /**
+ * Constructor.
+ */
+ public DefaultMarkupLoader()
+ {
+ }
+
+ /**
+ *
+ * @see org.apache.wicket.markup.loader.IMarkupLoader#loadMarkup(org.apache.wicket.MarkupContainer,
+ * org.apache.wicket.markup.MarkupResourceStream,
+ * org.apache.wicket.markup.loader.IMarkupLoader, boolean)
+ */
+ public final Markup loadMarkup(final MarkupContainer container,
+ final MarkupResourceStream markupResourceStream, final IMarkupLoader baseLoader,
+ final boolean enforceReload) throws IOException, ResourceStreamNotFoundException
+ {
+ IMarkupLoader loader = new InheritedMarkupMarkupLoader();
+ return loader.loadMarkup(container, markupResourceStream, new SimpleMarkupLoader(),
+ enforceReload);
+ }
+}
Propchange: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/DefaultMarkupLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java?view=auto&rev=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java (added)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java Sun Jun 17 00:58:20 2007
@@ -0,0 +1,64 @@
+/*
+ * 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.loader;
+
+import java.io.IOException;
+
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.Markup;
+import org.apache.wicket.markup.MarkupCache;
+import org.apache.wicket.markup.MarkupParser;
+import org.apache.wicket.markup.MarkupParserFactory;
+import org.apache.wicket.markup.MarkupResourceStream;
+import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
+
+/**
+ * IMarkupLoader are loading the actual markup for a specific Wicket container
+ * and resource stream. In case of markup inheritance it means that 2+ markup
+ * files must be read and merged. In order to be flexible the interface has been
+ * designed in a way that multiple IMarkupLoader can be chained to easily build
+ * up more complex loaders.
+ *
+ * @see MarkupCache
+ * @see MarkupParser
+ * @see MarkupParserFactory
+ *
+ * @author Juergen Donnerstag
+ */
+public interface IMarkupLoader
+{
+ /**
+ * Loads markup from a resource stream.
+ *
+ * @param container
+ * The original requesting markup container
+ * @param markupResourceStream
+ * The markup resource stream to load
+ * @param baseLoader
+ * This parameter can be use to chain IMarkupLoaders
+ * @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
+ * @throws IOException
+ * @throws ResourceStreamNotFoundException
+ */
+ Markup loadMarkup(final MarkupContainer container,
+ final MarkupResourceStream markupResourceStream, final IMarkupLoader baseLoader,
+ final boolean enforceReload) throws IOException, ResourceStreamNotFoundException;
+}
\ No newline at end of file
Propchange: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/IMarkupLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java?view=auto&rev=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java (added)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java Sun Jun 17 00:58:20 2007
@@ -0,0 +1,144 @@
+/*
+ * 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.loader;
+
+import java.io.IOException;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.Markup;
+import org.apache.wicket.markup.MarkupElement;
+import org.apache.wicket.markup.MarkupNotFoundException;
+import org.apache.wicket.markup.MarkupResourceStream;
+import org.apache.wicket.markup.MergedMarkup;
+import org.apache.wicket.markup.WicketTag;
+import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Merge the 2+ markups involved in markup inheritance. From a users perspective
+ * there is only one markup associated with the component, the merged one.
+ *
+ * @author Juergen Donnerstag
+ */
+public class InheritedMarkupMarkupLoader implements IMarkupLoader
+{
+ /** Log for reporting. */
+ private static final Logger log = LoggerFactory.getLogger(InheritedMarkupMarkupLoader.class);
+
+ /**
+ * Constructor.
+ *
+ * @param cache
+ */
+ public InheritedMarkupMarkupLoader()
+ {
+ }
+
+ /**
+ *
+ * @see org.apache.wicket.markup.loader.IMarkupLoader#loadMarkup(org.apache.wicket.MarkupContainer,
+ * org.apache.wicket.markup.MarkupResourceStream,
+ * org.apache.wicket.markup.loader.IMarkupLoader, boolean)
+ */
+ public final Markup loadMarkup(final MarkupContainer container,
+ final MarkupResourceStream markupResourceStream, final IMarkupLoader baseLoader,
+ final boolean enforceReload) throws IOException, ResourceStreamNotFoundException
+ {
+ // read and parse the markup
+ Markup markup = baseLoader.loadMarkup(container, markupResourceStream, null, enforceReload);
+ markup = checkForMarkupInheritance(container, markup, enforceReload);
+ return markup;
+ }
+
+ /**
+ * The markup has just been loaded and now we check if markup inheritance
+ * applies, which is if <wicket:extend> is found in the markup. If yes, than
+ * load the base markups and merge the markup elements to create an updated
+ * (merged) list of markup elements.
+ *
+ * @param container
+ * The original requesting markup container
+ * @param markup
+ * The markup to checked for inheritance
+ * @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 A markup object with the the base markup elements resolved.
+ * @TODO move into IMarkupLoader
+ */
+ private Markup checkForMarkupInheritance(final MarkupContainer container, final Markup markup,
+ final boolean enforceReload)
+ {
+ // Check if markup contains <wicket:extend> which tells us that
+ // we need to read the inherited markup as well.
+ int extendIndex = requiresBaseMarkup(markup);
+ if (extendIndex == -1)
+ {
+ // return a MarkupStream for the markup
+ return markup;
+ }
+
+ // get the base markup
+ final Markup baseMarkup = Application.get().getMarkupSettings().getMarkupCache().getMarkup(
+ container,
+ markup.getMarkupResourceData().getResource().getMarkupClass().getSuperclass(),
+ enforceReload);
+
+ if (baseMarkup == Markup.NO_MARKUP)
+ {
+ throw new MarkupNotFoundException(
+ "Base markup of inherited markup not found. Component class: " +
+ markup.getMarkupResourceData().getResource().getContainerInfo()
+ .getContainerClass().getName() +
+ " Enable debug messages for org.apache.wicket.util.resource.Resource to get a list of all filenames tried.");
+ }
+
+ // Merge base and derived markup
+ return new MergedMarkup(markup, baseMarkup, extendIndex);
+ }
+
+ /**
+ * Check if markup contains <wicket:extend> which tells us that we
+ * need to read the inherited markup as well. <wicket:extend> MUST BE
+ * the first wicket tag in the markup. Skip raw markup
+ *
+ * @param markup
+ * @return == 0, if no wicket:extend was found
+ * @TODO move into IMarkupLoader
+ */
+ private int requiresBaseMarkup(final Markup markup)
+ {
+ for (int i = 0; i < markup.size(); i++)
+ {
+ MarkupElement elem = (MarkupElement)markup.get(i);
+ if (elem instanceof WicketTag)
+ {
+ WicketTag wtag = (WicketTag)elem;
+ if (wtag.isExtendTag())
+ {
+ // Ok, inheritance is on and we must get the
+ // inherited markup as well.
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+}
Propchange: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/InheritedMarkupMarkupLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java?view=auto&rev=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java (added)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java Sun Jun 17 00:58:20 2007
@@ -0,0 +1,55 @@
+/*
+ * 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.loader;
+
+import java.io.IOException;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.Markup;
+import org.apache.wicket.markup.MarkupResourceStream;
+import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
+
+/**
+ * Load the markup via the MarkupParser, not more, not less. Caching is provided
+ * separately as well as Inherited-Markup merging.
+ *
+ * @author Juergen Donnerstag
+ */
+public class SimpleMarkupLoader implements IMarkupLoader
+{
+ /**
+ * Constructor.
+ */
+ public SimpleMarkupLoader()
+ {
+ }
+
+ /**
+ *
+ * @see org.apache.wicket.markup.loader.IMarkupLoader#loadMarkup(org.apache.wicket.MarkupContainer,
+ * org.apache.wicket.markup.MarkupResourceStream,
+ * org.apache.wicket.markup.loader.IMarkupLoader, boolean)
+ */
+ public final Markup loadMarkup(final MarkupContainer container,
+ final MarkupResourceStream markupResourceStream, final IMarkupLoader baseLoader,
+ final boolean enforceReload) throws IOException, ResourceStreamNotFoundException
+ {
+ return Application.get().getMarkupSettings().getMarkupParserFactory().newMarkupParser(
+ markupResourceStream).parse();
+ }
+}
Propchange: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/loader/SimpleMarkupLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IMarkupSettings.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IMarkupSettings.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IMarkupSettings.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IMarkupSettings.java Sun Jun 17 00:58:20 2007
@@ -16,6 +16,7 @@
*/
package org.apache.wicket.settings;
+import org.apache.wicket.markup.IMarkupCache;
import org.apache.wicket.markup.IMarkupParserFactory;
import org.apache.wicket.markup.MarkupParserFactory;
@@ -72,6 +73,13 @@
IMarkupParserFactory getMarkupParserFactory();
/**
+ * The markup cache also loads the markup if not yet avaiable in the cache.
+ *
+ * @return markup cache
+ */
+ IMarkupCache getMarkupCache();
+
+ /**
* @return Returns the stripComments.
* @see IMarkupSettings#setStripComments(boolean)
*/
@@ -95,7 +103,8 @@
* Application default for automatic link resolution. Please
*
* @see org.apache.wicket.markup.resolver.AutoLinkResolver and
- * @see org.apache.wicket.markup.parser.filter.WicketLinkTagHandler for more details.
+ * @see org.apache.wicket.markup.parser.filter.WicketLinkTagHandler for more
+ * details.
*
* @param automaticLinking
* The automaticLinking to set.
@@ -150,6 +159,15 @@
* new factory
*/
void setMarkupParserFactory(IMarkupParserFactory factory);
+
+ /**
+ * Sets a new markup cache which will also be used to load markup if not yet
+ * available in the cache.
+ *
+ * @param markupCache
+ * new markup cache
+ */
+ void setMarkupCache(IMarkupCache markupCache);
/**
* Enables stripping of markup comments denoted in markup by HTML comment
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java Sun Jun 17 00:58:20 2007
@@ -34,7 +34,9 @@
import org.apache.wicket.authorization.IAuthorizationStrategy;
import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener;
import org.apache.wicket.authorization.UnauthorizedInstantiationException;
+import org.apache.wicket.markup.IMarkupCache;
import org.apache.wicket.markup.IMarkupParserFactory;
+import org.apache.wicket.markup.MarkupCache;
import org.apache.wicket.markup.MarkupParserFactory;
import org.apache.wicket.markup.html.IPackageResourceGuard;
import org.apache.wicket.markup.html.PackageResourceGuard;
@@ -169,6 +171,9 @@
/** Factory for creating markup parsers */
private IMarkupParserFactory markupParserFactory;
+ /** A markup cache which will load the markup if required. */
+ private IMarkupCache markupCache;
+
/** To help prevent denial of service attacks */
private int maxPageMaps = 5;
@@ -1239,5 +1244,27 @@
public boolean isOutputMarkupContainerClassName()
{
return outputMarkupContainerClassName;
+ }
+
+ /**
+ * @see org.apache.wicket.settings.IMarkupSettings#getMarkupCache()
+ */
+ public IMarkupCache getMarkupCache()
+ {
+ if (this.markupCache == null)
+ {
+ // Construct markup cache for this application
+ this.markupCache = new MarkupCache();
+ }
+
+ return this.markupCache;
+ }
+
+ /**
+ * @see org.apache.wicket.settings.IMarkupSettings#setMarkupCache(org.apache.wicket.markup.MarkupCache)
+ */
+ public void setMarkupCache(final IMarkupCache markupCache)
+ {
+ this.markupCache = markupCache;
}
}
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/watch/ModificationWatcher.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/watch/ModificationWatcher.java?view=diff&rev=548018&r1=548017&r2=548018
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/watch/ModificationWatcher.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/util/watch/ModificationWatcher.java Sun Jun 17 00:58:20 2007
@@ -20,6 +20,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import org.apache.wicket.util.listener.ChangeListenerSet;
import org.apache.wicket.util.listener.IChangeListener;
@@ -190,5 +191,13 @@
{
task.stop();
}
+ }
+
+ /**
+ * @return Gets all IModifiable entries currently maintained
+ */
+ public final Set getEntries()
+ {
+ return this.modifiableToEntry.keySet();
}
}