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}