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 2006/11/05 21:10:21 UTC

svn commit: r471520 - in /incubator/wicket/trunk/wicket/src/main/java/wicket: ./ markup/html/ markup/html/internal/ markup/parser/filter/ markup/parser/onLoadListener/ markup/resolver/

Author: jdonnerstag
Date: Sun Nov  5 12:10:21 2006
New Revision: 471520

URL: http://svn.apache.org/viewvc?view=rev&rev=471520
Log:
Resolvers are the better solution

Added:
    incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketHeaderResolver.java   (with props)
Removed:
    incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/WicketHeaderMarkupLoadListener.java
Modified:
    incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java
    incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java
    incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java
    incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java
    incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java
    incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketMessageResolver.java

Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java?view=diff&rev=471520&r1=471519&r2=471520
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java Sun Nov  5 12:10:21 2006
@@ -35,11 +35,11 @@
 import wicket.application.IComponentInstantiationListener;
 import wicket.markup.MarkupCache;
 import wicket.markup.html.image.resource.DefaultButtonImageResourceFactory;
-import wicket.markup.parser.onLoadListener.WicketHeaderMarkupLoadListener;
 import wicket.markup.resolver.AutoComponentResolver;
 import wicket.markup.resolver.FragmentResolver;
 import wicket.markup.resolver.MarkupInheritanceResolver;
 import wicket.markup.resolver.ParentResolver;
+import wicket.markup.resolver.WicketHeaderResolver;
 import wicket.markup.resolver.WicketLinkResolver;
 import wicket.markup.resolver.WicketMessageResolver;
 import wicket.protocol.http.IRequestLogger;
@@ -724,12 +724,13 @@
 		pageSettings.addComponentResolver(new ParentResolver());
 		pageSettings.addComponentResolver(new MarkupInheritanceResolver());
 		pageSettings.addComponentResolver(new WicketLinkResolver());
+		pageSettings.addComponentResolver(new WicketHeaderResolver());
 		pageSettings.addComponentResolver(new WicketMessageResolver());
 		pageSettings.addComponentResolver(new FragmentResolver());
 		pageSettings.addComponentResolver(new AutoComponentResolver());
 
 		// Install default markup load listener
