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.request.component; 018 019import org.apache.wicket.Component; 020import org.apache.wicket.WicketRuntimeException; 021import org.apache.wicket.behavior.Behavior; 022import org.apache.wicket.behavior.InvalidBehaviorIdException; 023import org.apache.wicket.model.IDetachable; 024 025/** 026 * Base interface for components. The purpose of this interface is to make certain parts of Wicket 027 * easier to mock and unit test. 028 * 029 * @author Matej Knopp 030 */ 031public interface IRequestableComponent 032{ 033 /** 034 * Gets this component's path. 035 * 036 * @return Colon separated path to this component in the component hierarchy 037 */ 038 String getPageRelativePath(); 039 040 /** 041 * Gets the id of this component. 042 * 043 * @return The id of this component 044 */ 045 String getId(); 046 047 /** 048 * Returns page this component belongs to. 049 * 050 * @return The page holding this component 051 * @throws WicketRuntimeException 052 * Thrown if component is not yet attached to a Page. 053 */ 054 IRequestablePage getPage() throws WicketRuntimeException; 055 056 /** 057 * Gets the component at the given path. 058 * 059 * @param path 060 * Path to component 061 * @return The component at the path 062 */ 063 IRequestableComponent get(String path); 064 065 /** 066 * Gets a stable id for the specified non-temporary behavior. The id remains stable from the 067 * point this method is first called for the behavior until the behavior has been removed from 068 * the component. This includes from one request to the next, when the component itself is 069 * retained for the next request (i.e. is stateful). Note that the bookkeeping required for 070 * these stable ids increases the memory footprint of the component. 071 * 072 * @param behavior 073 * @return a stable id for the specified behavior 074 * @throws IllegalArgumentException when the behavior is temporary 075 */ 076 int getBehaviorId(Behavior behavior); 077 078 /** 079 * Gets the behavior for the specified id 080 * 081 * @param id 082 * @return behavior or {@code null} if none 083 * @throws InvalidBehaviorIdException 084 * when behavior with this id cannot be found 085 */ 086 Behavior getBehaviorById(int id); 087 088 /** 089 * Detaches the component. 090 * <p> 091 * NOTE: this method is not inherited from {@link IDetachable} on purpose. in Wicket the 092 * assumption for a long time has been that {@link Component}s do not implement 093 * {@link IDetachable}; doing so may lead to some very nasty side-effects. Consider 094 * {@code AbstractPropertyModel#detach()} which looks like this: 095 * 096 * <pre> 097 * public void detach() 098 * { 099 * // Detach nested object if it's a detachable 100 * if (target instanceof IDetachable) 101 * { 102 * ((IDetachable) target).detach(); 103 * } 104 * } 105 * </pre> 106 * 107 * If the model was constructed thusly, which is quite common: {@code new PropertyModel(this, 108 * "person")} and {@link Component} implemented {@link IDetachable} then calling @{code 109 * model.detach()} will cause an infinite loop with the model trying to detach the component and 110 * the component trying to detach the model. 111 * 112 * </p> 113 */ 114 void detach(); 115 116 /** 117 * @return {@code true} if it is save to call an {@link org.apache.wicket.IRequestListener} on 118 * this component when the owner page is freshly created after expiration 119 */ 120 boolean canCallListenerAfterExpiry(); 121}