diff options
author | Artur Signell <artur@vaadin.com> | 2012-08-30 17:24:36 +0300 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2012-08-30 17:24:36 +0300 |
commit | 7b25b3886ea95bc6495506fbe9472e45fcbde684 (patch) | |
tree | 0b93cb65dab437feb46720659a63b8f1ef48f7f4 /uitest/src/com/vaadin/launcher | |
parent | 8941056349e302e687e40e94c13709e75f256d73 (diff) | |
download | vaadin-framework-7b25b3886ea95bc6495506fbe9472e45fcbde684.tar.gz vaadin-framework-7b25b3886ea95bc6495506fbe9472e45fcbde684.zip |
Renamed tests -> uitest and tests/testbench -> uitest/src (#9299)
Diffstat (limited to 'uitest/src/com/vaadin/launcher')
-rw-r--r-- | uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java | 302 | ||||
-rw-r--r-- | uitest/src/com/vaadin/launcher/DemoLauncher.java | 227 | ||||
-rw-r--r-- | uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java | 231 | ||||
-rw-r--r-- | uitest/src/com/vaadin/launcher/jetty-webdefault.xml | 281 | ||||
-rw-r--r-- | uitest/src/com/vaadin/launcher/keystore | bin | 0 -> 1367 bytes | |||
-rw-r--r-- | uitest/src/com/vaadin/launcher/util/BrowserLauncher.java | 139 |
6 files changed, 1180 insertions, 0 deletions
diff --git a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java new file mode 100644 index 0000000000..e05979ede0 --- /dev/null +++ b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java @@ -0,0 +1,302 @@ +/* + * Copyright 2011 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.launcher; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.vaadin.Application; +import com.vaadin.UIRequiresMoreInformationException; +import com.vaadin.server.AbstractApplicationServlet; +import com.vaadin.server.AbstractUIProvider; +import com.vaadin.server.WrappedHttpServletRequest; +import com.vaadin.server.WrappedRequest; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.UI; + +@SuppressWarnings("serial") +public class ApplicationRunnerServlet extends AbstractApplicationServlet { + + /** + * The name of the application class currently used. Only valid within one + * request. + */ + private LinkedHashSet<String> defaultPackages = new LinkedHashSet<String>(); + + private final ThreadLocal<HttpServletRequest> request = new ThreadLocal<HttpServletRequest>(); + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + super.init(servletConfig); + String initParameter = servletConfig + .getInitParameter("defaultPackages"); + if (initParameter != null) { + Collections.addAll(defaultPackages, initParameter.split(",")); + } + String str = TestBase.class.getName().replace('.', '/') + ".class"; + URL url = getDeploymentConfiguration().getClassLoader() + .getResource(str); + if ("file".equals(url.getProtocol())) { + File comVaadinTests = new File(url.getPath()).getParentFile() + .getParentFile(); + addDirectories(comVaadinTests, defaultPackages, "com.vaadin.tests"); + + } + } + + private void addDirectories(File parent, LinkedHashSet<String> packages, + String parentPackage) { + packages.add(parentPackage); + + for (File f : parent.listFiles()) { + if (f.isDirectory()) { + String newPackage = parentPackage + "." + f.getName(); + addDirectories(f, packages, newPackage); + } + } + } + + @Override + protected void service(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + this.request.set(request); + try { + super.service(request, response); + } finally { + this.request.set(null); + } + } + + @Override + protected URL getApplicationUrl(HttpServletRequest request) + throws MalformedURLException { + URL url = super.getApplicationUrl(request); + + String path = url.toString(); + path += getApplicationRunnerApplicationClassName(request); + path += "/"; + + return new URL(path); + } + + @Override + protected Application getNewApplication(HttpServletRequest request) + throws ServletException { + + // Creates a new application instance + try { + final Class<?> classToRun = getClassToRun(); + if (UI.class.isAssignableFrom(classToRun)) { + Application application = new Application(); + application.addUIProvider(new AbstractUIProvider() { + + @Override + public Class<? extends UI> getUIClass( + Application application, WrappedRequest request) + throws UIRequiresMoreInformationException { + return (Class<? extends UI>) classToRun; + } + }); + return application; + } else if (Application.class.isAssignableFrom(classToRun)) { + return (Application) classToRun.newInstance(); + } else { + throw new ServletException(classToRun.getCanonicalName() + + " is neither an Application nor a UI"); + } + } catch (final IllegalAccessException e) { + throw new ServletException(e); + } catch (final InstantiationException e) { + throw new ServletException(e); + } catch (final ClassNotFoundException e) { + throw new ServletException( + new InstantiationException( + "Failed to load application class: " + + getApplicationRunnerApplicationClassName(request))); + } + + } + + private String getApplicationRunnerApplicationClassName( + HttpServletRequest request) { + return getApplicationRunnerURIs(request).applicationClassname; + } + + private static class URIS { + String staticFilesPath; + // String applicationURI; + // String context; + // String runner; + String applicationClassname; + + } + + /** + * Parses application runner URIs. + * + * If request URL is e.g. + * http://localhost:8080/vaadin/run/com.vaadin.demo.Calc then + * <ul> + * <li>context=vaadin</li> + * <li>Runner servlet=run</li> + * <li>Vaadin application=com.vaadin.demo.Calc</li> + * </ul> + * + * @param request + * @return string array containing widgetset URI, application URI and + * context, runner, application classname + */ + private static URIS getApplicationRunnerURIs(HttpServletRequest request) { + final String[] urlParts = request.getRequestURI().toString() + .split("\\/"); + String context = null; + // String runner = null; + URIS uris = new URIS(); + String applicationClassname = null; + String contextPath = request.getContextPath(); + if (urlParts[1].equals(contextPath.replaceAll("\\/", ""))) { + // class name comes after web context and runner application + context = urlParts[1]; + // runner = urlParts[2]; + if (urlParts.length == 3) { + throw new IllegalArgumentException("No application specified"); + } + applicationClassname = urlParts[3]; + + uris.staticFilesPath = "/" + context; + // uris.applicationURI = "/" + context + "/" + runner + "/" + // + applicationClassname; + // uris.context = context; + // uris.runner = runner; + uris.applicationClassname = applicationClassname; + } else { + // no context + context = ""; + // runner = urlParts[1]; + if (urlParts.length == 2) { + throw new IllegalArgumentException("No application specified"); + } + applicationClassname = urlParts[2]; + + uris.staticFilesPath = "/"; + // uris.applicationURI = "/" + runner + "/" + applicationClassname; + // uris.context = context; + // uris.runner = runner; + uris.applicationClassname = applicationClassname; + } + return uris; + } + + @Override + protected Class<? extends Application> getApplicationClass() + throws ClassNotFoundException { + Class<?> classToRun = getClassToRun(); + if (UI.class.isAssignableFrom(classToRun)) { + return Application.class; + } else if (Application.class.isAssignableFrom(classToRun)) { + return classToRun.asSubclass(Application.class); + } else { + throw new ClassCastException(classToRun.getCanonicalName() + + " is not an Application nor a UI"); + } + } + + private Class<?> getClassToRun() throws ClassNotFoundException { + // TODO use getClassLoader() ? + + Class<?> appClass = null; + + String baseName = getApplicationRunnerApplicationClassName(request + .get()); + try { + appClass = getClass().getClassLoader().loadClass(baseName); + return appClass; + } catch (Exception e) { + // + for (String pkg : defaultPackages) { + try { + appClass = getClass().getClassLoader().loadClass( + pkg + "." + baseName); + } catch (ClassNotFoundException ee) { + // Ignore as this is expected for many packages + } catch (Exception e2) { + // TODO: handle exception + getLogger().log( + Level.FINE, + "Failed to find application class " + pkg + "." + + baseName, e2); + } + if (appClass != null) { + return appClass; + } + } + + } + + throw new ClassNotFoundException(); + } + + @Override + protected String getRequestPathInfo(HttpServletRequest request) { + String path = request.getPathInfo(); + if (path == null) { + return null; + } + + path = path.substring(1 + getApplicationRunnerApplicationClassName( + request).length()); + return path; + } + + @Override + protected String getStaticFilesLocation(HttpServletRequest request) { + URIS uris = getApplicationRunnerURIs(request); + String staticFilesPath = uris.staticFilesPath; + if (staticFilesPath.equals("/")) { + staticFilesPath = ""; + } + + return staticFilesPath; + } + + @Override + protected WrappedHttpServletRequest createWrappedRequest( + HttpServletRequest request) { + return new WrappedHttpServletRequest(request, + getDeploymentConfiguration()) { + @Override + public String getRequestPathInfo() { + return ApplicationRunnerServlet.this.getRequestPathInfo(this); + } + }; + } + + private Logger getLogger() { + return Logger.getLogger(ApplicationRunnerServlet.class.getName()); + } + +} diff --git a/uitest/src/com/vaadin/launcher/DemoLauncher.java b/uitest/src/com/vaadin/launcher/DemoLauncher.java new file mode 100644 index 0000000000..d858b91483 --- /dev/null +++ b/uitest/src/com/vaadin/launcher/DemoLauncher.java @@ -0,0 +1,227 @@ +/* + * Copyright 2011 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.launcher; + +import java.awt.FlowLayout; +import java.awt.HeadlessException; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.WindowConstants; + +import com.vaadin.launcher.util.BrowserLauncher; + +/** + * This class starts servlet container and opens a simple control dialog. + * + */ +public class DemoLauncher { + + public static void main(String[] args) throws Exception { + + final Map<String, String> serverArgs = DevelopmentServerLauncher + .parseArguments(args); + boolean deployed = false; + try { + // Default deployment: embedded.war + deployed = deployEmbeddedWarfile(serverArgs); + } catch (final IOException e1) { + e1.printStackTrace(); + deployed = false; + } + + // Check if deployment was succesful + if (!deployed && !serverArgs.containsKey("webroot")) { + // Default deployment failed, try other means + if (new File("WebContent").exists()) { + // Using WebContent directory as webroot + serverArgs.put("webroot", "WebContent"); + } else { + System.err.print("Failed to deploy Vaadin application. " + + "Please add --webroot parameter. Exiting."); + return; + } + } + + // Start the Jetty servlet container + final String url = DevelopmentServerLauncher.runServer(serverArgs, + "Demo Server"); + + if (!serverArgs.containsKey("nogui") && url != null) { + + // Open browser into application URL + BrowserLauncher.openBrowser(url); + + // Open control dialog + /* + * Swing components should never be manipulated outside the event + * dispatch thread. + */ + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + try { + openServerControlDialog(url); + } catch (HeadlessException e) { + // nop, starting from console + } + } + }); + } + } + + /** + * Open a control dialog for embedded server. + * + * @param applicationUrl + * Application URL + */ + private static void openServerControlDialog(final String applicationUrl) { + + // Main frame + final String title = "Desktop Server"; + final JFrame frame = new JFrame(title); + frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + + // Create link label and listen mouse click + final JLabel link = new JLabel("<html>" + + "<center>Desktop Server is running at: <br>" + "<a href=\"" + + applicationUrl + "\">" + applicationUrl + + "</a><br>Close this window to shutdown the server.</center>" + + "</html>"); + link.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + BrowserLauncher.openBrowser(applicationUrl); + } + }); + + // Create a panel and add components to it. + final JPanel contentPane = new JPanel(new FlowLayout()); + frame.setContentPane(contentPane); + contentPane.add(link); + + // Close confirmation + final JLabel question = new JLabel( + "This will stop the server. Are you sure?"); + final JButton okButton = new JButton("OK"); + final JButton cancelButton = new JButton("Cancel"); + + // List for close verify buttons + final ActionListener buttonListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == okButton) { + System.exit(0); + } else { + Rectangle bounds = frame.getBounds(); + frame.setTitle(title); + contentPane.removeAll(); + contentPane.add(link); + contentPane.setBounds(bounds); + frame.setBounds(bounds); + frame.setVisible(true); + frame.repaint(); + } + } + }; + okButton.addActionListener(buttonListener); + cancelButton.addActionListener(buttonListener); + + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + final Rectangle bounds = frame.getBounds(); + frame.setTitle("Confirm close"); + contentPane.removeAll(); + contentPane.add(question); + contentPane.add(okButton); + contentPane.add(cancelButton); + frame.setBounds(bounds); + frame.setVisible(true); + frame.repaint(); + } + }); + + // Position the window nicely + final java.awt.Dimension screenSize = java.awt.Toolkit + .getDefaultToolkit().getScreenSize(); + final int w = 270; + final int h = 95; + final int margin = 20; + frame.setBounds(new Rectangle(screenSize.width - w - margin, + screenSize.height - h - margin * 2, w, h)); + frame.toFront(); + frame.setVisible(true); + } + + /** + * Deploy file named "embedded.war" from classpath (inside jar file). + * + * @param args + * @return + * @throws IOException + */ + protected static boolean deployEmbeddedWarfile(Map<String, String> args) + throws IOException { + final String embeddedWarfileName = "/embedded.war"; + final InputStream embeddedWarfile = DemoLauncher.class + .getResourceAsStream(embeddedWarfileName); + if (embeddedWarfile != null) { + final File tempWarfile = File.createTempFile("embedded", ".war") + .getAbsoluteFile(); + tempWarfile.getParentFile().mkdirs(); + tempWarfile.deleteOnExit(); + + final String embeddedWebroot = "winstoneEmbeddedWAR"; + final File tempWebroot = new File(tempWarfile.getParentFile(), + embeddedWebroot); + tempWebroot.mkdirs(); + + final OutputStream out = new FileOutputStream(tempWarfile, true); + int read = 0; + final byte buffer[] = new byte[2048]; + while ((read = embeddedWarfile.read(buffer)) != -1) { + out.write(buffer, 0, read); + } + out.close(); + embeddedWarfile.close(); + + args.put("warfile", tempWarfile.getAbsolutePath()); + args.put("webroot", tempWebroot.getAbsolutePath()); + args.remove("webappsDir"); + args.remove("hostsDir"); + return true; + } + return false; + } +} diff --git a/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java b/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java new file mode 100644 index 0000000000..6162820dac --- /dev/null +++ b/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java @@ -0,0 +1,231 @@ +/* + * Copyright 2011 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.launcher; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.HashMap; +import java.util.Map; + +import org.mortbay.jetty.Connector; +import org.mortbay.jetty.Server; +import org.mortbay.jetty.nio.SelectChannelConnector; +import org.mortbay.jetty.security.SslSocketConnector; +import org.mortbay.jetty.webapp.WebAppContext; + +import com.vaadin.launcher.util.BrowserLauncher; + +/** + * Class for running Jetty servlet container within Eclipse project. + * + */ +public class DevelopmentServerLauncher { + + private static final String KEYSTORE = "src/com/vaadin/launcher/keystore"; + private final static int serverPort = 8888; + + /** + * Main function for running Jetty. + * + * Command line Arguments are passed through to Jetty, see runServer method + * for options. + * + * @param args + * @throws Exception + */ + public static void main(String[] args) { + System.setProperty("java.awt.headless", "true"); + + // Pass-through of arguments for Jetty + final Map<String, String> serverArgs = parseArguments(args); + + if (serverArgs.containsKey("shutdownPort")) { + int port = Integer.parseInt(serverArgs.get("shutdownPort")); + try { + // Try to notify another instance that it's time to close + Socket socket = new Socket((String) null, port); + // Wait until the other instance says it has closed + socket.getInputStream().read(); + // Then tidy up + socket.close(); + } catch (IOException e) { + // Ignore if port is not open + } + } + + // Start Jetty + System.out.println("Starting Jetty servlet container."); + String url; + try { + url = runServer(serverArgs, "Development Server Mode"); + // Start Browser + if (serverArgs.containsKey("gui") && url != null) { + System.out.println("Starting Web Browser."); + + // Open browser into application URL + BrowserLauncher.openBrowser(url); + } + } catch (Exception e) { + // NOP exception already on console by jetty + } + } + + /** + * Run the server with specified arguments. + * + * @param serverArgs + * @return + * @throws Exception + * @throws Exception + */ + protected static String runServer(Map<String, String> serverArgs, + String mode) throws Exception { + + // Assign default values for some arguments + assignDefault(serverArgs, "webroot", "WebContent"); + assignDefault(serverArgs, "httpPort", "" + serverPort); + assignDefault(serverArgs, "context", ""); + + int port = serverPort; + try { + port = Integer.parseInt(serverArgs.get("httpPort")); + } catch (NumberFormatException e) { + // keep default value for port + } + + // Add help for System.out + System.out + .println("-------------------------------------------------\n" + + "Starting Vaadin in " + + mode + + ".\n" + + "Running in http://localhost:" + + port + + "\n-------------------------------------------------\n"); + + final Server server = new Server(); + + final Connector connector = new SelectChannelConnector(); + + connector.setPort(port); + if (serverArgs.containsKey("withssl")) { + final SslSocketConnector sslConnector = new SslSocketConnector(); + sslConnector.setPort(8444); + sslConnector.setTruststore(KEYSTORE); + sslConnector.setTrustPassword("password"); + sslConnector.setKeystore(KEYSTORE); + sslConnector.setKeyPassword("password"); + sslConnector.setPassword("password"); + server.setConnectors(new Connector[] { connector, sslConnector }); + } else { + server.setConnectors(new Connector[] { connector }); + } + + final WebAppContext webappcontext = new WebAppContext(); + String path = DevelopmentServerLauncher.class.getPackage().getName() + .replace(".", File.separator); + webappcontext.setDefaultsDescriptor(path + File.separator + + "jetty-webdefault.xml"); + webappcontext.setContextPath(serverArgs.get("context")); + webappcontext.setWar(serverArgs.get("webroot")); + server.setHandler(webappcontext); + + try { + server.start(); + + if (serverArgs.containsKey("shutdownPort")) { + int shutdownPort = Integer.parseInt(serverArgs + .get("shutdownPort")); + final ServerSocket serverSocket = new ServerSocket( + shutdownPort, 1, InetAddress.getByName("127.0.0.1")); + new Thread() { + @Override + public void run() { + try { + System.out + .println("Waiting for shutdown signal on port " + + serverSocket.getLocalPort()); + // Start waiting for a close signal + Socket accept = serverSocket.accept(); + // First stop listening to the port + serverSocket.close(); + // Then stop the jetty server + server.stop(); + // Send a byte to tell the other process that it can + // start jetty + OutputStream outputStream = accept + .getOutputStream(); + outputStream.write(0); + outputStream.flush(); + // Finally close the socket + accept.close(); + } catch (Exception e) { + e.printStackTrace(); + } + }; + + }.start(); + + } + } catch (Exception e) { + server.stop(); + throw e; + } + + return "http://localhost:" + port + serverArgs.get("context"); + } + + /** + * Assign default value for given key. + * + * @param map + * @param key + * @param value + */ + private static void assignDefault(Map<String, String> map, String key, + String value) { + if (!map.containsKey(key)) { + map.put(key, value); + } + } + + /** + * Parse all command line arguments into a map. + * + * Arguments format "key=value" are put into map. + * + * @param args + * @return map of arguments key value pairs. + */ + protected static Map<String, String> parseArguments(String[] args) { + final Map<String, String> map = new HashMap<String, String>(); + for (int i = 0; i < args.length; i++) { + final int d = args[i].indexOf("="); + if (d > 0 && d < args[i].length() && args[i].startsWith("--")) { + final String name = args[i].substring(2, d); + final String value = args[i].substring(d + 1); + map.put(name, value); + } + } + return map; + } + +} diff --git a/uitest/src/com/vaadin/launcher/jetty-webdefault.xml b/uitest/src/com/vaadin/launcher/jetty-webdefault.xml new file mode 100644 index 0000000000..5a2465af5a --- /dev/null +++ b/uitest/src/com/vaadin/launcher/jetty-webdefault.xml @@ -0,0 +1,281 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> + +<!-- ===================================================================== --> +<!-- This file contains the default descriptor for web applications. --> +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<!-- The intent of this descriptor is to include jetty specific or common --> +<!-- configuration for all webapps. If a context has a webdefault.xml --> +<!-- descriptor, it is applied before the contexts own web.xml file --> +<!-- --> +<!-- A context may be assigned a default descriptor by: --> +<!-- + Calling WebApplicationContext.setDefaultsDescriptor --> +<!-- + Passed an arg to addWebApplications --> +<!-- --> +<!-- This file is used both as the resource within the jetty.jar (which is --> +<!-- used as the default if no explicit defaults descriptor is set) and it --> +<!-- is copied to the etc directory of the Jetty distro and explicitly --> +<!-- by the jetty.xml file. --> +<!-- --> +<!-- ===================================================================== --> +<web-app + xmlns="http://java.sun.com/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" + metadata-complete="true" + version="2.5"> + + <description> + Default web.xml file. + This file is applied to a Web application before it's own WEB_INF/web.xml file + </description> + + + <!-- ==================================================================== --> + <!-- Context params to control Session Cookies --> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <!-- UNCOMMENT TO ACTIVATE + <context-param> + <param-name>org.mortbay.jetty.servlet.SessionDomain</param-name> + <param-value>127.0.0.1</param-value> + </context-param> + + <context-param> + <param-name>org.mortbay.jetty.servlet.SessionPath</param-name> + <param-value>/</param-value> + </context-param> + + <context-param> + <param-name>org.mortbay.jetty.servlet.MaxAge</param-name> + <param-value>-1</param-value> + </context-param> + --> + + <context-param> + <param-name>org.mortbay.jetty.webapp.NoTLDJarPattern</param-name> + <param-value>start.jar|ant-.*\.jar|dojo-.*\.jar|jetty-.*\.jar|jsp-api-.*\.jar|junit-.*\.jar|servlet-api-.*\.jar|dnsns\.jar|rt\.jar|jsse\.jar|tools\.jar|sunpkcs11\.jar|sunjce_provider\.jar|xerces.*\.jar</param-value> + </context-param> + + + + <!-- ==================================================================== --> + <!-- The default servlet. --> + <!-- This servlet, normally mapped to /, provides the handling for static --> + <!-- content, OPTIONS and TRACE methods for the context. --> + <!-- The following initParameters are supported: --> + <!-- --> + <!-- acceptRanges If true, range requests and responses are --> + <!-- supported --> + <!-- --> + <!-- dirAllowed If true, directory listings are returned if no --> + <!-- welcome file is found. Else 403 Forbidden. --> + <!-- --> + <!-- redirectWelcome If true, redirect welcome file requests --> + <!-- else use request dispatcher forwards --> + <!-- --> + <!-- gzip If set to true, then static content will be served--> + <!-- as gzip content encoded if a matching resource is --> + <!-- found ending with ".gz" --> + <!-- --> + <!-- resoureBase Can be set to replace the context resource base --> + <!-- --> + <!-- relativeResourceBase --> + <!-- Set with a pathname relative to the base of the --> + <!-- servlet context root. Useful for only serving --> + <!-- static content from only specific subdirectories. --> + <!-- --> + <!-- useFileMappedBuffer --> + <!-- If set to true (the default), a memory mapped --> + <!-- file buffer will be used to serve static content --> + <!-- when using an NIO connector. Setting this value --> + <!-- to false means that a direct buffer will be used --> + <!-- instead. If you are having trouble with Windows --> + <!-- file locking, set this to false. --> + <!-- --> + <!-- cacheControl If set, all static content will have this value --> + <!-- set as the cache-control header. --> + <!-- --> + <!-- maxCacheSize Maximum size of the static resource cache --> + <!-- --> + <!-- maxCachedFileSize Maximum size of any single file in the cache --> + <!-- --> + <!-- maxCachedFiles Maximum number of files in the cache --> + <!-- --> + <!-- cacheType "nio", "bio" or "both" to determine the type(s) --> + <!-- of resource cache. A bio cached buffer may be used--> + <!-- by nio but is not as efficient as a nio buffer. --> + <!-- An nio cached buffer may not be used by bio. --> + <!-- --> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <servlet> + <servlet-name>default</servlet-name> + <servlet-class>org.mortbay.jetty.servlet.DefaultServlet</servlet-class> + <init-param> + <param-name>acceptRanges</param-name> + <param-value>true</param-value> + </init-param> + <init-param> + <param-name>dirAllowed</param-name> + <param-value>true</param-value> + </init-param> + <init-param> + <param-name>redirectWelcome</param-name> + <param-value>false</param-value> + </init-param> + <init-param> + <param-name>maxCacheSize</param-name> + <param-value>256000000</param-value> + </init-param> + <init-param> + <param-name>maxCachedFileSize</param-name> + <param-value>10000000</param-value> + </init-param> + <init-param> + <param-name>maxCachedFiles</param-name> + <param-value>1000</param-value> + </init-param> + <init-param> + <param-name>cacheType</param-name> + <param-value>both</param-value> + </init-param> + <init-param> + <param-name>gzip</param-name> + <param-value>true</param-value> + </init-param> + <init-param> + <param-name>useFileMappedBuffer</param-name> + <param-value>false</param-value> + </init-param> + <!-- + <init-param> + <param-name>cacheControl</param-name> + <param-value>max-age=3600,public</param-value> + </init-param> + --> + <load-on-startup>0</load-on-startup> + </servlet> + + <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> + + + <!-- ==================================================================== --> + <!-- Dynamic Servlet Invoker. --> + <!-- This servlet invokes anonymous servlets that have not been defined --> + <!-- in the web.xml or by other means. The first element of the pathInfo --> + <!-- of a request passed to the envoker is treated as a servlet name for --> + <!-- an existing servlet, or as a class name of a new servlet. --> + <!-- This servlet is normally mapped to /servlet/* --> + <!-- This servlet support the following initParams: --> + <!-- --> + <!-- nonContextServlets If false, the invoker can only load --> + <!-- servlets from the contexts classloader. --> + <!-- This is false by default and setting this --> + <!-- to true may have security implications. --> + <!-- --> + <!-- verbose If true, log dynamic loads --> + <!-- --> + <!-- * All other parameters are copied to the --> + <!-- each dynamic servlet as init parameters --> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <!-- Uncomment for dynamic invocation + <servlet> + <servlet-name>invoker</servlet-name> + <servlet-class>org.mortbay.jetty.servlet.Invoker</servlet-class> + <init-param> + <param-name>verbose</param-name> + <param-value>false</param-value> + </init-param> + <init-param> + <param-name>nonContextServlets</param-name> + <param-value>false</param-value> + </init-param> + <init-param> + <param-name>dynamicParam</param-name> + <param-value>anyValue</param-value> + </init-param> + <load-on-startup>0</load-on-startup> + </servlet> + + <servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> + --> + + + + <!-- ==================================================================== --> + <session-config> + <session-timeout>30</session-timeout> + </session-config> + + <!-- ==================================================================== --> + <!-- Default MIME mappings --> + <!-- The default MIME mappings are provided by the mime.properties --> + <!-- resource in the org.mortbay.jetty.jar file. Additional or modified --> + <!-- mappings may be specified here --> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <!-- UNCOMMENT TO ACTIVATE + <mime-mapping> + <extension>mysuffix</extension> + <mime-type>mymime/type</mime-type> + </mime-mapping> + --> + + <!-- ==================================================================== --> + <welcome-file-list> + <welcome-file>index.html</welcome-file> + <welcome-file>index.htm</welcome-file> + <welcome-file>index.jsp</welcome-file> + </welcome-file-list> + + <!-- ==================================================================== --> + <locale-encoding-mapping-list> + <locale-encoding-mapping><locale>ar</locale><encoding>ISO-8859-6</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>be</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>bg</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>ca</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>cs</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>da</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>de</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>el</locale><encoding>ISO-8859-7</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>en</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>es</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>et</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>fi</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>fr</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>hr</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>hu</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>is</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>it</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>iw</locale><encoding>ISO-8859-8</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>ja</locale><encoding>Shift_JIS</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>ko</locale><encoding>EUC-KR</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>lt</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>lv</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>mk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>nl</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>no</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>pl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>pt</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>ro</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>ru</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>sh</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>sk</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>sl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>sq</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>sr</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>sv</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>tr</locale><encoding>ISO-8859-9</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>uk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>zh</locale><encoding>GB2312</encoding></locale-encoding-mapping> + <locale-encoding-mapping><locale>zh_TW</locale><encoding>Big5</encoding></locale-encoding-mapping> + </locale-encoding-mapping-list> + + <security-constraint> + <web-resource-collection> + <web-resource-name>Disable TRACE</web-resource-name> + <url-pattern>/</url-pattern> + <http-method>TRACE</http-method> + </web-resource-collection> + <auth-constraint/> + </security-constraint> + +</web-app> + diff --git a/uitest/src/com/vaadin/launcher/keystore b/uitest/src/com/vaadin/launcher/keystore Binary files differnew file mode 100644 index 0000000000..1314185e2a --- /dev/null +++ b/uitest/src/com/vaadin/launcher/keystore diff --git a/uitest/src/com/vaadin/launcher/util/BrowserLauncher.java b/uitest/src/com/vaadin/launcher/util/BrowserLauncher.java new file mode 100644 index 0000000000..c9b3622894 --- /dev/null +++ b/uitest/src/com/vaadin/launcher/util/BrowserLauncher.java @@ -0,0 +1,139 @@ +/* + * Copyright 2011 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.launcher.util; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * This class opens default browser for DemoLauncher class. Default browser is + * detected by the operating system. + * + */ +public class BrowserLauncher { + + /** + * Open browser on specified URL. + * + * @param url + */ + public static void openBrowser(String url) { + + final Runtime runtime = Runtime.getRuntime(); + boolean started = false; + + final String os = System.getProperty("os.name", "windows") + .toLowerCase(); + + // Linux + if (os.indexOf("linux") >= 0) { + // See if the default browser is Konqueror by resolving the symlink. + boolean isDefaultKonqueror = false; + try { + // Find out the location of the x-www-browser link from path. + Process process = runtime.exec("which x-www-browser"); + BufferedInputStream ins = new BufferedInputStream( + process.getInputStream()); + BufferedReader bufreader = new BufferedReader( + new InputStreamReader(ins)); + String defaultLinkPath = bufreader.readLine(); + ins.close(); + + // The path is null if the link did not exist. + if (defaultLinkPath != null) { + // See if the default browser is Konqueror. + File file = new File(defaultLinkPath); + String canonical = file.getCanonicalPath(); + if (canonical.indexOf("konqueror") != -1) { + isDefaultKonqueror = true; + } + } + } catch (IOException e1) { + // The symlink was probably not found, so this is ok. + } + + // Try x-www-browser, which is symlink to the default browser, + // except if we found that it is Konqueror. + if (!started && !isDefaultKonqueror) { + try { + runtime.exec("x-www-browser " + url); + started = true; + } catch (final IOException e) { + } + } + + // Try firefox + if (!started) { + try { + runtime.exec("firefox " + url); + started = true; + } catch (final IOException e) { + } + } + + // Try mozilla + if (!started) { + try { + runtime.exec("mozilla " + url); + started = true; + } catch (final IOException e) { + } + } + + // Try konqueror + if (!started) { + try { + runtime.exec("konqueror " + url); + started = true; + } catch (final IOException e) { + } + } + } + + // OS X + if (os.indexOf("mac os x") >= 0) { + + // Try open + if (!started) { + try { + runtime.exec("open " + url); + started = true; + } catch (final IOException e) { + } + } + } + + // Try cmd /start command on windows + if (os.indexOf("win") >= 0) { + if (!started) { + try { + runtime.exec("cmd /c start " + url); + started = true; + } catch (final IOException e) { + } + } + } + + if (!started) { + System.out.println("Failed to open browser. Please go to " + url); + } + } + +} |