-		getMarkupSettings().addMarkupLoadListener(new WicketHeaderMarkupLoadListener());
+//		getMarkupSettings().addMarkupLoadListener(new WicketHeaderMarkupLoadListener());
 
 		// Install button image resource factory
 		getResourceSettings().addResourceFactory("buttonFactory",

Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java?view=diff&rev=471520&r1=471519&r2=471520
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java Sun Nov  5 12:10:21 2006
@@ -23,9 +23,15 @@
 
 import wicket.Component;
 import wicket.MarkupContainer;
+import wicket.Page;
+import wicket.markup.ComponentTag;
+import wicket.markup.MarkupElement;
+import wicket.markup.MarkupException;
 import wicket.markup.MarkupFragment;
 import wicket.markup.MarkupStream;
+import wicket.markup.html.internal.HeaderContainer;
 import wicket.markup.html.internal.WicketHeadContainer;
+import wicket.markup.parser.filter.HtmlHeaderSectionHandler;
 import wicket.model.IModel;
 
 /**
@@ -85,7 +91,7 @@
 		{
 			return fragment;
 		}
-		
+
 		return getAssociatedMarkup(true).getChildFragment(id, true);
 	}
 
@@ -97,18 +103,136 @@
 	{
 		if (isVisible())
 		{
-			// Load the markup and create the header containers if necessary
-			getAssociatedMarkup(true);
-			
-			for (Component child : this)
+			renderHead(response, getAssociatedMarkup(true));
+
+			super.renderHead(response);
+		}
+	}
+
+	/**
+	 * 
+	 * @param response
+	 * @param fragment
+	 */
+	private void renderHead(final IHeaderResponse response, final MarkupFragment fragment)
+	{
+		// Get the header container <head> from the page
+		final Page page = getPage();
+		final HeaderContainer headerContainer = (HeaderContainer)page
+				.get(HtmlHeaderSectionHandler.HEADER_ID);
+
+		// Search for wicket:head in the associated markup, create container for
+		// these tags and copy the body onload and onunload attributes
+		fragment.visitChildren(MarkupFragment.class, new MarkupFragment.IVisitor()
+		{
+			private boolean foundBody = false;
+
+			/**
+			 * @see wicket.markup.MarkupFragment.IVisitor#visit(wicket.markup.MarkupElement,
+			 *      wicket.markup.MarkupFragment)
+			 */
+			public Object visit(final MarkupElement element, final MarkupFragment parent)
 			{
-				if (child instanceof WicketHeadContainer)
+				final MarkupFragment frag = (MarkupFragment)element;
+				final ComponentTag tag = frag.getTag();
+
+				// if <wicket:head>, than
+				if (tag.isWicketHeadTag())
+				{
+					if (foundBody == true)
+					{
+						throwMarkupException(fragment, tag,
+								"<wicket:head> must be before the <body>, <wicket:panel> ... tag");
+					}
+
+					// Create a new wicket header container
+					WicketHeadContainer header = newWicketHeaderContainer(frag);
+
+					// Determine if the wicket:head markup should be printed or
+					// not.
+					header.setEnable(headerContainer.okToRender(header));
+					header.render(new MarkupStream(frag));
+
+					return CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
+				}
+				else if (tag.isBodyTag())
 				{
-					child.render(new MarkupStream(child.getMarkupFragment()));
+					// Found <body>. "Copy" the attributes to the page's body
+					// tag, if the container loading the markup is not a Page
+					foundBody = true;
+					if (page instanceof WebPage)
+					{
+						addBodyModifier(BodyContainer.ONLOAD, tag);
+						addBodyModifier(BodyContainer.ONUNLOAD, tag);
+					}
 				}
+				else if (tag.isMajorWicketComponentTag())
+				{
+					// Allow for improved error messages
+					foundBody = true;
+				}
+
+				return CONTINUE_TRAVERSAL;
 			}
-			
-			super.renderHead(response);
+		});
+	}
+
+	/**
+	 * Create a new WicketHeadContainer. Users may wish subclass the method to
+	 * implemented more sophisticated header scoping stragegies.
+	 * 
+	 * @param fragment
+	 *            The markup fragment associated with the wicket:head
+	 * @return The new header part container s
+	 */
+	public WicketHeadContainer newWicketHeaderContainer(final MarkupFragment fragment)
+	{
+		return new WicketHeadContainer(this, fragment.getTag().getId() + getPage().getAutoIndex(), fragment);
+	}
+
+	/**
+	 * Throw a MarkupException
+	 * 
+	 * @param parent
+	 *            The associated markup file
+	 * @param tag
+	 *            The element causing the error
+	 * @param message
+	 *            The error message
+	 */
+	private void throwMarkupException(final MarkupFragment parent, final MarkupElement tag,
+			final String message)
+	{
+		// Create a MarkupStream and position it at the error location
+		MarkupStream markupStream = new MarkupStream(parent);
+		while (markupStream.hasMore())
+		{
+			if (markupStream.next() == tag)
+			{
+				break;
+			}
+		}
+		throw new MarkupException(markupStream,
+				"<wicket:head> must be before the <body>, <wicket:panel> ... tag");
+	}
+
+	/**
+	 * Attach an AttributeModifier to the body container which appends the new
+	 * value to the onLoad attribute
+	 * 
+	 * @param attribute
+	 *            The body tags attribute name
+	 * @param tag
+	 *            The tag to "copy" the attributes from
+	 */
+	private void addBodyModifier(final String attribute, final ComponentTag tag)
+	{
+		final CharSequence value = tag.getString(attribute);
+		if (value != null)
+		{
+			// Attach an AttributeModifier to the body container
+			// which appends the new value to the onLoad attribute
+			((WebPage)this.getPage()).getBodyContainer().addModifier(attribute, value, this);
 		}
 	}
 }

Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java?view=diff&rev=471520&r1=471519&r2=471520
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java Sun Nov  5 12:10:21 2006
@@ -184,8 +184,8 @@
 	}
 
 	/**
-	 * Gets the container for the &lt;head&gt; tag, which will also render
-	 * the &lt;wicket:head&gt; tags.
+	 * Gets the container for the &lt;head&gt; tag, which will also render the
+	 * &lt;wicket:head&gt; tags.
 	 * 
 	 * @return The header container
 	 */
