]> source.dussan.org Git - vaadin-framework.git/commitdiff
Refactor how base paths are determined when resolving (#11776)
authorArtur Signell <artur@vaadin.com>
Mon, 2 Sep 2013 20:49:10 +0000 (23:49 +0300)
committerVaadin Code Review <review@vaadin.com>
Thu, 26 Sep 2013 06:10:50 +0000 (06:10 +0000)
Change-Id: Ibf07046280d5f61df21681310ec28993b6daf50f

theme-compiler/src/com/vaadin/sass/internal/resolver/AbstractResolver.java
theme-compiler/src/com/vaadin/sass/internal/resolver/ClassloaderResolver.java
theme-compiler/src/com/vaadin/sass/internal/resolver/FilesystemResolver.java

index ac11f1fa0e2d2b855361e5bd3d981b833b47a0de..f0464d098bb79ca774aa580c54d25288edc872b3 100644 (file)
@@ -18,6 +18,8 @@ package com.vaadin.sass.internal.resolver;
 
 import java.io.File;
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Stack;
 
 import org.w3c.css.sac.InputSource;
@@ -44,22 +46,81 @@ public abstract class AbstractResolver implements ScssStylesheetResolver,
     @Override
     public InputSource resolve(ScssStylesheet parentStylesheet,
             String identifier) {
-        InputSource source = null;
-        if (parentStylesheet != null) {
-            StringBuilder filePathBuilder = new StringBuilder(
-                    parentStylesheet.getFileName());
-            filePathBuilder.append(File.separatorChar).append(identifier);
-            if (!filePathBuilder.toString().endsWith(".scss")) {
-                filePathBuilder.append(".scss");
+        // Remove a possible ".scss" suffix
+        identifier = identifier.replaceFirst(".scss$", "");
+
+        List<String> potentialParentPaths = getPotentialParentPaths(
+                parentStylesheet, identifier);
+
+        // remove path from identifier as it has already been added to the
+        // parent path
+        if (identifier.contains("/")) {
+            identifier = identifier.substring(identifier.lastIndexOf("/") + 1);
+        }
+
+        for (String path : potentialParentPaths) {
+            InputSource source = normalizeAndResolve(path + "/" + identifier);
+
+            if (source != null) {
+                return source;
             }
-            source = normalizeAndResolve(filePathBuilder.toString());
+
+        }
+
+        return normalizeAndResolve(identifier);
+    }
+
+    /**
+     * Retrieves the parent paths which should be used while resolving relative
+     * identifiers. By default uses the parent stylesheet location and a
+     * possible absolute path in the identifier.
+     * 
+     * @param parentStylesheet
+     *            The parent stylesheet or null if there is no parent
+     * @param identifier
+     *            The identifier to be resolved
+     * @return a list of paths in which to look for the relative import
+     */
+    protected List<String> getPotentialParentPaths(
+            ScssStylesheet parentStylesheet, String identifier) {
+        List<String> potentialParents = new ArrayList<String>();
+        if (parentStylesheet != null) {
+            potentialParents.add(extractFullPath(
+                    parentStylesheet.getDirectory(), identifier));
         }
 
-        if (source == null) {
-            source = normalizeAndResolve(identifier);
+        // Identifier can be a full path so extract the path part also as a
+        // potential parent
+        if (identifier.contains("/")) {
+            potentialParents.add(extractFullPath("", identifier));
         }
 
-        return source;
+        return potentialParents;
+
+    }
+
+    /**
+     * Extracts the full path from the path combined with the identifier
+     * 
+     * @param path
+     *            The base path
+     * @param identifier
+     *            The identifier which may contain a path part, separated by "/"
+     *            from the real identifier
+     * @return a normalized version of the path where identifier does not
+     *         contain any directory information
+     */
+    protected String extractFullPath(String path, String identifier) {
+        int lastSlashPosition = identifier.lastIndexOf("/");
+        if (lastSlashPosition == -1) {
+            return path;
+        }
+        String identifierPath = identifier.substring(0, lastSlashPosition);
+        if ("".equals(path)) {
+            return identifierPath;
+        } else {
+            return path + "/" + identifierPath;
+        }
     }
 
     /**
index 68752b459afdd4331489fdc77daea8ba3b5d0c18..755073bc4c9228c05cf22f3635c94104b916106b 100644 (file)
@@ -15,7 +15,6 @@
  */
 package com.vaadin.sass.internal.resolver;
 
-import java.io.File;
 import java.io.InputStream;
 
 import org.w3c.css.sac.InputSource;
@@ -24,22 +23,11 @@ public class ClassloaderResolver extends AbstractResolver {
 
     @Override
     public InputSource resolveNormalized(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;
+        if (!fileName.endsWith(".css")) {
+            fileName += ".scss";
         }
 
-        // Ensure only "/" is used, also in Windows
-        fileName = fileName.replace(File.separatorChar, '/');
-
         // Filename should be a relative path starting with VAADIN/...
         int vaadinIdx = fileName.lastIndexOf("VAADIN/");
         if (vaadinIdx > -1) {
index 3fec33ae13f682171180947f216234dadbdcd9ab..786d0875daf9b88c2ac89d16b654e8f68782b2c2 100644 (file)
@@ -18,24 +18,46 @@ package com.vaadin.sass.internal.resolver;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
+import java.util.List;
 
 import org.w3c.css.sac.InputSource;
 
+import com.vaadin.sass.internal.ScssStylesheet;
+
 public class FilesystemResolver extends AbstractResolver {
 
+    private String[] customPaths = null;
+
+    public FilesystemResolver(String... customPaths) {
+        this.customPaths = customPaths;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * com.vaadin.sass.internal.resolver.AbstractResolver#getPotentialPaths(
+     * com.vaadin.sass.internal.ScssStylesheet, java.lang.String)
+     */
     @Override
-    public InputSource resolveNormalized(String identifier) {
-        // identifier should not have .scss, fileName should
-        String ext = ".scss";
-        if (identifier.endsWith(".css")) {
-            ext = ".css";
+    protected List<String> getPotentialParentPaths(
+            ScssStylesheet parentStyleSheet, String identifier) {
+        List<String> potentialPaths = super.getPotentialParentPaths(
+                parentStyleSheet, identifier);
+        if (customPaths != null) {
+            for (String path : customPaths) {
+                potentialPaths.add(extractFullPath(path, identifier));
+            }
         }
+
+        return potentialPaths;
+    }
+
+    @Override
+    public InputSource resolveNormalized(String identifier) {
         String fileName = identifier;
-        if (identifier.endsWith(ext)) {
-            identifier = identifier.substring(0,
-                    identifier.length() - ext.length());
-        } else {
-            fileName = fileName + ext;
+        if (!fileName.endsWith(".css")) {
+            fileName += ".scss";
         }
 
         try {