package pl.matisoft.soy.compile;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.template.soy.SoyFileSet;
import com.google.template.soy.data.SoyMapData;
import com.google.template.soy.jssrc.SoyJsSrcOptions;
import com.google.template.soy.msgs.SoyMsgBundle;
import com.google.template.soy.tofu.SoyTofu;
import com.google.template.soy.tofu.SoyTofuOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pl.matisoft.soy.config.SoyViewConfigDefaults;
import pl.matisoft.soy.global.compile.CompileTimeGlobalModelResolver;
import pl.matisoft.soy.global.compile.EmptyCompileTimeGlobalModelResolver;
import javax.annotation.Nullable;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* Created with IntelliJ IDEA.
* User: mszczap
* Date: 20.06.13
* Time: 17:40
*/
public class DefaultTofuCompiler implements TofuCompiler {
private static final Logger logger = LoggerFactory.getLogger(DefaultTofuCompiler.class);
private boolean hotReloadMode = SoyViewConfigDefaults.DEFAULT_HOT_RELOAD_MODE;
private CompileTimeGlobalModelResolver compileTimeGlobalModelResolver = new EmptyCompileTimeGlobalModelResolver();
private SoyJsSrcOptions soyJsSrcOptions = new SoyJsSrcOptions();
private SoyTofuOptions soyTofuOptions = createSoyTofuOptions();
@Override
public SoyTofu compile(@Nullable final Collection<URL> urls) throws IOException {
Preconditions.checkNotNull("compileTimeGlobalModelResolver", compileTimeGlobalModelResolver);
if (urls == null || urls.isEmpty()) {
throw new IOException("Unable to compile, no urls found");
}
logger.debug("SoyTofu compilation of templates:" + urls.size());
final long time1 = System.currentTimeMillis();
final SoyFileSet.Builder sfsBuilder = new SoyFileSet.Builder();
for (final URL url : urls) {
sfsBuilder.add(url);
}
addCompileTimeGlobalModel(sfsBuilder);
final SoyFileSet soyFileSet = sfsBuilder.build();
final SoyTofuOptions soyTofuOptions = createSoyTofuOptions();
final SoyTofu soyTofu = soyFileSet.compileToTofu(soyTofuOptions);
final long time2 = System.currentTimeMillis();
logger.debug("SoyTofu compilation complete." + (time2 - time1) + " ms");
return soyTofu;
}
private void addCompileTimeGlobalModel(final SoyFileSet.Builder sfsBuilder) {
final Optional<SoyMapData> soyMapData = compileTimeGlobalModelResolver.resolveData();
if (soyMapData.isPresent()) {
final Map<String, ?> mapData = soyMapData.get().asMap();
if (mapData.size() > 0) {
logger.debug("Setting compile time globals, entries number:" + mapData.size());
sfsBuilder.setCompileTimeGlobals(mapData);
}
}
}
private SoyTofuOptions createSoyTofuOptions() {
final SoyTofuOptions soyTofuOptions = new SoyTofuOptions();
soyTofuOptions.setUseCaching(isHotReloadModeOff());
return soyTofuOptions;
}
@Override
public final Optional<String> compileToJsSrc(@Nullable final URL url, @Nullable final SoyMsgBundle soyMsgBundle) {
if (url == null) {
return Optional.absent();
}
final Collection<String> compiledTemplates = compileToJsSrc(Lists.newArrayList(url), soyMsgBundle);
if (compiledTemplates.isEmpty()) {
return Optional.absent();
}
return Optional.fromNullable(compiledTemplates.iterator().next());
}
@Override
public Collection<String> compileToJsSrc(Collection<URL> templates, @Nullable SoyMsgBundle soyMsgBundle) {
Preconditions.checkNotNull("soyJsSrcOptions", soyJsSrcOptions);
logger.debug("SoyJavaScript compilation of template:" + templates);
final long time1 = System.currentTimeMillis();
final SoyFileSet soyFileSet = buildSoyFileSetFrom(templates);
final List<String> ret = soyFileSet.compileToJsSrc(soyJsSrcOptions, soyMsgBundle);
final long time2 = System.currentTimeMillis();
logger.debug("SoyJavaScript compilation complete." + (time2 - time1) + " ms");
return ret;
}
private SoyFileSet buildSoyFileSetFrom(final Collection<URL> urls) {
final SoyFileSet.Builder builder = new SoyFileSet.Builder();
for (final URL url : urls) {
builder.setAllowExternalCalls(true);
builder.add(url);
}
addCompileTimeGlobalModel(builder);
return builder.build();
}
public void setHotReloadMode(final boolean hotReloadMode) {
this.hotReloadMode = hotReloadMode;
}
public void setCompileTimeGlobalModelResolver(final CompileTimeGlobalModelResolver compileTimeGlobalModelResolver) {
this.compileTimeGlobalModelResolver = compileTimeGlobalModelResolver;
}
public void setSoyJsSrcOptions(final SoyJsSrcOptions soyJsSrcOptions) {
this.soyJsSrcOptions = soyJsSrcOptions;
}
public boolean isHotReloadMode() {
return hotReloadMode;
}
public boolean isHotReloadModeOff() {
return !hotReloadMode;
}
public SoyJsSrcOptions getSoyJsSrcOptions() {
return soyJsSrcOptions;
}
public SoyTofuOptions getSoyTofuOptions() {
return soyTofuOptions;
}
public void setSoyTofuOptions(SoyTofuOptions soyTofuOptions) {
this.soyTofuOptions = soyTofuOptions;
}
}