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 2011/01/11 21:50:07 UTC

svn commit: r1057859 [1/2] - in /wicket/trunk: wicket-core/src/main/java/org/apache/wicket/ wicket-core/src/main/java/org/apache/wicket/markup/ wicket-core/src/main/java/org/apache/wicket/markup/html/ wicket-core/src/main/java/org/apache/wicket/markup/...

Author: jdonnerstag
Date: Tue Jan 11 20:50:04 2011
New Revision: 1057859

URL: http://svn.apache.org/viewvc?rev=1057859&view=rev
Log:
initial version of WICKET-3314 Allow any Component to be a "Panel" or "Fragment" via configuration
Issue: WICKET-3314

Added:
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java
Removed:
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/ContainerWithAssociatedMarkupHelper.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java
Modified:
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/Component.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/WicketTag.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/EnumLabel.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/Label.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/MultiLineLabel.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AbstractChoice.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoice.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/SimpleFormComponentLabel.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/TextArea.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/include/Include.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/AutoMarkupLabel.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/Enclosure.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HtmlHeaderContainer.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/ExternalLink.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Fragment.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/resolver/WicketMessageResolver.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/transformer/AbstractOutputTransformerContainer.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/resource/filtering/HeaderResponseFilteredResponseContainer.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/TestPage_1.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyComponent.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyLabel.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/NestedFormsPage.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/panel/InlinePanelPage_5.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java
    wicket/trunk/wicket-datetime/src/main/java/org/apache/wicket/datetime/markup/html/basic/DateLabel.java
    wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/stockquote/StockQuoteLabel.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/AjaxEditableChoiceLabel.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/AjaxEditableLabel.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/AjaxEditableMultiLineLabel.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/basic/SmartLinkLabel.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/basic/SmartLinkMultiLineLabel.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/palette/component/AbstractOptions.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/select/SelectOptions.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/repeater/data/table/filter/FilterForm.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tabs/AbstractTab.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tabs/ITab.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tabs/PanelCachingTab.java
    wicket/trunk/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/tree/DefaultAbstractTree.java
    wicket/trunk/wicket-velocity/src/main/java/org/apache/wicket/velocity/markup/html/VelocityPanel.java

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/Component.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/Component.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/Component.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/Component.java Tue Jan 11 20:50:04 2011
@@ -44,6 +44,7 @@ import org.apache.wicket.markup.WicketTa
 import org.apache.wicket.markup.html.IHeaderContributor;
 import org.apache.wicket.markup.html.IHeaderResponse;
 import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
+import org.apache.wicket.markup.html.panel.IMarkupSourcingStrategy;
 import org.apache.wicket.model.IComponentAssignedModel;
 import org.apache.wicket.model.IComponentInheritedModel;
 import org.apache.wicket.model.IModel;
@@ -2490,7 +2491,15 @@ public abstract class Component
 			if (tag.isOpen())
 			{
 				// Render the body
-				onComponentTagBody(markupStream, tag);
+				IMarkupSourcingStrategy provider = getMarkupSourcingStrategy();
+				if (provider != null)
+				{
+					provider.onComponentTagBody(this, markupStream, tag);
+				}
+				else
+				{
+					onComponentTagBody(markupStream, tag);
+				}
 			}
 
 			// Render close tag
@@ -2560,6 +2569,41 @@ public abstract class Component
 		}
 	}
 
+	// Will be re-created instead of persisted when session is replicated.
+	// Markup sourcing strategy are meant to be stateless.
+	private transient IMarkupSourcingStrategy markupSourcingStrategy;
+
+	/**
+	 * Get the markup sourcing strategy for the component. If null,
+	 * {@link #newMarkupSourcingStrategy()} will be called. A return value of null indicates that no
+	 * specific strategy is attached to the Component, which is perfectly ok.
+	 * 
+	 * @return Markup sourcing strategy or null if no strategy is registered
+	 */
+	protected final IMarkupSourcingStrategy getMarkupSourcingStrategy()
+	{
+		if (markupSourcingStrategy == null)
+		{
+			markupSourcingStrategy = newMarkupSourcingStrategy();
+		}
+		return markupSourcingStrategy;
+	}
+
+	/**
+	 * If {@link #getMarkupSourcingStrategy()} return null, this method will be called. By default
+	 * it returns null, which means that no markup strategy is attached to the component.
+	 * 
+	 * Please note that markup source strategies are not persisted. Instead they get re-created by
+	 * calling this method again. That's ok since markup sourcing strategies usually do not maintain
+	 * a state.
+	 * 
+	 * @return Markup sourcing strategy
+	 */
+	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
+	{
+		return null;
+	}
+
 	/**
 	 * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT.
 	 * 
@@ -2588,6 +2632,13 @@ public abstract class Component
 			if (response.wasRendered(this) == false)
 			{
 				renderHead(response);
+
+				IMarkupSourcingStrategy provider = getMarkupSourcingStrategy();
+				if (provider != null)
+				{
+					provider.renderHead(this, container);
+				}
+
 				response.markRendered(this);
 			}
 
@@ -3701,7 +3752,7 @@ public abstract class Component
 
 	/**
 	 * Processes the component tag.
-	 * <p/>
+	 * 
 	 * Overrides of this method most likely should call the super implementation.
 	 * 
 	 * @param tag
@@ -3725,6 +3776,12 @@ public abstract class Component
 			path = path.replace(":", "_");
 			tag.put("wicketpath", path);
 		}
+
+		IMarkupSourcingStrategy provider = getMarkupSourcingStrategy();
+		if (provider != null)
+		{
+			provider.onComponentTag(this, tag);
+		}
 	}
 
 	/**
@@ -3735,7 +3792,7 @@ public abstract class Component
 	 * @param openTag
 	 *            The open tag for the body
 	 */
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 	}
 

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java Tue Jan 11 20:50:04 2011
@@ -35,6 +35,7 @@ import org.apache.wicket.markup.MarkupTy
 import org.apache.wicket.markup.RawMarkup;
 import org.apache.wicket.markup.WicketTag;
 import org.apache.wicket.markup.html.border.Border;
+import org.apache.wicket.markup.html.panel.IMarkupSourcingStrategy;
 import org.apache.wicket.markup.resolver.ComponentResolvers;
 import org.apache.wicket.model.IComponentInheritedModel;
 import org.apache.wicket.model.IModel;
@@ -452,6 +453,16 @@ public abstract class MarkupContainer ex
 	 */
 	public IMarkupFragment getMarkup(final Component child)
 	{
+		IMarkupSourcingStrategy provider = getMarkupSourcingStrategy();
+		if (provider != null)
+		{
+			IMarkupFragment markup = provider.getMarkup(this, child);
+			if (markup != null)
+			{
+				return markup;
+			}
+		}
+
 		// Get the markup for the container
 		IMarkupFragment markup = getMarkup();
 		if (markup == null)
@@ -1506,7 +1517,7 @@ public abstract class MarkupContainer ex
 	 *            The open tag for the body
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		renderComponentTagBody(markupStream, openTag);
 	}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/WicketTag.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/WicketTag.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/WicketTag.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/WicketTag.java Tue Jan 11 20:50:04 2011
@@ -17,7 +17,7 @@
 package org.apache.wicket.markup;
 
 import org.apache.wicket.markup.html.border.Border;
-import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.html.panel.PanelMarkupSourcingStrategy;
 import org.apache.wicket.markup.parser.XmlTag;
 import org.apache.wicket.markup.parser.filter.EnclosureHandler;
 import org.apache.wicket.markup.parser.filter.WicketLinkTagHandler;
