package net.sf.egonet.web; import java.io.IOException; import java.net.URL; import org.apache.wicket.protocol.http.WebApplication; import org.apache.wicket.protocol.http.WicketServlet; import net.sf.egonet.controller.EgonetMonitor; import net.sf.egonet.persistence.DB; import net.sf.egonet.web.page.IndexPage; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.mortbay.jetty.Server; //import org.mortbay.jetty.handler.ResourceHandler; import org.mortbay.jetty.servlet.Context; import org.mortbay.jetty.servlet.DefaultServlet; import org.mortbay.jetty.servlet.ServletHolder; import org.mortbay.resource.Resource; public class Main extends WebApplication { private static SessionFactory dbSessionFactory; private static Class<?> homePage; private static EgonetMonitor egonetMonitor; private static boolean usingDBSessionFactoryManager; public Main() { if (this.homePage == null) { this.homePage = IndexPage.class; } if (!usingDBSessionFactoryManager) { // See setUsingDBSessionFactoryManager() try { dbSessionFactory = new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { System.err.println("Caught an exception while trying to initialize hibernate session factory: "+ex); } } } protected void onDestroy() { dbSessionFactory.close(); } public static SessionFactory getDBSessionFactory() { return dbSessionFactory; } /** * Call this method when Egonet must switch context among an arbitrary * number of studies while maintaining each study's database connectivity. * See, for example, method useSessionFactory() in class * DBSessionFactoryManager, which is used by the InterviewController class. * * @param dbSessionFactory SessionFactory instance associated with a study */ public static void setDBSessionFactory( SessionFactory dbSessionFactory ) { Main.dbSessionFactory = dbSessionFactory; } /** * @see org.apache.wicket.Application#getHomePage() */ @Override public Class<?> getHomePage() { return homePage; } /** * This method allows a client to specify an alternate home page. It must * be called before the constructor for this class is called. * * @param homePage the HTML page that will be displayed when app starts up */ public static void setHomePage( Class<?> homePage ) { Main.homePage = homePage; } protected String applicationClassName = "net.sf.egonet.web.Main"; public static Server createAndConfigureServer() { return createAndConfigureServer("net.sf.egonet.web.Main",8080,true); } public static Server createAndConfigureServer(String applicationClassName, Integer port, Boolean localOnly) { Server server = new Server(port); // TODO: Restrict access to localhost: 0.0.0.0 -> 192.168.1.1? /* Context staticContext = new Context(server,"/static",0); staticContext.setHandler(new ResourceHandler()); // maybe extend resource handler to pull from classpath staticContext.setResourceBase("./static/"); staticContext.setContextPath("/static"); */ Context embeddedContext = new Context(server,"/static",0); ServletHolder embeddedHolder = new ServletHolder(new StaticContentFromClasspathServlet()); embeddedContext.addServlet(embeddedHolder, "/*"); Context context = new Context(server, "/", Context.SESSIONS); if(localOnly) { context.setVirtualHosts(new String[]{"127.0.0.1"}); } ServletHolder servletHolder = new ServletHolder(new WicketServlet()); servletHolder.setInitParameter("applicationClassName", applicationClassName); servletHolder.setInitOrder(1); context.addServlet(servletHolder, "/*"); return server; } // Mostly copied from http://www.codecommit.com/blog/java/so-long-wtp-embedded-jetty-for-me public static void main(String[] args) throws Exception { Server server = createAndConfigureServer(); server.start(); DB.migrate(); server.join(); } public static class StaticContentFromClasspathServlet extends DefaultServlet { public Resource getResource(String pathInContext) { try { URL url = getResourceFromClasspath(pathInContext); return Resource.newResource(url); } catch(IOException ex) { System.err.println("Caught an IOException: "+ex); } return null; } public static URL getResourceFromClasspath(String name) { if (name == null || name.length()==0) { return null; } return StaticContentFromClasspathServlet.class.getResource(name); } } /** * Call this method when database session factories for more than one * study must be maintained. Do not call this method when traditional * Egonet behavior is desired (or call it with an argument of 'false'). * * @param usingManager whether or not multiple studies must be managed in a single Egonet session */ public static void setUsingDBSessionFactoryManager( boolean usingManager ) { usingDBSessionFactoryManager = usingManager; } /** * Call this method when there is a single EgonetMonitor implementor that * wants to be notified by this class of certain events. * * Note: If this kind of event notification is generally useful, the more * robust event listener implementation should be used. * * @param egonetMonitor an instance of EgonetMonitor */ public static void registerEgonetMonitor( EgonetMonitor egonetMonitor ) { Main.egonetMonitor = egonetMonitor; } /** * Call this method to indicate that the user has performed some action, * such as answering a question or navigating to another screen. */ public static void userActivityOccurred() { if (egonetMonitor != null) { egonetMonitor.userActivityOccurred(); } } /** * Call this method to indicate that the interview has ended the current * interview. */ public static void interviewHasEnded() { if (egonetMonitor != null) { egonetMonitor.interviewHasEnded(); } } }