com.android.tools.idea.gradle.project.AndroidGradleProjectComponent.java Source code

Java tutorial

Introduction

Here is the source code for com.android.tools.idea.gradle.project.AndroidGradleProjectComponent.java

Source

/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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.android.tools.idea.gradle.project;

import com.android.tools.idea.gradle.GradleImportNotificationListener;
import com.android.tools.idea.gradle.util.Projects;
import com.android.tools.idea.gradle.variant.view.BuildVariantView;
import com.google.common.collect.Lists;
import com.intellij.ProjectTopics;
import com.intellij.compiler.CompilerWorkspaceConfiguration;
import com.intellij.compiler.options.ExternalBuildOptionListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.ModuleListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.Function;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class AndroidGradleProjectComponent extends AbstractProjectComponent {
    private static final Logger LOG = Logger.getInstance(AndroidGradleProjectComponent.class);

    @Nullable
    private Disposable myDisposable;

    public AndroidGradleProjectComponent(Project project) {
        super(project);
    }

    /**
     * This method is called when a project is created and when it is opened.
     */
    @Override
    public void projectOpened() {
        if (!Projects.isGradleProject(myProject)) {
            CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration
                    .getInstance(myProject);
            boolean wasUsingExternalMake = workspaceConfiguration.USE_COMPILE_SERVER;
            if (wasUsingExternalMake) {
                String format = "Disabled 'External Build' for non-Gradle Android project '%1$s' until issue '%2$s' is fixed.";
                String msg = String.format(format, myProject.getName(),
                        "https://code.google.com/p/android/issues/detail?id=56843");
                LOG.info(msg);
                workspaceConfiguration.USE_COMPILE_SERVER = false;
                MessageBus messageBus = myProject.getMessageBus();
                messageBus.syncPublisher(ExternalBuildOptionListener.TOPIC)
                        .externalBuildOptionChanged(workspaceConfiguration.USE_COMPILE_SERVER);
            }
            return;
        }

        configureGradleProject(true);
    }

    public void configureGradleProject(boolean reImportProject) {
        if (myDisposable != null) {
            return;
        }
        myDisposable = new Disposable() {
            @Override
            public void dispose() {
            }
        };

        listenForProjectChanges(myProject, myDisposable);

        GradleImportNotificationListener.attachToManager();
        Projects.ensureExternalBuildIsEnabledForGradleProject(myProject);

        if (reImportProject) {
            Projects.setProjectBuildAction(myProject, Projects.BuildAction.SOURCE_GEN);
            try {
                // Prevent IDEA from refreshing project. We want to do it ourselves.
                myProject.putUserData(ExternalSystemDataKeys.NEWLY_IMPORTED_PROJECT, Boolean.TRUE);

                GradleProjectImporter.getInstance().reImportProject(myProject);
            } catch (ConfigurationException e) {
                Messages.showErrorDialog(e.getMessage(), e.getTitle());
                LOG.info(e);
            }
        }
    }

    private static void listenForProjectChanges(@NotNull Project project, @NotNull Disposable disposable) {
        GradleBuildFileUpdater buildFileUpdater = new GradleBuildFileUpdater(project);

        GradleModuleListener moduleListener = new GradleModuleListener();
        moduleListener.addModuleListener(buildFileUpdater);

        MessageBusConnection connection = project.getMessageBus().connect(disposable);
        connection.subscribe(ProjectTopics.MODULES, moduleListener);
        connection.subscribe(VirtualFileManager.VFS_CHANGES, buildFileUpdater);
    }

    @Override
    public void projectClosed() {
        if (myDisposable != null) {
            Disposer.dispose(myDisposable);
        }
    }

    private static class GradleModuleListener implements ModuleListener {
        @NotNull
        private final List<ModuleListener> additionalListeners = Lists.newArrayList();

        @Override
        public void moduleAdded(Project project, Module module) {
            updateBuildVariantView(project);
            for (ModuleListener listener : additionalListeners) {
                listener.moduleAdded(project, module);
            }
        }

        @Override
        public void beforeModuleRemoved(Project project, Module module) {
            for (ModuleListener listener : additionalListeners) {
                listener.beforeModuleRemoved(project, module);
            }
        }

        @Override
        public void modulesRenamed(Project project, List<Module> modules,
                Function<Module, String> oldNameProvider) {
            updateBuildVariantView(project);
            for (ModuleListener listener : additionalListeners) {
                listener.modulesRenamed(project, modules, oldNameProvider);
            }
        }

        @Override
        public void moduleRemoved(Project project, Module module) {
            updateBuildVariantView(project);
            for (ModuleListener listener : additionalListeners) {
                listener.moduleRemoved(project, module);
            }
        }

        private static void updateBuildVariantView(@NotNull Project project) {
            BuildVariantView.getInstance(project).updateContents();
        }

        void addModuleListener(@NotNull ModuleListener listener) {
            additionalListeners.add(listener);
        }
    }
}