@@ -154,7 +154,7 @@ public class WicketTag extends Component
 	 */
 	public final boolean isPanelTag()
 	{
-		return Panel.PANEL.equalsIgnoreCase(getName());
+		return PanelMarkupSourcingStrategy.PANEL.equalsIgnoreCase(getName());
 	}
 
 	/**

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/EnumLabel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/EnumLabel.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/EnumLabel.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/EnumLabel.java Tue Jan 11 20:50:04 2011
@@ -74,7 +74,7 @@ public class EnumLabel<T extends Enum<T>
 	}
 
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		replaceComponentTagBody(markupStream, openTag, getStringValue());
 	}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/Label.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/Label.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/Label.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/Label.java Tue Jan 11 20:50:04 2011
@@ -108,7 +108,7 @@ public class Label extends WebComponent
 	 * {@inheritDoc}
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		replaceComponentTagBody(markupStream, openTag, getDefaultModelObjectAsString());
 	}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/MultiLineLabel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/MultiLineLabel.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/MultiLineLabel.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/basic/MultiLineLabel.java Tue Jan 11 20:50:04 2011
@@ -73,7 +73,7 @@ public class MultiLineLabel extends WebC
 	}
 
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		CharSequence body = Strings.toMultilineMarkup(getDefaultModelObjectAsString());
 		replaceComponentTagBody(markupStream, openTag, body);

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java Tue Jan 11 20:50:04 2011
@@ -27,7 +27,9 @@ import org.apache.wicket.markup.MarkupFr
 import org.apache.wicket.markup.MarkupStream;
 import org.apache.wicket.markup.TagUtils;
 import org.apache.wicket.markup.html.TransparentWebMarkupContainer;
-import org.apache.wicket.markup.html.WebMarkupContainerWithAssociatedMarkup;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.panel.BorderMarkupSourcingStrategy;
+import org.apache.wicket.markup.html.panel.IMarkupSourcingStrategy;
 import org.apache.wicket.markup.parser.XmlTag.TagType;
 import org.apache.wicket.markup.parser.filter.WicketTagIdentifier;
 import org.apache.wicket.markup.resolver.IComponentResolver;
@@ -127,9 +129,7 @@ import org.apache.wicket.util.lang.Args;
  * @author Jonathan Locke
  * @author Juergen Donnerstag
  */
-public abstract class Border extends WebMarkupContainerWithAssociatedMarkup
-	implements
-		IComponentResolver
+public abstract class Border extends WebMarkupContainer implements IComponentResolver
 {
 	private static final long serialVersionUID = 1L;
 
@@ -281,6 +281,9 @@ public abstract class Border extends Web
 		return getBodyContainer().get(path);
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public Component resolve(final MarkupContainer container, final MarkupStream markupStream,
 		final ComponentTag tag)
 	{
@@ -298,27 +301,13 @@ public abstract class Border extends Web
 		return null;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
-	protected void onComponentTag(final ComponentTag tag)
-	{
-		if (tag.isOpen() == false)
-		{
-			throw new MarkupException(
-				"The border tag must be an open tag. Open-close is not allowed: " + tag.toString());
-		}
-
-		super.onComponentTag(tag);
-	}
-
-	@Override
-	protected final void onComponentTagBody(final MarkupStream markupStream,
-		final ComponentTag openTag)
+	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
 	{
-		// Render the associated markup
-		renderAssociatedMarkup("border",
-			"Markup for a border component must begin a tag like '<wicket:border>'");
-
-		markupStream.skipToMatchingCloseTag(openTag);
+		return new BorderMarkupSourcingStrategy();
 	}
 
 	/**
@@ -375,7 +364,8 @@ public abstract class Border extends Web
 			return childMarkup;
 		}
 
-		return findMarkupInAssociatedFileHeader(child);
+		return ((BorderMarkupSourcingStrategy)getMarkupSourcingStrategy()).findMarkupInAssociatedFileHeader(
+			this, child);
 	}
 
 	/**
@@ -415,8 +405,7 @@ public abstract class Border extends Web
 		}
 
 		@Override
-		protected void onComponentTagBody(final MarkupStream markupStream,
-			final ComponentTag openTag)
+		public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 		{
 			// skip the <wicket:body> body
 			if (markupStream.getPreviousTag().isOpen())

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AbstractChoice.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AbstractChoice.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AbstractChoice.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AbstractChoice.java Tue Jan 11 20:50:04 2011
@@ -329,7 +329,7 @@ public abstract class AbstractChoice<T, 
 	 *            The open tag for the body
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		List<? extends E> choices = getChoices();
 		final AppendingStringBuffer buffer = new AppendingStringBuffer((choices.size() * 50) + 16);

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoice.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoice.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoice.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoice.java Tue Jan 11 20:50:04 2011
@@ -298,8 +298,7 @@ public class CheckBoxMultipleChoice<T> e
 	 *      org.apache.wicket.markup.ComponentTag)
 	 */
 	@Override
-	protected final void onComponentTagBody(final MarkupStream markupStream,
-		final ComponentTag openTag)
+	public final void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		// Iterate through choices
 		final List<? extends T> choices = getChoices();

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java Tue Jan 11 20:50:04 2011
@@ -1502,7 +1502,7 @@ public class Form<T> extends WebMarkupCo
 	 *            The open tag for the body
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		if (isRootForm())
 		{

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java Tue Jan 11 20:50:04 2011
@@ -16,16 +16,9 @@
  */
 package org.apache.wicket.markup.html.form;
 
-import org.apache.wicket.Component;
 import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.IMarkupFragment;
-import org.apache.wicket.markup.MarkupStream;
-import org.apache.wicket.markup.html.ContainerWithAssociatedMarkupHelper;
-import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.markup.html.panel.Panel.PanelMarkupHelper;
-import org.apache.wicket.markup.parser.XmlTag.TagType;
-import org.apache.wicket.markup.parser.filter.WicketTagIdentifier;
+import org.apache.wicket.markup.html.panel.IMarkupSourcingStrategy;
+import org.apache.wicket.markup.html.panel.PanelMarkupSourcingStrategy;
 import org.apache.wicket.model.IModel;
 
 /**
@@ -119,17 +112,6 @@ public abstract class FormComponentPanel
 {
 	private static final long serialVersionUID = 1L;
 
-	static
-	{
-		// register "wicket:panel"
-		WicketTagIdentifier.registerWellKnownTagName(Panel.PANEL);
-	}
-
-	private ContainerWithAssociatedMarkupHelper markupHelper;
-
-	/** If if tag was an open-close tag */
-	private boolean wasOpenCloseTag = false;
-
 	/**
 	 * Construct.
 	 * 
@@ -152,7 +134,7 @@ public abstract class FormComponentPanel
 	}
 
 	/**
-	 * @see org.apache.wicket.markup.html.form.FormComponent#checkRequired()
+	 * {@inheritDoc}
 	 */
 	@Override
 	public boolean checkRequired()
@@ -161,70 +143,24 @@ public abstract class FormComponentPanel
 	}
 
 	/**
-	 * Check the associated markup file for a wicket header tag
-	 * 
-	 * @see org.apache.wicket.Component#renderHead(org.apache.wicket.markup.html.internal.HtmlHeaderContainer)
+	 * {@inheritDoc}
 	 */
 	@Override
-	public void renderHead(HtmlHeaderContainer container)
+	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
 	{
-		if (markupHelper == null)
-		{
-			markupHelper = new ContainerWithAssociatedMarkupHelper(this);
-		}
-
-		markupHelper.renderHeadFromAssociatedMarkupFile(container);
-
-		super.renderHead(container);
+		return new PanelMarkupSourcingStrategy();
 	}
 
 	/**
-	 * 
-	 * @see org.apache.wicket.Component#onComponentTag(org.apache.wicket.markup.ComponentTag)
+	 * {@inheritDoc}
 	 */
 	@Override
 	protected void onComponentTag(final ComponentTag tag)
 	{
-		if (tag.isOpenClose())
-		{
-			wasOpenCloseTag = true;
-
-			// Convert <span wicket:id="myPanel" /> into
-			// <span wicket:id="myPanel">...</span>
-			tag.setType(TagType.OPEN);
-		}
 		super.onComponentTag(tag);
 
 		// remove unapplicable attributes that might have been set by the call to super
 		tag.remove("name");
 		tag.remove("disabled");
 	}
-
-	/**
-	 * 
-	 * @see org.apache.wicket.Component#onComponentTagBody(org.apache.wicket.markup.MarkupStream,
-	 *      org.apache.wicket.markup.ComponentTag)
-	 */
-	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
-	{
-		// Render the associated markup
-		renderAssociatedMarkup("panel",
-			"Markup for a panel component has to contain part '<wicket:panel>'");
-
-		if (wasOpenCloseTag == false)
-		{
-			// Skip any raw markup in the body
-			markupStream.skipRawMarkup();
-		}
-	}
-
-	/**
-	 * @see org.apache.wicket.MarkupContainer#getMarkup(org.apache.wicket.Component)
-	 */
-	@Override
-	public IMarkupFragment getMarkup(final Component child)
-	{
-		return PanelMarkupHelper.getMarkup(this, child);
-	}
 }

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java Tue Jan 11 20:50:04 2011
@@ -337,8 +337,7 @@ public class RadioChoice<T> extends Abst
 	 * @see org.apache.wicket.Component#onComponentTagBody(MarkupStream, ComponentTag)
 	 */
 	@Override
-	protected final void onComponentTagBody(final MarkupStream markupStream,
-		final ComponentTag openTag)
+	public final void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		// Iterate through choices
 		final List<? extends T> choices = getChoices();

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/SimpleFormComponentLabel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/SimpleFormComponentLabel.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/SimpleFormComponentLabel.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/SimpleFormComponentLabel.java Tue Jan 11 20:50:04 2011
@@ -54,7 +54,7 @@ public class SimpleFormComponentLabel ex
 	 *      org.apache.wicket.markup.ComponentTag)
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		replaceComponentTagBody(markupStream, openTag, getDefaultModelObjectAsString());
 	}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/TextArea.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/TextArea.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/TextArea.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/TextArea.java Tue Jan 11 20:50:04 2011
