From 0cd60f6227fdaec97e018b9aa76ad83f98d24be9 Mon Sep 17 00:00:00 2001 From: Gr1ver Date: Wed, 25 Feb 2015 11:21:17 +0300 Subject: [PATCH 1/9] added support for importing absolute paths --- src/main/java/org/lesscss/LessSource.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/lesscss/LessSource.java b/src/main/java/org/lesscss/LessSource.java index 30b6f98..d40efbd 100644 --- a/src/main/java/org/lesscss/LessSource.java +++ b/src/main/java/org/lesscss/LessSource.java @@ -14,6 +14,8 @@ */ package org.lesscss; +import static java.util.regex.Pattern.MULTILINE; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -23,7 +25,6 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static java.util.regex.Pattern.MULTILINE; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.BOMInputStream; @@ -217,7 +218,9 @@ private Resource getImportedResource(String importedResource) throws IOException if( importedResource.startsWith("http:") || importedResource.startsWith("https:") ) { return new HttpResource(importedResource); } else { - return resource.createRelative(importedResource); + File importedFile = new File(importedResource); + return importedFile.isAbsolute() ? new FileResource(importedFile) : + resource.createRelative(importedFile.getPath()); } } catch (URISyntaxException e) { throw (IOException)new IOException( importedResource ).initCause(e); @@ -229,13 +232,13 @@ private String includeImportedContent(LessSource importedLessSource, Matcher imp builder.append(normalizedContent.substring(0, importMatcher.start(1))); String mediaQuery = importMatcher.group(8); - if( mediaQuery != null && mediaQuery.length() > 0) { + if( (mediaQuery != null) && (mediaQuery.length() > 0)) { builder.append("@media"); builder.append( mediaQuery ); builder.append("{\n"); } builder.append(importedLessSource.getNormalizedContent()); - if( mediaQuery != null && mediaQuery.length() > 0 ) { + if( (mediaQuery != null) && (mediaQuery.length() > 0) ) { builder.append("}\n"); } builder.append(normalizedContent.substring(importMatcher.end(1))); From b45fbd2f81c16a6d3c491df75acebba93f5d39c4 Mon Sep 17 00:00:00 2001 From: Gr1ver Date: Wed, 25 Feb 2015 11:22:24 +0300 Subject: [PATCH 2/9] fix for workspaces which path contains whitespaces --- src/test/java/org/lesscss/LessSourceTest.java | 74 ++++++++++--------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src/test/java/org/lesscss/LessSourceTest.java b/src/test/java/org/lesscss/LessSourceTest.java index 8d18a4d..a1a441d 100644 --- a/src/test/java/org/lesscss/LessSourceTest.java +++ b/src/test/java/org/lesscss/LessSourceTest.java @@ -14,33 +14,35 @@ */ package org.lesscss; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.reflect.FieldUtils; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.AdditionalMatchers; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.matchers.JUnitMatchers.containsString; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.verifyStatic; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; import java.util.LinkedHashMap; import java.util.Map; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.matchers.JUnitMatchers.containsString; -import static org.powermock.api.mockito.PowerMockito.*; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; @PrepareForTest({FileUtils.class, IOUtils.class, LessSource.class, FileResource.class}) @RunWith(PowerMockRunner.class) @@ -55,11 +57,11 @@ public class LessSourceTest { @Mock private LessSource import1; @Mock private LessSource import2; @Mock private LessSource import3; - + private Map imports; private long lastModified = 1l; - + @Before public void setUp() throws Exception { imports = new LinkedHashMap(); @@ -67,24 +69,24 @@ public void setUp() throws Exception { imports.put("import2", import2); imports.put("import3", import3); - URL sourceUrl = getClass().getResource("/compatibility/a_source.less"); - sourceFile = new File(sourceUrl.getFile()); + URL sourceUrl = getClass().getResource("/compatibility/a_source.less"); + sourceFile = new File(sourceUrl.toURI().getSchemeSpecificPart()); } - + @Test public void testNewLessSourceWithoutImports() throws Exception { - + FileResource fileResource = new FileResource(sourceFile); lessSource = new LessSource(fileResource); - + assertEquals(sourceFile.getAbsolutePath(), lessSource.getAbsolutePath()); assertEquals("content", lessSource.getContent()); assertEquals("content", lessSource.getNormalizedContent()); assertEquals(sourceFile.lastModified(), lessSource.getLastModified()); assertEquals(sourceFile.lastModified(), lessSource.getLastModifiedIncludingImports()); assertEquals(0, lessSource.getImports().size()); - + verifyStatic(); FileUtils.readFileToString(sourceFile); } @@ -93,38 +95,38 @@ public void testNewLessSourceWithoutImports() throws Exception { public void testNewLessSourceFileNull() throws Exception { lessSource = new LessSource((Resource)null); } - + @Test(expected = IOException.class) public void testNewLessSourceFileNotFound() throws Exception { when(file.exists()).thenReturn(false); lessSource = new LessSource(new FileResource(file)); } - + @Test public void testLastModifiedIncludingImportsWhenNoImportModifiedLater() throws Exception { mockFile(true,"content","absolutePath"); - + when(import1.getLastModifiedIncludingImports()).thenReturn(0l); when(import2.getLastModifiedIncludingImports()).thenReturn(0l); when(import3.getLastModifiedIncludingImports()).thenReturn(0l); - + lessSource = new LessSource(new FileResource(file)); FieldUtils.writeField(lessSource, "imports", imports, true); - + assertEquals(1l, lessSource.getLastModifiedIncludingImports()); } - + @Test public void testLastModifiedIncludingImportsWhenImportModifiedLater() throws Exception { mockFile(true,"content","absolutePath"); - + when(import1.getLastModifiedIncludingImports()).thenReturn(0l); when(import2.getLastModifiedIncludingImports()).thenReturn(2l); when(import3.getLastModifiedIncludingImports()).thenReturn(0l); - + lessSource = new LessSource(new FileResource(file)); FieldUtils.writeField(lessSource, "imports", imports, true); - + assertEquals(2l, lessSource.getLastModifiedIncludingImports()); } @@ -140,9 +142,9 @@ public void testWithBadEncodingLessFile() throws Exception { assertThat(content, not(containsString("↓"))); } - private String readLessSourceWithEncoding(String encoding) throws IOException, IllegalAccessException { + private String readLessSourceWithEncoding(String encoding) throws IOException, IllegalAccessException, URISyntaxException { URL sourceUrl = getClass().getResource("/compatibility/utf8-content.less"); - File sourceFile = new File(sourceUrl.getFile()); + File sourceFile = new File(sourceUrl.toURI().getSchemeSpecificPart()); LessSource lessSource = new LessSource(new FileResource(sourceFile), Charset.forName(encoding)); return (String) FieldUtils.readField(lessSource, "content", true); } From 9bfe27279cb0606f64ee558e524fc38dd2f93c01 Mon Sep 17 00:00:00 2001 From: Gr1ver Date: Wed, 25 Feb 2015 11:45:19 +0300 Subject: [PATCH 3/9] Added expression evaluator interface and call it before import. Rise plugin version --- pom.xml | 2 +- .../java/org/lesscss/ExpressionEvaluator.java | 8 ++ src/main/java/org/lesscss/LessSource.java | 93 ++++++++++++++++--- 3 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 src/main/java/org/lesscss/ExpressionEvaluator.java diff --git a/pom.xml b/pom.xml index 70324cf..0fb30b2 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.lesscss lesscss - 1.7.0.1.2-SNAPSHOT + 1.8.0.1.2-SNAPSHOT jar Official LESS CSS Compiler for Java Official LESS CSS Compiler for Java diff --git a/src/main/java/org/lesscss/ExpressionEvaluator.java b/src/main/java/org/lesscss/ExpressionEvaluator.java new file mode 100644 index 0000000..dc994f9 --- /dev/null +++ b/src/main/java/org/lesscss/ExpressionEvaluator.java @@ -0,0 +1,8 @@ +package org.lesscss; + +/** + * @author gr1ver + */ +public interface ExpressionEvaluator { + public String evaluate(String string); +} diff --git a/src/main/java/org/lesscss/LessSource.java b/src/main/java/org/lesscss/LessSource.java index d40efbd..8d04548 100644 --- a/src/main/java/org/lesscss/LessSource.java +++ b/src/main/java/org/lesscss/LessSource.java @@ -48,8 +48,37 @@ public class LessSource { private Resource resource; private String content; private String normalizedContent; + private ExpressionEvaluator expressionEvaluator; private Map imports = new LinkedHashMap(); + /** + * Simple helper method to handle simple files. This delegates + * to @see #LessSource(Resource) . + *

+ * Expression evaluator is null. + *

+ * + * @param input a File to use as input. + * + * @throws IOException + */ + public LessSource(File input) throws IOException { + this( new FileResource(input) ); + } + + /** + * Simple helper method to handle simple files. This delegates + * to @see #LessSource(Resource) . + * + * @param input a File to use as input. + * @param expressionEvaluator used to evaluate expressions in imports + * + * @throws IOException + */ + public LessSource(File input, ExpressionEvaluator expressionEvaluator) throws IOException { + this(new FileResource(input), expressionEvaluator); + } + /** * Constructs a new LessSource. *

@@ -58,6 +87,9 @@ public class LessSource { *

* The resource is read using the default Charset of the platform *

+ *

+ * Expression evaluator is null. + *

* * @param resource The File reference to the LESS source to read. * @throws FileNotFoundException If the LESS source (or one of its imports) could not be found. @@ -67,11 +99,32 @@ public LessSource(Resource resource) throws IOException { this(resource, Charset.defaultCharset()); } + /** + * Constructs a new LessSource. + *

+ * This will read the metadata and content of the LESS source, and will automatically resolve the imports. + *

+ *

+ * The resource is read using the default Charset of the platform + *

+ * + * @param resource The File reference to the LESS source to read. + * @param expressionEvaluator used to evaluate expressions in imports + * @throws FileNotFoundException If the LESS source (or one of its imports) could not be found. + * @throws IOException If the LESS source cannot be read. + */ + public LessSource(Resource resource, ExpressionEvaluator expressionEvaluator) throws IOException { + this(resource, Charset.defaultCharset(), expressionEvaluator); + } + /** * Constructs a new LessSource. *

* This will read the metadata and content of the LESS resource, and will automatically resolve the imports. *

+ *

+ * Expression evaluator is null. + *

* * @param resource The File reference to the LESS resource to read. * @param charset charset used to read the less resource. @@ -79,6 +132,22 @@ public LessSource(Resource resource) throws IOException { * @throws IOException If the LESS resource cannot be read. */ public LessSource(Resource resource, Charset charset) throws IOException { + this(resource, charset, null); + } + + /** + * Constructs a new LessSource. + *

+ * This will read the metadata and content of the LESS resource, and will automatically resolve the imports. + *

+ * + * @param resource The File reference to the LESS resource to read. + * @param charset charset used to read the less resource. + * @param expressionEvaluator used to evaluate expressions in imports + * @throws FileNotFoundException If the LESS resource (or one of its imports) could not be found. + * @throws IOException If the LESS resource cannot be read. + */ + public LessSource(Resource resource, Charset charset, ExpressionEvaluator expressionEvaluator) throws IOException { if (resource == null) { throw new IllegalArgumentException("Resource must not be null."); } @@ -86,22 +155,11 @@ public LessSource(Resource resource, Charset charset) throws IOException { throw new IOException("Resource " + resource + " not found."); } this.resource = resource; + this.expressionEvaluator = expressionEvaluator; this.content = this.normalizedContent = loadResource(resource, charset); resolveImports(); } - /** - * Simple helper method to handle simple files. This delegates - * to @see #LessSource(Resource) . - * - * @param input a File to use as input. - * - * @throws IOException - */ - public LessSource(File input) throws IOException { - this( new FileResource(input) ); - } - private String loadResource(Resource resource, Charset charset) throws IOException { BOMInputStream inputStream = new BOMInputStream( resource.getInputStream() ); try { @@ -200,7 +258,7 @@ private void resolveImports() throws IOException { logger.debug("Importing %s", importedResource); if( !imports.containsKey(importedResource) ) { - LessSource importedLessSource = new LessSource(getImportedResource(importedResource)); + LessSource importedLessSource = new LessSource(getImportedResource(evaluateExpressions(importedResource))); imports.put(importedResource, importedLessSource); normalizedContent = includeImportedContent(importedLessSource, importMatcher); @@ -245,6 +303,15 @@ private String includeImportedContent(LessSource importedLessSource, Matcher imp return builder.toString(); } + /** + * Performs call to evaluator if it is specified + * @param str + * @return evaluated string if evaluator is specified, original string otherwise + */ + private String evaluateExpressions(String str) { + return expressionEvaluator == null ? str : expressionEvaluator.evaluate(str); + } + public String getName() { return resource.getName(); } From 225637c24bf5cf1b627862be580cf94608261d61 Mon Sep 17 00:00:00 2001 From: Gr1ver Date: Wed, 25 Feb 2015 14:19:00 +0300 Subject: [PATCH 4/9] rise version --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 0fb30b2..2c2d619 100644 --- a/pom.xml +++ b/pom.xml @@ -244,13 +244,13 @@ GitHub - http://github.com/marceloverdijk/lesscss-java/issues + https://github.com/Gr1ver/lesscss-java/issues - scm:git:git@github.com:marceloverdijk/lesscss-java.git - scm:git:git@github.com:marceloverdijk/lesscss-java.git - http://github.com/marceloverdijk/lesscss-java + scm:git:git@github.com:Gr1ver/lesscss-java.git + scm:git:git@github.com:Gr1ver/lesscss-java.git + https://github.com/Gr1ver/lesscss-java From 0dedb2e3b4f17728cc27aa958d823daee4c835ef Mon Sep 17 00:00:00 2001 From: Gr1ver Date: Wed, 25 Feb 2015 15:15:17 +0300 Subject: [PATCH 5/9] expression evaluator --- src/main/java/org/lesscss/LessSource.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/lesscss/LessSource.java b/src/main/java/org/lesscss/LessSource.java index 8d04548..9daa265 100644 --- a/src/main/java/org/lesscss/LessSource.java +++ b/src/main/java/org/lesscss/LessSource.java @@ -154,6 +154,9 @@ public LessSource(Resource resource, Charset charset, ExpressionEvaluator expres if (!resource.exists()) { throw new IOException("Resource " + resource + " not found."); } + if(expressionEvaluator == null) { + logger.debug("Evaluator is Null"); + } this.resource = resource; this.expressionEvaluator = expressionEvaluator; this.content = this.normalizedContent = loadResource(resource, charset); @@ -251,14 +254,14 @@ public Map getImports() { private void resolveImports() throws IOException { Matcher importMatcher = IMPORT_PATTERN.matcher(normalizedContent); while (importMatcher.find()) { - String importedResource = importMatcher.group(5); + String importedResource = evaluateExpressions(importMatcher.group(5)); importedResource = importedResource.matches(".*\\.(le?|c)ss$") ? importedResource : importedResource + ".less"; String importType = importMatcher.group(3)==null ? importedResource.substring(importedResource.lastIndexOf(".") + 1) : importMatcher.group(3); if (importType.equals("less")) { logger.debug("Importing %s", importedResource); if( !imports.containsKey(importedResource) ) { - LessSource importedLessSource = new LessSource(getImportedResource(evaluateExpressions(importedResource))); + LessSource importedLessSource = new LessSource(getImportedResource(importedResource)); imports.put(importedResource, importedLessSource); normalizedContent = includeImportedContent(importedLessSource, importMatcher); @@ -309,7 +312,14 @@ private String includeImportedContent(LessSource importedLessSource, Matcher imp * @return evaluated string if evaluator is specified, original string otherwise */ private String evaluateExpressions(String str) { - return expressionEvaluator == null ? str : expressionEvaluator.evaluate(str); + String result; + if(expressionEvaluator == null) { + result = str; + } else { + result = expressionEvaluator.evaluate(str); + logger.debug(String.format("Evaluate string: %s result in: %s", str, result)); + } + return result; } public String getName() { From bb68a5fa3b4ae4b8169e68a898811f2776e9f54d Mon Sep 17 00:00:00 2001 From: Gr1ver Date: Wed, 25 Feb 2015 17:59:07 +0300 Subject: [PATCH 6/9] normalizing path --- src/main/java/org/lesscss/LessSource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/lesscss/LessSource.java b/src/main/java/org/lesscss/LessSource.java index 9daa265..a5ddbb7 100644 --- a/src/main/java/org/lesscss/LessSource.java +++ b/src/main/java/org/lesscss/LessSource.java @@ -26,6 +26,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.BOMInputStream; import org.lesscss.logging.LessLogger; @@ -254,7 +255,7 @@ public Map getImports() { private void resolveImports() throws IOException { Matcher importMatcher = IMPORT_PATTERN.matcher(normalizedContent); while (importMatcher.find()) { - String importedResource = evaluateExpressions(importMatcher.group(5)); + String importedResource = FilenameUtils.normalize(evaluateExpressions(importMatcher.group(5))); importedResource = importedResource.matches(".*\\.(le?|c)ss$") ? importedResource : importedResource + ".less"; String importType = importMatcher.group(3)==null ? importedResource.substring(importedResource.lastIndexOf(".") + 1) : importMatcher.group(3); if (importType.equals("less")) { From 87b578f52f75b2cff02dc1e594463a044f793cef Mon Sep 17 00:00:00 2001 From: Gr1ver Date: Wed, 25 Feb 2015 18:06:32 +0300 Subject: [PATCH 7/9] fix: setting evaluator deeper in imports --- src/main/java/org/lesscss/LessSource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/lesscss/LessSource.java b/src/main/java/org/lesscss/LessSource.java index a5ddbb7..6971d72 100644 --- a/src/main/java/org/lesscss/LessSource.java +++ b/src/main/java/org/lesscss/LessSource.java @@ -262,7 +262,7 @@ private void resolveImports() throws IOException { logger.debug("Importing %s", importedResource); if( !imports.containsKey(importedResource) ) { - LessSource importedLessSource = new LessSource(getImportedResource(importedResource)); + LessSource importedLessSource = new LessSource(getImportedResource(importedResource), expressionEvaluator); imports.put(importedResource, importedLessSource); normalizedContent = includeImportedContent(importedLessSource, importMatcher); From 485c236f5a72ae3ae230424ecec88aac5dfdeae0 Mon Sep 17 00:00:00 2001 From: Gr1ver Date: Wed, 25 Feb 2015 18:44:40 +0300 Subject: [PATCH 8/9] fix: normalizing paths --- src/main/java/org/lesscss/LessSource.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/lesscss/LessSource.java b/src/main/java/org/lesscss/LessSource.java index 6971d72..7e3a140 100644 --- a/src/main/java/org/lesscss/LessSource.java +++ b/src/main/java/org/lesscss/LessSource.java @@ -164,6 +164,10 @@ public LessSource(Resource resource, Charset charset, ExpressionEvaluator expres resolveImports(); } + private static String defaultString(String str1, String defaultStr) { + return str1 == null ? defaultStr : str1; + } + private String loadResource(Resource resource, Charset charset) throws IOException { BOMInputStream inputStream = new BOMInputStream( resource.getInputStream() ); try { @@ -255,7 +259,8 @@ public Map getImports() { private void resolveImports() throws IOException { Matcher importMatcher = IMPORT_PATTERN.matcher(normalizedContent); while (importMatcher.find()) { - String importedResource = FilenameUtils.normalize(evaluateExpressions(importMatcher.group(5))); + String importedResource = normalizePath(evaluateExpressions(importMatcher.group(5))); + importedResource = importedResource.matches(".*\\.(le?|c)ss$") ? importedResource : importedResource + ".less"; String importType = importMatcher.group(3)==null ? importedResource.substring(importedResource.lastIndexOf(".") + 1) : importMatcher.group(3); if (importType.equals("less")) { @@ -275,6 +280,10 @@ private void resolveImports() throws IOException { } } + private String normalizePath(String path) { + return path == null ? null : defaultString(FilenameUtils.normalize(path), path); + } + private Resource getImportedResource(String importedResource) throws IOException { try { if( importedResource.startsWith("http:") || importedResource.startsWith("https:") ) { From b622fed0b3b01afbe3fbf3837bde7b5b05326fa3 Mon Sep 17 00:00:00 2001 From: Gr1ver Date: Wed, 25 Feb 2015 18:50:11 +0300 Subject: [PATCH 9/9] fix urls --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2c2d619..066bc72 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ jar Official LESS CSS Compiler for Java Official LESS CSS Compiler for Java - http://github.com/marceloverdijk/lesscss-java + http://github.com/Gr1ver/lesscss-java org.sonatype.oss