summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2014-11-15 18:24:17 +0200
committerVaadin Code Review <review@vaadin.com>2015-01-09 12:43:17 +0000
commit07e00fe8e09a224be2631df2e1ae2b8cbb46d466 (patch)
tree589780fa20039daab44c4e0a10aa4d3db80feaa5 /server
parent441472f311ef9f38af233705d2480766c50e51d1 (diff)
downloadvaadin-framework-07e00fe8e09a224be2631df2e1ae2b8cbb46d466.tar.gz
vaadin-framework-07e00fe8e09a224be2631df2e1ae2b8cbb46d466.zip
Persist scss cache (#15228)
Change-Id: I29bf746c3100df15bb04cc03b28ae64db4c5f987
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/server/VaadinServlet.java124
1 files changed, 120 insertions, 4 deletions
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index d1242676da..aa76dc8e08 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/com/vaadin/server/VaadinServlet.java
@@ -28,6 +28,7 @@ import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
@@ -45,14 +46,21 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import com.google.gwt.thirdparty.guava.common.base.Charsets;
+import com.google.gwt.thirdparty.guava.common.io.Files;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.VaadinServletConfiguration.InitParameterName;
import com.vaadin.sass.internal.ScssStylesheet;
import com.vaadin.server.communication.ServletUIInitHandler;
import com.vaadin.shared.JsonConstants;
+import com.vaadin.shared.Version;
import com.vaadin.ui.UI;
import com.vaadin.util.CurrentInstance;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonObject;
+
@SuppressWarnings("serial")
public class VaadinServlet extends HttpServlet implements Constants {
@@ -61,14 +69,47 @@ public class VaadinServlet extends HttpServlet implements Constants {
private final String css;
private final List<String> sourceUris;
private final long timestamp;
+ private final String scssFileName;
- public ScssCacheEntry(String css, List<String> sourceUris) {
+ public ScssCacheEntry(String scssFileName, String css,
+ List<String> sourceUris) {
+ this.scssFileName = scssFileName;
this.css = css;
this.sourceUris = sourceUris;
timestamp = getLastModified();
}
+ public ScssCacheEntry(JsonObject json) {
+ css = json.getString("css");
+ timestamp = Long.parseLong(json.getString("timestamp"));
+
+ sourceUris = new ArrayList<String>();
+
+ JsonArray uris = json.getArray("uris");
+ for (int i = 0; i < uris.length(); i++) {
+ sourceUris.add(uris.getString(i));
+ }
+
+ // Not set for cache entries read from disk
+ scssFileName = null;
+ }
+
+ public String asJson() {
+ JsonArray uris = Json.createArray();
+ for (String uri : sourceUris) {
+ uris.set(uris.length(), uri);
+ }
+
+ JsonObject object = Json.createObject();
+ object.put("version", Version.getFullVersion());
+ object.put("timestamp", Long.toString(timestamp));
+ object.put("uris", uris);
+ object.put("css", css);
+
+ return object.toJson();
+ }
+
public String getCss() {
return css;
}
@@ -117,6 +158,10 @@ public class VaadinServlet extends HttpServlet implements Constants {
}
}
+ public String getScssFileName() {
+ return scssFileName;
+ }
+
}
private VaadinServletService servletService;
@@ -612,7 +657,14 @@ public class VaadinServlet extends HttpServlet implements Constants {
* Global cache of scss compilation results. This map is protected from
* concurrent access by {@link #SCSS_MUTEX}.
*/
- private static final Map<String, ScssCacheEntry> scssCache = new HashMap<String, ScssCacheEntry>();
+ private final Map<String, ScssCacheEntry> scssCache = new HashMap<String, ScssCacheEntry>();
+
+ /**
+ * Keeps track of whether a warning about not being able to persist cache
+ * files has already been printed. The flag is protected from concurrent
+ * access by {@link #SCSS_MUTEX}.
+ */
+ private static boolean scssCompileWarWarningEmitted = false;
/**
* Returns the default theme. Must never return null.
@@ -900,10 +952,20 @@ public class VaadinServlet extends HttpServlet implements Constants {
synchronized (SCSS_MUTEX) {
ScssCacheEntry cacheEntry = scssCache.get(scssFilename);
+ if (cacheEntry == null) {
+ try {
+ cacheEntry = loadPersistedScssCache(scssFilename, sc);
+ } catch (Exception e) {
+ getLogger().log(Level.WARNING,
+ "Could not read persisted scss cache", e);
+ }
+ }
+
if (cacheEntry == null || !cacheEntry.isStillValid()) {
cacheEntry = compileScssOnTheFly(filename, scssFilename, sc);
- scssCache.put(scssFilename, cacheEntry);
+ persistCacheEntry(cacheEntry);
}
+ scssCache.put(scssFilename, cacheEntry);
if (cacheEntry == null) {
// compilation did not produce any result, but logged a message
@@ -920,6 +982,29 @@ public class VaadinServlet extends HttpServlet implements Constants {
}
}
+ private ScssCacheEntry loadPersistedScssCache(String scssFilename,
+ ServletContext sc) throws IOException {
+ String realFilename = sc.getRealPath(scssFilename);
+
+ File scssCacheFile = getScssCacheFile(new File(realFilename));
+ if (!scssCacheFile.exists()) {
+ return null;
+ }
+
+ String jsonString = Files.toString(scssCacheFile, Charsets.UTF_8);
+
+ JsonObject entryJson = Json.parse(jsonString);
+
+ String cacheVersion = entryJson.getString("version");
+ if (!Version.getFullVersion().equals(cacheVersion)) {
+ // Compiled for some other Vaadin version, discard cache
+ scssCacheFile.delete();
+ return null;
+ }
+
+ return new ScssCacheEntry(entryJson);
+ }
+
private ScssCacheEntry compileScssOnTheFly(String filename,
String scssFilename, ServletContext sc) throws IOException {
String realFilename = sc.getRealPath(scssFilename);
@@ -951,7 +1036,8 @@ public class VaadinServlet extends HttpServlet implements Constants {
return null;
}
- return new ScssCacheEntry(scss.printState(), scss.getSourceUris());
+ return new ScssCacheEntry(realFilename, scss.printState(),
+ scss.getSourceUris());
}
/**
@@ -1196,6 +1282,36 @@ public class VaadinServlet extends HttpServlet implements Constants {
getService().destroy();
}
+ private static void persistCacheEntry(ScssCacheEntry cacheEntry) {
+ String scssFileName = cacheEntry.getScssFileName();
+ if (scssFileName == null) {
+ if (!scssCompileWarWarningEmitted) {
+ getLogger()
+ .warning(
+ "Could not persist scss cache because no real file was found for the compiled scss file. "
+ + "This might happen e.g. if serving the scss file directly from a .war file.");
+ scssCompileWarWarningEmitted = true;
+ }
+ return;
+ }
+
+ File scssFile = new File(scssFileName);
+ File cacheFile = getScssCacheFile(scssFile);
+
+ String cacheEntryJsonString = cacheEntry.asJson();
+
+ try {
+ Files.write(cacheEntryJsonString, cacheFile, Charsets.UTF_8);
+ } catch (IOException e) {
+ getLogger().log(Level.WARNING,
+ "Error persisting scss cache " + cacheFile, e);
+ }
+ }
+
+ private static File getScssCacheFile(File scssFile) {
+ return new File(scssFile.getParentFile(), scssFile.getName() + ".cache");
+ }
+
/**
* Escapes characters to html entities. An exception is made for some
* "safe characters" to keep the text somewhat readable.