diff options
author | Marc Englund <marc@vaadin.com> | 2012-08-29 16:11:57 +0300 |
---|---|---|
committer | Marc Englund <marc@vaadin.com> | 2012-08-29 16:12:09 +0300 |
commit | cac34cbc8f8ca82c44525985b4b422d89388ca79 (patch) | |
tree | b379983549b73be39ce91643888313f632704201 | |
parent | a2ac034dc7b4af1dc4efc582de504df2b90c70ff (diff) | |
download | vaadin-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.java | 6 | ||||
-rw-r--r-- | sass/src/com/vaadin/sass/ScssServlet.java | 2 | ||||
-rw-r--r-- | sass/src/com/vaadin/sass/ScssStylesheet.java | 50 | ||||
-rw-r--r-- | sass/src/com/vaadin/sass/resolver/ClassloaderResolver.java | 39 | ||||
-rw-r--r-- | sass/src/com/vaadin/sass/resolver/FilesystemResolver.java | 40 | ||||
-rw-r--r-- | sass/src/com/vaadin/sass/resolver/ScssStylesheetResolver.java | 20 | ||||
-rw-r--r-- | sass/src/com/vaadin/sass/resolver/VaadinResolver.java | 46 | ||||
-rw-r--r-- | sass/src/com/vaadin/sass/visitor/ImportVisitor.java | 30 | ||||
-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.java | 2 |
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; } |