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.markup.html.pages; 018 019import org.apache.wicket.markup.head.IHeaderResponse; 020import org.apache.wicket.markup.head.MetaDataHeaderItem; 021import org.apache.wicket.markup.head.OnLoadHeaderItem; 022import org.apache.wicket.markup.html.WebPage; 023import org.apache.wicket.markup.html.link.Link; 024import org.apache.wicket.model.IModel; 025import org.apache.wicket.model.LoadableDetachableModel; 026import org.apache.wicket.protocol.http.ClientProperties; 027import org.apache.wicket.protocol.http.WebSession; 028import org.apache.wicket.protocol.http.request.WebClientInfo; 029import org.apache.wicket.request.cycle.RequestCycle; 030 031/** 032 * This page uses a form post right after the page has loaded in the browser, using JavaScript or 033 * alternative means to detect and pass on settings to the embedded form. The form submit method 034 * updates this session's {@link org.apache.wicket.core.request.ClientInfo} object and then redirects to 035 * the original location as was passed in as a URL argument in the constructor. 036 * <p> 037 * If JavaScript is not enabled in the browser, a "refresh" meta-header will initiate a get on this page to 038 * continue with the original destination. As a fallback the user can click a link to do the same. 039 * <p> 040 * This page is being used by the default implementation of {@link org.apache.wicket.Session#getClientInfo()}, 041 * which in turn uses 042 * {@link org.apache.wicket.settings.RequestCycleSettings#getGatherExtendedBrowserInfo() a setting} to 043 * determine whether this page should be redirected to (it does when it is true). 044 * 045 * @author Eelco Hillenius 046 */ 047public class BrowserInfoPage extends WebPage 048{ 049 private static final long serialVersionUID = 1L; 050 051 private BrowserInfoForm browserInfoForm; 052 053 /** 054 * Bookmarkable constructor. 055 */ 056 public BrowserInfoPage() 057 { 058 initComps(); 059 } 060 061 @Override 062 public void renderHead(IHeaderResponse response) 063 { 064 super.renderHead(response); 065 066 response.render(OnLoadHeaderItem.forScript( 067 String.format("Wicket.BrowserInfo.submitForm('%s')", browserInfoForm.getFormMarkupId()))); 068 } 069 070 @Override 071 public boolean isVersioned() 072 { 073 return false; 074 } 075 076 protected WebClientInfo newWebClientInfo(RequestCycle requestCycle) 077 { 078 return new WebClientInfo(requestCycle); 079 } 080 081 /** 082 * Adds components. 083 */ 084 private void initComps() 085 { 086 IModel<WebClientInfo> info = new LoadableDetachableModel<WebClientInfo>() { 087 @Override 088 protected WebClientInfo load() 089 { 090 return newWebClientInfo(getRequestCycle()); 091 } 092 }; 093 094 IModel<ClientProperties> properties = new LoadableDetachableModel<ClientProperties>() 095 { 096 @Override 097 protected ClientProperties load() 098 { 099 return info.getObject().getProperties(); 100 } 101 }; 102 103 add(new ContinueLink("link", info)); 104 105 browserInfoForm = new BrowserInfoForm("postback", properties) 106 { 107 private static final long serialVersionUID = 1L; 108 109 @Override 110 protected void afterSubmit() 111 { 112 getModelObject().setJavaScriptEnabled(true); 113 114 WebSession.get().setClientInfo(info.getObject()); 115 116 continueToOriginalDestination(); 117 118 // switch to home page if no original destination was intercepted 119 setResponsePage(getApplication().getHomePage()); 120 } 121 }; 122 add(browserInfoForm); 123 } 124 125 protected ClientProperties newClientInfo() 126 { 127 return WebSession.get().getClientInfo().getProperties(); 128 } 129 130 private static class ContinueLink extends Link<WebClientInfo> { 131 132 public ContinueLink(String id, IModel<WebClientInfo> info) 133 { 134 super(id, info); 135 } 136 137 @Override 138 public void renderHead(IHeaderResponse response) 139 { 140 String content = "0; url=" + getURL(); 141 142 response.render(MetaDataHeaderItem.forHttpEquiv("refresh", content)); 143 } 144 145 @Override 146 public void onClick() 147 { 148 getModelObject().getProperties().setJavaScriptEnabled(false); 149 150 WebSession.get().setClientInfo(getModelObject()); 151 152 continueToOriginalDestination(); 153 154 // switch to home page if no original destination was intercepted 155 setResponsePage(getApplication().getHomePage()); 156 } 157 }; 158}