View Javadoc
1   package org.argeo.eclipse.ui.jetty;
2   
3   import java.io.IOException;
4   import java.lang.management.ManagementFactory;
5   import java.nio.file.Files;
6   import java.nio.file.Path;
7   
8   import javax.servlet.ServletContextEvent;
9   import javax.servlet.ServletContextListener;
10  
11  import org.eclipse.jetty.server.Connector;
12  import org.eclipse.jetty.server.Server;
13  import org.eclipse.jetty.server.ServerConnector;
14  import org.eclipse.jetty.servlet.DefaultServlet;
15  import org.eclipse.jetty.servlet.ServletContextHandler;
16  import org.eclipse.jetty.servlet.ServletHolder;
17  import org.eclipse.jetty.util.resource.Resource;
18  import org.eclipse.jetty.util.thread.QueuedThreadPool;
19  import org.eclipse.rap.rwt.application.AbstractEntryPoint;
20  import org.eclipse.rap.rwt.application.ApplicationRunner;
21  import org.eclipse.rap.rwt.engine.RWTServlet;
22  import org.eclipse.swt.SWT;
23  import org.eclipse.swt.widgets.Composite;
24  import org.eclipse.swt.widgets.Control;
25  import org.eclipse.swt.widgets.Label;
26  
27  /** A minimal RWT runner based on embedded Jetty. */
28  public class RwtRunner {
29  
30  	private final Server server;
31  	private final ServerConnector serverConnector;
32  	private Path tempDir;
33  
34  	public RwtRunner() {
35  		server = new Server(new QueuedThreadPool(10, 1));
36  		serverConnector = new ServerConnector(server);
37  		serverConnector.setPort(0);
38  		server.setConnectors(new Connector[] { serverConnector });
39  	}
40  
41  	protected Control createUi(Composite parent, Object context) {
42  		return new Label(parent, SWT.NONE);
43  	}
44  
45  	public void init() {
46  		ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
47  		context.setContextPath("/");
48  		server.setHandler(context);
49  
50  		String entryPoint = "app";
51  
52  		// rwt-resources requires a file system
53  		try {
54  			tempDir = Files.createTempDirectory("argeo-rwtRunner");
55  			context.setBaseResource(Resource.newResource(tempDir.resolve("www").toString()));
56  		} catch (IOException e) {
57  			throw new IllegalStateException("Cannot create temporary directory", e);
58  		}
59  		context.addEventListener(new ServletContextListener() {
60  			ApplicationRunner applicationRunner;
61  
62  			@Override
63  			public void contextInitialized(ServletContextEvent sce) {
64  				applicationRunner = new ApplicationRunner(
65  						(application) -> application.addEntryPoint("/" + entryPoint, () -> new AbstractEntryPoint() {
66  							private static final long serialVersionUID = 5678385921969090733L;
67  
68  							@Override
69  							protected void createContents(Composite parent) {
70  								createUi(parent, null);
71  							}
72  						}, null), sce.getServletContext());
73  				applicationRunner.start();
74  			}
75  
76  			@Override
77  			public void contextDestroyed(ServletContextEvent sce) {
78  				applicationRunner.stop();
79  			}
80  		});
81  
82  		context.addServlet(new ServletHolder(new RWTServlet()), "/" + entryPoint);
83  
84  		// Required to serve rwt-resources. It is important that this is last.
85  		ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
86  		context.addServlet(holderPwd, "/");
87  
88  		try {
89  			server.start();
90  		} catch (Exception e) {
91  			throw new IllegalStateException("Cannot start Jetty server", e);
92  		}
93  	}
94  
95  	public void destroy() {
96  		try {
97  			serverConnector.close();
98  			server.stop();
99  			// TODO delete temp dir
100 		} catch (Exception e) {
101 			e.printStackTrace();
102 		}
103 	}
104 
105 	public Integer getEffectivePort() {
106 		return serverConnector.getLocalPort();
107 	}
108 
109 	public void waitFor() throws InterruptedException {
110 		server.join();
111 	}
112 
113 	public static void main(String[] args) throws Exception {
114 		RwtRunner rwtRunner = new RwtRunner() {
115 
116 			@Override
117 			protected Control createUi(Composite parent, Object context) {
118 				Label label = new Label(parent, SWT.NONE);
119 				label.setText("Hello world!");
120 				return label;
121 			}
122 		};
123 		rwtRunner.init();
124 		Runtime.getRuntime().addShutdownHook(new Thread(() -> rwtRunner.destroy(), "Jetty shutdown"));
125 
126 		long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
127 		System.out.println("App available in " + jvmUptime + " ms, on port " + rwtRunner.getEffectivePort());
128 
129 		// open browser in app mode
130 		Thread.sleep(2000);// wait for RWT to be ready
131 		Runtime.getRuntime().exec("google-chrome --app=http://localhost:" + rwtRunner.getEffectivePort() + "/app");
132 
133 		rwtRunner.waitFor();
134 	}
135 }