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.cycle; 018 019import org.apache.wicket.MetaDataKey; 020import org.apache.wicket.core.request.handler.IPageRequestHandler; 021import org.apache.wicket.request.IRequestHandler; 022import org.apache.wicket.request.IRequestHandlerDelegate; 023 024/** 025 * Registers and retrieves first and last executed {@link IPageRequestHandler} in a request cycle. 026 * Can be used to find out what is the requested page and what is the actual response page. 027 * <p> 028 * To use it an application needs to register it with: 029 * <pre><code> 030 * application.getRequestCycleListeners().add(new PageRequestHandlerTracker()); 031 * </code></pre> 032 * <p> 033 * The result can then be accessed at the end of each {@link RequestCycle} with: 034 * <pre><code> 035 * IPageRequestHandler first = PageRequestHandlerTracker.getFirstHandler(RequestCycle.get()); 036 * IPageRequestHandler last = PageRequestHandlerTracker.getLastHandler(RequestCycle.get()); 037 * </code></pre> 038 * 039 * @since 1.5.8 040 */ 041public class PageRequestHandlerTracker implements IRequestCycleListener 042{ 043 /** 044 * The key for the first handler 045 */ 046 public static final MetaDataKey<IPageRequestHandler> FIRST_HANDLER_KEY = new MetaDataKey<>() {}; 047 048 /** 049 * The key for the last handler 050 */ 051 public static final MetaDataKey<IPageRequestHandler> LAST_HANDLER_KEY = new MetaDataKey<>() {}; 052 053 @Override 054 public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler) 055 { 056 registerFirstHandler(cycle,handler); 057 registerLastHandler(cycle,handler); 058 } 059 060 /** 061 * Registers pagerequesthandler when it's resolved ,keeps up with the most recent handler resolved 062 * 063 * @param cycle 064 * the current request cycle 065 * @param handler 066 * the request handler to register 067 */ 068 private void registerLastHandler(RequestCycle cycle, IRequestHandler handler) 069 { 070 final IPageRequestHandler pageRequestHandler = findPageRequestHandler(handler); 071 if (pageRequestHandler != null) 072 { 073 cycle.setMetaData(LAST_HANDLER_KEY, pageRequestHandler); 074 } 075 } 076 077 /** 078 * Registers firsthandler if it's not already registered 079 * 080 * @param cycle 081 * the current request cycle 082 * @param handler 083 * the request handler to register 084 */ 085 private void registerFirstHandler(RequestCycle cycle, IRequestHandler handler) 086 { 087 if (getFirstHandler(cycle) == null) 088 { 089 final IPageRequestHandler pageRequestHandler = findPageRequestHandler(handler); 090 if (pageRequestHandler != null) 091 { 092 cycle.setMetaData(FIRST_HANDLER_KEY, pageRequestHandler); 093 } 094 } 095 } 096 097 /** 098 * Looking for IPageRequestHandler 099 * 100 * @param handler 101 * @return IPageRequestHandler if exist otherwise null 102 */ 103 private IPageRequestHandler findPageRequestHandler(IRequestHandler handler) 104 { 105 if (handler instanceof IPageRequestHandler) 106 { 107 return (IPageRequestHandler)handler; 108 } 109 if (handler instanceof IRequestHandlerDelegate) 110 { 111 return findPageRequestHandler(((IRequestHandlerDelegate)handler).getDelegateHandler()); 112 } 113 return null; 114 } 115 116 /** 117 * retrieves last handler from request cycle 118 * 119 * @param cycle 120 * @return last handler 121 */ 122 public static IPageRequestHandler getLastHandler(RequestCycle cycle) 123 { 124 return cycle.getMetaData(LAST_HANDLER_KEY); 125 } 126 127 /** 128 * retrieves first handler from the request cycle 129 * 130 * @param cycle 131 * @return first handler 132 */ 133 public static IPageRequestHandler getFirstHandler(RequestCycle cycle) 134 { 135 return cycle.getMetaData(FIRST_HANDLER_KEY); 136 } 137}