From 6b4e798c6c6ae3a4a3998383a7054f63dd3c8921 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 10 May 2015 00:54:09 -0700 Subject: [PATCH] GUAC-587: Use ExtensionModule to load extensions and set up app.css / app.js. --- .../basic/BasicServletContextListener.java | 2 + .../net/basic/extension/ExtensionModule.java | 105 ++++++++++++++++++ .../net/basic/extension/package-info.java | 27 +++++ .../net/basic/rest/RESTServletModule.java | 6 - 4 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/ExtensionModule.java create mode 100644 guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/package-info.java diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/BasicServletContextListener.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/BasicServletContextListener.java index 82f3983de..e6f342f2c 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/BasicServletContextListener.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/BasicServletContextListener.java @@ -30,6 +30,7 @@ import javax.servlet.ServletContextEvent; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.environment.Environment; import org.glyptodon.guacamole.environment.LocalEnvironment; +import org.glyptodon.guacamole.net.basic.extension.ExtensionModule; import org.glyptodon.guacamole.net.basic.log.LogModule; import org.glyptodon.guacamole.net.basic.rest.RESTAuthModule; import org.glyptodon.guacamole.net.basic.rest.RESTServletModule; @@ -83,6 +84,7 @@ public class BasicServletContextListener extends GuiceServletContextListener { return Guice.createInjector(Stage.PRODUCTION, new EnvironmentModule(environment), new LogModule(environment), + new ExtensionModule(environment), new RESTAuthModule(environment, sessionMap), new RESTServletModule(), new TunnelModule() diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/ExtensionModule.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/ExtensionModule.java new file mode 100644 index 000000000..60502c542 --- /dev/null +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/ExtensionModule.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.glyptodon.guacamole.net.basic.extension; + +import com.google.inject.servlet.ServletModule; +import java.io.File; +import java.io.FileFilter; +import org.glyptodon.guacamole.environment.Environment; +import org.glyptodon.guacamole.net.basic.resource.ResourceServlet; +import org.glyptodon.guacamole.net.basic.resource.WebApplicationResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A Guice Module which loads all extensions within the + * GUACAMOLE_HOME/extensions directory, if any. + * + * @author Michael Jumper + */ +public class ExtensionModule extends ServletModule { + + /** + * Logger for this class. + */ + private final Logger logger = LoggerFactory.getLogger(ExtensionModule.class); + + /** + * The name of the directory within GUACAMOLE_HOME containing all + * extensions. + */ + private static final String EXTENSIONS_DIRECTORY = "extensions"; + + /** + * The string that the filenames of all extensions must end with to be + * recognized as extensions. + */ + private static final String EXTENSION_SUFFIX = ".jar"; + + /** + * The Guacamole server environment. + */ + private final Environment environment; + + /** + * Creates a module which loads all extensions within the + * GUACAMOLE_HOME/extensions directory. + * + * @param environment + * The environment to use when configuring authentication. + */ + public ExtensionModule(Environment environment) { + this.environment = environment; + } + + @Override + protected void configureServlets() { + + // Retrieve and validate extensions directory + File extensionsDir = new File(environment.getGuacamoleHome(), EXTENSIONS_DIRECTORY); + if (!extensionsDir.isDirectory()) + return; + + // Retrieve list of all extension files within extensions directory + File[] extensions = extensionsDir.listFiles(new FileFilter() { + + @Override + public boolean accept(File file) { + return file.isFile() && file.getName().endsWith(EXTENSION_SUFFIX); + } + + }); + + // Load each extension + for (File extension : extensions) { + // TODO: Actually load extension + logger.info("Loading extension: \"{}\"", extension.getName()); + } + + // TODO: Pull these from extensions, dynamically concatenated + serve("/app.js").with(new ResourceServlet(new WebApplicationResource(getServletContext(), "/guacamole.min.js"))); + serve("/app.css").with(new ResourceServlet(new WebApplicationResource(getServletContext(), "/guacamole.min.css"))); + + } + +} diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/package-info.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/package-info.java new file mode 100644 index 000000000..198e4c4b7 --- /dev/null +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/extension/package-info.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Classes which represent and facilitate the loading of extensions to the + * Guacamole web application. + */ +package org.glyptodon.guacamole.net.basic.extension; diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTServletModule.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTServletModule.java index 34bfb0790..a6e54c7a6 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTServletModule.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTServletModule.java @@ -27,8 +27,6 @@ import com.google.inject.matcher.Matchers; import com.google.inject.servlet.ServletModule; import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; import org.codehaus.jackson.jaxrs.JacksonJsonProvider; -import org.glyptodon.guacamole.net.basic.resource.ResourceServlet; -import org.glyptodon.guacamole.net.basic.resource.WebApplicationResource; import org.glyptodon.guacamole.net.basic.rest.auth.TokenRESTService; import org.glyptodon.guacamole.net.basic.rest.clipboard.ClipboardRESTService; import org.glyptodon.guacamole.net.basic.rest.connection.ConnectionRESTService; @@ -73,10 +71,6 @@ public class RESTServletModule extends ServletModule { bind(JacksonJsonProvider.class).in(Scopes.SINGLETON); serve("/api/*").with(GuiceContainer.class); - // TODO: Pull these from extensions, dynamically concatenated - serve("/app.js").with(new ResourceServlet(new WebApplicationResource(getServletContext(), "/guacamole.min.js"))); - serve("/app.css").with(new ResourceServlet(new WebApplicationResource(getServletContext(), "/guacamole.min.css"))); - } }