From bad3f6a6b5102a3392472b4a3f8c7c833d94c9e3 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 2 Sep 2013 23:49:10 +0300 Subject: [PATCH] Refactor how base paths are determined when resolving (#11776) Change-Id: Ibf07046280d5f61df21681310ec28993b6daf50f --- .../internal/resolver/AbstractResolver.java | 83 ++++++++++++++++--- .../resolver/ClassloaderResolver.java | 16 +--- .../internal/resolver/FilesystemResolver.java | 42 +++++++--- 3 files changed, 106 insertions(+), 35 deletions(-) diff --git a/theme-compiler/src/com/vaadin/sass/internal/resolver/AbstractResolver.java b/theme-compiler/src/com/vaadin/sass/internal/resolver/AbstractResolver.java index ac11f1fa0e..f0464d098b 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/resolver/AbstractResolver.java +++ b/theme-compiler/src/com/vaadin/sass/internal/resolver/AbstractResolver.java @@ -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 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 getPotentialParentPaths( + ScssStylesheet parentStylesheet, String identifier) { + List potentialParents = new ArrayList(); + 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; + } } /** diff --git a/theme-compiler/src/com/vaadin/sass/internal/resolver/ClassloaderResolver.java b/theme-compiler/src/com/vaadin/sass/internal/resolver/ClassloaderResolver.java index 68752b459a..755073bc4c 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/resolver/ClassloaderResolver.java +++ b/theme-compiler/src/com/vaadin/sass/internal/resolver/ClassloaderResolver.java @@ -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) { diff --git a/theme-compiler/src/com/vaadin/sass/internal/resolver/FilesystemResolver.java b/theme-compiler/src/com/vaadin/sass/internal/resolver/FilesystemResolver.java index 3fec33ae13..786d0875da 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/resolver/FilesystemResolver.java +++ b/theme-compiler/src/com/vaadin/sass/internal/resolver/FilesystemResolver.java @@ -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 getPotentialParentPaths( + ScssStylesheet parentStyleSheet, String identifier) { + List 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 { -- 2.39.5