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.core.request.handler; 018 019import org.apache.wicket.Page; 020import org.apache.wicket.feedback.FeedbackDelay; 021import org.apache.wicket.request.component.IRequestableComponent; 022import org.apache.wicket.request.component.IRequestablePage; 023import org.apache.wicket.request.mapper.parameter.PageParameters; 024import org.apache.wicket.util.lang.Args; 025 026/** 027 * Extension of {@link PageProvider} that is also capable of providing a Component belonging to the 028 * page. 029 * 030 * @see PageProvider 031 * 032 * @author Matej Knopp 033 */ 034public class PageAndComponentProvider extends PageProvider implements IPageAndComponentProvider 035{ 036 private IRequestableComponent component; 037 038 private String componentPath; 039 040 /** 041 * @see PageProvider#PageProvider(IRequestablePage) 042 * 043 * @param page 044 * @param componentPath 045 */ 046 public PageAndComponentProvider(IRequestablePage page, String componentPath) 047 { 048 super(page); 049 setComponentPath(componentPath); 050 } 051 052 /** 053 * @see PageProvider#PageProvider(IRequestablePage) 054 * 055 * @param page 056 * @param component 057 */ 058 public PageAndComponentProvider(IRequestablePage page, IRequestableComponent component) 059 { 060 super(page); 061 062 Args.notNull(component, "component"); 063 064 this.component = component; 065 } 066 067 /** 068 * @see PageProvider#PageProvider(Class, PageParameters) 069 * 070 * @param pageClass 071 * @param pageParameters 072 * @param componentPath 073 */ 074 public PageAndComponentProvider(Class<? extends IRequestablePage> pageClass, 075 PageParameters pageParameters, String componentPath) 076 { 077 super(pageClass, pageParameters); 078 setComponentPath(componentPath); 079 } 080 081 /** 082 * @see PageProvider#PageProvider(Class) 083 * 084 * @param pageClass 085 * @param componentPath 086 */ 087 public PageAndComponentProvider(Class<? extends IRequestablePage> pageClass, 088 String componentPath) 089 { 090 super(pageClass); 091 setComponentPath(componentPath); 092 } 093 094 /** 095 * @see PageProvider#PageProvider(Integer, Class, Integer) 096 * 097 * @param pageId 098 * @param pageClass 099 * @param renderCount 100 * @param componentPath 101 */ 102 public PageAndComponentProvider(int pageId, Class<? extends IRequestablePage> pageClass, 103 Integer renderCount, String componentPath) 104 { 105 super(pageId, pageClass, renderCount); 106 setComponentPath(componentPath); 107 } 108 109 /** 110 * @see PageProvider#PageProvider(Integer, Class, Integer) 111 * 112 * @param pageId 113 * @param pageClass 114 * @param pageParameters 115 * @param renderCount 116 * @param componentPath 117 */ 118 public PageAndComponentProvider(Integer pageId, Class<? extends IRequestablePage> pageClass, 119 PageParameters pageParameters, Integer renderCount, String componentPath) 120 { 121 super(pageId, pageClass, pageParameters, renderCount); 122 setComponentPath(componentPath); 123 } 124 125 /** 126 * @see PageProvider#PageProvider(Integer, Integer) 127 * 128 * @param pageId 129 * @param renderCount 130 * @param componentPath 131 */ 132 public PageAndComponentProvider(int pageId, Integer renderCount, String componentPath) 133 { 134 super(pageId, renderCount); 135 setComponentPath(componentPath); 136 } 137 138 public PageAndComponentProvider(IRequestablePage page, IRequestableComponent component, 139 PageParameters parameters) 140 { 141 super(page); 142 143 Args.notNull(component, "component"); 144 145 this.component = component; 146 if (parameters != null) 147 { 148 setPageParameters(parameters); 149 } 150 } 151 152 @Override 153 public IRequestableComponent getComponent() 154 { 155 if (component == null) 156 { 157 IRequestablePage page = getPageInstance(); 158 component = page != null ? page.get(componentPath) : null; 159 if (component == null) 160 { 161 162 /* 163 * on stateless pages it is possible that the component may not yet exist because it 164 * couldve been created in one of the lifecycle callbacks of this page. Lets invoke 165 * the callbacks to give the page a chance to create the missing component. 166 */ 167 168 // make sure this page instance was just created so the page can be stateless 169 if (page.isPageStateless()) 170 { 171 Page p = (Page)page; 172 p.internalInitialize(); 173 174 // preparation of feedbacks is delayed into the render phase 175 try (FeedbackDelay delay = new FeedbackDelay(p.getRequestCycle())) { 176 p.beforeRender(); 177 p.markRendering(false); 178 179 // note: no invocation of delay.onBeforeRender() 180 } 181 component = page.get(componentPath); 182 } 183 } 184 } 185 if (component == null) 186 { 187 throw new ComponentNotFoundException("Could not find component '" + componentPath + 188 "' on page '" + getPageClass()); 189 } 190 return component; 191 } 192 193 /** 194 * @see org.apache.wicket.core.request.handler.IPageAndComponentProvider#getComponentPath() 195 */ 196 @Override 197 public String getComponentPath() 198 { 199 if (componentPath != null) 200 { 201 return componentPath; 202 } 203 else 204 { 205 return component.getPageRelativePath(); 206 } 207 } 208 209 /** 210 * 211 * @param componentPath 212 */ 213 private void setComponentPath(String componentPath) 214 { 215 Args.notNull(componentPath, "componentPath"); 216 217 this.componentPath = componentPath; 218 } 219}