@@ -60,8 +60,7 @@ public class TextArea<T> extends Abstrac
 	 * @see org.apache.wicket.Component#onComponentTagBody(MarkupStream, ComponentTag)
 	 */
 	@Override
-	protected final void onComponentTagBody(final MarkupStream markupStream,
-		final ComponentTag openTag)
+	public final void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		checkComponentTag(openTag, "textarea");
 

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java Tue Jan 11 20:50:04 2011
@@ -273,7 +273,7 @@ public class Image extends WebComponent 
 	 * @see org.apache.wicket.Component#onComponentTagBody(MarkupStream, ComponentTag)
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 	}
 }

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/include/Include.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/include/Include.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/include/Include.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/include/Include.java Tue Jan 11 20:50:04 2011
@@ -158,7 +158,7 @@ public class Include extends WebComponen
 	}
 
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		String content = importAsString();
 		replaceComponentTagBody(markupStream, openTag, content);

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/AutoMarkupLabel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/AutoMarkupLabel.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/AutoMarkupLabel.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/AutoMarkupLabel.java Tue Jan 11 20:50:04 2011
@@ -44,7 +44,7 @@ class AutoMarkupLabel extends WebCompone
 	}
 
 	@Override
-	protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
+	public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
 	{
 		replaceComponentTagBody(markupStream, openTag, markup);
 	}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/Enclosure.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/Enclosure.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/Enclosure.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/Enclosure.java Tue Jan 11 20:50:04 2011
@@ -154,7 +154,7 @@ public class Enclosure extends WebMarkup
 	}
 
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		// TODO this is where I wish we had something like "enum(TAG, BODY, NONE, ALL) isVisible()"
 		// set the enclosure visibility

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HtmlHeaderContainer.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HtmlHeaderContainer.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HtmlHeaderContainer.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HtmlHeaderContainer.java Tue Jan 11 20:50:04 2011
@@ -107,7 +107,7 @@ public class HtmlHeaderContainer extends
 	 * render them as well.
 	 */
 	@Override
-	protected final void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
+	public final void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
 	{
 		// We are able to automatically add <head> to the page if it is
 		// missing. But we only want to add it, if we have content to be

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/AbstractLink.java Tue Jan 11 20:50:04 2011
@@ -157,7 +157,7 @@ public abstract class AbstractLink exten
 	 * @see org.apache.wicket.Component#onComponentTagBody(MarkupStream, ComponentTag)
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		// Draw anything before the body?
 		if (!isLinkEnabled() && getBeforeDisabledLink() != null)

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/ExternalLink.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/ExternalLink.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/ExternalLink.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/link/ExternalLink.java Tue Jan 11 20:50:04 2011
@@ -209,7 +209,7 @@ public class ExternalLink extends Abstra
 	 *      org.apache.wicket.markup.ComponentTag)
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		// Draw anything before the body?
 		if (!isLinkEnabled() && getBeforeDisabledLink() != null)