@@ -193,7 +193,7 @@
 	{
 		return (HeaderContainer)get(HtmlHeaderSectionHandler.HEADER_ID);
 	}
-	
+
 	/**
 	 * Gets the markup type for a WebPage, which is "html" by default. Support
 	 * for pages in another markup language, such as VXML, would require the
@@ -281,9 +281,13 @@
 	 */
 	protected void onAssociatedMarkupLoaded(final MarkupFragment markup)
 	{
+		// Create a body container, assuming that all HTML pages require a
+		// <body> tag
 		new HtmlBodyContainer(this, BodyOnLoadHandler.BODY_ID);
-		this.bodyContainer = new BodyContainer(this, BodyOnLoadHandler.BODY_ID);
 		
+		// Add this little helper to the page
+		this.bodyContainer = new BodyContainer(this, BodyOnLoadHandler.BODY_ID);
+
 		// The <head> container. It can be accessed, replaced
 		// and attribute modifiers can be attached.
 		// HtmlHeaderSectionHandler guarantees the <head> tag does exist.
@@ -294,7 +298,7 @@
 		{
 			add(new PageMapChecker());
 		}
-		
+
 		// Do all the default staff
 		super.onAssociatedMarkupLoaded(markup);
 	}
@@ -367,7 +371,7 @@
 		public final void renderHead(final IHeaderResponse headResponse)
 		{
 			Response response = headResponse.getResponse();
-			
+
 			final WebRequestCycle cycle = (WebRequestCycle)getRequestCycle();
 			final IRequestTarget target = cycle.getRequestTarget();
 

Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java?view=diff&rev=471520&r1=471519&r2=471520
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java Sun Nov  5 12:10:21 2006
@@ -42,22 +42,39 @@
 	private boolean enable = true;
 
 	/**
+	 * The (auto-)component is created during the render phase and removed at
+	 * the end of the render phase
+	 */
+	private transient MarkupFragment fragment;
+
+	/**
 	 * @param parent
 	 *            The owner parent of this component
 	 * @param id
 	 *            The component id
 	 * @param fragment
-	 *            The markup fragment associated with the wicket:head
+	 *            The associated markup
 	 */
 	public WicketHeadContainer(final MarkupContainer parent, final String id,
 			final MarkupFragment fragment)
 	{
 		super(parent, id);
 
-		// It is an auto component; make sure the markup loads properly
-		getMarkupFragment();
-
 		setRenderBodyOnly(true);
+		
+		this.fragment = fragment;
+		String namespace = this.fragment.getMarkup().getWicketNamespace();
+		this.scope = this.fragment.getTag().getAttributes().getString(namespace + ":scope");
+	}
+
+	/**
+	 * 
+	 * @see wicket.Component#getMarkupFragment()
+	 */
+	@Override
+	public MarkupFragment getMarkupFragment()
+	{
+		return this.fragment;
 	}
 
 	/**
@@ -89,13 +106,6 @@
 	 */
 	public final String getScope()
 	{
-		if (this.scope == null)
-		{
-			String namespace = getMarkupFragment().getMarkup().getWicketNamespace();
-			this.scope = getMarkupFragment().getTag().getAttributes().getString(
-					namespace + ":scope");
-		}
-
 		return this.scope;
 	}
 
@@ -126,7 +136,7 @@
 			{
 				getRequestCycle().setResponse(NullResponse.getInstance());
 			}
-			
+
 			// Render <wicket:head> with the markup fragment assigned
 			super.onRender(new MarkupStream(getMarkupFragment()));
 		}
