Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: nextapp/echoservlet/Initializer.java


1   /* 
2    * This file is part of the Echo Web Application Framework (hereinafter "Echo").
3    * Copyright (C) 2002-2004 NextApp, Inc.
4    *
5    * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6    *
7    * The contents of this file are subject to the Mozilla Public License Version
8    * 1.1 (the "License"); you may not use this file except in compliance with
9    * the License. You may obtain a copy of the License at
10   * http://www.mozilla.org/MPL/
11   *
12   * Software distributed under the License is distributed on an "AS IS" basis,
13   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14   * for the specific language governing rights and limitations under the
15   * License.
16   *
17   * Alternatively, the contents of this file may be used under the terms of
18   * either the GNU General Public License Version 2 or later (the "GPL"), or
19   * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20   * in which case the provisions of the GPL or the LGPL are applicable instead
21   * of those above. If you wish to allow use of your version of this file only
22   * under the terms of either the GPL or the LGPL, and not to allow others to
23   * use your version of this file under the terms of the MPL, indicate your
24   * decision by deleting the provisions above and replace them with the notice
25   * and other provisions required by the GPL or the LGPL. If you do not delete
26   * the provisions above, a recipient may use your version of this file under
27   * the terms of any one of the MPL, the GPL or the LGPL.
28   */
29  
30  package nextapp.echoservlet;
31  
32  import java.io.IOException;
33  import java.io.Serializable;
34  import java.util.Enumeration;
35  import java.util.HashMap;
36  import java.util.Map;
37  
38  import javax.servlet.http.HttpSession;
39  
40  import nextapp.echo.EchoInstance;
41  
42  import nextapp.echoservlet.html.Html;
43  import nextapp.echoservlet.resource.ResourceNames;
44  
45  /**
46   * The service is responsible for initializing applications.  This is 
47   * the first service that will be invoked when an application starts up.  It 
48   * provides a client detection page that will use JavaScript to gather 
49   * information about public properties of the client browser, storing them in
50   * a form.  The form is submitted immediately thereafter, invoking this
51   * service a second time.  The form data will be parsed by a new 
52   * <code>ClientProperties</code> object that is created
53   * from this service.  An InstancePeer and related objects are then created 
54   * for the application, stored in the user's session, and initialized.
55   * The service() method of the application's default window is then invoked,
56   * allowing the application to take control.
57   */
58  final class Initializer 
59  implements Serializable, Service {
60  
61      /** 
62       * A prefix for the session key used to temporarily store initial parameters.
63       */
64      public static final String PARAMETERS_KEY_PREFIX = "InitialParameters.";
65  
66      /** The Id of this service */
67      private static final Id ID = new Id(ClientObjects.STD_PREFIX + "start");
68  
69      /**
70       * The HTTP form parameter name used by the client detection script 
71       * to indicate client detection information has been retrieved.
72       */ 
73      public static final String PARAMETER_DETECT_COMPLETE = ClientObjects.STD_PREFIX + "detectComplete";
74  
75      /**
76       * The client detection service.  It is not necessary that this service 
77       * be registered with the EchoServer.
78       */
79      private static final Service SERVICE_CLIENT_DETECT 
80              = Template.createFromResource(ClientObjects.STD_PREFIX + "clidet", ResourceNames.CLIENT_DETECT);
81  
82      /**
83       * The client detection service.  It is not necessary that this service 
84       * be registered with the EchoServer.
85       */
86      private static final Service SERVICE_STARTUP_CONTAINER 
87              = Template.createFromResource(ClientObjects.STD_PREFIX + "startcon", ResourceNames.STARTUP_CONTAINER);
88      
89      static {
90          EchoServer.addGlobalService(SERVICE_CLIENT_DETECT);
91      }
92      
93      /**
94       * Creates one-time-use variable data used to start the application.
95       *
96       * @param conn The connection for which the variable data will be used.
97       * @return The generated <code>VariableData</code> object.
98       */
99      public static VariableData createInitialVariableData(Connection conn) {
100         VariableData initialVariableData = new VariableData();
101         EchoServer server = conn.getServer();
102         
103         initialVariableData.set(VariableData.APPLICATION_URI, conn.getApplicationUri());
104         initialVariableData.set(VariableData.STARTUP_WINDOW_TITLE,
105                 Html.encode(server.getApplicationProperties().get(ApplicationProperties.STARTUP_WINDOW_TITLE)));
106         initialVariableData.set(VariableData.STARTUP_WINDOW_TEXT,
107                 Html.encode(server.getApplicationProperties().get(ApplicationProperties.STARTUP_WINDOW_TEXT)));
108         initialVariableData.set(VariableData.STARTUP_NO_SCRIPT_ERROR_TEXT,
109                 Html.encode(server.getApplicationProperties().get(ApplicationProperties.STARTUP_NO_SCRIPT_ERROR_TEXT)));
110         initialVariableData.set(VariableData.STARTUP_DELAY,
111                 server.getApplicationProperties().get(ApplicationProperties.STARTUP_DELAY));
112         initialVariableData.set(VariableData.SPLASH_SCREEN_URI,
113                 conn.correctUri(server.getApplicationProperties().get(ApplicationProperties.SPLASH_SCREEN_URI)));
114         initialVariableData.set(VariableData.SESSION_EXPIRATION_URI, server.getSessionExpirationUri(conn.getApplicationUri()));
115         if (conn.getServer().getApplicationProperties().get(ApplicationProperties.SPLASH_SCREEN_URI) == null) {
116             initialVariableData.set(VariableData.CLIENT_DETECT_TARGET_FRAME, "_self");
117         } else {
118             initialVariableData.set(VariableData.CLIENT_DETECT_URI, ClientObjects.getServiceUri(conn, SERVICE_CLIENT_DETECT));
119             initialVariableData.set(VariableData.CLIENT_DETECT_TARGET_FRAME, "_parent");
120         }
121         
122         return initialVariableData;
123     }
124         
125     /**
126      * Creates an Initializer service.  Only initializer service is used by the
127      * entire application.
128      */
129     Initializer() {
130         super();
131     }
132     
133     /**
134      * @see nextapp.echoservlet.Service#getId()
135      */
136     public Id getId() {
137         return ID;
138     }
139     
140     /**
141      * Saves the initial servlet parameters so that they
142      * can later be available to the application
143      * instance.
144      *  
145      * @param conn The Connection with the parameters
146      * @param parameterMapSessionKey The session key in which to store the parameter map.
147      */
148     private void saveInitialParameters(Connection conn, String parameterMapSessionKey) {
149         Map parameterMap = new HashMap();
150         for (Enumeration e = conn.getParameterNames(); e.hasMoreElements();) {
151             String paramName = (String) e.nextElement();
152             parameterMap.put(paramName,conn.getRequest().getParameterValues(paramName));
153         }
154         if (parameterMap.size() > 0) {
155             // We only save the parameter map into the session if there are any extra parameters
156             // on startup.  Otherwise the session will not be created here.
157             conn.getRequest().getSession(true).setAttribute(parameterMapSessionKey,parameterMap);   
158         }
159     }
160 
161     /**
162      * @see nextapp.echoservlet.Service#service(Connection)
163      */
164     public void service(Connection conn)
165     throws IOException {
166 
167         // Our initial parameter session key
168         String parameterMapSessionKey = PARAMETERS_KEY_PREFIX + conn.getApplicationUri();
169         
170         if (conn.getParameter(PARAMETER_DETECT_COMPLETE) == null) {
171             // First request (client detection has not taken place): Do client detection.
172             if (conn.getServer().getApplicationProperties().get(ApplicationProperties.SPLASH_SCREEN_URI) == null) {
173                 // save any intial URL parameters for later
174                 saveInitialParameters(conn,parameterMapSessionKey);
175 
176                 // Display visible client detection page with "application starting" message.
177                 SERVICE_CLIENT_DETECT.service(conn);
178             } else {
179                 // Display frameset containing hidden client detection page and visible splash screen.
180                 SERVICE_STARTUP_CONTAINER.service(conn);
181             }
182         } else {
183             // Second request (client detection has taken place): Start application, display initial window content.
184             
185             // Create client properties object from connection.
186             ClientProperties clientProperties = new ClientProperties(conn);
187             
188             // Create a new instance of the application.  (The instance is not yet initialized, as its init() method has not yet 
189             // been called.)
190             EchoInstance instance = conn.getServer().newInstance();
191             
192             // Mark the EchoInstance as active for this thread, such that invoking
193             // EchoInstance.getEchoInstance() will return it.
194             instance.markActive(true);
195             
196             if (instance.getLocale() == null) {
197                 // Only set locale if application has not set it.
198                 instance.setLocale(conn.getServer().getDefaultLocale(conn.getRequest()));
199             }
200             
201             // Create an InstancePeer for the new instance.  
202             InstancePeer instancePeer = new InstancePeer(instance, conn.getApplicationUri());
203             
204             // Add the connection to the InstancePeer.
205             instancePeer.addConnection(conn);
206             
207             // Store the client properties.
208             instancePeer.setClientProperties(clientProperties);
209             
210             // Store the principal.
211             instancePeer.setUserPrincipal(conn.getRequest().getUserPrincipal());
212             
213             // Assign the connection to the InstancePeer.
214             conn.setInstancePeer(instancePeer);
215             
216             // Store initial parameters if required.
217             HttpSession session = conn.getRequest().getSession(true);
218             Map parameterMap = (Map) session.getAttribute(parameterMapSessionKey);
219             session.removeAttribute(parameterMapSessionKey);
220             if (parameterMap != null) {
221                 instance.setAttribute(InitialParameters.ATTRIBUTE_NAME, new InitialParametersImpl(parameterMap));
222             }
223             
224             // Retrieve any persistent cookies.
225             instancePeer.getCookieManager().retrieveCookies(conn.getRequest());
226             
227             // Initialize the InstancePeer.  The InstancePeer initialization code will initialize the application
228             // instance by calling EchoInstance.init(),
229             instancePeer.init();
230             
231             // Set any cookies stored in the initialization request.
232             instancePeer.getCookieManager().storeCookies(conn.getResponse());
233             
234             // Render the main window.
235             ((Service) instancePeer.getPeer(instancePeer.getDefaultWindowId())).service(conn);
236 
237             // Remove the connection from the InstancePeer.
238             instancePeer.removeConnection(conn);
239             
240             // Mark the EchoInstance as inactive for this thread, such that invoking
241             // EchoInstance.getEchoInstance() will return null
242             instance.markActive(false);
243         }
244     }
245 }