From 20c466714002f915e03452cbfb0c3173c1a5d30c Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 4 Jul 2011 16:20:00 +0400 Subject: [PATCH 01/16] EA-27799 - assert: WindowManagerImpl.findFrameFor --- .../spellchecker/engine/BaseSpellChecker.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java b/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java index 7f3e6e116b29..e0e11f26a3e2 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java +++ b/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java @@ -24,6 +24,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.spellchecker.compress.CompressedDictionary; @@ -115,12 +116,13 @@ public class BaseSpellChecker implements SpellCheckerEngine { } private void _doLoadDictionaryAsync(final Loader loader, final Consumer consumer) { - UIUtil.invokeLaterIfNeeded(new Runnable() { + final Runnable runnable = new Runnable() { @Override public void run() { + if (myProject.isDisposed()) return; LOG.debug("Loading " + loader.getName()); ProgressManager.getInstance() - .run(new Task.Backgroundable(myProject,"Loading spellchecker dictionary...", false, + .run(new Task.Backgroundable(myProject, "Loading spellchecker dictionary...", false, new PerformInBackgroundOption() { @Override public boolean shouldStartInBackground() { @@ -163,7 +165,22 @@ public class BaseSpellChecker implements SpellCheckerEngine { } }); } - }); + }; + + + if (!myProject.isInitialized()) { + StartupManager.getInstance(myProject).runWhenProjectIsInitialized( + new Runnable() { + @Override + public void run() { + UIUtil.invokeLaterIfNeeded(runnable); + } + } + ); + + } else { + UIUtil.invokeLaterIfNeeded(runnable); + } } private void queueDictionaryLoad(final Loader loader, final Consumer consumer) { From 3548eef45133ddc15734f45c21a3256d3f2892a1 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Tue, 28 Jun 2011 17:56:40 +0400 Subject: [PATCH 02/16] avoid massive logging --- .../src/org/jetbrains/android/logcat/AndroidLogcatUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatUtil.java b/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatUtil.java index 5d38f73b56e1..c3fbf4d5c0ba 100644 --- a/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatUtil.java +++ b/plugins/android/src/org/jetbrains/android/logcat/AndroidLogcatUtil.java @@ -124,7 +124,7 @@ public class AndroidLogcatUtil { return super.ready(); } catch (IOException e) { - LOG.info(e); + LOG.debug(e); return false; } } From 521a79d209fa8e656b97f4332dc1d26632b613d3 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Tue, 28 Jun 2011 21:40:34 +0400 Subject: [PATCH 03/16] clean up --- .../android/newProject/AndroidModuleBuilder.java | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java index 9b09f1aef046..b1111bc18b9f 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java @@ -75,11 +75,7 @@ import static com.android.sdklib.SdkConstants.FN_DEFAULT_PROPERTIES; import static org.jetbrains.android.util.AndroidUtils.createChildDirectoryIfNotExist; /** - * Created by IntelliJ IDEA. - * User: Eugene.Kudelevsky - * Date: Jun 26, 2009 - * Time: 7:32:27 PM - * To change this template use File | Settings | File Templates. + * @author Eugene.Kudelevsky */ public class AndroidModuleBuilder extends JavaModuleBuilder { private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.newProject.AndroidModuleBuilder"); @@ -135,12 +131,6 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { createDirectoryStructure(contentRoot, sourceRoot, facet); } else { - // todo: after X release - /*if (myProjectType == ProjectType.LIBRARY) { - ExcludedEntriesConfiguration configuration = - ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getExcludedEntriesConfiguration(); - configuration.addExcludeEntryDescription(new ExcludeEntryDescription(contentRoot, true, false, project)); - }*/ createProjectByAndroidTool(contentRoot, sourceRoot, facet); } } @@ -458,10 +448,6 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { configuration.LIBRARY_PROJECT = true; } model.addFacet(facet); - /*if (configuration.ADD_ANDROID_LIBRARY) { - LibraryOrderEntry libraryEntry = rootModel.addLibraryEntry(myPlatform.getLibrary()); - libraryEntry.setScope(DependencyScope.PROVIDED); - }*/ model.commit(); return facet; } From 50e5c8c4f82ecf41d194ba16776b524f54a0a862 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Wed, 29 Jun 2011 10:43:11 +0400 Subject: [PATCH 04/16] import dependencies from default.properties --- .../android/facet/AndroidFacetType.java | 79 +++++++++++++++++-- 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java index 6f945fe6dc7e..250db542c053 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java @@ -25,18 +25,19 @@ import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.StdFileTypes; -import com.intellij.openapi.module.JavaModuleType; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; +import com.intellij.util.ArrayUtil; import org.jetbrains.android.dom.manifest.Manifest; import org.jetbrains.android.newProject.AndroidModuleType; import org.jetbrains.android.sdk.*; @@ -128,17 +129,14 @@ public class AndroidFacetType extends FacetType readPropertyFile(@NotNull Module module, @NotNull String propertyFileName) { for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) { final VirtualFile vFile = contentRoot.findChild(propertyFileName); if (vFile != null) { final Properties properties = new Properties(); try { properties.load(new FileInputStream(new File(vFile.getPath()))); - final String value = properties.getProperty(propertyKey); - if (value != null) { - return value; - } + return new Pair(properties, vFile); } catch (IOException e) { LOG.info(e); @@ -148,6 +146,19 @@ public class AndroidFacetType extends FacetType pair = readPropertyFile(module, propertyFileName); + if (pair != null) { + final String value = pair.first.getProperty(propertyKey); + if (value != null) { + return value; + } + } + return null; + } + @Nullable private static Sdk findSuitableAndroidSdk(@NotNull String targetHashString, @Nullable String sdkDir) { final List androidSdks = ProjectJdkTable.getInstance().getSdksOfType(AndroidSdkType.getInstance()); @@ -221,6 +232,55 @@ public class AndroidFacetType extends FacetType pair = readPropertyFile(module, SdkConstants.FN_DEFAULT_PROPERTIES); + if (pair != null) { + final VirtualFile baseDir = pair.second.getParent(); + String libDirPath; + int i = 1; + do { + libDirPath = pair.first.getProperty("android.library.reference." + i); + if (libDirPath != null) { + final VirtualFile libDir = findFileByAbsoluteOrRelativePath(baseDir, FileUtil.toSystemIndependentName(libDirPath)); + if (libDir != null) { + final Module depModule = ModuleUtil.findModuleForFile(libDir, module.getProject()); + + if (depModule != null && + (allowedDepModule == null || allowedDepModule == depModule) && + ArrayUtil.find(ModuleRootManager.getInstance(depModule).getContentRoots(), libDir) >= 0 && + !ModuleRootManager.getInstance(module).isDependsOn(depModule)) { + model.addModuleOrderEntry(depModule); + } + } + } + i++; + } + while (libDirPath != null); + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + model.commit(); + } + }); + } + public void registerDetectors(FacetDetectorRegistry detectorRegistry) { FacetDetector detector = new FacetDetector() { public AndroidFacetConfiguration detectFacet(VirtualFile source, Collection existentFacetConfigurations) { @@ -244,8 +304,11 @@ public class AndroidFacetType extends FacetType Date: Wed, 29 Jun 2011 13:14:16 +0400 Subject: [PATCH 05/16] clean up; do not invoke useless removeDeviceChangeListener --- .../jetbrains/android/run/DeviceChooser.java | 44 +------------------ 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java b/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java index e78d25dfc054..91c5ee67c3d3 100644 --- a/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java +++ b/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java @@ -47,7 +47,7 @@ import static com.intellij.openapi.util.text.StringUtil.capitalize; * Time: 6:02:59 PM * To change this template use File | Settings | File Templates. */ -public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.IDeviceChangeListener { +public class DeviceChooser extends DialogWrapper { public static final IDevice[] EMPTY_DEVICE_ARRAY = new IDevice[0]; private final AndroidFacet myFacet; @@ -95,16 +95,6 @@ public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.I if (selectedSerials != null) { resetSelection(selectedSerials); } - /*try { - AdbManager.run(new Runnable() { - public void run() { - AndroidDebugBridge.addDeviceChangeListener(DeviceChooser.this); - } - }, false); - } - catch (AdbNotRespondingException e) { - Messages.showErrorDialog(facet.getModule().getProject(), e.getMessage(), CommonBundle.getErrorTitle()); - }*/ } private void resetSelection(@NotNull String[] selectedSerials) { @@ -160,12 +150,6 @@ public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.I return state != null ? capitalize(state.name().toLowerCase()) : ""; } - @Override - protected void dispose() { - super.dispose(); - AndroidDebugBridge.removeDeviceChangeListener(this); - } - @Override protected void doOKAction() { mySelectedRows = myDeviceTable.getSelectedRows(); @@ -233,32 +217,6 @@ public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.I } } - public void deviceConnected(IDevice device) { - /*ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - updateTable(); - } - });*/ - } - - public void deviceDisconnected(IDevice device) { - /*ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - updateTable(); - } - });*/ - } - - public void deviceChanged(IDevice device, int changeMask) { - /*if ((changeMask & (IDevice.CHANGE_STATE | IDevice.CHANGE_BUILD_INFO)) != 0) { - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - updateTable(); - } - }); - }*/ - } - private class MyDeviceTableModel extends AbstractTableModel { private final IDevice[] myDevices; From 089cfe09a92d2537198f20a07b6b78e6dc40175f Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Sun, 3 Jul 2011 15:51:32 +0400 Subject: [PATCH 06/16] IDEA-60190 full support of importing of dependencies from default.properties: create missing modules, ask user --- .../newProjectWizard/SourcePathsStep.java | 10 +- .../messages/AndroidBundle.properties | 9 +- .../android/facet/AndroidFacetType.java | 237 +------------ .../AddModuleDependencyTask.java | 72 ++++ .../CreateNewModuleTask.java | 88 +++++ .../ImportDependenciesDialog.java | 62 ++++ .../ImportDependenciesTask.java | 16 + .../ImportDependenciesUtil.java | 316 ++++++++++++++++++ .../importDependencies/ImportModuleTask.java | 112 +++++++ .../ImportSourceRootsDialog.java | 51 +++ .../importDependencies/ModuleProvider.java | 100 ++++++ .../ModuleProvidingTask.java | 25 ++ .../newProject/AndroidModuleBuilder.java | 23 +- .../android/sdk/AndroidSdkUtils.java | 131 +++++++- .../jetbrains/android/util/AndroidUtils.java | 99 +++++- 15 files changed, 1082 insertions(+), 269 deletions(-) create mode 100644 plugins/android/src/org/jetbrains/android/importDependencies/AddModuleDependencyTask.java create mode 100644 plugins/android/src/org/jetbrains/android/importDependencies/CreateNewModuleTask.java create mode 100644 plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesDialog.java create mode 100644 plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesTask.java create mode 100644 plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesUtil.java create mode 100644 plugins/android/src/org/jetbrains/android/importDependencies/ImportModuleTask.java create mode 100644 plugins/android/src/org/jetbrains/android/importDependencies/ImportSourceRootsDialog.java create mode 100644 plugins/android/src/org/jetbrains/android/importDependencies/ModuleProvider.java create mode 100644 plugins/android/src/org/jetbrains/android/importDependencies/ModuleProvidingTask.java diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SourcePathsStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SourcePathsStep.java index 2e614e1bce34..3a43c0b69879 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SourcePathsStep.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SourcePathsStep.java @@ -328,11 +328,15 @@ public class SourcePathsStep extends AbstractStepWithProgress>> calculate() { - String contentEntryPath = getContentRootPath(); - if (contentEntryPath == null) { + return calculateSourceRoots(getContentRootPath()); + } + + @NotNull + public static List>> calculateSourceRoots(final String contentRootPath) { + if (contentRootPath == null) { return EMPTY_STRING_STRING_ARRAY; } - final File entryFile = new File(contentEntryPath); + final File entryFile = new File(contentRootPath); if (!entryFile.exists()) { return EMPTY_STRING_STRING_ARRAY; } diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties index 0e4e94f73ffe..d22dcb4327c4 100644 --- a/plugins/android/resources/messages/AndroidBundle.properties +++ b/plugins/android/resources/messages/AndroidBundle.properties @@ -239,4 +239,11 @@ no.jdk.error=You need to create at least one JSDK of versions 1.5 or 1.6 cannot.parse.sdk.error=Cannot parse Android SDK android.add.sdk.tooltip=Add SDK android.console.tool.window.title=Android Console -ddms.corrupted.error=Debug info is not available. Please close other application using ADB: DDMS, Eclipse \ No newline at end of file +ddms.corrupted.error=Debug info is not available. Please close other application using ADB: DDMS, Eclipse +android.import.dependencies.error.message.header=Importing finished with errors: +android.import.dependencies.add.module.dependency.task.title=Add dependency {0} --> {1} +android.import.dependencies.new.module.task.title=Create library module {0} in {1} +android.import.dependencies.import.module.task.title=Import library module {0} from {1} +android.import.dependencies.dialog.title=Import Android dependencies from property files +android.import.dependencies.source.roots.dialog.title=Import source roots +android.import.dependencies.source.roots.dialog.label=Choose source roots to add to your project \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java index 250db542c053..6bc271984929 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java @@ -15,51 +15,36 @@ */ package org.jetbrains.android.facet; -import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkConstants; import com.intellij.facet.Facet; import com.intellij.facet.FacetType; import com.intellij.facet.autodetecting.FacetDetector; import com.intellij.facet.autodetecting.FacetDetectorRegistry; -import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.StdFileTypes; -import com.intellij.openapi.module.*; +import com.intellij.openapi.module.JavaModuleType; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.ProjectJdkTable; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; -import com.intellij.util.ArrayUtil; import org.jetbrains.android.dom.manifest.Manifest; +import org.jetbrains.android.importDependencies.ImportDependenciesUtil; import org.jetbrains.android.newProject.AndroidModuleType; -import org.jetbrains.android.sdk.*; +import org.jetbrains.android.sdk.AndroidSdkUtils; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; import java.util.Collection; -import java.util.List; -import java.util.Properties; /** * @author yole */ public class AndroidFacetType extends FacetType { - private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.facet.AndroidFacetType"); - public AndroidFacetType() { super(AndroidFacet.ID, "android", "Android"); } @@ -69,26 +54,6 @@ public class AndroidFacetType extends FacetType readPropertyFile(@NotNull Module module, @NotNull String propertyFileName) { - for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) { - final VirtualFile vFile = contentRoot.findChild(propertyFileName); - if (vFile != null) { - final Properties properties = new Properties(); - try { - properties.load(new FileInputStream(new File(vFile.getPath()))); - return new Pair(properties, vFile); - } - catch (IOException e) { - LOG.info(e); - } - } - } - return null; - } - - @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") - @Nullable - private static String getPropertyValue(@NotNull Module module, @NotNull String propertyFileName, @NotNull String propertyKey) { - final Pair pair = readPropertyFile(module, propertyFileName); - if (pair != null) { - final String value = pair.first.getProperty(propertyKey); - if (value != null) { - return value; - } - } - return null; - } - - @Nullable - private static Sdk findSuitableAndroidSdk(@NotNull String targetHashString, @Nullable String sdkDir) { - final List androidSdks = ProjectJdkTable.getInstance().getSdksOfType(AndroidSdkType.getInstance()); - for (Sdk sdk : androidSdks) { - final AndroidSdkAdditionalData data = (AndroidSdkAdditionalData)sdk.getSdkAdditionalData(); - if (data != null) { - final AndroidPlatform androidPlatform = data.getAndroidPlatform(); - if (androidPlatform != null) { - final String baseDir = FileUtil.toSystemIndependentName(androidPlatform.getSdk().getLocation()); - if ((sdkDir == null || FileUtil.pathsEqual(baseDir, sdkDir)) && - targetHashString.equals(androidPlatform.getTarget().hashString())) { - return sdk; - } - } - } - } - return null; - } - - private static boolean tryToImportFromPropertyFiles(@NotNull Module module) { - final String targetHashString = getPropertyValue(module, SdkConstants.FN_DEFAULT_PROPERTIES, "target"); - if (targetHashString == null) { - return false; - } - - String sdkDir = getPropertyValue(module, SdkConstants.FN_LOCAL_PROPERTIES, "sdk.dir"); - if (sdkDir != null) { - sdkDir = FileUtil.toSystemIndependentName(sdkDir); - } - - final Sdk sdk = findSuitableAndroidSdk(targetHashString, sdkDir); - if (sdk != null) { - setSdk(module, sdk); - return true; - } - - if (sdkDir != null && tryToCreateAndSetAndroidSdk(module, sdkDir, targetHashString)) { - return true; - } - - final String androidHomeValue = System.getenv(AndroidSdkUtils.ANDROID_HOME_ENV); - if (androidHomeValue != null && - tryToCreateAndSetAndroidSdk(module, FileUtil.toSystemIndependentName(androidHomeValue), targetHashString)) { - return true; - } - - for (String dir : AndroidSdkUtils.getAndroidSdkPathsFromExistingPlatforms()) { - if (tryToCreateAndSetAndroidSdk(module, dir, targetHashString)) { - return true; - } - } - return false; - } - - private static boolean tryToCreateAndSetAndroidSdk(@NotNull Module module, @NotNull String baseDir, @NotNull String targetHashString) { - final AndroidSdk sdkObject = AndroidSdk.parse(baseDir, new EmptySdkLog()); - if (sdkObject != null) { - final IAndroidTarget target = sdkObject.findTargetByHashString(targetHashString); - if (target != null) { - final Sdk androidSdk = AndroidSdkUtils.createNewAndroidPlatform(target, sdkObject.getLocation(), true); - if (androidSdk != null) { - setSdk(module, androidSdk); - return true; - } - } - } - return false; - } - public boolean isSuitableModuleType(ModuleType moduleType) { return moduleType instanceof JavaModuleType || moduleType instanceof AndroidModuleType; } - @Nullable - private static VirtualFile findFileByAbsoluteOrRelativePath(@NotNull VirtualFile baseDir, @NotNull String path) { - VirtualFile libDir = LocalFileSystem.getInstance().findFileByPath(path); - return libDir != null ? libDir : LocalFileSystem.getInstance().findFileByPath(baseDir.getPath() + '/' + path); - } - - private static void updateBackwardDependencies(@NotNull Module module) { - for (Module module1 : ModuleManager.getInstance(module.getProject()).getModules()) { - if (module1 != module) { - updateDependencies(module1, module); - } - } - } - - private static void updateDependencies(@NotNull Module module, @Nullable Module allowedDepModule) { - final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); - final Pair pair = readPropertyFile(module, SdkConstants.FN_DEFAULT_PROPERTIES); - if (pair != null) { - final VirtualFile baseDir = pair.second.getParent(); - String libDirPath; - int i = 1; - do { - libDirPath = pair.first.getProperty("android.library.reference." + i); - if (libDirPath != null) { - final VirtualFile libDir = findFileByAbsoluteOrRelativePath(baseDir, FileUtil.toSystemIndependentName(libDirPath)); - if (libDir != null) { - final Module depModule = ModuleUtil.findModuleForFile(libDir, module.getProject()); - - if (depModule != null && - (allowedDepModule == null || allowedDepModule == depModule) && - ArrayUtil.find(ModuleRootManager.getInstance(depModule).getContentRoots(), libDir) >= 0 && - !ModuleRootManager.getInstance(module).isDependsOn(depModule)) { - model.addModuleOrderEntry(depModule); - } - } - } - i++; - } - while (libDirPath != null); - } - - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - model.commit(); - } - }); - } - public void registerDetectors(FacetDetectorRegistry detectorRegistry) { FacetDetector detector = new FacetDetector() { public AndroidFacetConfiguration detectFacet(VirtualFile source, Collection existentFacetConfigurations) { @@ -293,22 +80,24 @@ public class AndroidFacetType extends FacetType() { + @Override + public Module compute() { + final Module depModule = + ModuleManager.getInstance(myProject) + .newModule(myContentRoot.getPath() + '/' + myContentRoot.getName() + ".iml", StdModuleTypes.JAVA); + final ModifiableRootModel model = ModuleRootManager.getInstance(depModule).getModifiableModel(); + model.addContentEntry(myContentRoot); + model.commit(); + return depModule; + } + }); + AndroidUtils.addAndroidFacetIfNecessary(depModule, myContentRoot, true); + AndroidSdkUtils.setupAndroidPlatformInNeccessary(depModule); + setDepModule(depModule); + return null; + } + + @NotNull + @Override + public String getTitle() { + final String contentRootPath = FileUtil.toSystemDependentName(myContentRoot.getPath()); + return AndroidBundle.message("android.import.dependencies.new.module.task.title", getModuleName(), contentRootPath); + } + + @Override + public String getModuleName() { + return myContentRoot.getName(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CreateNewModuleTask that = (CreateNewModuleTask)o; + + if (!myContentRoot.equals(that.myContentRoot)) return false; + if (!myProject.equals(that.myProject)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = myProject.hashCode(); + result = 31 * result + myContentRoot.hashCode(); + return result; + } + + @NotNull + public VirtualFile getContentRoot() { + return myContentRoot; + } +} diff --git a/plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesDialog.java b/plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesDialog.java new file mode 100644 index 000000000000..87495c49c3d9 --- /dev/null +++ b/plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesDialog.java @@ -0,0 +1,62 @@ +package org.jetbrains.android.importDependencies; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.CheckBoxList; +import com.intellij.ui.CollectionListModel; +import com.intellij.ui.components.JBScrollPane; +import com.intellij.util.containers.HashMap; +import org.jetbrains.android.util.AndroidBundle; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author Eugene.Kudelevsky + */ +class ImportDependenciesDialog extends DialogWrapper { + private final CheckBoxList myCheckBoxList = new CheckBoxList(); + private final List myTasks; + private final Map myTask2Checkbox = new HashMap(); + + protected ImportDependenciesDialog(Project project, List tasks) { + super(project, false); + setTitle(AndroidBundle.message("android.import.dependencies.dialog.title")); + + myTasks = tasks; + + final JCheckBox[] checkBoxes = new JCheckBox[tasks.size()]; + + for (int i = 0; i < checkBoxes.length; i++) { + final ImportDependenciesTask task = tasks.get(i); + final JCheckBox checkBox = new JCheckBox(task.getTitle()); + checkBox.setSelected(true); + checkBoxes[i] = checkBox; + myTask2Checkbox.put(task, checkBox); + } + + myCheckBoxList.setModel(new CollectionListModel(checkBoxes)); + + init(); + } + + @Override + protected JComponent createCenterPanel() { + final JBScrollPane pane = new JBScrollPane(myCheckBoxList); + pane.setPreferredSize(new Dimension(500, 200)); + return pane; + } + + public List getSelectedTasks() { + final List result = new ArrayList(); + for (ImportDependenciesTask task : myTasks) { + if (myTask2Checkbox.get(task).isSelected()) { + result.add(task); + } + } + return result; + } +} diff --git a/plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesTask.java b/plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesTask.java new file mode 100644 index 000000000000..831665f42039 --- /dev/null +++ b/plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesTask.java @@ -0,0 +1,16 @@ +package org.jetbrains.android.importDependencies; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** +* @author Eugene.Kudelevsky +*/ +abstract class ImportDependenciesTask { + + @Nullable + public abstract Exception perform(); + + @NotNull + public abstract String getTitle(); +} diff --git a/plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesUtil.java b/plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesUtil.java new file mode 100644 index 000000000000..34c0f2c6fc39 --- /dev/null +++ b/plugins/android/src/org/jetbrains/android/importDependencies/ImportDependenciesUtil.java @@ -0,0 +1,316 @@ +package org.jetbrains.android.importDependencies; + +import com.android.sdklib.SdkConstants; +import com.intellij.CommonBundle; +import com.intellij.ide.highlighter.ModuleFileType; +import com.intellij.ide.util.newProjectWizard.SourcePathsStep; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Trinity; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.*; +import com.intellij.util.containers.HashMap; +import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.*; + +/** + * @author Eugene.Kudelevsky + */ +public class ImportDependenciesUtil { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.importDependencies.ImportDependenciesUtil"); + private static final Key WAIT_FOR_IMPORTING_DEPENDENCIES_KEY = new Key("WAIT_FOR_IMPORTING_DEPENDENCIES_KEY"); + private static final Object LOCK = new Object(); + + private ImportDependenciesUtil() { + } + + public static void importDependencies(@NotNull Module module, + final boolean updateBackwardDependencies) { + synchronized (LOCK) { + final Project project = module.getProject(); + + module.putUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY, Boolean.TRUE); + + if (project.getUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY) != Boolean.TRUE) { + project.putUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY, Boolean.TRUE); + StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + importDependenciesForMarkedModules(project, updateBackwardDependencies); + } + }); + } + }); + } + } + } + + private static void importDependenciesForMarkedModules(Project project, boolean updateBackwardDependencies) { + if (project.getUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY) != Boolean.TRUE) { + return; + } + + project.putUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY, null); + + final List modulesToProcess = new ArrayList(); + + for (Module module : ModuleManager.getInstance(project).getModules()) { + if (module.getUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY) == Boolean.TRUE) { + module.putUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY, null); + modulesToProcess.add(module); + } + } + + final List tasks = new OrderedSet(); + final List unresolvedDependencies = new ArrayList(); + + for (Module module : modulesToProcess) { + importDependencies(module, updateBackwardDependencies, tasks, unresolvedDependencies); + } + + final Map libDir2ModuleProvidingTask = new HashMap(); + for (ImportDependenciesTask task : tasks) { + if (task instanceof ModuleProvidingTask) { + final ModuleProvidingTask moduleProvidingTask = (ModuleProvidingTask)task; + libDir2ModuleProvidingTask.put(moduleProvidingTask.getContentRoot(), moduleProvidingTask); + } + } + + for (MyUnresolvedDependency unresolvedDependency : unresolvedDependencies) { + final ModuleProvidingTask taskProvidingDepModule = libDir2ModuleProvidingTask.get(unresolvedDependency.myLibDir); + if (taskProvidingDepModule != null) { + tasks.add(new AddModuleDependencyTask(unresolvedDependency.myModuleProvider, + ModuleProvider.create(taskProvidingDepModule))); + } + } + + if (tasks.size() > 0) { + doImportDependencies(project, tasks); + } + } + + private static void importDependencies(Module module, + boolean updateBackwardDependencies, + List tasks, + List unresolvedDependencies) { + importDependencies(module, null, tasks, unresolvedDependencies); + + if (updateBackwardDependencies) { + importBackwardDependencies(module, tasks, unresolvedDependencies); + } + } + + private static void doImportDependencies(@NotNull Project project, @NotNull List tasks) { + final ImportDependenciesDialog dialog = new ImportDependenciesDialog(project, tasks); + dialog.show(); + + if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) { + return; + } + + final List selectedTasks = dialog.getSelectedTasks(); + final StringBuilder messageBuilder = new StringBuilder(); + boolean failed = false; + final List createNewModuleTasks = new ArrayList(); + + for (ImportDependenciesTask selectedTask : selectedTasks) { + final Exception error = selectedTask.perform(); + if (error != null) { + LOG.info(error); + if (messageBuilder.length() > 0) { + messageBuilder.append('\n'); + } + messageBuilder.append(error.getMessage()); + failed = true; + } + else if (selectedTask instanceof CreateNewModuleTask) { + createNewModuleTasks.add((CreateNewModuleTask)selectedTask); + } + } + + if (createNewModuleTasks.size() > 0) { + final List>> sourceRoots = new ArrayList>>(); + for (CreateNewModuleTask task : createNewModuleTasks) { + final String contentRootPath = task.getContentRoot().getPath(); + sourceRoots.addAll(SourcePathsStep.calculateSourceRoots(contentRootPath)); + } + + if (sourceRoots.size() > 0) { + final ImportSourceRootsDialog sourceRootsDialog = new ImportSourceRootsDialog(project, sourceRoots); + sourceRootsDialog.show(); + + if (sourceRootsDialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) { + addSourceRoots(project, sourceRootsDialog.getMarkedElements()); + } + } + } + + if (failed) { + Messages.showErrorDialog(project, AndroidBundle.message("android.import.dependencies.error.message.header") + + "\n" + + messageBuilder.toString(), CommonBundle.getErrorTitle()); + } + } + + private static void addSourceRoots(final Project project, final Collection>> sourceRoots) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + for (Trinity> sourceRootTrinity : sourceRoots) { + final VirtualFile sourceRoot = LocalFileSystem.getInstance() + .refreshAndFindFileByPath(FileUtil.toSystemIndependentName(sourceRootTrinity.first)); + if (sourceRoot == null) { + LOG.debug(new Exception("Cannot find source root " + sourceRootTrinity.first)); + continue; + } + + final Module module = ModuleUtil.findModuleForFile(sourceRoot, project); + if (module == null) { + LOG.debug(new Exception("Cannot find module for file " + sourceRoot.getPath())); + continue; + } + + final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); + final ContentEntry[] entries = model.getContentEntries(); + if (entries.length > 0) { + entries[0].addSourceFolder(sourceRoot, false, sourceRootTrinity.second); + } + else { + LOG.debug(new Exception("Module " + module.getName() + " has no content entries")); + } + model.commit(); + } + } + }); + } + + @Nullable + private static VirtualFile findFileByAbsoluteOrRelativePath(@NotNull VirtualFile baseDir, @NotNull String path) { + VirtualFile libDir = LocalFileSystem.getInstance().findFileByPath(path); + return libDir != null ? libDir : LocalFileSystem.getInstance().findFileByPath(baseDir.getPath() + '/' + path); + } + + @Nullable + private static VirtualFile findModuleFileChild(@NotNull VirtualFile dir) { + for (VirtualFile child : dir.getChildren()) { + if (child.getFileType() instanceof ModuleFileType) { + return child; + } + } + return null; + } + + private static class MyUnresolvedDependency { + final ModuleProvider myModuleProvider; + final VirtualFile myLibDir; + + private MyUnresolvedDependency(ModuleProvider moduleProvider, VirtualFile libDir) { + myModuleProvider = moduleProvider; + myLibDir = libDir; + } + } + + private static void importDependencies(@NotNull Module module, + @Nullable Module allowedDepModule, + @NotNull List tasks, + @NotNull List unresolvedDependencies) { + final Project project = module.getProject(); + final ModuleProvider moduleProvider = ModuleProvider.create(module); + final Pair pair = AndroidUtils.readPropertyFile(module, SdkConstants.FN_DEFAULT_PROPERTIES); + + if (pair != null) { + doImportDependencies(module, allowedDepModule, tasks, unresolvedDependencies, project, moduleProvider, pair); + } + } + + private static void importDependenciesForNewModule(@NotNull Project project, + @NotNull ModuleProvider newModuleProvider, + @NotNull VirtualFile newModuleContentRoot, + @NotNull List tasks, + @NotNull List unresolvedDependencies) { + final Pair properties = + AndroidUtils.readPropertyFile(newModuleContentRoot, SdkConstants.FN_DEFAULT_PROPERTIES); + if (properties != null) { + doImportDependencies(null, null, tasks, unresolvedDependencies, project, newModuleProvider, properties); + } + } + + private static void doImportDependencies(@Nullable Module module, + @Nullable Module allowedDepModule, + @NotNull List tasks, + @NotNull List unresolvedDependencies, + @NotNull Project project, + @NotNull ModuleProvider moduleProvider, + @NotNull Pair defaultProperties) { + final VirtualFile baseDir = defaultProperties.second.getParent(); + String libDirPath; + int i = 1; + do { + libDirPath = defaultProperties.first.getProperty("android.library.reference." + i); + if (libDirPath != null) { + final VirtualFile libDir = findFileByAbsoluteOrRelativePath(baseDir, FileUtil.toSystemIndependentName(libDirPath)); + if (libDir != null) { + final Module depModule = ModuleUtil.findModuleForFile(libDir, project); + + if (depModule != null) { + if ((allowedDepModule == null || allowedDepModule == depModule) && + ArrayUtil.find(ModuleRootManager.getInstance(depModule).getContentRoots(), libDir) >= 0 && + !(module != null && ModuleRootManager.getInstance(module).isDependsOn(depModule))) { + + tasks.add(new AddModuleDependencyTask(moduleProvider, ModuleProvider.create(depModule))); + } + } + else { + final VirtualFile libModuleFile = findModuleFileChild(libDir); + final ModuleProvidingTask task = libModuleFile != null && new File(libModuleFile.getPath()).exists() + ? new ImportModuleTask(project, libModuleFile.getPath(), libDir) + : new CreateNewModuleTask(project, libDir); + if (!tasks.contains(task)) { + tasks.add(task); + final ModuleProvider newModuleProvider = ModuleProvider.create(task); + tasks.add(new AddModuleDependencyTask(moduleProvider, newModuleProvider)); + importDependenciesForNewModule(project, newModuleProvider, libDir, tasks, unresolvedDependencies); + } + else { + unresolvedDependencies.add(new MyUnresolvedDependency(moduleProvider, libDir)); + } + } + } + } + i++; + } + while (libDirPath != null); + } + + private static void importBackwardDependencies(@NotNull Module module, @NotNull List tasks, + @NotNull List unresolvedDependencies) { + for (Module module1 : ModuleManager.getInstance(module.getProject()).getModules()) { + if (module1 != module) { + importDependencies(module1, module, tasks, unresolvedDependencies); + } + } + } +} diff --git a/plugins/android/src/org/jetbrains/android/importDependencies/ImportModuleTask.java b/plugins/android/src/org/jetbrains/android/importDependencies/ImportModuleTask.java new file mode 100644 index 000000000000..f922215c49e5 --- /dev/null +++ b/plugins/android/src/org/jetbrains/android/importDependencies/ImportModuleTask.java @@ -0,0 +1,112 @@ +package org.jetbrains.android.importDependencies; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleWithNameAlreadyExists; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; +import org.jdom.JDOMException; +import org.jetbrains.android.sdk.AndroidSdkUtils; +import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidUtils; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; + +/** +* @author Eugene.Kudelevsky +*/ +class ImportModuleTask extends ModuleProvidingTask { + private final Project myProject; + private final String myModuleFilePath; + private final VirtualFile myContentRoot; + + public ImportModuleTask(@NotNull Project project, + @NotNull String moduleFilePath, + @NotNull VirtualFile contentRoot) { + myModuleFilePath = moduleFilePath; + myContentRoot = contentRoot; + myProject = project; + } + + @Override + public Exception perform() { + final Module[] moduleWrapper = {null}; + final Exception exception = ApplicationManager.getApplication().runWriteAction(new Computable() { + @Override + public Exception compute() { + try { + moduleWrapper[0] = ModuleManager.getInstance(myProject).loadModule(myModuleFilePath); + } + catch (InvalidDataException e) { + return e; + } + catch (IOException e) { + return e; + } + catch (JDOMException e) { + return e; + } + catch (ModuleWithNameAlreadyExists e) { + return e; + } + return null; + } + }); + + if (exception != null) { + return exception; + } + assert moduleWrapper[0] != null; + AndroidUtils.addAndroidFacetIfNecessary(moduleWrapper[0], myContentRoot, true); + AndroidSdkUtils.setupAndroidPlatformInNeccessary(moduleWrapper[0]); + setDepModule(moduleWrapper[0]); + return null; + } + + @NotNull + @Override + public String getTitle() { + return AndroidBundle + .message("android.import.dependencies.import.module.task.title", getModuleName(), FileUtil.toSystemDependentName(myModuleFilePath)); + } + + @Override + public String getModuleName() { + return FileUtil.getNameWithoutExtension(new File(myModuleFilePath).getName()); + } + + @NotNull + @Override + public VirtualFile getContentRoot() { + return myContentRoot; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ImportModuleTask that = (ImportModuleTask)o; + + if (!myContentRoot.equals(that.myContentRoot)) return false; + if (!myModuleFilePath.equals(that.myModuleFilePath)) return false; + if (!myProject.equals(that.myProject)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = myProject.hashCode(); + result = 31 * result + myModuleFilePath.hashCode(); + result = 31 * result + myContentRoot.hashCode(); + return result; + } +} diff --git a/plugins/android/src/org/jetbrains/android/importDependencies/ImportSourceRootsDialog.java b/plugins/android/src/org/jetbrains/android/importDependencies/ImportSourceRootsDialog.java new file mode 100644 index 000000000000..6aa84cd5ba79 --- /dev/null +++ b/plugins/android/src/org/jetbrains/android/importDependencies/ImportSourceRootsDialog.java @@ -0,0 +1,51 @@ +package org.jetbrains.android.importDependencies; + +import com.intellij.ide.util.ElementsChooser; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.Trinity; +import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; +import java.util.Collection; +import java.util.List; + +/** + * @author Eugene.Kudelevsky + */ +class ImportSourceRootsDialog extends DialogWrapper { + private final ElementsChooser>> mySourcePathsChooser; + + public ImportSourceRootsDialog(@NotNull Project project, @NotNull List>> sourceRoots) { + super(project, false); + + setTitle(AndroidBundle.message("android.import.dependencies.source.roots.dialog.title")); + + mySourcePathsChooser = new ElementsChooser>>(true) { + public String getItemText(@NotNull Trinity> sourceRootTrinity) { + return sourceRootTrinity.second.length() > 0 + ? sourceRootTrinity.first + " (" + sourceRootTrinity.second + ")" + : sourceRootTrinity.first; + } + }; + mySourcePathsChooser.setElements(sourceRoots, true); + + init(); + } + + @Override + protected JComponent createCenterPanel() { + final JPanel panel = new JPanel(new VerticalFlowLayout()); + panel.setPreferredSize(new Dimension(350, 200)); + panel.add(new JLabel(AndroidBundle.message("android.import.dependencies.source.roots.dialog.label"))); + panel.add(mySourcePathsChooser); + return panel; + } + + public List>> getMarkedElements() { + return mySourcePathsChooser.getMarkedElements(); + } +} diff --git a/plugins/android/src/org/jetbrains/android/importDependencies/ModuleProvider.java b/plugins/android/src/org/jetbrains/android/importDependencies/ModuleProvider.java new file mode 100644 index 000000000000..8d7893d20fca --- /dev/null +++ b/plugins/android/src/org/jetbrains/android/importDependencies/ModuleProvider.java @@ -0,0 +1,100 @@ +package org.jetbrains.android.importDependencies; + +import com.intellij.openapi.module.Module; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** +* @author Eugene.Kudelevsky +*/ +abstract class ModuleProvider { + + private ModuleProvider() { + } + + @Nullable + public abstract Module getModule(); + + @NotNull + public abstract String getModuleName(); + + public static ModuleProvider create(@NotNull final ModuleProvidingTask task) { + return new MyNewModuleProvider(task); + } + + public static ModuleProvider create(@NotNull final Module module) { + return new MyExistingModuleProvider(module); + } + + private static class MyNewModuleProvider extends ModuleProvider { + private final ModuleProvidingTask myTask; + + public MyNewModuleProvider(@NotNull ModuleProvidingTask task) { + myTask = task; + } + + @Override + public Module getModule() { + return myTask.getDepModule(); + } + + @NotNull + @Override + public String getModuleName() { + return myTask.getModuleName(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MyNewModuleProvider that = (MyNewModuleProvider)o; + + if (!myTask.equals(that.myTask)) return false; + + return true; + } + + @Override + public int hashCode() { + return myTask.hashCode(); + } + } + + private static class MyExistingModuleProvider extends ModuleProvider { + private final Module myModule; + + public MyExistingModuleProvider(Module module) { + myModule = module; + } + + @Override + public Module getModule() { + return myModule; + } + + @NotNull + @Override + public String getModuleName() { + return myModule.getName(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MyExistingModuleProvider that = (MyExistingModuleProvider)o; + + if (!myModule.equals(that.myModule)) return false; + + return true; + } + + @Override + public int hashCode() { + return myModule.hashCode(); + } + } +} diff --git a/plugins/android/src/org/jetbrains/android/importDependencies/ModuleProvidingTask.java b/plugins/android/src/org/jetbrains/android/importDependencies/ModuleProvidingTask.java new file mode 100644 index 000000000000..ea79be4d2c18 --- /dev/null +++ b/plugins/android/src/org/jetbrains/android/importDependencies/ModuleProvidingTask.java @@ -0,0 +1,25 @@ +package org.jetbrains.android.importDependencies; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +/** +* @author Eugene.Kudelevsky +*/ +abstract class ModuleProvidingTask extends ImportDependenciesTask { + private Module myDepModule; + + public Module getDepModule() { + return myDepModule; + } + + protected void setDepModule(Module depModule) { + myDepModule = depModule; + } + + public abstract String getModuleName(); + + @NotNull + public abstract VirtualFile getContentRoot(); +} diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java index b1111bc18b9f..18433faae697 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java @@ -23,8 +23,6 @@ import com.intellij.execution.RunManagerEx; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.ui.ConsoleViewContentType; -import com.intellij.facet.FacetManager; -import com.intellij.facet.ModifiableFacetModel; import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.ide.util.projectWizard.JavaModuleBuilder; import com.intellij.openapi.application.ApplicationManager; @@ -54,8 +52,8 @@ import org.jetbrains.android.dom.manifest.Manifest; import org.jetbrains.android.dom.resources.ResourceElement; import org.jetbrains.android.dom.resources.ResourceValue; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.facet.AndroidFacetConfiguration; import org.jetbrains.android.facet.AndroidRootUtil; +import org.jetbrains.android.importDependencies.ImportDependenciesUtil; import org.jetbrains.android.resourceManagers.LocalResourceManager; import org.jetbrains.android.run.testing.AndroidTestRunConfiguration; import org.jetbrains.android.run.testing.AndroidTestRunConfigurationType; @@ -95,9 +93,10 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { VirtualFile[] files = rootModel.getContentRoots(); if (files.length > 0) { final VirtualFile contentRoot = files[0]; - final AndroidFacet facet = addAndroidFacet(rootModel, contentRoot); + final AndroidFacet facet = AndroidUtils.addAndroidFacet(rootModel, contentRoot, myProjectType == ProjectType.LIBRARY); if (myProjectType == null) { + ImportDependenciesUtil.importDependencies(rootModel.getModule(), true); return; } @@ -436,22 +435,6 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { } } - @NotNull - private AndroidFacet addAndroidFacet(ModifiableRootModel rootModel, VirtualFile contentRoot) { - Module module = rootModel.getModule(); - final FacetManager facetManager = FacetManager.getInstance(module); - ModifiableFacetModel model = facetManager.createModifiableModel(); - AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null); - AndroidFacetConfiguration configuration = facet.getConfiguration(); - configuration.init(module, contentRoot); - if (myProjectType == ProjectType.LIBRARY) { - configuration.LIBRARY_PROJECT = true; - } - model.addFacet(facet); - model.commit(); - return facet; - } - private void createResourcesAndLibs(final Project project, final VirtualFile rootDir) { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { diff --git a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java index cfdf228602e7..7df1b80744a0 100644 --- a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java +++ b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java @@ -19,18 +19,23 @@ package org.jetbrains.android.sdk; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.module.Module; import com.intellij.openapi.projectRoots.*; import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil; import com.intellij.openapi.roots.JavadocOrderRootType; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.HashSet; +import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.android.util.OrderRoot; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -81,15 +86,6 @@ public class AndroidSdkUtils { return platformDir; } - public static VirtualFile[] chooseAndroidSdkPath(@NotNull Component parent) { - return FileChooser.chooseFiles(parent, new FileChooserDescriptor(false, true, false, false, false, false) { - @Override - public boolean isFileSelectable(VirtualFile file) { - return super.isFileSelectable(file) && isAndroidSdk(file.getPath()) || isAndroidPlatform(file); - } - }); - } - public static List getLibraryRootsForTarget(@NotNull IAndroidTarget target, @Nullable String sdkPath) { List result = new ArrayList(); VirtualFile platformDir = getPlatformDir(target); @@ -259,4 +255,121 @@ public class AndroidSdkUtils { return result; } + + private static boolean tryToSetAndroidPlatform(Module module, Sdk sdk) { + AndroidPlatform platform = AndroidPlatform.parse(sdk); + if (platform != null) { + setSdk(module, sdk); + return true; + } + return false; + } + + private static void setSdk(Module module, Sdk sdk) { + final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); + model.setSdk(sdk); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + model.commit(); + } + }); + } + + private static void setupPlatform(@NotNull Module module) { + if (tryToImportFromPropertyFiles(module)) { + return; + } + + PropertiesComponent component = PropertiesComponent.getInstance(); + if (component.isValueSet(DEFAULT_PLATFORM_NAME_PROPERTY)) { + String defaultPlatformName = component.getValue(DEFAULT_PLATFORM_NAME_PROPERTY); + Sdk defaultLib = ProjectJdkTable.getInstance().findJdk(defaultPlatformName, AndroidSdkType.getInstance().getName()); + if (defaultLib != null && tryToSetAndroidPlatform(module, defaultLib)) { + return; + } + } + for (Sdk sdk : ProjectJdkTable.getInstance().getSdksOfType(AndroidSdkType.getInstance())) { + if (tryToSetAndroidPlatform(module, sdk)) { + component.setValue(DEFAULT_PLATFORM_NAME_PROPERTY, sdk.getName()); + return; + } + } + } + + @Nullable + private static Sdk findSuitableAndroidSdk(@NotNull String targetHashString, @Nullable String sdkDir) { + final List androidSdks = ProjectJdkTable.getInstance().getSdksOfType(AndroidSdkType.getInstance()); + for (Sdk sdk : androidSdks) { + final AndroidSdkAdditionalData data = (AndroidSdkAdditionalData)sdk.getSdkAdditionalData(); + if (data != null) { + final AndroidPlatform androidPlatform = data.getAndroidPlatform(); + if (androidPlatform != null) { + final String baseDir = FileUtil.toSystemIndependentName(androidPlatform.getSdk().getLocation()); + if ((sdkDir == null || FileUtil.pathsEqual(baseDir, sdkDir)) && + targetHashString.equals(androidPlatform.getTarget().hashString())) { + return sdk; + } + } + } + } + return null; + } + + private static boolean tryToImportFromPropertyFiles(@NotNull Module module) { + final String targetHashString = AndroidUtils.getPropertyValue(module, SdkConstants.FN_DEFAULT_PROPERTIES, "target"); + if (targetHashString == null) { + return false; + } + + String sdkDir = AndroidUtils.getPropertyValue(module, SdkConstants.FN_LOCAL_PROPERTIES, "sdk.dir"); + if (sdkDir != null) { + sdkDir = FileUtil.toSystemIndependentName(sdkDir); + } + + final Sdk sdk = findSuitableAndroidSdk(targetHashString, sdkDir); + if (sdk != null) { + setSdk(module, sdk); + return true; + } + + if (sdkDir != null && tryToCreateAndSetAndroidSdk(module, sdkDir, targetHashString)) { + return true; + } + + final String androidHomeValue = System.getenv(ANDROID_HOME_ENV); + if (androidHomeValue != null && + tryToCreateAndSetAndroidSdk(module, FileUtil.toSystemIndependentName(androidHomeValue), targetHashString)) { + return true; + } + + for (String dir : getAndroidSdkPathsFromExistingPlatforms()) { + if (tryToCreateAndSetAndroidSdk(module, dir, targetHashString)) { + return true; + } + } + return false; + } + + private static boolean tryToCreateAndSetAndroidSdk(@NotNull Module module, @NotNull String baseDir, @NotNull String targetHashString) { + final AndroidSdk sdkObject = AndroidSdk.parse(baseDir, new EmptySdkLog()); + if (sdkObject != null) { + final IAndroidTarget target = sdkObject.findTargetByHashString(targetHashString); + if (target != null) { + final Sdk androidSdk = createNewAndroidPlatform(target, sdkObject.getLocation(), true); + if (androidSdk != null) { + setSdk(module, androidSdk); + return true; + } + } + } + return false; + } + + public static void setupAndroidPlatformInNeccessary(Module module) { + Sdk currentSdk = ModuleRootManager.getInstance(module).getSdk(); + if (currentSdk == null || !(currentSdk.getSdkType().equals(AndroidSdkType.getInstance()))) { + setupPlatform(module); + } + } } diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java index 06925f9a9c9d..9ca055f8fb05 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java @@ -30,6 +30,8 @@ import com.intellij.execution.impl.ConsoleViewImpl; import com.intellij.execution.process.*; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.facet.FacetManager; +import com.intellij.facet.ModifiableFacetModel; import com.intellij.facet.ProjectFacetManager; import com.intellij.ide.util.DefaultPsiElementCellRenderer; import com.intellij.openapi.application.ApplicationManager; @@ -40,17 +42,11 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.DependencyScope; -import com.intellij.openapi.roots.ModuleOrderEntry; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.*; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -79,18 +75,18 @@ import org.jetbrains.android.dom.manifest.Application; import org.jetbrains.android.dom.manifest.IntentFilter; import org.jetbrains.android.dom.manifest.Manifest; import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.facet.AndroidFacetConfiguration; import org.jetbrains.android.run.AndroidRunConfiguration; import org.jetbrains.android.run.AndroidRunConfigurationType; -import org.jetbrains.android.sdk.AndroidSdk; -import org.jetbrains.android.sdk.AndroidSdkAdditionalData; -import org.jetbrains.android.sdk.AndroidSdkType; -import org.jetbrains.android.sdk.EmptySdkLog; +import org.jetbrains.android.sdk.*; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.util.*; import java.util.List; @@ -712,4 +708,83 @@ public class AndroidUtils { } return false; } + + public static void addAndroidFacetIfNecessary(@NotNull final Module module, + @NotNull final VirtualFile contentRoot, + final boolean library) { + if (AndroidFacet.getInstance(module) == null) { + addAndroidFacet(module, contentRoot, library); + } + } + + @NotNull + public static AndroidFacet addAndroidFacet(@NotNull final Module module, @NotNull final VirtualFile contentRoot, final boolean library) { + return ApplicationManager.getApplication().runWriteAction(new Computable() { + @Override + public AndroidFacet compute() { + final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); + final AndroidFacet facet = addAndroidFacet(model, contentRoot, library); + model.commit(); + return facet; + } + }); + } + + @NotNull + public static AndroidFacet addAndroidFacet(ModifiableRootModel rootModel, VirtualFile contentRoot, boolean library) { + Module module = rootModel.getModule(); + final FacetManager facetManager = FacetManager.getInstance(module); + ModifiableFacetModel model = facetManager.createModifiableModel(); + AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null); + AndroidFacetConfiguration configuration = facet.getConfiguration(); + configuration.init(module, contentRoot); + if (library) { + configuration.LIBRARY_PROJECT = true; + } + model.addFacet(facet); + model.commit(); + return facet; + } + + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") + @Nullable + public static Pair readPropertyFile(@NotNull Module module, @NotNull String propertyFileName) { + for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) { + final Pair result = readPropertyFile(contentRoot, propertyFileName); + if (result != null) { + return result; + } + } + return null; + } + + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") + @Nullable + public static Pair readPropertyFile(@NotNull VirtualFile contentRoot, @NotNull String propertyFileName) { + final VirtualFile vFile = contentRoot.findChild(propertyFileName); + if (vFile != null) { + final Properties properties = new Properties(); + try { + properties.load(new FileInputStream(new File(vFile.getPath()))); + return new Pair(properties, vFile); + } + catch (IOException e) { + LOG.info(e); + } + } + return null; + } + + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") + @Nullable + public static String getPropertyValue(@NotNull Module module, @NotNull String propertyFileName, @NotNull String propertyKey) { + final Pair pair = readPropertyFile(module, propertyFileName); + if (pair != null) { + final String value = pair.first.getProperty(propertyKey); + if (value != null) { + return value; + } + } + return null; + } } From da5b4e162d1f955fd9204b429e8333a7c1391920 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Sun, 3 Jul 2011 16:09:18 +0400 Subject: [PATCH 07/16] clean up --- .../android/facet/AndroidFacetEditorTab.java | 114 ++---------------- 1 file changed, 7 insertions(+), 107 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java index 1605e94678da..2b233b330437 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java @@ -16,29 +16,19 @@ package org.jetbrains.android.facet; import com.android.sdklib.SdkConstants; -import com.intellij.compiler.CompilerConfiguration; -import com.intellij.compiler.CompilerConfigurationImpl; import com.intellij.facet.ui.FacetEditorContext; import com.intellij.facet.ui.FacetEditorTab; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.compiler.options.ExcludeEntryDescription; -import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.module.Module; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.LibraryOrderEntry; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.OrderEntry; -import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.roots.ui.configuration.projectRoot.GlobalLibrariesConfigurable; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.CollectionListModel; import com.intellij.ui.ComboboxWithBrowseButton; @@ -63,7 +53,10 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; /** * @author yole @@ -106,7 +99,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { public AndroidFacetEditorTab(FacetEditorContext context, AndroidFacetConfiguration androidFacetConfiguration) { final Project project = context.getProject(); - LibraryTable.ModifiableModel model = GlobalLibrariesConfigurable.getInstance(project).getModelProvider().getModifiableModel(); myConfiguration = androidFacetConfiguration; myContext = context; @@ -251,16 +243,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { return ArrayUtil.toStringArray(result); } - private boolean isUnderModuleDir(VirtualFile vFile) { - if (vFile == null) return false; - File file = new File(vFile.getPath()); - String moduleDirPath = new File(myContext.getModule().getModuleFilePath()).getParent(); - if (moduleDirPath != null) { - moduleDirPath = FileUtil.toSystemIndependentName(moduleDirPath); - } - return moduleDirPath != null && VfsUtil.isAncestor(new File(moduleDirPath), file, true); - } - @Nls public String getDisplayName() { return "Android SDK Settings"; @@ -353,29 +335,13 @@ public class AndroidFacetEditorTab extends FacetEditorTab { return !FileUtil.pathsEqual(pathFromConfig, pathFromTextField); } - // if library was removed in the same project-structure dialog - - @Nullable - private static LibraryOrderEntry findLibraryOrderEntryByName(@NotNull ModifiableRootModel model, @NotNull String name) { - for (OrderEntry entry : model.getOrderEntries()) { - if (entry instanceof LibraryOrderEntry) { - if (name.equals(((LibraryOrderEntry)entry).getLibraryName())) { - return (LibraryOrderEntry)entry; - } - } - } - return null; - } - @Nullable private String toRelativePath(String absPath) { absPath = FileUtil.toSystemIndependentName(absPath); String moduleDirPath = AndroidRootUtil.getModuleDirPath(myContext.getModule()); if (moduleDirPath != null) { moduleDirPath = FileUtil.toSystemIndependentName(moduleDirPath); - //if (VfsUtil.isAncestor(new File(moduleDirPath), new File(absPath), true)) { - return FileUtil.getRelativePath(moduleDirPath, absPath, '/'); - //} + return FileUtil.getRelativePath(moduleDirPath, absPath, '/'); } return null; } @@ -448,16 +414,7 @@ public class AndroidFacetEditorTab extends FacetEditorTab { } myConfiguration.LIBS_FOLDER_RELATIVE_PATH = '/' + getAndCheckRelativePath(absLibsPath, false); - //myConfiguration.ADD_ANDROID_LIBRARY = myAddAndroidLibrary.isSelected(); - if (myConfiguration.LIBRARY_PROJECT != myIsLibraryProjectCheckbox.isSelected()) { - // todo: after X release - /*if (myIsLibraryProjectCheckbox.isSelected()) { - excludeAllContentRootsFromCompilation(myContext.getModule()); - } - else { - includeAllContentRootsToCompilation(myContext.getModule()); - }*/ runApt = true; } @@ -529,44 +486,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { } } - private static void excludeAllContentRootsFromCompilation(@NotNull Module module) { - Project project = module.getProject(); - ExcludedEntriesConfiguration configuration = - ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getExcludedEntriesConfiguration(); - for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) { - configuration.addExcludeEntryDescription(new ExcludeEntryDescription(contentRoot, true, false, project)); - } - } - - private static void includeAllContentRootsToCompilation(@NotNull Module module) { - Project project = module.getProject(); - - VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); - Set contentRootSet = new HashSet(Arrays.asList(contentRoots)); - - ExcludedEntriesConfiguration configuration = - ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getExcludedEntriesConfiguration(); - ExcludeEntryDescription[] descriptions = configuration.getExcludeEntryDescriptions(); - configuration.removeAllExcludeEntryDescriptions(); - for (ExcludeEntryDescription description : descriptions) { - VirtualFile file = description.getVirtualFile(); - if (file != null && !contentRootSet.contains(file)) { - configuration.addExcludeEntryDescription(description); - } - } - } - - @NotNull - private String[] getNewResOverlayValue() throws ConfigurationException { - ListModel model = myResOverlayList.getModel(); - String[] newResOverlayValue = new String[model.getSize()]; - for (int i = 0; i < model.getSize(); i++) { - String element = (String)model.getElementAt(i); - newResOverlayValue[i] = '/' + getAndCheckRelativePath(element, false); - } - return newResOverlayValue; - } - private String getAndCheckRelativePath(String absPath, boolean checkExists) throws ConfigurationException { if (absPath.indexOf('/') < 0 && absPath.indexOf(File.separatorChar) < 0) { throw new ConfigurationException(AndroidBundle.message("file.must.be.under.module.error", FileUtil.toSystemDependentName(absPath))); @@ -583,8 +502,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { public void reset() { resetOptions(myConfiguration); - - //myAddAndroidLibrary.setSelected(myConfiguration.ADD_ANDROID_LIBRARY); myIsLibraryProjectCheckbox.setSelected(myConfiguration.LIBRARY_PROJECT); } @@ -712,16 +629,8 @@ public class AndroidFacetEditorTab extends FacetEditorTab { } } } - VirtualFile[] files = FileChooser.chooseFiles(myContentPanel, new FileChooserDescriptor(false, true, false, false, false, false) /*{ - @Override - public void validateSelectedFiles(VirtualFile[] files) throws Exception { - assert files.length == 1; - VirtualFile file = files[0]; - if (!isUnderModuleDir(file)) { - throw new Exception(AndroidBundle.message("file.must.be.under.module.error", FileUtil.toSystemDependentName(file.getPath()))); - } - } - }*/, initialFile); + VirtualFile[] files = + FileChooser.chooseFiles(myContentPanel, new FileChooserDescriptor(false, true, false, false, false, false), initialFile); if (files.length > 0) { assert files.length == 1; myTextField.setText(FileUtil.toSystemDependentName(files[0].getPath())); @@ -778,15 +687,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { } return file.isDirectory() || !chooseManifest || SdkConstants.FN_ANDROID_MANIFEST_XML.equals(file.getName()); } - - /*@Override - public void validateSelectedFiles(VirtualFile[] files) throws Exception { - for (VirtualFile file : files) { - if (!isUnderModuleDir(file)) { - throw new Exception(AndroidBundle.message("file.must.be.under.module.error", FileUtil.toSystemDependentName(file.getPath()))); - } - } - }*/ }, initialFile); } } From 141a9e27c2b327e09575d1643d18fa7f3aa41b52 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Sun, 3 Jul 2011 20:40:48 +0400 Subject: [PATCH 08/16] fix: pass hash string --- .../org/jetbrains/android/newProject/AndroidModuleBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java index 18433faae697..f4bbd5845e03 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java @@ -335,7 +335,7 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { } Properties properties = FileTemplateManager.getInstance().getDefaultProperties(); - properties.setProperty("TARGET", "android-" + platform.getTarget().getVersion().getApiString()); + properties.setProperty("TARGET", platform.getTarget().hashString()); AndroidFileTemplateProvider.createFromTemplate(project, contentRoot, "default.properties", FN_DEFAULT_PROPERTIES, properties); } catch (Exception e) { From 571990dce7c682479642010ea2b3c62f200219d7 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Sun, 3 Jul 2011 20:43:39 +0400 Subject: [PATCH 09/16] IDEA-66203 keep default.properties file up to date --- plugins/android/android.iml | 1 + plugins/android/src/META-INF/plugin.xml | 1 + .../jetbrains/android/facet/AndroidFacet.java | 149 +++++++++++++++++- .../android/facet/AndroidFacetType.java | 2 +- .../ImportDependenciesUtil.java | 10 +- .../jetbrains/android/util/AndroidUtils.java | 42 ++++- 6 files changed, 191 insertions(+), 14 deletions(-) diff --git a/plugins/android/android.iml b/plugins/android/android.iml index 3ff4eba44447..620b7ba080dc 100644 --- a/plugins/android/android.iml +++ b/plugins/android/android.iml @@ -44,6 +44,7 @@ + diff --git a/plugins/android/src/META-INF/plugin.xml b/plugins/android/src/META-INF/plugin.xml index d543451f06db..3058a2ff9845 100644 --- a/plugins/android/src/META-INF/plugin.xml +++ b/plugins/android/src/META-INF/plugin.xml @@ -63,6 +63,7 @@ JUnit + com.intellij.properties org.jetbrains.idea.maven diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java index 3f3dcc647b54..ce68c4b84218 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java @@ -24,6 +24,7 @@ import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; import com.android.sdklib.internal.avd.AvdManager; import com.intellij.CommonBundle; +import com.intellij.ProjectTopics; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.configurations.ParametersList; import com.intellij.execution.process.ProcessHandler; @@ -32,6 +33,9 @@ import com.intellij.facet.Facet; import com.intellij.facet.FacetManager; import com.intellij.facet.FacetTypeId; import com.intellij.facet.FacetTypeRegistry; +import com.intellij.lang.properties.psi.PropertiesElementFactory; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.lang.properties.psi.Property; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; @@ -39,16 +43,21 @@ import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.CompilerModuleExtension; +import com.intellij.openapi.roots.ModuleRootEvent; +import com.intellij.openapi.roots.ModuleRootListener; +import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileAdapter; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.ProjectScope; @@ -76,10 +85,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.jetbrains.android.util.AndroidUtils.EMULATOR; import static org.jetbrains.android.util.AndroidUtils.SYSTEM_RESOURCE_PACKAGE; @@ -370,6 +376,141 @@ public class AndroidFacet extends Facet { }); } }); + + getModule().getMessageBus().connect(this).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() { + + private String[] myDependencies; + + public void beforeRootsChange(final ModuleRootEvent event) { + } + + public void rootsChanged(final ModuleRootEvent event) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (!isDisposed()) { + PsiDocumentManager.getInstance(getModule().getProject()).commitAllDocuments(); + + final PropertiesFile propertiesFile = AndroidUtils.findPropertyFile(getModule(), SdkConstants.FN_DEFAULT_PROPERTIES); + if (propertiesFile == null) { + return; + } + + updateTargetProperty(propertiesFile); + updateLibraryProperty(propertiesFile); + + final String[] dependencies = collectDependencies(); + if (myDependencies == null || !Comparing.equal(myDependencies, dependencies)) { + updateDependenciesInPropertyFile(propertiesFile, dependencies); + myDependencies = dependencies; + } + } + } + }); + } + }); + } + + private void updateDependenciesInPropertyFile(@NotNull final PropertiesFile propertiesFile, @NotNull final String[] dependencies) { + final VirtualFile vFile = propertiesFile.getVirtualFile(); + if (vFile == null) { + return; + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + for (Property property : propertiesFile.getProperties()) { + final String name = property.getName(); + if (name != null && name.startsWith(AndroidUtils.ANDROID_LIBRARY_REFERENCE_PROPERTY_PREFIX)) { + property.delete(); + } + } + + final VirtualFile baseDir = vFile.getParent(); + final String baseDirPath = baseDir.getPath(); + final Project project = getModule().getProject(); + + int index = 1; + for (String dependency : dependencies) { + final String relPath = FileUtil.getRelativePath(baseDirPath, dependency, '/'); + final String value = relPath != null ? relPath : dependency; + propertiesFile.addProperty( + PropertiesElementFactory.createProperty(project, AndroidUtils.ANDROID_LIBRARY_REFERENCE_PROPERTY_PREFIX + index, value)); + index++; + } + } + }); + } + + private String[] collectDependencies() { + final List dependenciesList = new ArrayList(); + + for (AndroidFacet depFacet : AndroidUtils.getAndroidDependencies(getModule(), true)) { + final Module depModule = depFacet.getModule(); + final VirtualFile libDir = getBaseAndroidContentRoot(depModule); + if (libDir != null) { + dependenciesList.add(libDir.getPath()); + } + } + + final String[] dependencies = ArrayUtil.toStringArray(dependenciesList); + Arrays.sort(dependencies); + return dependencies; + } + + @Nullable + private static VirtualFile getBaseAndroidContentRoot(@NotNull Module module) { + final VirtualFile manifestFile = AndroidRootUtil.getManifestFile(module); + final VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); + if (manifestFile != null) { + for (VirtualFile contentRoot : contentRoots) { + if (VfsUtil.isAncestor(contentRoot, manifestFile, true)) { + return contentRoot; + } + } + } + return contentRoots.length > 0 ? contentRoots[0] : null; + } + + private void updateTargetProperty(@NotNull final PropertiesFile propertiesFile) { + final IAndroidTarget androidTarget = getConfiguration().getAndroidTarget(); + if (androidTarget != null) { + final String targetPropertyValue = androidTarget.hashString(); + final Property property = propertiesFile.findPropertyByKey(AndroidUtils.ANDROID_TARGET_PROPERTY); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + if (property == null) { + final Property newProperty = PropertiesElementFactory.createProperty(propertiesFile.getProject(), + AndroidUtils.ANDROID_TARGET_PROPERTY, targetPropertyValue); + propertiesFile.addProperty(newProperty); + } + else { + property.setValue(targetPropertyValue); + } + } + }); + } + } + + public void updateLibraryProperty(@NotNull final PropertiesFile propertiesFile) { + final Property property = propertiesFile.findPropertyByKey(AndroidUtils.ANDROID_LIBRARY_PROPERTY); + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + if (property != null) { + property.setValue(Boolean.toString(getConfiguration().LIBRARY_PROJECT)); + } + else if (getConfiguration().LIBRARY_PROJECT) { + final Property newProperty = PropertiesElementFactory.createProperty(propertiesFile.getProject(), + AndroidUtils.ANDROID_LIBRARY_PROPERTY, + Boolean.TRUE.toString()); + propertiesFile.addProperty(newProperty); + } + } + }); } @Override diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java index 6bc271984929..b14ae78870c8 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetType.java @@ -93,7 +93,7 @@ public class AndroidFacetType extends FacetType CONSOLE_VIEW_KEY = new Key("AndroidConsoleView"); + @NonNls public static final String ANDROID_LIBRARY_PROPERTY = "android.library"; + @NonNls public static final String ANDROID_TARGET_PROPERTY = "target"; + @NonNls public static final String ANDROID_LIBRARY_REFERENCE_PROPERTY_PREFIX = "android.library.reference."; + private AndroidUtils() { } @@ -746,6 +755,25 @@ public class AndroidUtils { return facet; } + @Nullable + public static PropertiesFile findPropertyFile(@NotNull final Module module, @NotNull String propertyFileName) { + for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) { + final VirtualFile vFile = contentRoot.findChild(propertyFileName); + if (vFile != null) { + final PsiFile psiFile = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiFile compute() { + return PsiManager.getInstance(module.getProject()).findFile(vFile); + } + }); + if (psiFile instanceof PropertiesFile) { + return (PropertiesFile)psiFile; + } + } + } + return null; + } + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") @Nullable public static Pair readPropertyFile(@NotNull Module module, @NotNull String propertyFileName) { @@ -787,4 +815,16 @@ public class AndroidUtils { } return null; } + + @Nullable + public static VirtualFile findFileByAbsoluteOrRelativePath(@Nullable VirtualFile baseDir, @NotNull String path) { + VirtualFile libDir = LocalFileSystem.getInstance().findFileByPath(path); + if (libDir != null) { + return libDir; + } + else if (baseDir != null) { + return LocalFileSystem.getInstance().findFileByPath(baseDir.getPath() + '/' + path); + } + return null; + } } From cfc902cee0d9efc83c5f29c6dc901a04c3edbb7d Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 4 Jul 2011 14:57:11 +0200 Subject: [PATCH 10/16] logging (3) --- .../src/com/intellij/help/impl/HelpManagerImpl.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java b/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java index 682e3bd6221e..3937d33e377c 100644 --- a/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java @@ -92,15 +92,19 @@ public class HelpManagerImpl extends HelpManager { for (IdeaPluginDescriptor pluginDescriptor : pluginDescriptors) { HelpSetPath[] sets = pluginDescriptor.getHelpSets(); for (HelpSetPath hsPath : sets) { - URL hsURL = - new URL("jar:file:///" + pluginDescriptor.getPath().getAbsolutePath() + "/help/" + hsPath.getFile() + "!" + hsPath.getPath()); + final String url = "jar:file:///" + pluginDescriptor.getPath().getAbsolutePath() + "/help/" + hsPath.getFile() + + "!" + hsPath.getPath(); try { + URL hsURL = new URL(url); HelpSet pluginHelpSet = new HelpSet(null, hsURL); helpSet.add(pluginHelpSet); } catch (HelpSetException e) { LOG.error(e); } + catch (Exception e) { + LOG.info("Error adding plugin help url " + url, e); + } } } From 411eb163649985abe1d62eecdf414c50c042739e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 29 Jun 2011 15:10:41 +0400 Subject: [PATCH 11/16] utility method --- platform/util/src/com/intellij/util/ArrayUtil.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platform/util/src/com/intellij/util/ArrayUtil.java b/platform/util/src/com/intellij/util/ArrayUtil.java index 40e9191af38d..2f4b65ef489c 100644 --- a/platform/util/src/com/intellij/util/ArrayUtil.java +++ b/platform/util/src/com/intellij/util/ArrayUtil.java @@ -552,6 +552,13 @@ public class ArrayUtil { return -1; } + public static int indexOf(@NotNull Object[] objects, Object object, int start, int end) { + for (int i = start; i < end; i++) { + if (Comparing.equal(objects[i], object)) return i; + } + return -1; + } + public static int indexOf(@NotNull List objects, T object, @NotNull Equality comparator) { for (int i = 0; i < objects.size(); i++) { if (comparator.equals(objects.get(i), object)) return i; From 91f2572950cd7f2110fdffc2e708d0d1a743a10e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 30 Jun 2011 14:56:00 +0400 Subject: [PATCH 12/16] NPE --- .../com/intellij/psi/PsiConcurrencyStressTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java b/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java index 4e936c54984a..ee4667f9adbc 100644 --- a/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java @@ -151,7 +151,13 @@ public class PsiConcurrencyStressTest extends PsiTestCase { super.visitElement(element); final HighlightInfoHolder infoHolder = new HighlightInfoHolder(myFile, HighlightInfoFilter.EMPTY_ARRAY); - new HighlightVisitorImpl(getProject()).visit(element, infoHolder); + final HighlightVisitorImpl visitor = new HighlightVisitorImpl(getProject()); + visitor.analyze(new Runnable() { + @Override + public void run() { + visitor.visit(element, infoHolder); + } + }, false, myFile); } }); break; From 8c3f5833b151397c0feeeaea26c6ad2b233f32f8 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 30 Jun 2011 17:39:09 +0400 Subject: [PATCH 13/16] supply message --- .../daemon/LightAdvHighlightingPerformanceTest.java | 2 +- .../com/intellij/codeInsight/daemon/RecursiveVisitorTest.java | 4 ++-- .../com/intellij/openapi/vfs/VirtualFilePointerTest.java | 2 +- .../com/intellij/spellchecker/compress/DictionaryTest.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingPerformanceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingPerformanceTest.java index 35e521a15530..95b1dd2ded1f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingPerformanceTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingPerformanceTest.java @@ -83,7 +83,7 @@ public class LightAdvHighlightingPerformanceTest extends LightDaemonAnalyzerTest CodeInsightTestFixtureImpl.ensureIndexesUpToDate(getProject()); final List infos = new ArrayList(); - PlatformTestUtil.startPerformanceTest(maxMillis, new ThrowableRunnable() { + PlatformTestUtil.startPerformanceTest(getTestName(false), maxMillis, new ThrowableRunnable() { @Override public void run() throws Exception { infos.clear(); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/RecursiveVisitorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/RecursiveVisitorTest.java index 7cc83db10214..c8d7facfa0da 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/RecursiveVisitorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/RecursiveVisitorTest.java @@ -19,7 +19,7 @@ public class RecursiveVisitorTest extends LightDaemonAnalyzerTestCase{ final PsiElement expression = JavaPsiFacade.getInstance(getProject()).getElementFactory().createStatementFromText(text.toString(), null); final int[] n = {0}; - PlatformTestUtil.startPerformanceTest(20, new ThrowableRunnable() { + PlatformTestUtil.startPerformanceTest(getTestName(false), 20, new ThrowableRunnable() { @Override public void run() throws Exception { n[0] = 0; @@ -46,7 +46,7 @@ public class RecursiveVisitorTest extends LightDaemonAnalyzerTestCase{ final PsiElement expression = JavaPsiFacade.getInstance(getProject()).getElementFactory().createStatementFromText(text.toString(), null); final int[] n = {0}; - PlatformTestUtil.startPerformanceTest(100, new ThrowableRunnable() { + PlatformTestUtil.startPerformanceTest(getTestName(false), 100, new ThrowableRunnable() { @Override public void run() throws Exception { n[0] = 0; diff --git a/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java b/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java index bf5d5a368b58..c916eff11e11 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java @@ -385,7 +385,7 @@ public class VirtualFilePointerTest extends IdeaTestCase { } public void testContainerDeletePerformance() throws Exception { - PlatformTestUtil.startPerformanceTest(3000, new ThrowableRunnable() { + PlatformTestUtil.startPerformanceTest("VF Pointer create/delete",3000, new ThrowableRunnable() { @Override public void run() throws Exception { Disposable parent = Disposer.newDisposable(); diff --git a/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/DictionaryTest.java b/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/DictionaryTest.java index c640a788baee..ad0acb20c8e5 100644 --- a/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/DictionaryTest.java +++ b/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/DictionaryTest.java @@ -63,7 +63,7 @@ public class DictionaryTest extends TestCase { public void loadDictionaryTest(@NotNull final String name, int wordCount) throws IOException { final Transformation transform = new Transformation(); - PlatformTestUtil.startPerformanceTest(times.get(name), new ThrowableRunnable() { + PlatformTestUtil.startPerformanceTest("load dictionary", times.get(name), new ThrowableRunnable() { @Override public void run() throws Exception { dictionary = CompressedDictionary @@ -72,7 +72,7 @@ public class DictionaryTest extends TestCase { }).cpuBound().assertTiming(); final Set wordsToStoreAndCheck = createWordSets(name, 50000, 1).getFirst(); - PlatformTestUtil.startPerformanceTest(2000, new ThrowableRunnable() { + PlatformTestUtil.startPerformanceTest("words contain",2000, new ThrowableRunnable() { @Override public void run() throws Exception { for (String s : wordsToStoreAndCheck) { From 4a2b8aa8431e88ad0d5fcb4ad4ae83547660f57e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 30 Jun 2011 18:32:06 +0400 Subject: [PATCH 14/16] cleanup --- .../intellij/codeInsight/daemon/impl/PassExecutorService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java index 8616ed24c445..1e5bbf036459 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java @@ -478,7 +478,7 @@ public abstract class PassExecutorService implements Disposable { synchronized (PassExecutorService.class) { StringBuilder s = new StringBuilder(); for (Object o : info) { - s.append(o.toString()); + s.append(o.toString()).append(" "); } String message = StringUtil.repeatSymbol(' ', getThreadNum() * 4) + " " + pass + " " From 679f78869d0ce5dbdd57cc4aa250bf13cfd1e756 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 30 Jun 2011 19:05:47 +0400 Subject: [PATCH 15/16] indexing bug fix --- .../com/intellij/util/containers/Queue.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/Queue.java b/platform/util/src/com/intellij/util/containers/Queue.java index 0ddf7b38fea1..c6d373e22943 100644 --- a/platform/util/src/com/intellij/util/containers/Queue.java +++ b/platform/util/src/com/intellij/util/containers/Queue.java @@ -22,7 +22,10 @@ public class Queue { private Object[] myArray; private int myFirst; private int myLast; - private boolean isInverted; + + // if true, elements are located at myFirst..myArray.length and 0..myLast + // otherwise, they are at myFirst..myLast + private boolean isWrapped; public Queue(int initialCapacity) { myArray = new Object[initialCapacity]; @@ -34,12 +37,12 @@ public class Queue { myArray = normalize(currentSize * 2); myFirst = 0; myLast = currentSize; - isInverted = false; + isWrapped = false; } myArray[myLast] = object; myLast++; if (myLast == myArray.length) { - isInverted = !isInverted; + isWrapped = !isWrapped; myLast = 0; } } @@ -49,20 +52,24 @@ public class Queue { } public int size() { - return isInverted ? myArray.length - myFirst + myLast : myLast - myFirst; + return isWrapped ? myArray.length - myFirst + myLast : myLast - myFirst; } public List toList() { return Arrays.asList(normalize(size())); } + public Object[] toArray() { + return normalize(size()); + } + public T pullFirst() { T result = (T)myArray[myFirst]; myArray[myFirst] = null; myFirst++; if (myFirst == myArray.length) { myFirst = 0; - isInverted = !isInverted; + isWrapped = !isWrapped; } return result; } @@ -79,14 +86,13 @@ public class Queue { private T[] normalize(int capacity) { T[] result = (T[])new Object[capacity]; - int tailLength; - if (isInverted) { - tailLength = copyFromTo(myFirst, myArray.length, result, 0); + if (isWrapped) { + int tailLength = copyFromTo(myFirst, myArray.length, result, 0); + copyFromTo(0, myLast, result, tailLength); } else { - tailLength = 0; + copyFromTo(myFirst, myLast, result, 0); } - copyFromTo(0, myLast, result, tailLength); return result; } @@ -94,7 +100,7 @@ public class Queue { for (int i = 0; i < myArray.length; i++) { myArray[i] = null; } - + isWrapped = false; myFirst = myLast = 0; } } From fc47b65dcd51cac60962b994645d895c8c88e319 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 4 Jul 2011 18:08:19 +0400 Subject: [PATCH 16/16] better initial dialog size --- .../refactoring/extractMethod/ExtractMethodDialog.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java index 8f575cfeaec8..1eb37c560ab6 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java @@ -40,6 +40,7 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NonNls; import javax.swing.*; +import javax.swing.border.Border; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; @@ -102,7 +103,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog { myVariableData = inputVariables; myHelpId = helpId; mySignature = new MethodSignatureComponent("", project, JavaFileType.INSTANCE); - mySignature.setPreferredSize(new Dimension(-1, 130)); + mySignature.setPreferredSize(new Dimension(450, 100)); setTitle(title); // Create UI components @@ -220,7 +221,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog { protected JPanel createOptionsPanel() { final JPanel optionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); - optionsPanel.add(new JLabel("Options: ")); + //optionsPanel.add(new JLabel("Options: ")); if (myStaticFlag || myCanBeStatic) { myMakeStatic.setEnabled(!myStaticFlag); @@ -235,6 +236,8 @@ public class ExtractMethodDialog extends AbstractExtractDialog { myMakeStatic.setSelected(false); myMakeStatic.setEnabled(false); } + final Border emptyBorder = IdeBorderFactory.createEmptyBorder(5, 0, 5, 4); + myMakeStatic.setBorder(emptyBorder); myFoldParameters.setSelected(myVariableData.isFoldingSelectedByDefault()); myFoldParameters.setVisible(myVariableData.isFoldable()); @@ -251,6 +254,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog { } }); optionsPanel.add(myFoldParameters); + myFoldParameters.setBorder(emptyBorder); boolean canBeVarargs = false; for (ParameterTablePanel.VariableData data : myInputVariables) { @@ -262,6 +266,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog { if (canBeVarargs) { myMakeVarargs = new NonFocusableCheckBox(RefactoringBundle.message("declare.varargs.checkbox")); + myMakeVarargs.setBorder(emptyBorder); updateVarargsEnabled(); myMakeVarargs.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { @@ -274,6 +279,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog { if (myCbChainedConstructor != null) { optionsPanel.add(myCbChainedConstructor); + myCbChainedConstructor.setBorder(emptyBorder); myCbChainedConstructor.addItemListener(new ItemListener() { public void itemStateChanged(final ItemEvent e) { if (myDefaultVisibility) {