com.intellij.compiler.impl.CompilerUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.intellij.compiler.impl.CompilerUtil.java

Source

/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * created at Jan 3, 2002
 * @author Jeka
 */
package com.intellij.compiler.impl;

import com.intellij.CommonBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
import com.intellij.util.ThrowableRunnable;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.mustbe.consulo.roots.ContentFolderScopes;

import java.io.File;
import java.io.FileFilter;
import java.util.*;

public class CompilerUtil {
    private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerUtil");

    public static String quotePath(String path) {
        if (path != null && path.indexOf(' ') != -1) {
            path = path.replaceAll("\\\\", "\\\\\\\\");
            path = '"' + path + '"';
        }
        return path;
    }

    public static void collectFiles(Collection<File> container, File rootDir, FileFilter fileFilter) {
        final File[] files = rootDir.listFiles(fileFilter);
        if (files == null) {
            return;
        }
        for (File file : files) {
            if (file.isDirectory()) {
                collectFiles(container, file, fileFilter);
            } else {
                container.add(file);
            }
        }
    }

    public static Map<Module, List<VirtualFile>> buildModuleToFilesMap(CompileContext context,
            VirtualFile[] files) {
        return buildModuleToFilesMap(context, Arrays.asList(files));
    }

    public static Map<Module, List<VirtualFile>> buildModuleToFilesMap(final CompileContext context,
            final List<VirtualFile> files) {
        //assertion: all files are different
        final Map<Module, List<VirtualFile>> map = new THashMap<Module, List<VirtualFile>>();
        ApplicationManager.getApplication().runReadAction(new Runnable() {
            public void run() {
                for (VirtualFile file : files) {
                    final Module module = context.getModuleByFile(file);

                    if (module == null) {
                        continue; // looks like file invalidated
                    }

                    List<VirtualFile> moduleFiles = map.get(module);
                    if (moduleFiles == null) {
                        moduleFiles = new ArrayList<VirtualFile>();
                        map.put(module, moduleFiles);
                    }
                    moduleFiles.add(file);
                }
            }
        });
        return map;
    }

    /**
     * must not be called inside ReadAction
     * @param files
     */
    public static void refreshIOFiles(@NotNull final Collection<File> files) {
        if (!files.isEmpty()) {
            LocalFileSystem.getInstance().refreshIoFiles(files);
        }
    }

    public static void refreshIODirectories(@NotNull final Collection<File> files) {
        final LocalFileSystem lfs = LocalFileSystem.getInstance();
        final List<VirtualFile> filesToRefresh = new ArrayList<VirtualFile>();
        for (File file : files) {
            final VirtualFile virtualFile = lfs.refreshAndFindFileByIoFile(file);
            if (virtualFile != null) {
                filesToRefresh.add(virtualFile);
            }
        }
        if (!filesToRefresh.isEmpty()) {
            RefreshQueue.getInstance().refresh(false, true, null, filesToRefresh);
        }
    }

    public static void refreshIOFile(final File file) {
        final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
        if (vFile != null) {
            vFile.refresh(false, false);
        }
    }

    public static void addLocaleOptions(final List<String> commandLine, final boolean launcherUsed) {
        // need to specify default encoding so that javac outputs messages in 'correct' language
        //noinspection HardCodedStringLiteral
        commandLine.add((launcherUsed ? "-J" : "") + "-D" + CharsetToolkit.FILE_ENCODING_PROPERTY + "="
                + CharsetToolkit.getDefaultSystemCharset().name());
        // javac's VM should use the same default locale that IDEA uses in order for javac to print messages in 'correct' language
        //noinspection HardCodedStringLiteral
        final String lang = System.getProperty("user.language");
        if (lang != null) {
            //noinspection HardCodedStringLiteral
            commandLine.add((launcherUsed ? "-J" : "") + "-Duser.language=" + lang);
        }
        //noinspection HardCodedStringLiteral
        final String country = System.getProperty("user.country");
        if (country != null) {
            //noinspection HardCodedStringLiteral
            commandLine.add((launcherUsed ? "-J" : "") + "-Duser.country=" + country);
        }
        //noinspection HardCodedStringLiteral
        final String region = System.getProperty("user.region");
        if (region != null) {
            //noinspection HardCodedStringLiteral
            commandLine.add((launcherUsed ? "-J" : "") + "-Duser.region=" + region);
        }
    }

    public static boolean isOfVersion(String versionString, String checkedVersion) {
        return versionString.contains(checkedVersion);
    }

    public static <T extends Throwable> void runInContext(CompileContext context, String title,
            ThrowableRunnable<T> action) throws T {
        if (title != null) {
            context.getProgressIndicator().pushState();
            context.getProgressIndicator().setText(title);
        }
        try {
            action.run();
        } finally {
            if (title != null) {
                context.getProgressIndicator().popState();
            }
        }
    }

    public static void logDuration(final String activityName, long duration) {
        LOG.info(activityName + " took " + duration + " ms: " + duration / 60000 + " min "
                + (duration % 60000) / 1000 + "sec");
    }

    public static void clearOutputDirectories(final Collection<File> outputDirectories) {
        final long start = System.currentTimeMillis();
        // do not delete directories themselves, or we'll get rootsChanged() otherwise
        final Collection<File> filesToDelete = new ArrayList<File>(outputDirectories.size() * 2);
        for (File outputDirectory : outputDirectories) {
            File[] files = outputDirectory.listFiles();
            if (files != null) {
                ContainerUtil.addAll(filesToDelete, files);
            }
        }
        if (filesToDelete.size() > 0) {
            FileUtil.asyncDelete(filesToDelete);

            // ensure output directories exist
            for (final File file : outputDirectories) {
                file.mkdirs();
            }
            final long clearStop = System.currentTimeMillis();

            refreshIODirectories(outputDirectories);

            final long refreshStop = System.currentTimeMillis();

            logDuration("Clearing output dirs", clearStop - start);
            logDuration("Refreshing output directories", refreshStop - clearStop);
        }
    }

    public static void computeIntersectingPaths(final Project project, final Collection<VirtualFile> outputPaths,
            final Collection<VirtualFile> result) {
        for (Module module : ModuleManager.getInstance(project).getModules()) {
            final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
            final VirtualFile[] sourceRoots = rootManager
                    .getContentFolderFiles(ContentFolderScopes.productionAndTest());
            for (final VirtualFile outputPath : outputPaths) {
                for (VirtualFile sourceRoot : sourceRoots) {
                    if (VfsUtilCore.isAncestor(outputPath, sourceRoot, true)
                            || VfsUtilCore.isAncestor(sourceRoot, outputPath, false)) {
                        result.add(outputPath);
                    }
                }
            }
        }
    }

    public static boolean askUserToContinueWithNoClearing(Project project,
            Collection<VirtualFile> affectedOutputPaths) {
        final StringBuilder paths = new StringBuilder();
        for (final VirtualFile affectedOutputPath : affectedOutputPaths) {
            if (paths.length() > 0) {
                paths.append(",\n");
            }
            paths.append(affectedOutputPath.getPath().replace('/', File.separatorChar));
        }
        final int answer = Messages.showOkCancelDialog(project,
                CompilerBundle.message("warning.sources.under.output.paths", paths.toString()),
                CommonBundle.getErrorTitle(), Messages.getWarningIcon());
        if (answer == Messages.OK) { // ok
            return true;
        } else {
            return false;
        }
    }
}