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; 018 019import java.io.Serializable; 020import java.util.ArrayList; 021import java.util.HashMap; 022import java.util.Iterator; 023import java.util.List; 024import java.util.Map; 025 026import org.apache.wicket.request.IRequestHandler; 027import org.apache.wicket.request.IRequestMapper; 028import org.apache.wicket.request.IWritableRequestParameters; 029import org.apache.wicket.request.Request; 030import org.apache.wicket.request.Url; 031import org.apache.wicket.request.Url.QueryParameter; 032import org.apache.wicket.request.cycle.RequestCycle; 033import org.apache.wicket.request.flow.ResetResponseException; 034import org.apache.wicket.core.request.handler.PageProvider; 035import org.apache.wicket.core.request.handler.RenderPageRequestHandler; 036import org.apache.wicket.core.request.handler.RenderPageRequestHandler.RedirectPolicy; 037import org.apache.wicket.request.http.WebRequest; 038import org.apache.wicket.request.mapper.parameter.PageParameters; 039import org.apache.wicket.util.string.StringValue; 040 041/** 042 * Causes Wicket to interrupt current request processing and immediately redirect to an intercept 043 * page. 044 */ 045public class RestartResponseAtInterceptPageException extends ResetResponseException 046{ 047 private static final long serialVersionUID = 1L; 048 049 /** 050 * Redirects to the specified {@code interceptPage}. 051 * 052 * @param interceptPage 053 */ 054 public RestartResponseAtInterceptPageException(Page interceptPage) 055 { 056 super(new RenderPageRequestHandler(new PageProvider(interceptPage), 057 RedirectPolicy.AUTO_REDIRECT)); 058 InterceptData.set(); 059 } 060 061 /** 062 * Redirects to the specified intercept page, this will result in a bookmarkable redirect. 063 * 064 * @param interceptPageClass 065 */ 066 public RestartResponseAtInterceptPageException(Class<? extends Page> interceptPageClass) 067 { 068 this(interceptPageClass, null); 069 } 070 071 /** 072 * Redirects to the specified intercept page, this will result in a bookmarkable redirect. 073 * 074 * @param interceptPageClass 075 * @param parameters 076 */ 077 public RestartResponseAtInterceptPageException(Class<? extends Page> interceptPageClass, 078 PageParameters parameters) 079 { 080 super(new RenderPageRequestHandler(new PageProvider(interceptPageClass, parameters), 081 RedirectPolicy.ALWAYS_REDIRECT)); 082 InterceptData.set(); 083 } 084 085 /** 086 * @return the url of the request when the interception happened or {@code null} 087 * or {@code null} if there was no interception yet 088 */ 089 public static Url getOriginalUrl() 090 { 091 Url originalUrl = null; 092 InterceptData data = InterceptData.get(); 093 if (data != null) 094 { 095 originalUrl = data.getOriginalUrl(); 096 } 097 return originalUrl; 098 } 099 100 /** 101 * @return the post parameters of thе request when the interception happened 102 * or {@code null} if there was no interception yet 103 */ 104 public static Map<String, List<StringValue>> getOriginalPostParameters() 105 { 106 Map<String, List<StringValue>> postParameters = null; 107 InterceptData data = InterceptData.get(); 108 if (data != null) 109 { 110 postParameters = data.getPostParameters(); 111 } 112 return postParameters; 113 } 114 115 /** 116 * INTERNAL CLASS, DO NOT USE 117 * 118 * @author igor.vaynberg 119 */ 120 static class InterceptData implements Serializable 121 { 122 private static final long serialVersionUID = 1L; 123 124 private Url originalUrl; 125 private Map<String, List<StringValue>> postParameters; 126 127 public Url getOriginalUrl() 128 { 129 return originalUrl; 130 } 131 132 public Map<String, List<StringValue>> getPostParameters() 133 { 134 return postParameters; 135 } 136 137 public static void set() 138 { 139 Session session = Session.get(); 140 session.bind(); 141 InterceptData data = new InterceptData(); 142 Request request = RequestCycle.get().getRequest(); 143 data.originalUrl = request.getOriginalUrl(); 144 Iterator<QueryParameter> itor = data.originalUrl.getQueryParameters().iterator(); 145 while (itor.hasNext()) 146 { 147 QueryParameter parameter = itor.next(); 148 String parameterName = parameter.getName(); 149 if (WebRequest.PARAM_AJAX.equals(parameterName) || 150 WebRequest.PARAM_AJAX_BASE_URL.equals(parameterName) || 151 WebRequest.PARAM_AJAX_REQUEST_ANTI_CACHE.equals(parameterName)) 152 { 153 itor.remove(); 154 } 155 } 156 157 data.postParameters = new HashMap<>(); 158 for (String s : request.getPostParameters().getParameterNames()) 159 { 160 if (WebRequest.PARAM_AJAX.equals(s) || WebRequest.PARAM_AJAX_BASE_URL.equals(s) || 161 WebRequest.PARAM_AJAX_REQUEST_ANTI_CACHE.equals(s)) 162 { 163 continue; 164 } 165 data.postParameters.put(s, new ArrayList<>(request.getPostParameters() 166 .getParameterValues(s))); 167 } 168 session.setMetaData(key, data); 169 } 170 171 public static InterceptData get() 172 { 173 if (Session.exists()) 174 { 175 return Session.get().getMetaData(key); 176 } 177 return null; 178 } 179 180 public static void clear() 181 { 182 if (Session.exists()) 183 { 184 Session.get().setMetaData(key, null); 185 } 186 } 187 188 private static final MetaDataKey<InterceptData> key = new MetaDataKey<>() 189 { 190 private static final long serialVersionUID = 1L; 191 }; 192 } 193 194 static void continueToOriginalDestination() 195 { 196 InterceptData data = InterceptData.get(); 197 if (data != null) 198 { 199 String url = RequestCycle.get().getUrlRenderer().renderUrl(data.originalUrl); 200 throw new NonResettingRestartException(url); 201 } 202 } 203 204 static void clearOriginalDestination() 205 { 206 InterceptData.clear(); 207 } 208 209 static IRequestMapper MAPPER = new IRequestMapper() 210 { 211 @Override 212 public int getCompatibilityScore(Request request) 213 { 214 return matchedData(request) != null ? Integer.MAX_VALUE : 0; 215 } 216 217 @Override 218 public Url mapHandler(IRequestHandler requestHandler) 219 { 220 return null; 221 } 222 223 @Override 224 public IRequestHandler mapRequest(Request request) 225 { 226 InterceptData data = matchedData(request); 227 if (data != null) 228 { 229 if (data.postParameters.isEmpty() == false && 230 request.getPostParameters() instanceof IWritableRequestParameters) 231 { 232 IWritableRequestParameters parameters = (IWritableRequestParameters)request.getPostParameters(); 233 parameters.reset(); 234 for (String s : data.postParameters.keySet()) 235 { 236 parameters.setParameterValues(s, data.postParameters.get(s)); 237 } 238 } 239 InterceptData.clear(); 240 } 241 return null; 242 } 243 244 private InterceptData matchedData(Request request) 245 { 246 InterceptData data = InterceptData.get(); 247 if (data != null && data.originalUrl.equals(request.getOriginalUrl())) 248 { 249 return data; 250 } 251 return null; 252 } 253 }; 254}