Skip to content
This repository was archived by the owner on Jan 9, 2019. It is now read-only.

Add the ability to specify the input encoding for the LessCompiler. #29

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 38 additions & 12 deletions src/main/java/org/lesscss/LessCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.io.Charsets;
import org.apache.commons.io.FileUtils;
import org.lesscss.logging.LessLogger;
import org.lesscss.logging.LessLoggerFactory;
Expand Down Expand Up @@ -66,7 +68,8 @@ public class LessCompiler {
private URL lessJs = LessCompiler.class.getClassLoader().getResource("META-INF/less.js");
private List<URL> customJs = Collections.emptyList();
private boolean compress = false;
private String encoding = null;
private String outputEncoding = null;
private String inputEncoding = null;

private Function doIt;

Expand Down Expand Up @@ -113,7 +116,7 @@ public URL getLessJs() {
* Sets the LESS JavaScript file used by the compiler.
* Must be set before {@link #init()} is called.
*
* @param The LESS JavaScript file used by the compiler.
* @param lessJs The LESS JavaScript file used by the compiler.
*/
public synchronized void setLessJs(URL lessJs) {
if (scope != null) {
Expand Down Expand Up @@ -181,26 +184,49 @@ public synchronized void setCompress(boolean compress) {
}

/**
* Returns the character encoding used by the compiler when writing the output <code>File</code>.
* Returns the character outputEncoding used by the compiler when writing the output <code>File</code>.
*
* @return The character encoding used by the compiler when writing the output <code>File</code>.
* @return The character outputEncoding used by the compiler when writing the output <code>File</code>.
*/
public String getEncoding() {
return encoding;
public String getOutputEncoding() {
return outputEncoding;
}

/**
* Sets the character encoding used by the compiler when writing the output <code>File</code>.
* If not set the platform default will be used.
* Must be set before {@link #init()} is called.
*
* @param The character encoding used by the compiler when writing the output <code>File</code>.
* @param outputEncoding The character encoding used by the compiler when writing the output <code>File</code>.
*/
public synchronized void setOutputEncoding(String outputEncoding) {
if (scope != null) {
throw new IllegalStateException("This method can only be called before init()");
}
this.outputEncoding = outputEncoding;
}

/**
* Returns the character encoding used by the compiler when reading the input <code>File</code>.
*
* @return The character encoding used by the compiler when reading the input <code>File</code>.
*/
public String getInputEncoding() {
return inputEncoding;
}

/**
* Sets the character encoding used by the compiler when reading the input <code>File</code>.
* If not set the platform default will be used.
* Must be set before {@link #init()} is called.
*
* @param inputEncoding The character encoding used by the compiler when reading the input <code>File</code>.
*/
public synchronized void setEncoding(String encoding) {
public synchronized void setInputEncoding(String inputEncoding) {
if (scope != null) {
throw new IllegalStateException("This method can only be called before init()");
}
this.encoding = encoding;
this.inputEncoding = inputEncoding;
}

/**
Expand Down Expand Up @@ -298,7 +324,7 @@ public String compile(String input) throws LessException {
* @throws IOException If the LESS file cannot be read.
*/
public String compile(File input) throws IOException, LessException {
LessSource lessSource = new LessSource(input);
LessSource lessSource = new LessSource(input, Charsets.toCharset(inputEncoding));
return compile(lessSource);
}

Expand All @@ -322,7 +348,7 @@ public void compile(File input, File output) throws IOException, LessException {
* @throws IOException If the LESS file cannot be read or the output file cannot be written.
*/
public void compile(File input, File output, boolean force) throws IOException, LessException {
LessSource lessSource = new LessSource(input);
LessSource lessSource = new LessSource(input, Charsets.toCharset(inputEncoding));
compile(lessSource, output, force);
}

Expand Down Expand Up @@ -358,7 +384,7 @@ public void compile(LessSource input, File output) throws IOException, LessExcep
public void compile(LessSource input, File output, boolean force) throws IOException, LessException {
if (force || !output.exists() || output.lastModified() < input.getLastModifiedIncludingImports()) {
String data = compile(input);
FileUtils.writeStringToFile(output, data, encoding);
FileUtils.writeStringToFile(output, data, outputEncoding);
}
}
}
7 changes: 6 additions & 1 deletion src/main/java/org/lesscss/LessSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class LessSource {
private String content;
private String normalizedContent;
private Map<String, LessSource> imports = new LinkedHashMap<String, LessSource>();
private Charset inputCharset;

/**
* Constructs a new <code>LessSource</code>.
Expand Down Expand Up @@ -76,10 +77,14 @@ public LessSource(File file, Charset charset) throws IOException {
if (file == null) {
throw new IllegalArgumentException("File must not be null.");
}
if(charset == null) {
throw new IllegalArgumentException("Charset must not be null");
}
if (!file.exists()) {
throw new FileNotFoundException("File " + file.getAbsolutePath() + " not found.");
}
this.file = file;
this.inputCharset = charset;
this.content = this.normalizedContent = FileUtils.readFileToString(file, charset);
resolveImports();
}
Expand Down Expand Up @@ -163,7 +168,7 @@ private void resolveImports() throws FileNotFoundException, IOException {
importedFile = importedFile.matches(".*\\.(le?|c)ss$") ? importedFile : importedFile + ".less";
boolean css = importedFile.matches(".*css$");
if (!css) {
LessSource importedLessSource = new LessSource(new File(file.getParentFile(), importedFile));
LessSource importedLessSource = new LessSource(new File(file.getParentFile(), importedFile), inputCharset);
imports.put(importedFile, importedLessSource);
normalizedContent = normalizedContent.substring(0, importMatcher.start()) + importedLessSource.getNormalizedContent() + normalizedContent.substring(importMatcher.end());
importMatcher = IMPORT_PATTERN.matcher(normalizedContent);
Expand Down
56 changes: 27 additions & 29 deletions src/test/java/org/lesscss/LessCompilerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.commons.io.Charsets;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.junit.Before;
Expand All @@ -48,10 +50,6 @@
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import org.lesscss.LessCompiler;
import org.lesscss.LessException;
import org.lesscss.LessSource;

@PrepareForTest({Context.class, FileUtils.class, LessCompiler.class})
@RunWith(PowerMockRunner.class)
public class LessCompilerTest {
Expand Down Expand Up @@ -275,14 +273,14 @@ public void testCompileFileToString() throws Exception {
FieldUtils.writeField(lessCompiler, "scope", scope, true);
FieldUtils.writeField(lessCompiler, "doIt", doIt, true);

whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);
whenNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String) null)).thenReturn(lessSource);
when(lessSource.getNormalizedContent()).thenReturn(less);

when(doIt.call(cx, scope, null, new Object[]{less, false})).thenReturn(css);

assertEquals(css, lessCompiler.compile(inputFile));

verifyNew(LessSource.class).withArguments(inputFile);
verifyNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null));
verify(lessSource).getNormalizedContent();

verify(doIt).call(cx, scope, null, new Object[]{less, false});
Expand All @@ -294,17 +292,17 @@ public void testCompileFileToFile() throws Exception {
when(Context.enter()).thenReturn(cx);
FieldUtils.writeField(lessCompiler, "scope", scope, true);
FieldUtils.writeField(lessCompiler, "doIt", doIt, true);
whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);

whenNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null)).thenReturn(lessSource);
when(lessSource.getNormalizedContent()).thenReturn(less);

when(doIt.call(cx, scope, null, new Object[]{less, false})).thenReturn(css);

mockStatic(FileUtils.class);

lessCompiler.compile(inputFile, outputFile);
verifyNew(LessSource.class).withArguments(inputFile);

verifyNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null));
verify(lessSource).getNormalizedContent();

verify(doIt).call(cx, scope, null, new Object[]{less, false});
Expand All @@ -319,17 +317,17 @@ public void testCompileFileToFileWithForceTrue() throws Exception {
when(Context.enter()).thenReturn(cx);
FieldUtils.writeField(lessCompiler, "scope", scope, true);
FieldUtils.writeField(lessCompiler, "doIt", doIt, true);
whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);

whenNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null)).thenReturn(lessSource);
when(lessSource.getNormalizedContent()).thenReturn(less);

when(doIt.call(cx, scope, null, new Object[]{less, false})).thenReturn(css);

mockStatic(FileUtils.class);

lessCompiler.compile(inputFile, outputFile, true);
verifyNew(LessSource.class).withArguments(inputFile);

verifyNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null));
verify(lessSource).getNormalizedContent();

verify(doIt).call(cx, scope, null, new Object[]{less, false});
Expand All @@ -346,17 +344,17 @@ public void testCompileFileToFileWithForceFalseAndOutputNotExists() throws Excep
FieldUtils.writeField(lessCompiler, "doIt", doIt, true);

when(outputFile.exists()).thenReturn(false);
whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);

whenNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null)).thenReturn(lessSource);
when(lessSource.getNormalizedContent()).thenReturn(less);

when(doIt.call(cx, scope, null, new Object[]{less, false})).thenReturn(css);

mockStatic(FileUtils.class);

lessCompiler.compile(inputFile, outputFile, false);
verifyNew(LessSource.class).withArguments(inputFile);

verifyNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null));

verify(outputFile).exists();

Expand All @@ -374,8 +372,8 @@ public void testCompileFileToFileWithForceFalseAndOutputExistsAndLessSourceModif
when(Context.enter()).thenReturn(cx);
FieldUtils.writeField(lessCompiler, "scope", scope, true);
FieldUtils.writeField(lessCompiler, "doIt", doIt, true);
whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);

whenNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null)).thenReturn(lessSource);

when(outputFile.exists()).thenReturn(true);
when(outputFile.lastModified()).thenReturn(1l);
Expand All @@ -388,8 +386,8 @@ public void testCompileFileToFileWithForceFalseAndOutputExistsAndLessSourceModif
mockStatic(FileUtils.class);

lessCompiler.compile(inputFile, outputFile, false);
verifyNew(LessSource.class).withArguments(inputFile);

verifyNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null));

verify(outputFile).exists();
verify(outputFile).lastModified();
Expand All @@ -409,17 +407,17 @@ public void testCompileFileToFileWithForceFalseAndOutputExistsAndLessSourceNotMo
when(Context.enter()).thenReturn(cx);
FieldUtils.writeField(lessCompiler, "scope", scope, true);
FieldUtils.writeField(lessCompiler, "doIt", doIt, true);
whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);

whenNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null)).thenReturn(lessSource);

when(outputFile.exists()).thenReturn(true);
when(outputFile.lastModified()).thenReturn(2l);

when(lessSource.getLastModifiedIncludingImports()).thenReturn(1l);

lessCompiler.compile(inputFile, outputFile, false);
verifyNew(LessSource.class).withArguments(inputFile);

verifyNew(LessSource.class).withArguments(inputFile, Charsets.toCharset((String)null));

verify(outputFile).exists();
verify(outputFile).lastModified();
Expand Down Expand Up @@ -601,11 +599,11 @@ public void testCompress() throws Exception {
public void testEncoding() throws Exception {
mockStatic(Context.class);
when(Context.enter()).thenReturn(cx);
lessCompiler.setEncoding("utf-8");
lessCompiler.setOutputEncoding("utf-8");
FieldUtils.writeField(lessCompiler, "scope", scope, true);
FieldUtils.writeField(lessCompiler, "doIt", doIt, true);

whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);
whenNew(LessSource.class).withArguments(inputFile, Charsets.toCharset(lessCompiler.getInputEncoding())).thenReturn(lessSource);
when(lessSource.getNormalizedContent()).thenReturn(less);

when(doIt.call(cx, scope, null, new Object[]{less, false})).thenReturn(css);
Expand All @@ -614,7 +612,7 @@ public void testEncoding() throws Exception {

lessCompiler.compile(inputFile, outputFile);

verifyNew(LessSource.class).withArguments(inputFile);
verifyNew(LessSource.class).withArguments(inputFile, Charsets.toCharset(lessCompiler.getInputEncoding()));
verify(lessSource).getNormalizedContent();

verify(doIt).call(cx, scope, null, new Object[]{less, false});
Expand Down
5 changes: 3 additions & 2 deletions src/test/java/org/lesscss/LessSourceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
package org.lesscss;

import org.apache.commons.io.Charsets;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.junit.Before;
Expand Down Expand Up @@ -75,7 +76,7 @@ public void testNewLessSourceWithoutImports() throws Exception {
assertEquals(0, lessSource.getImports().size());

verifyStatic();
FileUtils.readFileToString(file);
FileUtils.readFileToString(file, Charset.defaultCharset());
}

@Test(expected = IllegalArgumentException.class)
Expand Down Expand Up @@ -140,7 +141,7 @@ private String readLessSourceWithEncoding(String encoding) throws IOException, I
private File mockFile(boolean fileExists, String content, String absolutePath) throws IOException {
when(file.exists()).thenReturn(fileExists);
mockStatic(FileUtils.class);
when(FileUtils.readFileToString(file)).thenReturn(content);
when(FileUtils.readFileToString(file, Charset.defaultCharset())).thenReturn(content);
when(file.getAbsolutePath()).thenReturn(absolutePath);
when(file.lastModified()).thenReturn(lastModified);
when(file.getParent()).thenReturn("folder");
Expand Down