aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Englund <marc@vaadin.com>2012-08-29 16:11:57 +0300
committerMarc Englund <marc@vaadin.com>2012-08-29 16:12:09 +0300
commitcac34cbc8f8ca82c44525985b4b422d89388ca79 (patch)
treeb379983549b73be39ce91643888313f632704201
parenta2ac034dc7b4af1dc4efc582de504df2b90c70ff (diff)
downloadvaadin-framework-cac34cbc8f8ca82c44525985b4b422d89388ca79.tar.gz
vaadin-framework-cac34cbc8f8ca82c44525985b4b422d89388ca79.zip
Adds support for StylesheetResolvers, and implements such that look trought the classpath and in special Vaadin locations, fixes #9346
-rw-r--r--sass/src/com/vaadin/sass/SassCompiler.java6
-rw-r--r--sass/src/com/vaadin/sass/ScssServlet.java2
-rw-r--r--sass/src/com/vaadin/sass/ScssStylesheet.java50
-rw-r--r--sass/src/com/vaadin/sass/resolver/ClassloaderResolver.java39
-rw-r--r--sass/src/com/vaadin/sass/resolver/FilesystemResolver.java40
-rw-r--r--sass/src/com/vaadin/sass/resolver/ScssStylesheetResolver.java20
-rw-r--r--sass/src/com/vaadin/sass/resolver/VaadinResolver.java46
-rw-r--r--sass/src/com/vaadin/sass/visitor/ImportVisitor.java30
-rw-r--r--tests/sass/resources/css/control-directives.css (renamed from tests/sass/resources/css/control-directives.scss)0
-rw-r--r--tests/sass/src/com/vaadin/sass/AbstractTestBase.java2
10 files changed, 216 insertions, 19 deletions
diff --git a/sass/src/com/vaadin/sass/SassCompiler.java b/sass/src/com/vaadin/sass/SassCompiler.java
index 8e4df2a62e..555797066b 100644
--- a/sass/src/com/vaadin/sass/SassCompiler.java
+++ b/sass/src/com/vaadin/sass/SassCompiler.java
@@ -35,8 +35,10 @@ public class SassCompiler {
input = args[0];
output = args[1];
}
- File inputFile = new File(input);
- ScssStylesheet scss = ScssStylesheet.get(inputFile);
+
+ // ScssStylesheet.setStylesheetResolvers(new VaadinResolver());
+
+ ScssStylesheet scss = ScssStylesheet.get(input);
scss.compile();
if (output == null) {
System.out.println(scss.toString());
diff --git a/sass/src/com/vaadin/sass/ScssServlet.java b/sass/src/com/vaadin/sass/ScssServlet.java
index d85237aff2..a345ca1583 100644
--- a/sass/src/com/vaadin/sass/ScssServlet.java
+++ b/sass/src/com/vaadin/sass/ScssServlet.java
@@ -40,7 +40,7 @@ public class ScssServlet extends HttpServlet {
String scssPath = cssPath.replace(".css", ".scss");
File scssFile = new File(scssPath);
if (scssFile.exists()) {
- ScssStylesheet scss = ScssStylesheet.get(new File(cssPath));
+ ScssStylesheet scss = ScssStylesheet.get(cssPath);
try {
scss.compile();
} catch (Exception e) {
diff --git a/sass/src/com/vaadin/sass/ScssStylesheet.java b/sass/src/com/vaadin/sass/ScssStylesheet.java
index b5e744afc4..caef1720b1 100644
--- a/sass/src/com/vaadin/sass/ScssStylesheet.java
+++ b/sass/src/com/vaadin/sass/ScssStylesheet.java
@@ -19,13 +19,17 @@ package com.vaadin.sass;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.w3c.css.sac.CSSException;
+import org.w3c.css.sac.InputSource;
import com.vaadin.sass.handler.SCSSDocumentHandler;
import com.vaadin.sass.handler.SCSSDocumentHandlerImpl;
import com.vaadin.sass.parser.Parser;
+import com.vaadin.sass.resolver.ScssStylesheetResolver;
+import com.vaadin.sass.resolver.VaadinResolver;
import com.vaadin.sass.tree.Node;
import com.vaadin.sass.visitor.BlockVisitor;
import com.vaadin.sass.visitor.ExtendVisitor;
@@ -60,15 +64,49 @@ public class ScssStylesheet extends Node {
* @throws CSSException
* @throws IOException
*/
- public static ScssStylesheet get(File file) throws CSSException,
+ public static ScssStylesheet get(String identifier) throws CSSException,
IOException {
- Parser parser = new Parser();
- SCSSDocumentHandler handler = new SCSSDocumentHandlerImpl();
+ File file = new File(identifier);
file = file.getCanonicalFile();
- handler.getStyleSheet().setFileName(file.getAbsoluteFile().getParent());
+
+ SCSSDocumentHandler handler = new SCSSDocumentHandlerImpl();
+ ScssStylesheet stylesheet = handler.getStyleSheet();
+
+ InputSource source = stylesheet.resolveStylesheet(identifier);
+ if (source == null) {
+ return null;
+ }
+
+ Parser parser = new Parser();
parser.setDocumentHandler(handler);
- parser.parseStyleSheet(file.getAbsolutePath());
- return handler.getStyleSheet();
+ parser.parseStyleSheet(source);
+
+ return stylesheet;
+ }
+
+ private static ScssStylesheetResolver[] resolvers = null;
+
+ public static void setStylesheetResolvers(
+ ScssStylesheetResolver... styleSheetResolvers) {
+ resolvers = Arrays.copyOf(styleSheetResolvers,
+ styleSheetResolvers.length);
+ }
+
+ public InputSource resolveStylesheet(String identifier) {
+ if (resolvers == null) {
+ setStylesheetResolvers(new VaadinResolver());
+ }
+
+ for (ScssStylesheetResolver resolver : resolvers) {
+ InputSource source = resolver.resolve(identifier);
+ if (source != null) {
+ File f = new File(source.getURI());
+ setFileName(f.getParent());
+ return source;
+ }
+ }
+
+ return null;
}
/**
diff --git a/sass/src/com/vaadin/sass/resolver/ClassloaderResolver.java b/sass/src/com/vaadin/sass/resolver/ClassloaderResolver.java
new file mode 100644
index 0000000000..84ac6dc530
--- /dev/null
+++ b/sass/src/com/vaadin/sass/resolver/ClassloaderResolver.java
@@ -0,0 +1,39 @@
+package com.vaadin.sass.resolver;
+
+import java.io.InputStream;
+
+import org.w3c.css.sac.InputSource;
+
+public class ClassloaderResolver implements ScssStylesheetResolver {
+
+ @Override
+ public InputSource resolve(String identifier) {
+ // identifier should not have .scss, fileName should
+ String ext = ".scss";
+ if (identifier.endsWith(".css")) {
+ ext = ".css";
+ }
+ String fileName = identifier;
+ if (identifier.endsWith(ext)) {
+ identifier = identifier.substring(0,
+ identifier.length() - ext.length());
+ } else {
+ fileName = fileName + ext;
+ }
+
+ // Can the classloader find it?
+ InputStream is = getClass().getClassLoader().getResourceAsStream(
+ fileName);
+ if (is != null) {
+ InputSource source = new InputSource();
+ source.setByteStream(is);
+ source.setURI(fileName);
+ return source;
+
+ } else {
+ return null;
+ }
+
+ }
+
+}
diff --git a/sass/src/com/vaadin/sass/resolver/FilesystemResolver.java b/sass/src/com/vaadin/sass/resolver/FilesystemResolver.java
new file mode 100644
index 0000000000..2c6b92430f
--- /dev/null
+++ b/sass/src/com/vaadin/sass/resolver/FilesystemResolver.java
@@ -0,0 +1,40 @@
+package com.vaadin.sass.resolver;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import org.w3c.css.sac.InputSource;
+
+public class FilesystemResolver implements ScssStylesheetResolver {
+
+ @Override
+ public InputSource resolve(String identifier) {
+ // identifier should not have .scss, fileName should
+ String ext = ".scss";
+ if (identifier.endsWith(".css")) {
+ ext = ".css";
+ }
+ String fileName = identifier;
+ if (identifier.endsWith(ext)) {
+ identifier = identifier.substring(0,
+ identifier.length() - ext.length());
+ } else {
+ fileName = fileName + ext;
+ }
+
+ try {
+ InputStream is = new FileInputStream(fileName);
+ InputSource source = new InputSource();
+ source.setByteStream(is);
+ source.setURI(fileName);
+ return source;
+
+ } catch (FileNotFoundException e) {
+ // not found, try something else
+ return null;
+ }
+
+ }
+
+}
diff --git a/sass/src/com/vaadin/sass/resolver/ScssStylesheetResolver.java b/sass/src/com/vaadin/sass/resolver/ScssStylesheetResolver.java
new file mode 100644
index 0000000000..acb17612b3
--- /dev/null
+++ b/sass/src/com/vaadin/sass/resolver/ScssStylesheetResolver.java
@@ -0,0 +1,20 @@
+package com.vaadin.sass.resolver;
+
+import org.w3c.css.sac.InputSource;
+
+public interface ScssStylesheetResolver {
+ /**
+ * Called with the "identifier" of a stylesheet that the resolver should
+ * try to find. The identifier is basically a filename, like "runo.scss"
+ * or "addon/styles.scss", but might exclude ".scss". The resolver must
+ * {@link InputSource#setURI(String)} to the final location where the
+ * stylesheet was found, e.g "runo.scss" might result in a URI like
+ * "VAADIN/themes/runo/runo.scss".
+ *
+ * @param identifier
+ * used fo find stylesheet
+ * @return InputSource for stylesheet (with URI set) or null if not
+ * found
+ */
+ public InputSource resolve(String identifier);
+} \ No newline at end of file
diff --git a/sass/src/com/vaadin/sass/resolver/VaadinResolver.java b/sass/src/com/vaadin/sass/resolver/VaadinResolver.java
new file mode 100644
index 0000000000..93fdf6bfec
--- /dev/null
+++ b/sass/src/com/vaadin/sass/resolver/VaadinResolver.java
@@ -0,0 +1,46 @@
+package com.vaadin.sass.resolver;
+
+import org.w3c.css.sac.InputSource;
+
+public class VaadinResolver implements ScssStylesheetResolver {
+
+ @Override
+ public InputSource resolve(String identifier) {
+ String ext = ".scss";
+ if (identifier.endsWith(".css")) {
+ ext = ".css";
+ }
+
+ // 'normalize' identifier to use in themeFile
+ String fileName = identifier;
+ if (identifier.endsWith(ext)) {
+ identifier = identifier.substring(0,
+ identifier.length() - ext.length());
+ }
+ // also look here
+ String themeFile = "VAADIN/themes/" + identifier + "/" + fileName;
+
+ // first plain file
+ ScssStylesheetResolver resolver = new FilesystemResolver();
+ InputSource source = resolver.resolve(fileName);
+
+ if (source == null) {
+ // then file in theme
+ source = resolver.resolve(themeFile);
+ }
+
+ if (source == null) {
+ // then plain via classloader
+ resolver = new ClassloaderResolver();
+ source = resolver.resolve(identifier);
+
+ }
+ if (source == null) {
+ // then try theme via classloader
+ source = resolver.resolve(themeFile);
+ }
+
+ return source;
+ }
+
+}
diff --git a/sass/src/com/vaadin/sass/visitor/ImportVisitor.java b/sass/src/com/vaadin/sass/visitor/ImportVisitor.java
index 00c0f41073..bda040be39 100644
--- a/sass/src/com/vaadin/sass/visitor/ImportVisitor.java
+++ b/sass/src/com/vaadin/sass/visitor/ImportVisitor.java
@@ -17,6 +17,7 @@
package com.vaadin.sass.visitor;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
@@ -38,16 +39,27 @@ public class ImportVisitor implements Visitor {
if (child instanceof ImportNode) {
ImportNode importNode = (ImportNode) child;
if (!importNode.isPureCssImport()) {
- StringBuilder filePathBuilder = new StringBuilder(
- node.getFileName());
- filePathBuilder.append(File.separatorChar).append(
- importNode.getUri());
- if (!filePathBuilder.toString().endsWith(".scss")) {
- filePathBuilder.append(".scss");
- }
+
try {
- ScssStylesheet imported = ScssStylesheet.get(new File(
- filePathBuilder.toString()));
+
+ StringBuilder filePathBuilder = new StringBuilder(
+ node.getFileName());
+ filePathBuilder.append(File.separatorChar).append(
+ importNode.getUri());
+ if (!filePathBuilder.toString().endsWith(".scss")) {
+ filePathBuilder.append(".scss");
+ }
+
+ ScssStylesheet imported = ScssStylesheet
+ .get(filePathBuilder.toString());
+ if (imported == null) {
+ imported = ScssStylesheet.get(importNode.getUri());
+ }
+ if (imported == null) {
+ throw new FileNotFoundException(importNode.getUri()
+ + " (parent: " + node.getFileName() + ")");
+ }
+
traverse(imported);
String prefix = getUrlPrefix(importNode.getUri());
if (prefix != null) {
diff --git a/tests/sass/resources/css/control-directives.scss b/tests/sass/resources/css/control-directives.css
index 0a6f1f7233..0a6f1f7233 100644
--- a/tests/sass/resources/css/control-directives.scss
+++ b/tests/sass/resources/css/control-directives.css
diff --git a/tests/sass/src/com/vaadin/sass/AbstractTestBase.java b/tests/sass/src/com/vaadin/sass/AbstractTestBase.java
index 3593a6a19c..7647afbf68 100644
--- a/tests/sass/src/com/vaadin/sass/AbstractTestBase.java
+++ b/tests/sass/src/com/vaadin/sass/AbstractTestBase.java
@@ -36,7 +36,7 @@ public abstract class AbstractTestBase {
public ScssStylesheet getStyleSheet(String filename)
throws URISyntaxException, CSSException, IOException {
File file = getFile(filename);
- stylesheet = ScssStylesheet.get(file);
+ stylesheet = ScssStylesheet.get(file.getAbsolutePath());
return stylesheet;
}