package org.jetbrains.android;
import com.intellij.ProjectTopics;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootAdapter;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.impl.JavaLanguageLevelPusher;
import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.containers.HashSet;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.android.sdk.AndroidSdkType;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.Set;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidSdkLanguageLevelPusher extends AbstractProjectComponent {
private volatile Set<Sdk> myUsedAndroidSdks = Collections.emptySet();
protected AndroidSdkLanguageLevelPusher(@NotNull Project project, @NotNull final MessageBus messageBus) {
super(project);
StartupManager.getInstance(project).registerPreStartupActivity(new Runnable() {
@Override
public void run() {
updateLanguageLevelForAllUsedSdks();
messageBus.connect().subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
@Override
public void rootsChanged(final ModuleRootEvent event) {
updateLanguageLevelForAllUsedSdks();
}
});
}
});
}
private void updateLanguageLevelForAllUsedSdks() {
Set<Sdk> newUsedSdks = null;
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null && sdk.getSdkType() instanceof AndroidSdkType) {
if (newUsedSdks == null) {
newUsedSdks = new HashSet<Sdk>();
}
if (newUsedSdks.add(sdk) && !myUsedAndroidSdks.contains(sdk)) {
updateSdkLanguageLevel(myProject, sdk);
}
}
}
if (newUsedSdks != null) {
myUsedAndroidSdks = newUsedSdks;
}
}
private static void updateSdkLanguageLevel(@NotNull final Project project, @NotNull Sdk sdk) {
final JavaLanguageLevelPusher javaPusher = new JavaLanguageLevelPusher();
for (VirtualFile root : sdk.getRootProvider().getFiles(OrderRootType.SOURCES)) {
if (root.isValid()) {
final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
VfsUtilCore.visitChildrenRecursively(root, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
if (fileTypeManager.isFileIgnored(file)) {
return false;
}
if (file.isDirectory()) {
PushedFilePropertiesUpdater.getInstance(project).findAndUpdateValue(file, javaPusher, LanguageLevel.HIGHEST);
}
return true;
}
});
}
}
}
}