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 java.util.List; 020import org.apache.wicket.core.request.handler.ListenerRequestHandler; 021import org.apache.wicket.core.request.handler.PageAndComponentProvider; 022import org.apache.wicket.core.request.handler.PageProvider; 023import org.apache.wicket.core.request.handler.RenderPageRequestHandler; 024import org.apache.wicket.request.IRequestHandler; 025import org.apache.wicket.request.Request; 026import org.apache.wicket.request.Url; 027import org.apache.wicket.request.component.IRequestablePage; 028import org.apache.wicket.request.mapper.info.ComponentInfo; 029import org.apache.wicket.request.mapper.info.PageComponentInfo; 030import org.apache.wicket.request.mapper.info.PageInfo; 031 032/** 033 * Decodes and encodes the following URLs: 034 * 035 * <pre> 036 * Page Instance - Render (RenderPageRequestHandler) 037 * /wicket/page?2 038 * 039 * 040 * Page Instance - Listener (ListenerRequestHandler) 041 * /wicket/page?2-click-foo-bar-baz 042 * /wicket/page?2-click.1-foo-bar-baz (1 is behavior index) 043 * </pre> 044 * 045 * @author Matej Knopp 046 */ 047public class PageInstanceMapper extends AbstractComponentMapper 048{ 049 /** 050 * Construct. 051 */ 052 public PageInstanceMapper() 053 { 054 } 055 056 /** 057 * @see org.apache.wicket.request.IRequestMapper#mapRequest(org.apache.wicket.request.Request) 058 */ 059 @Override 060 public IRequestHandler mapRequest(Request request) 061 { 062 if (matches(request)) 063 { 064 Url url = request.getUrl(); 065 PageComponentInfo info = getPageComponentInfo(url); 066 if (info != null && info.getPageInfo().getPageId() != null) 067 { 068 Integer renderCount = info.getComponentInfo() != null ? info.getComponentInfo() 069 .getRenderCount() : null; 070 071 if (info.getComponentInfo() == null) 072 { 073 PageProvider provider = new PageProvider(info.getPageInfo().getPageId(), 074 renderCount); 075 provider.setPageSource(getContext()); 076 // render page 077 return new RenderPageRequestHandler(provider); 078 } 079 else 080 { 081 ComponentInfo componentInfo = info.getComponentInfo(); 082 083 PageAndComponentProvider provider = new PageAndComponentProvider( 084 info.getPageInfo().getPageId(), renderCount, 085 componentInfo.getComponentPath()); 086 087 provider.setPageSource(getContext()); 088 089 return new ListenerRequestHandler(provider, componentInfo.getBehaviorId()); 090 } 091 } 092 } 093 return null; 094 } 095 096 /** 097 * @see org.apache.wicket.request.IRequestMapper#mapHandler(org.apache.wicket.request.IRequestHandler) 098 */ 099 @Override 100 public Url mapHandler(IRequestHandler requestHandler) 101 { 102 PageComponentInfo info = null; 103 104 if (requestHandler instanceof RenderPageRequestHandler) 105 { 106 IRequestablePage page = ((RenderPageRequestHandler)requestHandler).getPage(); 107 108 PageInfo i = new PageInfo(page.getPageId()); 109 info = new PageComponentInfo(i, null); 110 } 111 else if (requestHandler instanceof ListenerRequestHandler) 112 { 113 ListenerRequestHandler handler = (ListenerRequestHandler)requestHandler; 114 IRequestablePage page = handler.getPage(); 115 String componentPath = handler.getComponentPath(); 116 117 Integer renderCount = null; 118 if (handler.includeRenderCount()) 119 { 120 renderCount = page.getRenderCount(); 121 } 122 123 PageInfo pageInfo = new PageInfo(page.getPageId()); 124 ComponentInfo componentInfo = new ComponentInfo(renderCount, componentPath, handler.getBehaviorIndex()); 125 info = new PageComponentInfo(pageInfo, componentInfo); 126 } 127 128 if (info != null) 129 { 130 Url url = new Url(); 131 url.getSegments().add(getContext().getNamespace()); 132 url.getSegments().add(getContext().getPageIdentifier()); 133 encodePageComponentInfo(url, info); 134 return url; 135 } 136 else 137 { 138 return null; 139 } 140 } 141 142 /** 143 * @see org.apache.wicket.request.IRequestMapper#getCompatibilityScore(org.apache.wicket.request.Request) 144 */ 145 @Override 146 public int getCompatibilityScore(final Request request) 147 { 148 int score = 0; 149 if (matches(request)) 150 { 151 score = Integer.MAX_VALUE; 152 } 153 return score; 154 } 155 156 /** 157 * Matches when the request url starts with 158 * {@link org.apache.wicket.core.request.mapper.IMapperContext#getNamespace()}/{@link org.apache.wicket.core.request.mapper.IMapperContext#getPageIdentifier()} 159 * or when the base url starts with 160 * {@link org.apache.wicket.core.request.mapper.IMapperContext#getNamespace()}/{@link org.apache.wicket.core.request.mapper.IMapperContext#getPageIdentifier()} 161 * and the request url with {@link org.apache.wicket.core.request.mapper.IMapperContext#getPageIdentifier()} 162 163 * @param request 164 * the request to check 165 * @return {@code true} if the conditions match 166 */ 167 private boolean matches(final Request request) 168 { 169 boolean matches = false; 170 Url url = request.getUrl(); 171 Url baseUrl = request.getClientUrl(); 172 String namespace = getContext().getNamespace(); 173 String pageIdentifier = getContext().getPageIdentifier(); 174 List<String> segments = url.getSegments(); 175 176 if (isNotPageInstanceUrl(segments, pageIdentifier)) 177 { 178 return false; 179 } 180 181 if (urlStartsWith(url, namespace, pageIdentifier)) 182 { 183 matches = true; 184 } 185 else if (urlStartsWith(baseUrl, namespace, pageIdentifier) && urlStartsWith(url, pageIdentifier)) 186 { 187 matches = true; 188 } 189 else if (urlStartsWith(baseUrl, pageIdentifier) && urlStartsWith(url, pageIdentifier)) 190 { 191 matches = true; 192 } 193 194 return matches; 195 } 196 197 198 private boolean isNotPageInstanceUrl(List<String> segments, String pageIdentifier) 199 { 200 if (segments.size() > 2 ) 201 { 202 return true; 203 } 204 205 int pageIdIndex = segments.indexOf(pageIdentifier); 206 207 //check if we have segments after pageIdentifier 208 return pageIdIndex < 0 || segments.size() - 1 > pageIdIndex; 209 } 210}