001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.wicket.markup.resolver;
018:
019: import org.apache.wicket.MarkupContainer;
020: import org.apache.wicket.WicketRuntimeException;
021: import org.apache.wicket.markup.ComponentTag;
022: import org.apache.wicket.markup.MarkupException;
023: import org.apache.wicket.markup.MarkupStream;
024: import org.apache.wicket.markup.WicketTag;
025: import org.apache.wicket.markup.html.WebMarkupContainer;
026: import org.apache.wicket.markup.html.WebPage;
027: import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
028: import org.apache.wicket.markup.parser.filter.HtmlHeaderSectionHandler;
029: import org.apache.wicket.markup.parser.filter.WicketTagIdentifier;
030:
031: /**
032: * This is a tag resolver which handles <head> and
033: * <wicket:head>tags. It must be registered (with the application) and
034: * assumes that a ComponentTag respectively a WicketTag has already been created
035: * (see HtmlheaderSectionHandler and WicketTagIdentifier).
036: * <p>
037: * Provided the current tag is a <head>, a HtmlHeaderContainer component
038: * is created, (auto) added to the component hierarchie and immediately
039: * rendered. Please see the javadoc for HtmlHeaderContainer on how it treats the
040: * tag.
041: * <p>
042: * In case of <wicket:head> a simple WebMarkupContainer handles the tag.
043: *
044: * @author Juergen Donnerstag
045: */
046: public class HtmlHeaderResolver implements IComponentResolver {
047: private static final long serialVersionUID = 1L;
048:
049: static {
050: // register "wicket:head"
051: WicketTagIdentifier.registerWellKnownTagName("head");
052: }
053:
054: /**
055: * Try to resolve the tag, then create a component, add it to the container
056: * and render it.
057: *
058: * @see org.apache.wicket.markup.resolver.IComponentResolver#resolve(MarkupContainer,
059: * MarkupStream, ComponentTag)
060: *
061: * @param container
062: * The container parsing its markup
063: * @param markupStream
064: * The current markupStream
065: * @param tag
066: * The current component tag while parsing the markup
067: * @return true, if componentId was handle by the resolver. False, otherwise
068: */
069: public boolean resolve(final MarkupContainer container,
070: final MarkupStream markupStream, final ComponentTag tag) {
071: // Only <head> component tags have the id == "_header"
072: if (tag.getId().equals(HtmlHeaderSectionHandler.HEADER_ID)) {
073: // Create a special header component which will gather additional
074: // input the <head> from 'contributors'.
075: final WebMarkupContainer header = new HtmlHeaderContainer(
076: HtmlHeaderSectionHandler.HEADER_ID
077: + container.getPage().getAutoIndex());
078: container.autoAdd(header, markupStream);
079:
080: // Yes, we handled the tag
081: return true;
082: } else if ((tag instanceof WicketTag)
083: && ((WicketTag) tag).isHeadTag()) {
084: // If we found <wicket:head> without surrounding <head> on a Page,
085: // than we have to add wicket:head into a automatically generated
086: // head first.
087: if (container instanceof WebPage) {
088: // Create a special header component which will gather
089: // additional input the <head> from 'contributors'.
090: final MarkupContainer header = new HtmlHeaderContainer(
091: HtmlHeaderSectionHandler.HEADER_ID
092: + container.getPage().getAutoIndex());
093:
094: // It is <wicket:head>. Because they do not provide any
095: // additional functionality they are merely a means of surrounding relevant
096: // markup. Thus we simply create a WebMarkupContainer to handle
097: // the tag.
098: final WebMarkupContainer header2 = new WebMarkupContainer(
099: HtmlHeaderSectionHandler.HEADER_ID) {
100: private static final long serialVersionUID = 1L;
101:
102: public boolean isTransparentResolver() {
103: return true;
104: }
105: };
106:
107: header2.setRenderBodyOnly(true);
108:
109: header.add(header2);
110:
111: container.autoAdd(header, markupStream);
112: } else if (container instanceof HtmlHeaderContainer) {
113: // It is <wicket:head>. Because they do not provide any
114: // additional functionality there are merely a means of surrounding
115: // relevant markup. Thus we simply create a WebMarkupContainer to handle
116: // the tag.
117: final WebMarkupContainer header = new WebMarkupContainer(
118: HtmlHeaderSectionHandler.HEADER_ID) {
119: private static final long serialVersionUID = 1L;
120:
121: public boolean isTransparentResolver() {
122: return true;
123: }
124: };
125: header.setRenderBodyOnly(true);
126:
127: try {
128: container.autoAdd(header, markupStream);
129: } catch (IllegalArgumentException ex) {
130: throw new WicketRuntimeException(
131: "If the root exception says something like "
132: + "\"A child with id '_header' already exists\" "
133: + "then you most likely forgot to override autoAdd() "
134: + "in your bordered page component.",
135: ex);
136: }
137: } else {
138: throw new MarkupException(
139: "Mis-placed <wicket:head>. <wicket:head> must be outside of <wicket:panel> and <wicket:border>");
140: }
141:
142: // Yes, we handled the tag
143: return true;
144: }
145:
146: // We were not able to handle the tag
147: return false;
148: }
149: }
|