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

io.protostuff.generator.CompilerModule Maven / Gradle / Ivy

There is a newer version: 3.1.40
Show newest version
package io.protostuff.generator;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.inject.multibindings.MapBinder.newMapBinder;

import com.google.inject.AbstractModule;
import com.google.inject.Provider;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.multibindings.MapBinder;
import com.google.inject.multibindings.Multibinder;
import io.protostuff.generator.dummy.DummyGenerator;
import io.protostuff.generator.html.HtmlCompiler;
import io.protostuff.generator.html.HtmlGenerator;
import io.protostuff.generator.html.json.enumeration.JsonEnumGenerator;
import io.protostuff.generator.html.json.index.JsonIndexGenerator;
import io.protostuff.generator.html.json.message.JsonMessageGenerator;
import io.protostuff.generator.html.json.pages.JsonPageGenerator;
import io.protostuff.generator.html.json.pages.JsonPagesIndexGenerator;
import io.protostuff.generator.html.json.proto.JsonProtoGenerator;
import io.protostuff.generator.html.json.service.JsonServiceGenerator;
import io.protostuff.generator.html.markdown.FlexmarkMarkdownProcessor;
import io.protostuff.generator.html.markdown.MarkdownProcessor;
import io.protostuff.generator.java.JavaExtensionProvider;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import javax.inject.Inject;

/**
 * Guice module for code generators.
 *
 * @author Kostiantyn Shchepanovskyi
 */
public class CompilerModule extends AbstractModule {

    public static final String JAVA_COMPILER_TEMPLATE = "io/protostuff/generator/java/main.stg";

    public static final String TEMPLATES_OPTION = "templates";
    public static final String EXTENSIONS_OPTION = "extensions";

    public static final String JAVA_COMPILER = "java";
    public static final String ST4_COMPILER = "st4";
    public static final String HTML_COMPILER = "html";
    public static final String DUMMY_COMPILER = "dummy";

    @Override
    protected void configure() {
        bind(CompilerRegistry.class);
        bind(CompilerUtils.class);
        bind(MarkdownProcessor.class).to(FlexmarkMarkdownProcessor.class).in(Scopes.SINGLETON);
        install(new FactoryModuleBuilder()
                .implement(ProtoCompiler.class, StCompiler.class)
                .build(StCompilerFactory.class));
        install(new FactoryModuleBuilder()
                .implement(ProtoCompiler.class, ExtensibleStCompiler.class)
                .build(ExtensibleStCompilerFactory.class));
        Multibinder htmlCompilerBinder = Multibinder.newSetBinder(binder(), HtmlCompiler.class);
        htmlCompilerBinder.addBinding().to(JsonIndexGenerator.class);
        htmlCompilerBinder.addBinding().to(JsonEnumGenerator.class);
        htmlCompilerBinder.addBinding().to(JsonMessageGenerator.class);
        htmlCompilerBinder.addBinding().to(JsonServiceGenerator.class);
        htmlCompilerBinder.addBinding().to(JsonProtoGenerator.class);
        htmlCompilerBinder.addBinding().to(JsonPagesIndexGenerator.class);
        htmlCompilerBinder.addBinding().to(JsonPageGenerator.class);
        MapBinder compilers = newMapBinder(binder(), String.class, ProtoCompiler.class);
        compilers.addBinding(HTML_COMPILER).to(HtmlGenerator.class);
        compilers.addBinding(JAVA_COMPILER).toProvider(JavaCompilerProvider.class);
        compilers.addBinding(ST4_COMPILER).toProvider(St4CompilerProvider.class);
        compilers.addBinding(DUMMY_COMPILER).to(DummyGenerator.class).in(Scopes.SINGLETON);
    }

    @Provides
    OutputStreamFactory outputStreamFactory() {
        return location -> {
            try {
                Path path = Paths.get(location);
                Path dir = path.getParent();
                Files.createDirectories(dir);
                return new FileOutputStream(location);
            } catch (IOException e) {
                throw new GeneratorException("Could not create file: %s", e, location);
            }
        };
    }

    public static class JavaCompilerProvider implements Provider {

        private final ExtensibleStCompilerFactory factory;

        @Inject
        public JavaCompilerProvider(ExtensibleStCompilerFactory factory) {
            this.factory = factory;
        }

        @Override
        public ProtoCompiler get() {
            ExtensionProvider extensionProvider = new JavaExtensionProvider();
            return factory.create(Collections.singletonList(JAVA_COMPILER_TEMPLATE), extensionProvider);
        }
    }

    public static class St4CompilerProvider implements Provider {

        private final ExtensibleStCompilerFactory factory;

        @Inject
        public St4CompilerProvider(ExtensibleStCompilerFactory factory) {
            this.factory = factory;
        }

        @Override
        public ProtoCompiler get() {
            // deffer compiler instantiation until wrapper is called with
            // configured template and extension provider class
            return module -> {
                try {
                    Map options = module.getOptions();
                    @SuppressWarnings("unchecked")
                    Collection templates = checkNotNull((Collection) options.get(TEMPLATES_OPTION),
                            TEMPLATES_OPTION + " is not set");
                    String extProviderClass = checkNotNull((String) options.get(EXTENSIONS_OPTION),
                            EXTENSIONS_OPTION + " is not set");
                    ExtensionProvider extensionProvider = instantiate(extProviderClass, ExtensionProvider.class);
                    ProtoCompiler compiler = factory.create(templates, extensionProvider);
                    compiler.compile(module);
                } catch (Exception e) {
                    throw new GeneratorException("Could not compile module: %s, module=%s", e, e.getMessage(), module);
                }
            };
        }

        private  T instantiate(final String className, final Class type) {
            try {
                Class clazz = Class.forName(className);
                Object instance = clazz.getDeclaredConstructor().newInstance();
                return type.cast(instance);
            } catch (Exception e) {
                throw new GeneratorException("Could not instantiate " + className, e);
            }
        }


    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy