/*
* Copyright wro4j@2011.
*/
package ro.isdc.wro.extensions.processor.support.less;
import java.io.IOException;
import java.io.InputStream;
import org.mozilla.javascript.ScriptableObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.isdc.wro.WroRuntimeException;
import ro.isdc.wro.extensions.locator.WebjarUriLocator;
import ro.isdc.wro.extensions.script.RhinoScriptBuilder;
import ro.isdc.wro.util.StopWatch;
import ro.isdc.wro.util.WroUtil;
/**
* This class is not thread-safe.<br/>
* The underlying implementation uses the webjar containing less.js library.
*
* @author Alex Objelean
* @since 1.3.0
*/
public class LessCss {
private static final Logger LOG = LoggerFactory.getLogger(LessCss.class);
/**
* The name of the sass script to be used by default.
*/
public static final String DEFAULT_LESS_JS = "less-1.3.3.min.js";
private static final String SCRIPT_INIT = "init.js";
private WebjarUriLocator webjarLocator;
private ScriptableObject scope;
/**
* Initialize script builder for evaluation.
*/
private RhinoScriptBuilder initScriptBuilder() {
try {
RhinoScriptBuilder builder = null;
if (scope == null) {
final InputStream initStream = LessCss.class.getResourceAsStream(SCRIPT_INIT);
builder = RhinoScriptBuilder.newClientSideAwareChain().evaluateChain(initStream, SCRIPT_INIT).evaluateChain(
getScriptAsStream(), DEFAULT_LESS_JS);
scope = builder.getScope();
} else {
builder = RhinoScriptBuilder.newChain(scope);
}
return builder;
} catch (final IOException ex) {
throw new IllegalStateException("Failed reading javascript less.js", ex);
} catch (final Exception e) {
LOG.error("Processing error:" + e.getMessage(), e);
throw new WroRuntimeException("Processing error", e);
}
}
/**
* @return stream of the less.js script.
*/
protected InputStream getScriptAsStream() throws IOException {
return getWebjarLocator().locate(WebjarUriLocator.createUri("less.min.js"));
}
/**
* @return {@link WebjarUriLocator} instance to retrieve webjars.
*/
private WebjarUriLocator getWebjarLocator() {
if (webjarLocator == null) {
webjarLocator = new WebjarUriLocator();
}
return webjarLocator;
}
/**
* @param data css content to process.
* @return processed css content.
*/
public String less(final String data) {
final StopWatch stopWatch = new StopWatch();
stopWatch.start("initContext");
final RhinoScriptBuilder builder = initScriptBuilder();
stopWatch.stop();
stopWatch.start("lessify");
try {
final String execute = "lessIt(" + WroUtil.toJSMultiLineString(data) + ");";
final Object result = builder.evaluate(execute, "lessIt");
return String.valueOf(result);
} finally {
stopWatch.stop();
LOG.debug(stopWatch.prettyPrint());
}
}
}