/* * 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.markup.ComponentTag; import org.apache.wicket.markup.MarkupException; import org.apache.wicket.markup.MarkupStream; /** * The Panel components markup sourcing strategy. * <p> * The strategy supports two modes on how to handle the body markup. A typical Panel will ignore the * body markup and replace it with the associated markup. The body markup is allowed to have raw * markup only and no Wicket components. But e.g. a Border component will associate the body markup * with a Body component which renders the markup including all any number of child Components. * * @author Juergen Donnerstag */ public class PanelMarkupSourcingStrategy extends AssociatedMarkupSourcingStrategy { // False for Panel and true for Border components. private final boolean allowWicketComponentsInBodyMarkup; /** * Constructor. * * @param wicketTagName * The tag name for <code><wicket:'name' ..></code>. Please note that any such * tag must have been registered via * <code>WicketTagIdentifier.registerWellKnownTagName("name");</code> * @param allowWicketComponentsInBodyMarkup * {@code false} for Panel and {@code true} for Border components. If Panel then the * body markup should only contain raw markup, which is ignored (removed), but no * Wicket Component. With Border components, the body markup will be associated with * the Body Component. */ public PanelMarkupSourcingStrategy(final String wicketTagName, final boolean allowWicketComponentsInBodyMarkup) { super(wicketTagName); this.allowWicketComponentsInBodyMarkup = allowWicketComponentsInBodyMarkup; } /** * Constructor. * * @param allowWicketComponentsInBodyMarkup * {@code false} for Panel and {@code true} for Border components. If Panel then the * body markup should only contain raw markup, which is ignored (removed), but no * Wicket Component. With Border components, the body markup will be associated with * the Body Component. */ public PanelMarkupSourcingStrategy(final boolean allowWicketComponentsInBodyMarkup) { this(Panel.PANEL, allowWicketComponentsInBodyMarkup); } /** * Skip the panel's body markup which is expected to contain raw markup only (no wicket * components) and which will be ignored / removed. It'll be replaced with the content of the * associated markup file. */ @Override public void onComponentTagBody(final Component component, final MarkupStream markupStream, final ComponentTag openTag) { if (allowWicketComponentsInBodyMarkup) { // Skip the body markup. Will be picked up by the Body component. markupStream.skipToMatchingCloseTag(openTag); } else { // Skip the components body. Like with Panels or Fragments, it'll be replaced with the // associated markup if (markupStream.getPreviousTag().isOpen()) { markupStream.skipRawMarkup(); if (markupStream.get().closes(openTag) == false) { StringBuilder msg = new StringBuilder(); msg.append("Close tag not found for tag: ") .append(openTag.toString()) .append(". For ") .append(component.getClass().getSimpleName()) .append(" Components only raw markup is allow in between the tags but not ") .append("other Wicket Component. Component: ") .append(component.toString()); throw new MarkupException(markupStream, msg.toString()); } } } renderAssociatedMarkup(component); } }