@@ -134,7 +144,7 @@
 		{
 			// make sure the markup stream is updated
 			markupStream.skipComponent();
-			
+
 			// restore the orginial respone object
 			getRequestCycle().setResponse(response);
 		}

Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java?view=diff&rev=471520&r1=471519&r2=471520
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java Sun Nov  5 12:10:21 2006
@@ -49,11 +49,11 @@
 	/** wicket tag which require unique ids */
 	private static List<String> requiresUniqueId = new ArrayList<String>();
 
-	static
-	{
-		// register wicket:head, wicket:extend, etc.
-		registerTagWhichRequiresUniqueId("head");
-	}
+//	static
+//	{
+//		// register wicket:head, wicket:extend, etc.
+//		registerTagWhichRequiresUniqueId("head");
+//	}
 
 	/** The current markup needed to get the markups namespace */
 	private final IMarkup markup;

Added: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketHeaderResolver.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketHeaderResolver.java?view=auto&rev=471520
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketHeaderResolver.java (added)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketHeaderResolver.java Sun Nov  5 12:10:21 2006
@@ -0,0 +1,72 @@
+/*
+ * $Id: WicketTagComponentResolver.java,v 1.4 2005/01/18 08:04:29 jonathanlocke
+ * Exp $ $Revision$ $Date: 2006-07-08 13:02:03 +0200 (Sa, 08 Jul 2006) $
+ * 
+ * ==============================================================================
+ * Licensed 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 wicket.markup.resolver;
+
+import wicket.Component;
+import wicket.MarkupContainer;
+import wicket.markup.ComponentTag;
+import wicket.markup.MarkupStream;
+import wicket.markup.html.internal.TransparentWebMarkupContainer;
+import wicket.markup.parser.filter.WicketTagIdentifier;
+
+/**
+ * Detect &lt;wicket:extend&gt; and &lt;wicket:child&gt; tags, which are
+ * silently ignored, because they have already been processed.
+ * 
+ * @author Juergen Donnerstag
+ */
+public class WicketHeaderResolver implements IComponentResolver
+{
+	private static final long serialVersionUID = 1L;
+
+	static
+	{
+		// register "wicket:head"
+		WicketTagIdentifier.registerWellKnownTagName("head");
+	}
+
+	/**
+	 * @see wicket.markup.resolver.IComponentResolver#resolve(MarkupContainer,
+	 *      MarkupStream, ComponentTag)
+	 * @param container
+	 *            The container parsing its markup
+	 * @param markupStream
+	 *            The current markupStream
+	 * @param tag
+	 *            The current component tag while parsing the markup
+	 * @return true, if componentId was handle by the resolver. False, otherwise
+	 */
+	public boolean resolve(final MarkupContainer container, final MarkupStream markupStream,
+			final ComponentTag tag)
+	{
+		// If <head>...<wicket:head...> ...</head> 
+		if (tag.isWicketHeadTag())
+		{
+			Component component = new TransparentWebMarkupContainer(container, Component.AUTO_COMPONENT_PREFIX
+					+ tag.getId());
+
+			component.setRenderBodyOnly(true);
+			component.render(markupStream);
+			
+			return true;
+		}
+
+		// We were not able to handle the id
+		return false;
+	}
+}
\ No newline at end of file

Propchange: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketHeaderResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketHeaderResolver.java
------------------------------------------------------------------------------
    svn:keywords = "LastChangedDate LastChangedRevision URL"

Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketMessageResolver.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketMessageResolver.java?view=diff&rev=471520&r1=471519&r2=471520
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketMessageResolver.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/WicketMessageResolver.java Sun Nov  5 12:10:21 2006
@@ -50,7 +50,6 @@
 		WicketTagIdentifier.registerWellKnownTagName("message");
 	}
 
-
 	private static final long serialVersionUID = 1L;
 
 	/**