org.apache.click.extras.gae
Class GoogleAppEngineListener

java.lang.Object
  extended by org.apache.click.extras.gae.GoogleAppEngineListener
All Implemented Interfaces:
EventListener, ServletContextListener

public class GoogleAppEngineListener
extends Object
implements ServletContextListener

Provides Google App Engine (GAE) support for Click applications.

To deploy Click applications to GAE, you need to set the GoogleAppEngineListener listener in your web.xml:

 <?xml version="1.0" encoding="utf-8"?>
 <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">

     <listener>
         <listener-class>org.apache.click.extras.gae.GoogleAppEngineListener</listener-class>
     </listener>

     <servlet>
         <servlet-name>ClickServlet</servlet-name>
         <servlet-class>org.apache.click.ClickServlet</servlet-class>
         <load-on-startup>0</load-on-startup>
     </servlet>
     <servlet-mapping>
         <servlet-name>ClickServlet</servlet-name>
         <url-pattern>*.htm</url-pattern>
     </servlet-mapping>
 </web-app> 
You also need to configure GAE to exclude *.htm files from being served as static resources. Also you should enable http-session support. You set these changes in the GAE file war/WEB-INF/appengine-web.xml:
 <?xml version="1.0" encoding="utf-8"?>
 <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
     <application>myapp</application>
     <version>1</version>

       <!-- Configure java.util.logging -->
     <system-properties>
         <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
     </system-properties>

     <!-- Enable HttpSession usage -->
     <sessions-enabled>true</sessions-enabled>

     <!-- Exclude *.htm files from being served as static files by GAE,
             because the *.htm extension is mapped to ClickServlet. -->
     <static-files>
         <exclude path="**.htm" />
     </static-files>

 </appengine-web-app> 

File Uploads

GAE does not allow web application to write to files on disk. This poses a problem for the FileField control that depends on Commons FileUpload which stores uploaded files on disk. To work around this limitation Click provides the MemoryFileUploadService which stores uploaded files in memory.

Below is an example configuration of a MemoryFileUploadService:

 <click-app charset="UTF-8">
     <pages package="com.myapp.pages"/>
     <mode value="production"/>

     <file-upload-service classname="org.apache.click.extras.gae.MemoryFileUploadService">
         <!-- Set the total request maximum size to 10mb (10 x 1024 x 1024 = 10485760).
                 The default request upload size is unlimited. -->
         <property name="sizeMax" value="10485760"/>

         <!-- Set the maximum individual file size to 2mb (2 x 1024 x 1024 = 2097152).
             The default file upload size is unlimited. -->
         <property name="fileSizeMax" value="2097152"/>
    </file-upload-service>
 </click-app> 

Performance Filter

If you use Click's PerformanceFilter you should also exclude the following static files from GAE, so that PerformanceFilter can set their expiry headers: *.css, *.js, *.png and *.gif. For example:
 <?xml version="1.0" encoding="utf-8"?>
 <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">

     ...

     <!-- Exclude the following files from being served as static files by GAE,
             as they will be processed by Click's PerformanceFilter. -->
     <static-files>
         <exclude path="**.htm" />
         <exclude path="**.css" />
         <exclude path="**.js" />
         <exclude path="**.png" />
         <exclude path="**.gif" />
     </static-files>

 </appengine-web-app> 

Deployment issues

On application startup, Click automatically deploys all its JavaScript, CSS and image resources to the "/click" folder in the root directory of the webapp. Since GAE doesn't allow writing to disk, Click cannot automatically deploy its resources.

Please see the user-guide section, Deploying resources in a restricted environment, for various solutions.


Constructor Summary
GoogleAppEngineListener()
          Creates a default GoogleAppEngineListener.
 
Method Summary
 void contextDestroyed(ServletContextEvent servletContextEvent)
          This method does nothing.
 void contextInitialized(ServletContextEvent servletContextEvent)
          Sets the Ognl Runtime SecurityManager to null so as not to interfere with Google App Engine (GAE).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

GoogleAppEngineListener

public GoogleAppEngineListener()
Creates a default GoogleAppEngineListener.

Method Detail

contextDestroyed

public void contextDestroyed(ServletContextEvent servletContextEvent)
This method does nothing.

Specified by:
contextDestroyed in interface ServletContextListener
Parameters:
servletContextEvent - the event class for notifications about changes to the servlet context

contextInitialized

public void contextInitialized(ServletContextEvent servletContextEvent)
Sets the Ognl Runtime SecurityManager to null so as not to interfere with Google App Engine (GAE). GAE provides its own strict SecurityManager which clashes with Ognl security checks.
 OgnlRuntime.setSecurityManager(null); 

Specified by:
contextInitialized in interface ServletContextListener
Parameters:
servletContextEvent - the event class for notifications about changes to the servlet context