Added: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java?rev=1057859&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java (added)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java Tue Jan 11 20:50:04 2011
@@ -0,0 +1,75 @@
+/*
+ * 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.html.panel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.IMarkupFragment;
+import org.apache.wicket.markup.MarkupException;
+import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
+import org.apache.wicket.markup.parser.XmlTag.TagType;
+
+/**
+ * Implements boiler plate as needed by most markup sourcing strategies.
+ * 
+ * @author Juergen Donnerstag
+ */
+public abstract class AbstractMarkupSourcingStrategy implements IMarkupSourcingStrategy
+{
+	/**
+	 * Make sure we open up open-close tags to open-body-close
+	 */
+	public void onComponentTag(final Component component, final ComponentTag tag)
+	{
+		if (tag.isOpenClose())
+		{
+			tag.setType(TagType.OPEN);
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void onComponentTagBody(final Component component, final MarkupStream markupStream,
+		final ComponentTag openTag)
+	{
+		// Skip the components body. It will be replaced by the associated markup or fragment
+		if (markupStream.getPreviousTag().isOpen())
+		{
+			markupStream.skipRawMarkup();
+			if (markupStream.get().closes(openTag) == false)
+			{
+				throw new MarkupException(markupStream, "Close tag not found for tag: " +
+					openTag.toString() + ". Component: " + component.toString());
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public abstract IMarkupFragment getMarkup(final MarkupContainer container, final Component child);
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void renderHead(final Component component, HtmlHeaderContainer container)
+	{
+	}
+}

Added: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java?rev=1057859&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java (added)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java Tue Jan 11 20:50:04 2011
@@ -0,0 +1,311 @@
+/*
+ * 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.html.panel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.IMarkupFragment;
+import org.apache.wicket.markup.MarkupElement;
+import org.apache.wicket.markup.MarkupException;
+import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.TagUtils;
+import org.apache.wicket.markup.WicketTag;
+import org.apache.wicket.markup.html.HeaderPartContainer;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
+import org.apache.wicket.util.lang.Classes;
+
+/**
+ * Boiler plate for markup sourcing strategy which retrieve the markup from associated markup files.
+ * 
+ * @author Juergen Donnerstag
+ */
+public abstract class AssociatedMarkupSourcingStrategy extends AbstractMarkupSourcingStrategy
+{
+	/** <wicket:head> is only allowed before <body>, </head>, <wicket:panel> etc. */
+	private boolean noMoreWicketHeadTagsAllowed = false;
+
+	/**
+	 * Constructor.
+	 */
+	public AssociatedMarkupSourcingStrategy()
+	{
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void onComponentTag(final Component component, final ComponentTag tag)
+	{
+		super.onComponentTag(component, tag);
+
+		// Copy attributes from <wicket:XXX> to the "calling" tag
+		IMarkupFragment markup = ((MarkupContainer)component).getMarkup(null);
+		String namespace = markup.getMarkupResourceStream().getWicketNamespace() + ":";
+
+		MarkupElement elem = markup.get(0);
+		if (elem instanceof ComponentTag)
+		{
+			ComponentTag panelTag = (ComponentTag)elem;
+			for (String key : panelTag.getAttributes().keySet())
+			{
+				// exclude "wicket:XX" attributes
+				if (key.startsWith(namespace) == false)
+				{
+					tag.append(key, panelTag.getAttribute(key), ", ");
+				}
+			}
+		}
+		else
+		{
+			throw new MarkupException(markup.getMarkupResourceStream(),
+				"Expected a Tag but found raw markup: " + elem.toString());
+		}
+	}
+
+	/**
+	 * Search the child's markup in the header section of the markup
+	 * 
+	 * @param container
+	 * @param child
+	 * @return Null, if not found
+	 */
+	public IMarkupFragment findMarkupInAssociatedFileHeader(final MarkupContainer container,
+		final Component child)
+	{
+		// Get the associated markup
+		IMarkupFragment markup = container.getAssociatedMarkup();
+		IMarkupFragment childMarkup = null;
+
+		// MarkupStream is good at searching markup
+		MarkupStream stream = new MarkupStream(markup);
+		while (stream.skipUntil(ComponentTag.class) && (childMarkup == null))
+		{
+			ComponentTag tag = stream.getTag();
+			if (TagUtils.isWicketHeadTag(tag))
+			{
+				if (tag.getMarkupClass() == null)
+				{
+					// find() can still fail an return null => continue the search
+					childMarkup = stream.getMarkupFragment().find(child.getId());
+				}
+			}
+			else if (TagUtils.isHeadTag(tag))
+			{
+				// find() can still fail an return null => continue the search
+				childMarkup = stream.getMarkupFragment().find(child.getId());
+			}
+
+			// Must be a direct child. We are not interested in grand children
+			if (tag.isOpen() && !tag.hasNoCloseTag())
+			{
+				stream.skipToMatchingCloseTag(tag);
+			}
+			stream.next();
+		}
+
+		return childMarkup;
+	}
+
+	/**
+	 * Render the header from the associated markup file
+	 */
+	@Override
+	public void renderHead(final Component component, HtmlHeaderContainer container)
+	{
+		if (!(component instanceof WebMarkupContainer))
+		{
+			throw new WicketRuntimeException(component.getClass().getSimpleName() +
+				" can only be associated with WebMarkupContainer.");
+		}
+
+		renderHeadFromAssociatedMarkupFile((WebMarkupContainer)component, container);
+	}
+
+	/**
+	 * Called by components like Panel and Border which have associated Markup and which may have a
+	 * &lt;wicket:head&gt; tag.
+	 * <p>
+	 * Whereas 'this' might be a Panel or Border, the HtmlHeaderContainer parameter has been added
+	 * to the Page as a container for all headers any of its components might wish to contribute to.
+	 * <p>
+	 * The headers contributed are rendered in the standard way.
+	 * 
+	 * @param container
+	 * @param htmlContainer
+	 *            The HtmlHeaderContainer added to the Page
+	 */
+	public final void renderHeadFromAssociatedMarkupFile(final WebMarkupContainer container,
+		final HtmlHeaderContainer htmlContainer)
+	{
+		// reset for each render in case the strategy is re-used
+		noMoreWicketHeadTagsAllowed = false;
+
+		// Gracefully getAssociateMarkupStream. Throws no exception in case
+		// markup is not found
+		final MarkupStream markupStream = container.getAssociatedMarkupStream(false);
+		if (markupStream == null)
+		{
+			return;
+		}
+
+		// Position pointer at current (first) header
+		noMoreWicketHeadTagsAllowed = false;
+		while (nextHeaderMarkup(markupStream) != -1)
+		{
+			// found <wicket:head>
+			String headerId = getHeaderId(container, markupStream);
+
+			// Create a HeaderPartContainer and associate the markup
+			HeaderPartContainer headerPart = getHeaderPart(container, headerId,
+				markupStream.getMarkupFragment());
+			if (headerPart != null)
+			{
+				// A component's header section must only be added once,
+				// no matter how often the same Component has been added
+				// to the page or any other container in the hierarchy.
+				if (htmlContainer.okToRenderComponent(headerPart.getScope(), headerPart.getId()))
+				{
+					// make sure the Page is accessible
+					headerPart.setParent(htmlContainer);
+					headerPart.render();
+				}
+			}
+
+			// Position the stream after <wicket:head>
+			markupStream.skipComponent();
+		}
+	}
+
+	/**
+	 * 
+	 * @param container
+	 * @param markupStream
+	 * @return The header id
+	 */
+	private String getHeaderId(final Component container, final MarkupStream markupStream)
+	{
+		Class<?> markupClass = markupStream.getTag().getMarkupClass();
+		if (markupClass == null)
+		{
+			markupClass = markupStream.getContainerClass();
+		}
+
+		// create a unique id for the HtmlHeaderContainer
+		StringBuilder builder = new StringBuilder(100);
+		builder.append("_");
+		builder.append(Classes.simpleName(markupClass));
+		if (container.getVariation() != null)
+		{
+			builder.append(container.getVariation());
+		}
+		builder.append("Header");
+		builder.append(markupStream.getCurrentIndex());
+		return builder.toString();
+	}
+
+	/**
+	 * Gets the header part of the Panel/Border. Returns null if it doesn't have a header tag.
+	 * 
+	 * @param container
+	 * @param id
+	 * @param markup
+	 * @return the header part for this panel/border or null if it doesn't have a wicket:head tag.
+	 */
+	private final HeaderPartContainer getHeaderPart(final WebMarkupContainer container,
+		final String id, final IMarkupFragment markup)
+	{
+		// Create a HtmlHeaderContainer for the header tag found
+		final MarkupElement element = markup.get(0);
+		if (element instanceof WicketTag)
+		{
+			final WicketTag wTag = (WicketTag)element;
+			if ((wTag.isHeadTag() == true) && (wTag.getNamespace() != null))
+			{
+				// Create the header container and associate the markup with it
+				return new HeaderPartContainer(id, container, markup);
+			}
+		}
+
+		throw new WicketRuntimeException("Programming error: expected a WicketTag: " +
+			markup.toString());
+	}
+
+	/**
+	 * Process next header markup fragment.
+	 * 
+	 * @param associatedMarkupStream
+	 * @return index or -1 when done
+	 */
+	private final int nextHeaderMarkup(final MarkupStream associatedMarkupStream)
+	{
+		// No associated markup => no header section
+		if (associatedMarkupStream == null)
+		{
+			return -1;
+		}
+
+		// Scan the markup for <wicket:head>.
+		MarkupElement elem = associatedMarkupStream.get();
+		while (elem != null)
+		{
+			if (elem instanceof WicketTag)
+			{
+				WicketTag tag = (WicketTag)elem;
+				if (tag.isOpen() && tag.isHeadTag())
+				{
+					if (noMoreWicketHeadTagsAllowed == true)
+					{
+						throw new MarkupException(
+							"<wicket:head> tags are only allowed before <body>, </head>, <wicket:panel> etc. tag");
+					}
+					return associatedMarkupStream.getCurrentIndex();
+				}
+				// wicket:head must be before border, panel or extend
+				// @TODO why is that? Why can't it be anywhere? (except insight wicket:fragment
+				else if (tag.isOpen() &&
+					(tag.isPanelTag() || tag.isBorderTag() || tag.isExtendTag()))
+				{
+					noMoreWicketHeadTagsAllowed = true;
+				}
+			}
+			else if (elem instanceof ComponentTag)
+			{
+				ComponentTag tag = (ComponentTag)elem;
+				// wicket:head must be before </head>
+				// @TODO why??
+				if (tag.isClose() && TagUtils.isHeadTag(tag))
+				{
+					noMoreWicketHeadTagsAllowed = true;
+				}
+				// wicket:head must be before <body>
+				// @TODO why??
+				else if (tag.isOpen() && TagUtils.isBodyTag(tag))
+				{
+					noMoreWicketHeadTagsAllowed = true;
+				}
+			}
+			elem = associatedMarkupStream.next();
+		}
+
+		// No (more) wicket:head found
+		return -1;
+	}
+}

Added: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java?rev=1057859&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java (added)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java Tue Jan 11 20:50:04 2011
@@ -0,0 +1,76 @@
+/*
+ * 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.html.panel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.IMarkupFragment;
+import org.apache.wicket.markup.MarkupException;
+import org.apache.wicket.markup.MarkupStream;
+
+/**
+ * 
+ * @author Juergen Donnerstag
+ */
+public class BorderMarkupSourcingStrategy extends AssociatedMarkupSourcingStrategy
+{
+	/**
+	 * Constructor.
+	 */
+	public BorderMarkupSourcingStrategy()
+	{
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void onComponentTag(Component component, ComponentTag tag)
+	{
+		if (tag.isOpen() == false)
+		{
+			throw new MarkupException(
+				"The border tag must be an open tag. Open-close is not allowed: " + tag.toString());
+		}
+
+		super.onComponentTag(component, tag);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void onComponentTagBody(Component component, MarkupStream markupStream,
+		ComponentTag openTag)
+	{
+		// Render the associated markup
+		((MarkupContainer)component).renderAssociatedMarkup("border",
+			"Markup for a border component must begin a tag like '<wicket:border>'");
+
+		markupStream.skipToMatchingCloseTag(openTag);
+	}
+
+	/**
+	 * Return null and thus use <code>component.getMarkup(child)</code> to provide the Markup
+	 */
+	@Override
+	public IMarkupFragment getMarkup(final MarkupContainer container, final Component child)
+	{
+		return null;
+	}
+}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Fragment.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Fragment.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Fragment.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Fragment.java Tue Jan 11 20:50:04 2011
@@ -18,15 +18,10 @@ package org.apache.wicket.markup.html.pa
 
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.IMarkupFragment;
-import org.apache.wicket.markup.MarkupException;
-import org.apache.wicket.markup.MarkupNotFoundException;
-import org.apache.wicket.markup.MarkupStream;
 import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.parser.XmlTag.TagType;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.util.lang.Objects;
+import org.apache.wicket.util.lang.Args;
 
 /**
  * Usually you either have a markup file or a xml tag with wicket:id="myComponent" to associate
@@ -55,10 +50,8 @@ public class Fragment extends WebMarkupC
 {
 	private static final long serialVersionUID = 1L;
 
-	/** The wicket:id of the associated markup fragment */
-	private String markupId;
+	private final String markupId;
 
-	/** The container providing the inline markup */
 	private final MarkupContainer markupProvider;
 
 	/**
@@ -97,138 +90,36 @@ public class Fragment extends WebMarkupC
 	{
 		super(id, model);
 
-		if (markupId == null)
-		{
-			throw new IllegalArgumentException("markupId cannot be null");
-		}
-
 		this.markupId = markupId;
 		this.markupProvider = markupProvider;
-	}
-
-	/**
-	 * The associated markup fragment can be modified
-	 * 
-	 * @param markupId
-	 */
-	public final void setMarkupTagReferenceId(final String markupId)
-	{
-		if (markupId == null)
-		{
-			throw new IllegalArgumentException("markupId cannot be null");
-		}
-		if (!Objects.equal(this.markupId, markupId))
-		{
-			addStateChange();
-		}
-		this.markupId = markupId;
-	}
 
-	/**
-	 * Make sure we open up open-close tags to open-body-close
-	 */
-	@Override
-	protected void onComponentTag(final ComponentTag tag)
-	{
-		if (tag.isOpenClose())
-		{
-			tag.setType(TagType.OPEN);
-		}
-		super.onComponentTag(tag);
+		Args.notNull(markupId, "markupId");
 	}
 
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
 	{
-		// Skip the components body. It will be replaced by the fragment
-		if (markupStream.getPreviousTag().isOpen())
+		return new FragmentMarkupSourcingStrategy(markupId, markupProvider)
 		{
-			markupStream.skipRawMarkup();
-			if (markupStream.get().closes(openTag) == false)
+			@Override
+			public IMarkupFragment chooseMarkup(Component component)
 			{
-				throw new MarkupException(markupStream, "close tag not found for tag: " +
-					openTag.toString() + ". Component: " + this.toString());
+				return Fragment.this.chooseMarkup(getMarkupProvider(component));
 			}
-		}
-
-		// Get the fragments open tag
-		MarkupStream stream = new MarkupStream(getMarkup(null));
-		ComponentTag fragmentOpenTag = stream.getTag();
-
-		// if it is an open close tag, skip this fragment.
-		if (!fragmentOpenTag.isOpenClose())
-		{
-			// We'll completely ignore the fragments open tag. It'll not be
-			// rendered
-			stream.next();
-
-			// Render the body of the fragment
-			super.onComponentTagBody(stream, fragmentOpenTag);
-		}
-	}
-
-	/**
-	 * Returns markup provider associated with this fragment
-	 * 
-	 * @return markup provider
-	 */
-	protected final MarkupContainer getMarkupProvider()
-	{
-		return (markupProvider != null ? markupProvider : getParent());
+		};
 	}
 
 	/**
 	 * Get the markup stream which shall be used to search for the fragment
 	 * 
+	 * @param provider
 	 * @return The markup stream to be used to find the fragment markup
 	 */
-	protected IMarkupFragment chooseMarkup()
-	{
-		return getMarkupProvider().getMarkup(null);
-	}
-
-	@Override
-	public IMarkupFragment getMarkup(final Component child)
+	protected IMarkupFragment chooseMarkup(final MarkupContainer provider)
 	{
-		// Get the markup to search for the fragment markup
-		IMarkupFragment markup = chooseMarkup();
-		if (markup == null)
-		{
-			throw new MarkupException("The fragments markup provider has no associated markup. " +
-				"No markup to search for fragment markup with id: " + markupId);
-		}
-
-		// Search for the fragment markup
-		IMarkupFragment childMarkup = markup.find(markupId);
-		if (childMarkup == null)
-		{
-			// There is one more option if the markup provider has associated markup
-			MarkupContainer markupProvider = getMarkupProvider();
-			if (markupProvider.hasAssociatedMarkup())
-			{
-				markup = markupProvider.getAssociatedMarkup();
-				if (markup != null)
-				{
-					childMarkup = markup.find(markupId);
-				}
-			}
-		}
-
-		if (childMarkup == null)
-		{
-			throw new MarkupNotFoundException("No Markup found for Fragment " + markupId +
-				" in providing markup container " + markupProvider.toString());
-		}
-
-		if (child == null)
-		{
-			return childMarkup;
-		}
-
-		// search for the child insight the fragment markup
-		return childMarkup.find(child.getId());
+		return provider.getMarkup(null);
 	}
 }

Added: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java?rev=1057859&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java (added)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java Tue Jan 11 20:50:04 2011
@@ -0,0 +1,148 @@
+/*
+ * 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.html.panel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.IMarkupFragment;
+import org.apache.wicket.markup.MarkupException;
+import org.apache.wicket.markup.MarkupNotFoundException;
+import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * 
+ * @author Juergen Donnerstag
+ */
+public class FragmentMarkupSourcingStrategy extends AbstractMarkupSourcingStrategy
+{
+	/** The wicket:id of the associated markup fragment */
+	private String markupId;
+
+	/** The container providing the inline markup */
+	private final MarkupContainer markupProvider;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param markupId
+	 *            The associated id of the associated markup fragment
+	 * @param markupProvider
+	 *            The component whose markup contains the fragment's markup
+	 */
+	public FragmentMarkupSourcingStrategy(final String markupId,
+		final MarkupContainer markupProvider)
+	{
+		Args.notNull(markupId, "markupId");
+
+		this.markupId = markupId;
+		this.markupProvider = markupProvider;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void onComponentTagBody(final Component component, final MarkupStream markupStream,
+		final ComponentTag openTag)
+	{
+		super.onComponentTagBody(component, markupStream, openTag);
+
+		// Get the fragments open tag
+		MarkupStream stream = new MarkupStream(getMarkup((MarkupContainer)component, null));
+		ComponentTag fragmentOpenTag = stream.getTag();
+
+		// if it is an open close tag, skip this fragment.
+		if (!fragmentOpenTag.isOpenClose())
+		{
+			// We'll completely ignore the fragments open tag. It'll not be
+			// rendered
+			stream.next();
+
+			// Render the body of the fragment
+			component.onComponentTagBody(stream, fragmentOpenTag);
+		}
+	}
+
+	/**
+	 * Returns markup provider associated with this fragment
+	 * 
+	 * @param component
+	 * @return markup provider
+	 */
+	protected final MarkupContainer getMarkupProvider(final Component component)
+	{
+		return (markupProvider != null ? markupProvider : component.getParent());
+	}
+
+	/**
+	 * Get the markup stream which shall be used to search for the fragment
+	 * 
+	 * @param component
+	 * @return The markup stream to be used to find the fragment markup
+	 */
+	public IMarkupFragment chooseMarkup(final Component component)
+	{
+		return getMarkupProvider(component).getMarkup(null);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public IMarkupFragment getMarkup(final MarkupContainer container, final Component child)
+	{
+		// Get the markup to search for the fragment markup
+		IMarkupFragment markup = chooseMarkup(container);
+		if (markup == null)
+		{
+			throw new MarkupException("The fragments markup provider has no associated markup. " +
+				"No markup to search for fragment markup with id: " + markupId);
+		}
+
+		// Search for the fragment markup
+		IMarkupFragment childMarkup = markup.find(markupId);
+		if (childMarkup == null)
+		{
+			// There is one more option if the markup provider has associated markup
+			MarkupContainer markupProvider = getMarkupProvider(container);
+			if (markupProvider.hasAssociatedMarkup())
+			{
+				markup = markupProvider.getAssociatedMarkup();
+				if (markup != null)
+				{
+					childMarkup = markup.find(markupId);
+				}
+			}
+		}
+
+		if (childMarkup == null)
+		{
+			throw new MarkupNotFoundException("No Markup found for Fragment " + markupId +
+				" in providing markup container " + markupProvider.toString());
+		}
+
+		if (child == null)
+		{
+			return childMarkup;
+		}
+
+		// search for the child insight the fragment markup
+		return childMarkup.find(child.getId());
+	}
+}

Added: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java?rev=1057859&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java (added)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java Tue Jan 11 20:50:04 2011
@@ -0,0 +1,88 @@
+/*
+ * 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.html.panel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.IMarkupFragment;
+import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
+
+/**
+ * Markup sourcing strategies determine whether a Component behaves like a "Panel" pulling its
+ * Markup from an associated Markup file, or like a Fragment pulling it from a another components
+ * Markup.
+ * 
+ * @author Juergen Donnerstag
+ */
+public interface IMarkupSourcingStrategy
+{
+	/**
+	 * Will be called in addition to {@link Component#renderHead(HtmlHeaderContainer)} and allows
+	 * the strategy to contribute to the &lt;head&gt; section of the response.
+	 * 
+	 * @see Component#renderHead(HtmlHeaderContainer)
+	 * 
+	 * @param component
+	 *            The component calling the strategy
+	 * @param container
+	 */
+	void renderHead(final Component component, HtmlHeaderContainer container);
+
+	/**
+	 * Will be called in addition to {@link Component#onComponentTag(ComponentTag)} and allows the
+	 * strategy to modify the component's tag or any of the tag attributes.
+	 * 
+	 * @see Component#onComponentTag(ComponentTag)
+	 * 
+	 * @param component
+	 *            The component calling the strategy
+	 * @param tag
+	 */
+	void onComponentTag(Component component, ComponentTag tag);
+
+	/**
+	 * Will <b>replace</b> the respective component's method.
+	 * <p>
+	 * It's perfectly valid to call <code>component.onComponentTagBody(markupStream, openTag)</code>
+	 * from insight this method.
+	 * 
+	 * @see Component#onComponentTagBody(MarkupStream, ComponentTag)
+	 * 
+	 * @param component
+	 *            The component calling the strategy
+	 * @param markupStream
+	 * @param openTag
+	 */
+	void onComponentTagBody(final Component component, final MarkupStream markupStream,
+		final ComponentTag openTag);
+
+	/**
+	 * Will <b>replace</b> the respective component's method. However by returning null, the
+	 * component's method will be called.
+	 * 
+	 * @see MarkupContainer#getMarkup(Component)
+	 * 
+	 * @param container
+	 *            The parent containing the child.
+	 * @param child
+	 *            The componen to find the markup for.
+	 * @return markup fragment
+	 */
+	IMarkupFragment getMarkup(final MarkupContainer container, final Component child);
+}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java Tue Jan 11 20:50:04 2011
@@ -16,24 +16,14 @@
  */
 package org.apache.wicket.markup.html.panel;
 
-import org.apache.wicket.Component;
-import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.IMarkupFragment;
-import org.apache.wicket.markup.MarkupException;
-import org.apache.wicket.markup.MarkupNotFoundException;
-import org.apache.wicket.markup.MarkupStream;
-import org.apache.wicket.markup.WicketTag;
-import org.apache.wicket.markup.html.WebMarkupContainerWithAssociatedMarkup;
-import org.apache.wicket.markup.parser.XmlTag.TagType;
-import org.apache.wicket.markup.parser.filter.WicketTagIdentifier;
+import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.model.IModel;
 
 /**
  * A panel is a reusable component that holds markup and other components.
  * <p>
  * Whereas WebMarkupContainer is an inline container like
- *
+ * 
  * <pre>
  *  ...
  *  &lt;span wicket:id=&quot;xxx&quot;&gt;
@@ -42,36 +32,27 @@ import org.apache.wicket.model.IModel;
  *  &lt;/span&gt;
  *  ...
  * </pre>
- *
+ * 
  * a Panel has its own associated markup file and the container content is taken from that file,
  * like:
- *
+ * 
  * <pre>
  *  &lt;span wicket:id=&quot;mypanel&quot;/&gt;
- *
+ * 
  *  TestPanel.html
  *  &lt;wicket:panel&gt;
  *    &lt;span wicket:id=&quot;mylabel&quot;&gt;My label&lt;/span&gt;
  *    ....
  *  &lt;/wicket:panel&gt;
  * </pre>
- *
+ * 
  * @author Jonathan Locke
  * @author Juergen Donnerstag
  */
-public abstract class Panel extends WebMarkupContainerWithAssociatedMarkup
+public abstract class Panel extends WebMarkupContainer
 {
 	private static final long serialVersionUID = 1L;
 
-	/** */
-	public static final String PANEL = "panel";
-
-	static
-	{
-		// register "wicket:panel"
-		WicketTagIdentifier.registerWellKnownTagName(PANEL);
-	}
-
 	/**
 	 * @see org.apache.wicket.Component#Component(String)
 	 */
@@ -88,120 +69,12 @@ public abstract class Panel extends WebM
 		super(id, model);
 	}
 
-	@Override
-	protected void onComponentTag(final ComponentTag tag)
-	{
-		if (tag.isOpenClose())
-		{
-			// Convert <span wicket:id="myPanel" /> into
-			// <span wicket:id="myPanel">...</span>
-			tag.setType(TagType.OPEN);
-		}
-		super.onComponentTag(tag);
-	}
-
-	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
-	{
-		// Render the associated markup
-		renderAssociatedMarkup(PANEL,
-			"Markup for a panel component has to contain part '<wicket:panel>'");
-
-		if (markupStream.getPreviousTag().isOpen())
-		{
-			// Skip any raw markup in the body
-			markupStream.skipRawMarkup();
-			if (markupStream.get().closes(openTag) == false)
-			{
-				throw new MarkupException(markupStream, "close tag not found for tag: " +
-					openTag.toString() + ". Component: " + this.toString());
-			}
-		}
-	}
-
-	@Override
-	public IMarkupFragment getMarkup(final Component child)
-	{
-		IMarkupFragment markup = PanelMarkupHelper.getMarkup(this, child);
-		if ((child == null) || (markup != null))
-		{
-			return markup;
-		}
-
-		return findMarkupInAssociatedFileHeader(child);
-	}
-
 	/**
-	 * Re-useable helper
-	 *
+	 * {@inheritDoc}
 	 */
-	public static class PanelMarkupHelper
+	@Override
+	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
 	{
-		/**
-		 * @see org.apache.wicket.MarkupContainer#getMarkup(org.apache.wicket.Component)
-		 *
-		 * @param parent
-		 * @param child
-		 * @return The markup associated with the child
-		 */
-		public static IMarkupFragment getMarkup(final MarkupContainer parent, final Component child)
-		{
-			IMarkupFragment markup = parent.getAssociatedMarkup();
-			if (markup == null)
-			{
-				throw new MarkupNotFoundException("Failed to find markup file associated. " +
-					parent.getClass().getSimpleName() + ": " + parent.toString());
-			}
-
-			// Find <wicket:panel>
-			IMarkupFragment panelMarkup = findPanelTag(markup);
-			if (panelMarkup == null)
-			{
-				throw new MarkupNotFoundException(
-					"Expected to find <wicket:panel> in associated markup file. Markup: " +
-						markup.toString());
-			}
-
-			// If child == null, than return the markup fragment starting with <wicket:panel>
-			if (child == null)
-			{
-				return panelMarkup;
-			}
-
-			// Find the markup for the child component
-			return panelMarkup.find(child.getId());
-		}
-
-		/**
-		 * Search for &lt;wicket:panel ...&gt; on the same level.
-		 *
-		 * @param markup
-		 * @return null, if not found
-		 */
-		private final static IMarkupFragment findPanelTag(final IMarkupFragment markup)
-		{
-			MarkupStream stream = new MarkupStream(markup);
-
-			while (stream.skipUntil(ComponentTag.class))
-			{
-				ComponentTag tag = stream.getTag();
-				if (tag.isOpen() || tag.isOpenClose())
-				{
-					if (tag instanceof WicketTag)
-					{
-						WicketTag wtag = (WicketTag)tag;
-						if (wtag.isPanelTag())
-						{
-							return stream.getMarkupFragment();
-						}
-					}
-					stream.skipToMatchingCloseTag(tag);
-				}
-
-				stream.next();
-			}
-
-			return null;
-		}
+		return new PanelMarkupSourcingStrategy();
 	}
 }

Added: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java?rev=1057859&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java (added)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java Tue Jan 11 20:50:04 2011
@@ -0,0 +1,133 @@
+/*
+ * 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.html.panel;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.IMarkupFragment;
+import org.apache.wicket.markup.MarkupNotFoundException;
+import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.WicketTag;
+import org.apache.wicket.markup.parser.filter.WicketTagIdentifier;
+
+/**
+ * 
+ * @author Juergen Donnerstag
+ */
+public class PanelMarkupSourcingStrategy extends AssociatedMarkupSourcingStrategy
+{
+	/** */
+	public static final String PANEL = "panel";
+
+	static
+	{
+		// register "wicket:panel"
+		WicketTagIdentifier.registerWellKnownTagName(PANEL);
+	}
+
+	/**
+	 * Constructor.
+	 */
+	public PanelMarkupSourcingStrategy()
+	{
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void onComponentTagBody(final Component component, final MarkupStream markupStream,
+		final ComponentTag openTag)
+	{
+		super.onComponentTagBody(component, markupStream, openTag);
+
+		// Render the associated markup
+		((MarkupContainer)component).renderAssociatedMarkup(PANEL,
+			"Markup for a panel component has to contain part '<wicket:panel>'");
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public IMarkupFragment getMarkup(final MarkupContainer parent, final Component child)
+	{
+		IMarkupFragment markup = parent.getAssociatedMarkup();
+		if (markup == null)
+		{
+			throw new MarkupNotFoundException("Failed to find markup file associated. " +
+				parent.getClass().getSimpleName() + ": " + parent.toString());
+		}
+
+		// Find <wicket:panel>
+		IMarkupFragment panelMarkup = findPanelTag(markup);
+		if (panelMarkup == null)
+		{
+			throw new MarkupNotFoundException(
+				"Expected to find <wicket:panel> in associated markup file. Markup: " +
+					markup.toString());
+		}
+
+		// If child == null, than return the markup fragment starting with <wicket:panel>
+		if (child == null)
+		{
+			return panelMarkup;
+		}
+
+		// Find the markup for the child component
+		markup = panelMarkup.find(child.getId());
+		if ((child == null) || (markup != null))
+		{
+			return markup;
+		}
+
+		return findMarkupInAssociatedFileHeader(parent, child);
+	}
+
+	/**
+	 * Search for &lt;wicket:panel ...&gt; on the same level.
+	 * 
+	 * @param markup
+	 * @return null, if not found
+	 */
+	private final static IMarkupFragment findPanelTag(final IMarkupFragment markup)
+	{
+		MarkupStream stream = new MarkupStream(markup);
+
+		while (stream.skipUntil(ComponentTag.class))
+		{
+			ComponentTag tag = stream.getTag();
+			if (tag.isOpen() || tag.isOpenClose())
+			{
+				if (tag instanceof WicketTag)
+				{
+					WicketTag wtag = (WicketTag)tag;
+					if (wtag.isPanelTag())
+					{
+						return stream.getMarkupFragment();
+					}
+				}
+				stream.skipToMatchingCloseTag(tag);
+			}
+
+			stream.next();
+		}
+
+		return null;
+	}
+}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/resolver/WicketMessageResolver.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/resolver/WicketMessageResolver.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/resolver/WicketMessageResolver.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/resolver/WicketMessageResolver.java Tue Jan 11 20:50:04 2011
@@ -196,8 +196,7 @@ public class WicketMessageResolver imple
 		}
 
 		@Override
-		protected void onComponentTagBody(final MarkupStream markupStream,
-			final ComponentTag openTag)
+		public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 		{
 			// Get the value from the properties file
 			final String key = getDefaultModelObjectAsString();

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/transformer/AbstractOutputTransformerContainer.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/transformer/AbstractOutputTransformerContainer.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/transformer/AbstractOutputTransformerContainer.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/transformer/AbstractOutputTransformerContainer.java Tue Jan 11 20:50:04 2011
@@ -94,8 +94,7 @@ public abstract class AbstractOutputTran
 		throws Exception;
 
 	@Override
-	protected final void onComponentTagBody(final MarkupStream markupStream,
-		final ComponentTag openTag)
+	public final void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		if (transformBodyOnly == true)
 		{

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/resource/filtering/HeaderResponseFilteredResponseContainer.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/resource/filtering/HeaderResponseFilteredResponseContainer.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/resource/filtering/HeaderResponseFilteredResponseContainer.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/resource/filtering/HeaderResponseFilteredResponseContainer.java Tue Jan 11 20:50:04 2011
@@ -59,7 +59,7 @@ public class HeaderResponseFilteredRespo
 	}
 
 	@Override
-	protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
+	public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
 	{
 		HeaderResponseContainerFilteringHeaderResponse response = HeaderResponseContainerFilteringHeaderResponse.get();
 		if (!response.isClosed())

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/TestPage_1.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/TestPage_1.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/TestPage_1.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/TestPage_1.java Tue Jan 11 20:50:04 2011
@@ -49,7 +49,7 @@ public class TestPage_1 extends WebPage
 			}
 
 			@Override
-			protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
+			public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
 			{
 				replaceComponentTagBody(markupStream, openTag, "body");
 			}

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyComponent.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyComponent.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyComponent.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyComponent.java Tue Jan 11 20:50:04 2011
@@ -156,9 +156,9 @@ public class MyComponent extends WebMark
 	 *      org.apache.wicket.markup.ComponentTag)
 	 */
 	@Override
-	protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
+	public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
 	{
-	 StringBuilder str = new StringBuilder();
+		StringBuilder str = new StringBuilder();
 
 		str.append("intParam: ").append(intParam).append("<br/>");
 		str.append("integerParam: ").append(integerParam.toString()).append("<br/>");

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyLabel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyLabel.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyLabel.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MyLabel.java Tue Jan 11 20:50:04 2011
@@ -68,7 +68,7 @@ public class MyLabel extends WebComponen
 	 *      org.apache.wicket.markup.ComponentTag)
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		replaceComponentTagBody(markupStream, openTag, text);
 	}

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/NestedFormsPage.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/NestedFormsPage.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/NestedFormsPage.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/NestedFormsPage.java Tue Jan 11 20:50:04 2011
@@ -147,7 +147,7 @@ public class NestedFormsPage extends Web
 		}
 
 		@Override
-		protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
+		public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
 		{
 			String state = form.isEnabled() ? "enabled" : "disabled";
 			replaceComponentTagBody(markupStream, openTag, "form is " + state);

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/panel/InlinePanelPage_5.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/panel/InlinePanelPage_5.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/panel/InlinePanelPage_5.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/panel/InlinePanelPage_5.java Tue Jan 11 20:50:04 2011
@@ -16,6 +16,7 @@
  */
 package org.apache.wicket.markup.html.panel;
 
+import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.IMarkupFragment;
 import org.apache.wicket.markup.html.WebPage;
 
@@ -58,7 +59,7 @@ public class InlinePanelPage_5 extends W
 		}
 
 		@Override
-		protected IMarkupFragment chooseMarkup()
+		protected IMarkupFragment chooseMarkup(final MarkupContainer provider)
 		{
 			return getAssociatedMarkup();
 		}

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java Tue Jan 11 20:50:04 2011
@@ -16,9 +16,14 @@
  */
 package org.apache.wicket.markup.parser.filter;
 
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.IMarkupFragment;
 import org.apache.wicket.markup.MarkupStream;
-import org.apache.wicket.markup.html.WebMarkupContainerWithAssociatedMarkup;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.panel.IMarkupSourcingStrategy;
+import org.apache.wicket.markup.html.panel.PanelMarkupSourcingStrategy;
 import org.apache.wicket.model.Model;
 
 
@@ -27,7 +32,7 @@ import org.apache.wicket.model.Model;
  * 
  * @author Chris Turner
  */
-public class HeaderSectionMyLabel extends WebMarkupContainerWithAssociatedMarkup
+public class HeaderSectionMyLabel extends WebMarkupContainer
 {
 	private static final long serialVersionUID = 1L;
 
@@ -43,12 +48,33 @@ public class HeaderSectionMyLabel extend
 	}
 
 	/**
-	 * @see org.apache.wicket.Component#onComponentTagBody(org.apache.wicket.markup.MarkupStream,
-	 *      org.apache.wicket.markup.ComponentTag)
+	 * {@inheritDoc}
 	 */
 	@Override
-	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
+	public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
 	{
 		replaceComponentTagBody(markupStream, openTag, getDefaultModelObjectAsString());
 	}
+
+	@Override
+	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
+	{
+		return new PanelMarkupSourcingStrategy()
+		{
+			@Override
+			public IMarkupFragment getMarkup(final MarkupContainer parent, final Component child)
+			{
+				MarkupStream markup = parent.getAssociatedMarkupStream(true);
+				markup.skipRawMarkup();
+				return markup.getMarkupFragment();
+			}
+
+			@Override
+			public void onComponentTagBody(Component component, MarkupStream markupStream,
+				ComponentTag openTag)
+			{
+				HeaderSectionMyLabel.this.onComponentTagBody(markupStream, openTag);
+			}
+		};
+	}
 }

Modified: wicket/trunk/wicket-datetime/src/main/java/org/apache/wicket/datetime/markup/html/basic/DateLabel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-datetime/src/main/java/org/apache/wicket/datetime/markup/html/basic/DateLabel.java?rev=1057859&r1=1057858&r2=1057859&view=diff
==============================================================================
--- wicket/trunk/wicket-datetime/src/main/java/org/apache/wicket/datetime/markup/html/basic/DateLabel.java (original)
+++ wicket/trunk/wicket-datetime/src/main/java/org/apache/wicket/datetime/markup/html/basic/DateLabel.java Tue Jan 11 20:50:04 2011
@@ -279,8 +279,11 @@ public class DateLabel extends Label
 		this.before = before;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
-	protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
+	public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag)
 	{
 		String s = getDefaultModelObjectAsString();
 		if (before != null)