📄 fragment.java
字号:
/* * 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.MarkupContainer;import org.apache.wicket.markup.ComponentTag;import org.apache.wicket.markup.MarkupException;import org.apache.wicket.markup.MarkupNotFoundException;import org.apache.wicket.markup.MarkupStream;import org.apache.wicket.markup.html.WebMarkupContainerWithAssociatedMarkup;import org.apache.wicket.markup.parser.XmlTag;import org.apache.wicket.model.IModel;import org.apache.wicket.util.lang.Objects;import org.apache.wicket.version.undo.Change;/** * Usually you either have a markup file or a xml tag with wicket:id="myComponent" to associate * markup with a component. However in some rare cases, especially when working with small panels it * is a bit awkward to maintain tiny pieces of markup in plenty of panel markup files. Use cases are * for example list views where list items are different depending on a state. * <p> * Fragments provide a means to maintain the panels tiny piece of markup. Since it can be anywhere, * the component whose markup contains the fragment's markup must be provided (markup provider). * <p> * * <pre> * <span wicket:id="myPanel">Example input (will be removed)</span> * * <wicket:fragment wicket:id="frag1">panel 1</wicket:fragment> * <wicket:fragment wicket:id="frag2">panel 2</wicket:fragment> * </pre> * <pre> * add(new Fragment("myPanel1", "frag1", myPage); * </pre> * * @author Juergen Donnerstag */public class Fragment extends WebMarkupContainerWithAssociatedMarkup{ private static final long serialVersionUID = 1L; /** The wicket:id of the associated markup fragment */ private String markupId; /** The container providing the inline markup */ private final MarkupContainer markupProvider; /** * Constructor. * * @see org.apache.wicket.Component#Component(String) * * @param id * The component id * @param markupId * The associated id of the associated markup fragment * * @deprecated use {@link #Fragment(String, String, MarkupContainer)} */ public Fragment(final String id, final String markupId) { this(id, markupId, null, null); } /** * Constructor. * * @see org.apache.wicket.Component#Component(String) * * @param id * The component id * @param markupId * The associated id of the associated markup fragment * @param model * The model for this fragment * * @deprecated use {@link #Fragment(String, String, MarkupContainer, IModel)} */ public Fragment(final String id, final String markupId, final IModel model) { this(id, markupId, null, model); } /** * Constructor. * * @see org.apache.wicket.Component#Component(String) * * @param id * The component id * @param markupId * The associated id of the associated markup fragment * @param markupProvider * The component whose markup contains the fragment's markup */ public Fragment(final String id, final String markupId, final MarkupContainer markupProvider) { this(id, markupId, markupProvider, null); } /** * Constructor. * * @see org.apache.wicket.Component#Component(String) * * @param id * The component id * @param markupId * The associated id of the associated markup fragment * @param markupProvider * The component whose markup contains the fragment's markup * @param model * The model for this fragment */ public Fragment(final String id, final String markupId, final MarkupContainer markupProvider, final IModel model) { 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(new Change() { private static final long serialVersionUID = 1L; private final String oldMarkupId = Fragment.this.markupId; public void undo() { Fragment.this.markupId = oldMarkupId; } }); } this.markupId = markupId; } /** * Make sure we open up open-close tags to open-body-close * * @see org.apache.wicket.Component#onComponentTag(org.apache.wicket.markup.ComponentTag) */ protected void onComponentTag(final ComponentTag tag) { if (tag.isOpenClose()) { tag.setType(XmlTag.OPEN); } super.onComponentTag(tag); } /** * * @see org.apache.wicket.Component#onComponentTagBody(org.apache.wicket.markup.MarkupStream, * org.apache.wicket.markup.ComponentTag) */ protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) { // Skip the components body. It will be replaced by the fragment if (((ComponentTag)markupStream.get(markupStream.getCurrentIndex() - 1)).isOpen()) { markupStream.skipRawMarkup(); } final MarkupStream providerMarkupStream = chooseMarkupStream(markupStream); if (providerMarkupStream == null) { throw new MarkupNotFoundException( "Fragment: No markup stream found for providing markup container " + markupProvider.toString() + ". Fragment: " + toString()); } renderFragment(providerMarkupStream, openTag); } /** * Get the markup stream which shall be used to search for the fragment * * @param markupStream * The markup stream is associated with the component (not the fragment) * @return The markup stream to be used to find the fragment markup */ protected MarkupStream chooseMarkupStream(final MarkupStream markupStream) { MarkupStream stream = null; // TODO Post 1.3: Cleanup this after deprecated constructors are removed if (markupProvider == null) { stream = markupStream; } else { stream = markupProvider.getAssociatedMarkupStream(false); if (stream == null) { // The following statement assumes that the markup provider is a // parent along the line up to the Page stream = markupProvider.getMarkupStream(); } } return stream; } /** * Render the markup starting at the current position of the markup strean * * @see #onComponentTagBody(MarkupStream, ComponentTag) * * @param providerMarkupStream * @param openTag */ private void renderFragment(final MarkupStream providerMarkupStream, final ComponentTag openTag) { // remember the current position in the markup. Will have to come back // to it. int currentIndex = providerMarkupStream.getCurrentIndex(); // Find the markup fragment int index = providerMarkupStream.findComponentIndex(null, markupId); if (index == -1) { throw new MarkupException("Markup of component class `" + providerMarkupStream.getContainerClass().getName() + "` does not contain a fragment with wicket:id `" + markupId + "`. Context: " + toString()); } // Set the markup stream position to where the fragment begins providerMarkupStream.setCurrentIndex(index); try { // Get the fragments open tag ComponentTag fragmentOpenTag = providerMarkupStream.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 providerMarkupStream.next(); // Render the body of the fragment super.onComponentTagBody(providerMarkupStream, fragmentOpenTag); } } finally { // Make sure the markup stream is positioned where we started back // at the original component providerMarkupStream.setCurrentIndex(currentIndex); } } /** * Position the markup stream at the child component relative to the <b>provider</b> markup * * @param path * @return The markup stream for the given component. */ public MarkupStream findComponentIndex(final String path) { MarkupStream markupStream = getAssociatedMarkupStream(true); int index = markupStream.findComponentIndex(markupId, path); if (index == -1) { throw new MarkupException("Markup of component class `" + markupStream.getContainerClass().getName() + "` does not contain a fragment with wicket:id `" + markupId + "`. Context: " + toString()); } markupStream.setCurrentIndex(index); return markupStream; } /** * @see org.apache.wicket.MarkupContainer#hasAssociatedMarkup() */ public boolean hasAssociatedMarkup() { return true; } /** * @see org.apache.wicket.MarkupContainer#getAssociatedMarkupStream(boolean) */ public MarkupStream getAssociatedMarkupStream(boolean throwException) { MarkupStream stream = null; // TODO Post 1.3: Cleanup this after deprecated constructors are removed if (markupProvider != null) { stream = markupProvider.getAssociatedMarkupStream(false); if (stream == null) { // The following statement assumes that the markup provider is a // parent along the line up to the Page stream = markupProvider.getMarkupStream(); } } // try self's markup stream if (stream == null) { stream = super.getAssociatedMarkupStream(false); } // if self doesn't have markup stream try the parent's if ((stream == null) && (getParent() != null)) { stream = getParent().getAssociatedMarkupStream(false); } // if we cant find any markup stream if ((stream == null) && throwException) { // fail, but fail with an error message that will point to this // component super.getAssociatedMarkupStream(true); } return stream; } /** * Returns markup provider associated with this fragment * * @return markup provider */ public final MarkupContainer getMarkupProvider() { return markupProvider; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -