]> source.dussan.org Git - vaadin-framework.git/commitdiff
Initial version of on-the-fly compilation of scss -> css (#9222)
authorArtur Signell <artur@vaadin.com>
Tue, 11 Sep 2012 12:42:42 +0000 (15:42 +0300)
committerArtur Signell <artur@vaadin.com>
Tue, 11 Sep 2012 12:42:42 +0000 (15:42 +0300)
server/ivy.xml
server/src/com/vaadin/server/VaadinServlet.java

index acc384ea30b55141486fcce877cb66a0cd317f38..d7988831008e4002767595b526d3856980df2e22 100644 (file)
@@ -43,6 +43,8 @@
         <!-- Project modules -->
         <dependency org="com.vaadin" name="vaadin-shared"
             rev="${vaadin.version}" conf="build,tests" />
+        <dependency org="com.vaadin" name="vaadin-theme-compiler"
+            rev="${vaadin.version}" conf="build,tests" />
 
         <!-- Jsoup for BootstrapHandler -->
         <dependency org="org.jsoup" name="jsoup" rev="1.6.3"
index a0f6a28ea68961fe707a3d4130efaccc96b311ef..c4173e1271f322ee33a3077d85e9ad827a74dcc9 100644 (file)
@@ -45,6 +45,7 @@ import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
 import com.vaadin.DefaultDeploymentConfiguration;
+import com.vaadin.sass.ScssStylesheet;
 import com.vaadin.server.AbstractCommunicationManager.Callback;
 import com.vaadin.server.ServletPortletHelper.ApplicationClassException;
 import com.vaadin.server.VaadinSession.SessionStartEvent;
@@ -941,16 +942,14 @@ public class VaadinServlet extends HttpServlet implements Constants {
             throws IOException, ServletException {
 
         final ServletContext sc = getServletContext();
-        URL resourceUrl = sc.getResource(filename);
-        if (resourceUrl == null) {
-            // try if requested file is found from classloader
-
-            // strip leading "/" otherwise stream from JAR wont work
-            filename = filename.substring(1);
-            resourceUrl = getVaadinService().getClassLoader().getResource(
-                    filename);
+        URL resourceUrl = findResourceURL(filename, sc);
 
-            if (resourceUrl == null) {
+        if (resourceUrl == null) {
+            // File not found, if this was a css request we still look for a
+            // scss file with the same name
+            if (serveOnTheFlyCompiledScss(filename, request, response, sc)) {
+                return;
+            } else {
                 // cannot serve requested file
                 getLogger()
                         .info("Requested resource ["
@@ -958,19 +957,19 @@ public class VaadinServlet extends HttpServlet implements Constants {
                                 + "] not found from filesystem or through class loader."
                                 + " Add widgetset and/or theme JAR to your classpath or add files to WebContent/VAADIN folder.");
                 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
-                return;
             }
+            return;
+        }
 
-            // security check: do not permit navigation out of the VAADIN
-            // directory
-            if (!isAllowedVAADINResourceUrl(request, resourceUrl)) {
-                getLogger()
-                        .info("Requested resource ["
-                                + filename
-                                + "] not accessible in the VAADIN directory or access to it is forbidden.");
-                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
-                return;
-            }
+        // security check: do not permit navigation out of the VAADIN
+        // directory
+        if (!isAllowedVAADINResourceUrl(request, resourceUrl)) {
+            getLogger()
+                    .info("Requested resource ["
+                            + filename
+                            + "] not accessible in the VAADIN directory or access to it is forbidden.");
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            return;
         }
 
         // Find the modification timestamp
@@ -1046,6 +1045,82 @@ public class VaadinServlet extends HttpServlet implements Constants {
         is.close();
     }
 
+    private URL findResourceURL(String filename, ServletContext sc)
+            throws MalformedURLException {
+        URL resourceUrl = sc.getResource(filename);
+        if (resourceUrl == null) {
+            // try if requested file is found from classloader
+
+            // strip leading "/" otherwise stream from JAR wont work
+            if (filename.startsWith("/")) {
+                filename = filename.substring(1);
+            }
+
+            resourceUrl = getVaadinService().getClassLoader().getResource(
+                    filename);
+        }
+        return resourceUrl;
+    }
+
+    private boolean serveOnTheFlyCompiledScss(String filename,
+            HttpServletRequest request, HttpServletResponse response,
+            ServletContext sc) throws IOException {
+        if (getVaadinService().getDeploymentConfiguration().isProductionMode()) {
+            // This is not meant for production mode.
+            return false;
+        }
+
+        if (!filename.endsWith(".css")) {
+            return false;
+        }
+
+        String scssFilename = filename.substring(0, filename.length() - 4)
+                + ".scss";
+        URL scssUrl = findResourceURL(scssFilename, sc);
+        if (scssUrl == null) {
+            // Is a css request but no scss file was found
+            return false;
+        }
+        // security check: do not permit navigation out of the VAADIN
+        // directory
+        if (!isAllowedVAADINResourceUrl(request, scssUrl)) {
+            getLogger()
+                    .info("Requested resource ["
+                            + filename
+                            + "] not accessible in the VAADIN directory or access to it is forbidden.");
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            // Handled, return true so no further processing is done
+            return true;
+        }
+        String realFilename = sc.getRealPath(scssFilename);
+        ScssStylesheet scss = ScssStylesheet.get(realFilename);
+        if (scss == null) {
+            getLogger()
+                    .warning(
+                            "Scss file "
+                                    + scssFilename
+                                    + " exists but ScssStylesheet was not able to find it");
+            return false;
+        }
+        try {
+            getLogger()
+                    .fine("Compiling " + realFilename + " for request to "
+                            + filename);
+            scss.compile();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+
+        // This is for development mode only so instruct the browser to never
+        // cache it
+        response.setHeader("Cache-Control", "no-cache");
+        final String mimetype = getVaadinService().getMimeType(filename);
+        writeResponse(response, mimetype, scss.toString());
+
+        return true;
+    }
+
     /**
      * Check whether a URL obtained from a classloader refers to a valid static
      * resource in the directory VAADIN.