All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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> 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> 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