com.facebook.buck.java.intellij.CompilerXml.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.java.intellij.CompilerXml.java

Source

/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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.
 */

package com.facebook.buck.java.intellij;

import com.facebook.buck.util.BuckConstant;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.io.Files;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;

class CompilerXml {

    private static final ImmutableList<String> WILDCARD_RESOURCES = ImmutableList.of("dtd", "ftl", "gif", "html",
            "jpeg", "jpg", "png", "properties", "tld", "xml", "json", "txt");

    /**
     * Exclude most directories that contain files generated by Buck.
     * We specifically do not include BuckConstant.ANNOTATION_DIR here (nor its parent dir
     * BuckConstant.BUCK_OUTPUT_DIRECTORY) because IntelliJ needs those sources to build.
     */
    private static final ImmutableSet<String> TOP_LEVEL_EXCLUDE_DIRS = ImmutableSet.of(Project.ANDROID_GEN_DIR,
            BuckConstant.SCRATCH_DIR, BuckConstant.GEN_DIR);

    private final List<SerializableModule> modules;

    CompilerXml(List<SerializableModule> modules) {
        this.modules = Lists.newArrayList(modules);

        // Sort the list of modules so that the XML generated by this class is consistent even if the
        // modules are read in in a different order between runs.
        Collections.sort(modules, SerializableModule.BUILDTARGET_NAME_COMARATOR);
    }

    private String generateXml() {
        StringBuilder buffer = new StringBuilder();

        buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        buffer.append("<project version=\"4\">\n");
        buffer.append("  <component name=\"CompilerConfiguration\">\n");
        buffer.append("    <option name=\"DEFAULT_COMPILER\" value=\"Javac\" />\n");

        // List all files that should be excluded from compilation.
        buffer.append("    <excludeFromCompile>\n");

        for (String excludeDir : TOP_LEVEL_EXCLUDE_DIRS) {
            buffer.append("      <directory url=\"file://$PROJECT_DIR$/" + excludeDir
                    + "\" includeSubdirectories=\"true\" />\n");
        }

        // Exclude several files associated with each module.
        for (SerializableModule module : modules) {
            String url = "file://$PROJECT_DIR$/" + module.getModuleDirectoryPath();
            buffer.append("      <file url=\"" + url + "/BUCK\" />\n");

            if (module.isAndroidModule()) {
                buffer.append("      <directory url=\"" + url + "/gen\" includeSubdirectories=\"true\" />\n");
                buffer.append("      <file url=\"" + url + "/project.properties\" />\n");
            }
        }
        buffer.append("    </excludeFromCompile>\n");

        buffer.append("    <resourceExtensions />\n");
        buffer.append("    <wildcardResourcePatterns>\n");
        for (String extension : WILDCARD_RESOURCES) {
            buffer.append("      <entry name=\"?*." + extension + "\" />\n");
        }
        buffer.append("    </wildcardResourcePatterns>\n");

        buffer.append("  </component>\n");
        buffer.append("</project>\n");

        return buffer.toString();
    }

    /**
     * Writes the {@code compilerXml} file if and only if its content needs to be updated.
     * @return true if {@code compilerXml} was written
     */
    boolean write(File compilerXml) throws IOException {
        final Charset charset = Charsets.US_ASCII;

        String existingXml = null;
        if (compilerXml.exists()) {
            existingXml = Files.toString(compilerXml, charset);
        }

        String newXml = generateXml();
        boolean compilerXmlNeedsToBeWritten = !newXml.equals(existingXml);

        if (compilerXmlNeedsToBeWritten) {
            Files.write(newXml, compilerXml, charset);
        }

        return compilerXmlNeedsToBeWritten;
    }
}