cdc.mf.html.AbstractGenerator Maven / Gradle / Ivy
The newest version!
package cdc.mf.html;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import cdc.util.files.Files;
import cdc.util.time.Chronometer;
/**
* Base class of ST4 generators.
*/
public abstract class AbstractGenerator {
protected final Logger logger;
protected final MfHtmlGenerationArgs args;
protected AbstractGenerator(MfHtmlGenerationArgs args) {
this.logger = LogManager.getLogger(getClass());
this.args = args;
}
protected void addDictionaries(STGroup stg) {
final Map hintsMap = new HashMap<>();
for (final MfHtmlGenerationHint hint : MfHtmlGenerationHint.values()) {
hintsMap.put(hint.name(), args.getHints().contains(hint));
}
stg.defineDictionary(MfParams.Names.HINTS, hintsMap);
}
protected void log(String message) {
if (args.getHints().contains(MfHtmlGenerationHint.VERBOSE)) {
logger.info(message);
}
}
protected class STWorker implements Callable {
final ST st;
final File relativePath;
protected STWorker(ST st,
File relativePath) {
this.st = st;
this.relativePath = relativePath;
}
@Override
public final File call() throws IOException {
return save(st, relativePath);
}
}
protected List invokeTasks(String title,
List extends Callable> tasks,
boolean parallel) throws ExecutionException {
log(title + ": invoke " + tasks.size() + (parallel ? " parallel tasks" : " sequential tasks"));
final List list = new ArrayList<>();
final Chronometer chrono = new Chronometer();
chrono.start();
final int threads = parallel ? Runtime.getRuntime().availableProcessors() * 4 : 1;
final ExecutorService service = Executors.newFixedThreadPool(threads);
final List> futures = new ArrayList<>();
for (final Callable task : tasks) {
futures.add(service.submit(task));
}
for (final Future future : futures) {
try {
list.add(future.get());
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
} catch (final ExecutionException e) {
logger.catching(e);
throw e;
}
}
service.shutdown();
chrono.suspend();
log(title + ": invoked " + tasks.size() + (parallel ? " parallel tasks" : " sequential tasks") + " (" + chrono + ")");
return list;
}
protected List invokeTasks(String title,
List extends Callable> tasks) throws ExecutionException {
return invokeTasks(title,
tasks,
args.getHints().contains(MfHtmlGenerationHint.PARALLEL));
}
protected File save(ST st,
File relativePath) throws IOException {
final Chronometer chrono = new Chronometer();
final File targetFile = new File(args.getBaseDir(), relativePath.getPath()).getCanonicalFile();
final File tmpFile = new File(targetFile.getPath() + ".tmp");
targetFile.getParentFile().mkdirs();
log("generate " + targetFile);
chrono.start();
st.write(tmpFile, ErrorListener.INSTANCE, "UTF-8", null, -1);
replaceIfNecessary(tmpFile, targetFile);
chrono.suspend();
log("generated " + targetFile + " (" + chrono + ")");
return targetFile;
}
private static void replaceIfNecessary(File tmp,
File target) throws IOException {
if (!target.exists() || !Files.haveSameContent(tmp, target)) {
Files.copyFile(tmp, target);
}
java.nio.file.Files.delete(tmp.toPath());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy