001package votorola.a.web.wic; // Copyright 2008-2009, 2012, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. 002 003import java.net.*; 004import java.util.*; 005import javax.servlet.http.*; 006import votorola.g.lang.*; 007import votorola.g.locale.*; 008import votorola.g.util.*; 009import org.apache.wicket.*; 010import org.apache.wicket.protocol.http.RequestUtils; 011import org.apache.wicket.request.Response; 012import org.apache.wicket.request.cycle.*; 013import org.apache.wicket.request.http.*; 014import org.apache.wicket.request.mapper.parameter.PageParameters; 015 016 017/** A request cycle in the Wicket web interface. 018 */ 019public final @ThreadRestricted("wicket") class VRequestCycle extends RequestCycle 020 implements BundleFormatter.GProvider 021{ 022 023 024 /** Constructs a VRequestCycle. 025 */ 026 VRequestCycle( RequestCycleContext _context ) 027 { 028 super( _context ); 029 final Locale loc = getRequest().getLocale(); 030 final ResourceBundle.Control c = new BundleControlU(); 031 bunA = new BundleFormatter( ResourceBundle.getBundle( "votorola.a.locale.A", loc, c )); 032 bunG = new BundleFormatter( ResourceBundle.getBundle( "votorola.g.locale.G", loc, c )); 033 bunW = new BundleFormatter( ResourceBundle.getBundle( "votorola.a.locale.W", loc, c )); 034 } 035 036 037 038 // ------------------------------------------------------------------------------------ 039 040 041 /** Returns the URI of the preferred context for fetching static GWT scripts. This is 042 * either the configured VOWicket.{@linkplain VOWicket#mirroredContextURI() 043 * mirroredContextURI}() or the absolute path to the context on the local container. 044 * 045 * @see #staticContextLocation() 046 */ 047 public String gwtContextLocation() 048 { 049 // return vRequest().getContextPath(); 050 ////// 051 // But if we run a cross-site linker (xs or xsiframe) then we can do this: 052 return staticContextLocation(); 053 ////// 054 // That could be a server or port other than the page origin. The browser's "same 055 // origin" security policy won't allow GWT's ordinary linker to load its scripts from 056 // there, apparently because the iframe it uses establishes a separate document with 057 // its own origin. We might get around that by setting the document's "domain" 058 // property (not sure), but that would have to be a config option under admin control 059 // in any case. 060 } 061 062 063 064 /** Returns the URI of the preferred location for fetching static files. This is 065 * either the configured VOWicket.{@linkplain VOWicket#mirroredContextURI() 066 * mirroredContextURI}() or the absolute path to the context on the local container. 067 * 068 * @see #gwtContextLocation() 069 */ 070 public String staticContextLocation() 071 { 072 final URI uri = VOWicket.get().mirroredContextURI(); 073 return uri == null? vRequest().getContextPath(): uri.toASCIIString(); 074 } 075 076 077 078 // /** Returns the page to be rendered for the current request in cases where the last 079 // * sheduled handler is of type 080 // * {@linkplain IComponentRequestHandler IComponentRequestHandler}, 081 // * {@linkplain IPageClassRequestHandler IPageClassRequestHandler}, or 082 // * {@linkplain IPageRequestHandler IPageRequestHandler}. 083 // * This method replicates the behaviour of getResponsePage() in Wicket 1.4, 084 // * which was removed in 1.5. 085 // * 086 // * @see <a href='http://ci.apache.org/projects/wicket/apidocs/1.4.x/org/apache/wicket/RequestCycle.html#getResponsePage()' 087 // * >1.4 API for RequestCycle.getResponsePage()</a> 088 // */ 089 // public final Page responsePage() { throw new UnsupportedOperationException(); } 090 // 091 // 092 // private volatile Page responsePage; 093 // 094 // { 095 // // Following advice: 096 // // https://issues.apache.org/jira/browse/WICKET-3643 097 // // https://cwiki.apache.org/WICKET/requestcycle-in-wicket-15.html 098 // getListeners().add( new AbstractRequestCycleListener() 099 // { 100 // public @Override @ThreadSafe void onRequestHandlerScheduled( 101 // final RequestCycle cycle, final IRequestHandler handler ) 102 // { 103 // assert cycle == VRequestCycle.this; 104 // NOT YET CODED 105 // } 106 // }); 107 // } 108 /// Left off coding when I realized the clients for this are dead code. Keep for reference. 109 110 111 112 /** Constructs an absolute, normalized URI for a bookmarkable page. 113 * 114 * @see #urlFor(Class,PageParameters) 115 * @see org.apache.wicket.Component#urlFor(Class,PageParameters) 116 */ 117 public URI uriFor( Class<? extends Page> pageClass ) 118 { 119 return uriFor( pageClass, /*parameters*/null ); 120 } 121 122 123 124 /** Constructs an absolute, normalized URI for a bookmarkable page with parameters. 125 * 126 * @see #urlFor(Class,PageParameters) 127 * @see org.apache.wicket.Component#urlFor(Class,PageParameters) 128 */ 129 public URI uriFor( Class<? extends Page> pageClass, PageParameters parameters ) 130 { 131 CharSequence cS = urlFor( pageClass, parameters ); // relative (1.3 and 1.5) and not bookmarkable as docs claim; while mapUrlFor is apparently relative too, though always to filter base 132 cS = RequestUtils.toAbsolutePath( // so correct it 133 ((HttpServletRequest)vRequest().getContainerRequest()).getRequestURL().toString(), 134 cS.toString() ); 135 try 136 { 137 final URI uri = new URI( cS.toString() ); 138 return uri.normalize(); // chop trailing dot segments, '././' - seen for Application.getHomePage() 139 } 140 catch( URISyntaxException x ) { throw new RuntimeException( x ); } 141 } 142 143 144 145 /** Constructs an absolute URI for the context path, without a trailing slash (/). 146 * 147 * @see HttpServletRequest#getContextPath() 148 */ 149 public URI uriForContextPath() 150 { 151 final HttpServletRequest sR = (HttpServletRequest)vRequest().getContainerRequest(); 152 final StringBuilder b = new StringBuilder(); 153 final String scheme = sR.getScheme(); 154 b.append( scheme ).append( "://" ).append( sR.getServerName() ); 155 final int port = sR.getServerPort(); 156 if( !scheme.equals("http") || port != 80 ) b.append( ':' ).append( port ); 157 b.append( sR.getContextPath() ); 158 try{ return new URI( b.toString() ); } 159 catch( URISyntaxException x ) { throw new RuntimeException( x ); } 160 } 161 162 163 164 /** @see #getRequest() 165 */ 166 public WebRequest vRequest() { return (WebRequest)getRequest(); } // vX not getX, per VSession.vApplication 167 168 169 170 /** @see #getOriginalResponse() 171 */ 172 public WebResponse vResponse() { return (WebResponse)getOriginalResponse(); } // vX not getX, per VSession.vApplication 173 174 175 176 // - B u n d l e - F o r m a t t e r . G - P r o v i d e r - ( e t c . ) -------------- 177 178 179 /** The application (A) bundle formatter. It uses bundle base name 180 * 'votorola.a.locale.A'. 181 * 182 * @see <a href='../../../../../../a/locale/A.properties'> 183 * locale/A.properties</a> 184 */ 185 public BundleFormatter bunA() { return bunA; } 186 187 188 private final BundleFormatter bunA; 189 190 191 192 public BundleFormatter bunG() { return bunG; } 193 194 195 private final BundleFormatter bunG; 196 197 198 199 /** The web (W) bundle formatter. It uses bundle base name 'votorola.a.locale.W'. 200 * 201 * @see <a href='../../../../../../a/locale/W.properties'> 202 * locale/W.properties</a> 203 */ 204 public BundleFormatter bunW() { return bunW; } 205 206 207 private final BundleFormatter bunW; 208 209 210 211 // /** Constructs a bundle formatter for the component's locale. 212 // */ 213 // public static BundleFormatter newBun( Component component ) 214 // { 215 // return new BundleFormatter( component.getLocale(), "votorola.a.locale.W" ); 216 // } 217 218 219 220 // - R e q u e s t - C y c l e -------------------------------------------------------- 221 222 223 public static VRequestCycle get() { return (VRequestCycle)RequestCycle.get(); } 224 225 226 227}