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 */ 017package org.apache.wicket.markup.html.panel; 018 019import org.apache.wicket.Component; 020import org.apache.wicket.DequeueContext; 021import org.apache.wicket.IQueueRegion; 022import org.apache.wicket.MarkupContainer; 023import org.apache.wicket.markup.IMarkupFragment; 024import org.apache.wicket.markup.html.WebMarkupContainer; 025import org.apache.wicket.model.IModel; 026import org.apache.wicket.util.lang.Args; 027 028/** 029 * Usually you either have a markup file or a xml tag with wicket:id="myComponent" to associate 030 * markup with a component. However in some use cases, especially when working with small panels it 031 * is a bit awkward to maintain tiny pieces of markup in plenty of panel markup files. Use cases are 032 * for example list views where list items are different depending on a state. 033 * <p> 034 * Fragments provide a means to maintain the panels tiny piece of markup. Since it can be anywhere, 035 * the component whose markup contains the fragment's markup must be provided (markup provider). 036 * <p> 037 * 038 * <pre> 039 * <span wicket:id="myPanel">Example input (will be removed)</span> 040 * 041 * <wicket:fragment wicket:id="frag1">panel 1</wicket:fragment> 042 * <wicket:fragment wicket:id="frag2">panel 2</wicket:fragment> 043 * </pre> 044 * 045 * <pre> 046 * add(new Fragment("myPanel1", "frag1", myPage); 047 * </pre> 048 * 049 * @author Juergen Donnerstag 050 */ 051public class Fragment extends WebMarkupContainer implements IQueueRegion 052{ 053 private static final long serialVersionUID = 1L; 054 055 /** The wicket:id of the associated markup fragment */ 056 private final String associatedMarkupId; 057 058 private final MarkupContainer markupProvider; 059 060 /** 061 * Constructor. 062 * 063 * @see org.apache.wicket.Component#Component(String) 064 * 065 * @param id 066 * The component id 067 * @param markupId 068 * The associated id of the associated markup fragment 069 * @param markupProvider 070 * The component whose markup contains the fragment's markup 071 */ 072 public Fragment(final String id, final String markupId, final MarkupContainer markupProvider) 073 { 074 this(id, markupId, markupProvider, null); 075 } 076 077 /** 078 * Constructor. 079 * 080 * @see org.apache.wicket.Component#Component(String) 081 * 082 * @param id 083 * The component id 084 * @param markupId 085 * The associated id of the associated markup fragment 086 * @param markupProvider 087 * The component whose markup contains the fragment's markup 088 * @param model 089 * The model for this fragment 090 */ 091 public Fragment(final String id, final String markupId, final MarkupContainer markupProvider, 092 final IModel<?> model) 093 { 094 super(id, model); 095 096 associatedMarkupId = Args.notNull(markupId, "markupId"); 097 this.markupProvider = markupProvider; 098 } 099 100 /** 101 * {@inheritDoc} 102 */ 103 @Override 104 protected IMarkupSourcingStrategy newMarkupSourcingStrategy() 105 { 106 return new FragmentMarkupSourcingStrategy(associatedMarkupId, markupProvider) 107 { 108 @Override 109 public IMarkupFragment chooseMarkup(Component component) 110 { 111 return Fragment.this.chooseMarkup(getMarkupProvider(component)); 112 } 113 }; 114 } 115 116 /** 117 * Get the markup stream which shall be used to search for the fragment 118 * 119 * @param provider 120 * @return The markup stream to be used to find the fragment markup 121 */ 122 protected IMarkupFragment chooseMarkup(final MarkupContainer provider) 123 { 124 return provider.getMarkup(null); 125 } 126 127 /** 128 * @return the markup id associated to this Fragment 129 */ 130 public final String getAssociatedMarkupId() 131 { 132 return associatedMarkupId; 133 } 134 135 136 @Override 137 public DequeueContext newDequeueContext() 138 { 139 IMarkupFragment markup = getMarkupSourcingStrategy().getMarkup(this, null); 140 if (markup == null) 141 { 142 return null; 143 } 144 145 return new DequeueContext(markup, this, true); 146 } 147}