com.dragome.web.helpers.serverside.DragomeCompilerLauncher.java Source code

Java tutorial

Introduction

Here is the source code for com.dragome.web.helpers.serverside.DragomeCompilerLauncher.java

Source

/*******************************************************************************
 * Copyright (c) 2011-2014 Fernando Petrola
 *
 * This file is part of Dragome SDK.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 ******************************************************************************/
package com.dragome.web.helpers.serverside;

import java.io.File;
import java.io.FileOutputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.jar.JarOutputStream;
import java.util.logging.Logger;

import org.apache.commons.io.FileUtils;

import com.dragome.commons.DragomeConfigurator;
import com.dragome.commons.compiler.BytecodeToJavascriptCompiler;
import com.dragome.commons.compiler.BytecodeToJavascriptCompilerConfiguration;
import com.dragome.commons.compiler.BytecodeTransformer;
import com.dragome.commons.compiler.annotations.CompilerType;
import com.dragome.commons.compiler.classpath.Classpath;
import com.dragome.commons.compiler.classpath.ClasspathEntry;
import com.dragome.commons.compiler.classpath.ClasspathFile;
import com.dragome.commons.compiler.classpath.ClasspathFileFilter;
import com.dragome.commons.compiler.classpath.serverside.JarClasspathEntry;
import com.dragome.services.ServiceLocator;
import com.dragome.services.WebServiceLocator;
import com.dragome.view.VisualActivity;
import com.dragome.web.helpers.DefaultClasspathFileFilter;

import proguard.Configuration;
import proguard.ConfigurationParser;
import proguard.ProGuard;

public class DragomeCompilerLauncher {
    private static Logger LOGGER = Logger.getLogger(DragomeCompilerLauncher.class.getName());

    public static void compileWithMainClass(Classpath classPath, String target) {
        ServiceLocator serviceLocator = ServiceLocator.getInstance();
        DragomeConfigurator configurator = serviceLocator.getConfigurator();
        String mainClassName = VisualActivity.class.getName();
        CompilerType defaultCompilerType = configurator.getDefaultCompilerType();
        BytecodeTransformer bytecodeTransformer = configurator.getBytecodeTransformer();

        ClasspathFileFilter classpathFilter = configurator.getClasspathFilter();
        if (classpathFilter == null)
            classpathFilter = new DefaultClasspathFileFilter();

        BytecodeToJavascriptCompiler bytecodeToJavascriptCompiler = WebServiceLocator.getInstance()
                .getBytecodeToJavascriptCompiler();

        configurator.sortClassPath(classPath);
        classPath = process(classPath, configurator);
        List<ClasspathEntry> extraClasspath = configurator.getExtraClasspath(classPath);
        classPath.addEntries(extraClasspath);

        BytecodeToJavascriptCompilerConfiguration compilerConfiguration = new BytecodeToJavascriptCompilerConfiguration(
                classPath, target, mainClassName, defaultCompilerType, bytecodeTransformer, classpathFilter,
                configurator.isCheckingCast(), configurator.isCaching());
        bytecodeToJavascriptCompiler.configure(compilerConfiguration);
        bytecodeToJavascriptCompiler.compile();
    }

    private static Classpath process(Classpath classPath, DragomeConfigurator configurator) {
        try {
            String path = null;

            String tempDir = System.getProperty("java.io.tmpdir");
            File tmpDir = new File(tempDir + File.separatorChar + "dragomeTemp");
            Path tmpPath = tmpDir.toPath();
            FileUtils.deleteDirectory(tmpDir);
            Files.createDirectories(tmpPath);
            File file = Files.createTempFile(tmpPath, "dragome-merged-", ".jar").toFile();
            file.deleteOnExit();
            path = file.getAbsolutePath();

            try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(file))) {
                List<ClasspathEntry> entries = classPath.getEntries();
                for (ClasspathEntry classpathEntry : entries)
                    classpathEntry.copyFilesToJar(jos, new DefaultClasspathFileFilter() {
                        private ArrayList<String> keepClass = new ArrayList<>();

                        public boolean accept(ClasspathFile classpathFile) {
                            boolean result = super.accept(classpathFile);

                            String entryName = classpathFile.getPath();
                            if (!keepClass.contains(entryName)) {
                                keepClass.add(entryName);

                                if (entryName.endsWith(".js") || entryName.endsWith(".class")
                                        || entryName.contains("MANIFEST") || entryName.contains(".html")
                                        || entryName.contains(".css"))
                                    result &= true;
                            }
                            return result;
                        }
                    });
            }

            if (configurator.isRemoveUnusedCode()) {
                return runProguard(file, configurator);
            } else
                return new Classpath(JarClasspathEntry.createFromPath(path));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static Classpath runProguard(File file, DragomeConfigurator configurator) throws Exception {
        URI uri = DragomeCompilerLauncher.class.getResource("/proguard.conf").toURI();
        Properties properties = System.getProperties();
        properties.put("in-jar-filename", file.getAbsolutePath());
        String outFilename = file.getAbsolutePath().replace(".jar", "-proguard.jar");
        new File(outFilename).deleteOnExit();
        properties.put("out-jar-filename", outFilename);
        ConfigurationParser parser = new ConfigurationParser(uri.toURL(), properties);
        URL additionalCodeKeepConfigFile = configurator.getAdditionalCodeKeepConfigFile();
        Configuration configuration = new Configuration();
        parser.parse(configuration);

        if (additionalCodeKeepConfigFile != null) {
            ConfigurationParser parserForAdditionalKeepCodeConfigFile = new ConfigurationParser(
                    additionalCodeKeepConfigFile, properties);
            parserForAdditionalKeepCodeConfigFile.parse(configuration);
        }

        new ProGuard(configuration).execute();
        return new Classpath(JarClasspathEntry.createFromPath(outFilename));
    }
}