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.mapper; 018 019import org.apache.wicket.Application; 020import org.apache.wicket.Session; 021import org.apache.wicket.protocol.http.BufferedWebResponse; 022import org.apache.wicket.protocol.http.WebApplication; 023import org.apache.wicket.request.IRequestCycle; 024import org.apache.wicket.request.IRequestHandler; 025import org.apache.wicket.request.IRequestMapper; 026import org.apache.wicket.request.Request; 027import org.apache.wicket.request.Url; 028import org.apache.wicket.request.cycle.RequestCycle; 029import org.apache.wicket.core.request.handler.BufferedResponseRequestHandler; 030import org.apache.wicket.session.ISessionStore; 031import org.apache.wicket.util.string.Strings; 032 033/** 034 * Encoder that intercepts requests for which there is already stored buffer with rendered data. 035 * 036 * @author Matej Knopp 037 */ 038public class BufferedResponseMapper implements IRequestMapper 039{ 040 /** 041 * Construct. 042 */ 043 public BufferedResponseMapper() 044 { 045 } 046 047 /** 048 * @return the current session id for stateful pages and <code>null</code> for stateless pages 049 * and non-http threads 050 */ 051 protected String getSessionId() 052 { 053 String sessionId = null; 054 055 if (Application.exists() && RequestCycle.get() != null) 056 { 057 ISessionStore sessionStore = Application.get().getSessionStore(); 058 IRequestCycle requestCycle = RequestCycle.get(); 059 Session session = sessionStore.lookup(requestCycle.getRequest()); 060 if (session != null) 061 { 062 sessionId = session.getId(); 063 } 064 } 065 066 return sessionId; 067 } 068 069 protected boolean hasBufferedResponse(Url url) 070 { 071 String sessionId = getSessionId(); 072 boolean hasResponse = false; 073 if (Strings.isEmpty(sessionId) == false) 074 { 075 hasResponse = WebApplication.get().hasBufferedResponse(sessionId, url); 076 } 077 return hasResponse; 078 } 079 080 protected BufferedWebResponse getAndRemoveBufferedResponse(Url url) 081 { 082 String sessionId = getSessionId(); 083 BufferedWebResponse response = null; 084 if (Strings.isEmpty(sessionId) == false) 085 { 086 response = WebApplication.get().getAndRemoveBufferedResponse(sessionId, url); 087 } 088 return response; 089 } 090 091 private Request getRequest(Request original) 092 { 093 // The buffers are stored under "real" URL which can be different 094 // than the URL handlers get due to global URL pre/postprocessing 095 // (i.e. prepending URL with language segment). 096 // Because of that we need find out the real URL from request cycle 097 098 if (RequestCycle.get() != null) 099 { 100 return RequestCycle.get().getRequest(); 101 } 102 else 103 { 104 return original; 105 } 106 } 107 108 /** 109 * @see org.apache.wicket.request.IRequestMapper#mapRequest(org.apache.wicket.request.Request) 110 */ 111 @Override 112 public IRequestHandler mapRequest(Request request) 113 { 114 request = getRequest(request); 115 116 BufferedWebResponse response = getAndRemoveBufferedResponse(request.getUrl()); 117 if (response != null) 118 { 119 return new BufferedResponseRequestHandler(response); 120 } 121 else 122 { 123 return null; 124 } 125 } 126 127 /** 128 * @see org.apache.wicket.request.IRequestMapper#mapHandler(org.apache.wicket.request.IRequestHandler) 129 */ 130 @Override 131 public Url mapHandler(IRequestHandler requestHandler) 132 { 133 return null; 134 } 135 136 /** 137 * @see org.apache.wicket.request.IRequestMapper#getCompatibilityScore(org.apache.wicket.request.Request) 138 */ 139 @Override 140 public int getCompatibilityScore(Request request) 141 { 142 request = getRequest(request); 143 144 if (hasBufferedResponse(request.getUrl())) 145 { 146 return Integer.MAX_VALUE; 147 } 148 else 149 { 150 return 0; 151 } 152 } 153}