Merge remote-tracking branch 'origin/master'
authorAlexander Lobas <Alexander.Lobas@jetbrains.com>
Mon, 30 Jan 2012 16:28:55 +0000 (20:28 +0400)
committerAlexander Lobas <Alexander.Lobas@jetbrains.com>
Mon, 30 Jan 2012 16:28:55 +0000 (20:28 +0400)
68 files changed:
.idea/libraries/Mocks.xml
java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java
java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java
java/debugger/impl/src/com/intellij/debugger/impl/EventQueue.java
java/debugger/impl/src/com/intellij/debugger/impl/EventQueueClosedException.java
java/debugger/impl/src/com/intellij/debugger/impl/InvokeAndWaitThread.java
java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java
java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java
java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java
java/idea-ui/src/com/intellij/openapi/projectRoots/ui/ProjectJdksEditor.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JdkComboBox.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleJdkConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdkConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java
java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaAnonymousClassesNodeProvider.java
java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java
java/java-tests/testData/codeInsight/completion/normal/NoClosingWhenChoosingWithParenBeforeIdentifier.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/completion/normal/NoClosingWhenChoosingWithParenBeforeIdentifier_after.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/completion/normal/NoGenericsWhenChoosingWithParen.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/completion/normal/NoGenericsWhenChoosingWithParen_after.java [new file with mode: 0644]
java/java-tests/testData/fileStructure/selection/Constructor.java [new file with mode: 0644]
java/java-tests/testData/fileStructure/selection/Constructor.tree [new file with mode: 0644]
java/java-tests/testData/fileStructure/selection/Field.java [new file with mode: 0644]
java/java-tests/testData/fileStructure/selection/Field.tree [new file with mode: 0644]
java/java-tests/testData/fileStructure/selection/InsideClass.java [new file with mode: 0644]
java/java-tests/testData/fileStructure/selection/InsideClass.tree [new file with mode: 0644]
java/java-tests/testData/fileStructure/selection/Method.java [new file with mode: 0644]
java/java-tests/testData/fileStructure/selection/Method.tree [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureSelectionTest.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureTestCase.java [new file with mode: 0644]
jps/jps-builders/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java
jps/jps-builders/src/org/jetbrains/jps/incremental/groovy/GroovycOSProcessHandler.java
jps/jps-builders/src/org/jetbrains/jps/incremental/messages/CompilerMessage.java
platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
platform/lang-api/src/com/intellij/codeInsight/completion/util/ParenthesesInsertHandler.java
platform/lang-impl/src/com/intellij/execution/util/ProgramParametersUtil.java
platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java
platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java
platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java
platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeStructure.java
platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
platform/platform-resources-en/src/messages/ApplicationBundle.properties
platform/platform-resources-en/src/messages/ProjectBundle.properties
platform/platform-resources/src/META-INF/LangExtensionPoints.xml
platform/platform-resources/src/fonts/Inconsolata.ttf [moved from resources/src/fonts/Inconsolata.ttf with 100% similarity]
platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymLinkHandlingTest.java
platform/testFramework/src/com/intellij/testFramework/FileStructureTestBase.java
platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightFixtureTestCase.java
platform/util/src/com/intellij/openapi/util/io/FileUtil.java
plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathReader.java
plugins/eclipse/src/org/jetbrains/idea/eclipse/importWizard/EclipseImportBuilder.java
plugins/git4idea/src/git4idea/branch/GitCheckoutNewBranchOperation.java
plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java
plugins/git4idea/src/git4idea/branch/GitWouldBeOverwrittenByCheckoutDialog.java
plugins/git4idea/src/git4idea/commands/Git.java
plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyClassNameInsertHandler.java
plugins/junit/src/com/intellij/execution/junit/TestDirectory.java
plugins/junit/src/com/intellij/execution/junit/TestObject.java
plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfiguration.java
plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java
plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java
xml/impl/src/com/intellij/xml/util/ColorSampleLookupValue.java

index 5a52b9d163915adb7ea10b4ea8b46d4e5bcf20d0..ba510628d7429c886d8800d35d62d919a7931352 100644 (file)
@@ -5,14 +5,21 @@
       <root url="jar://$PROJECT_DIR$/lib/dev/jmock-1.0.1.jar!/" />
       <root url="jar://$PROJECT_DIR$/lib/dev/jmock-cglib-1.0.1.jar!/" />
       <root url="jar://$PROJECT_DIR$/lib/dev/easymockclassextension.jar!/" />
-      <root url="jar://$PROJECT_DIR$/lib/dev/jmock-junit4-2.3.0-RC2.jar!/" />
-      <root url="jar://$PROJECT_DIR$/lib/dev/jmock-2.3.0-RC2.jar!/" />
       <root url="jar://$PROJECT_DIR$/lib/dev/objenesis-1.0.jar!/" />
-      <root url="jar://$PROJECT_DIR$/lib/dev/mockobjects-core-0.09.jar!/" />
-      <root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-library-1.0.jar!/" />
-      <root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-api-1.0.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/dev/mockobjects-core-0.09.jar!/ " />
+      <root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-core-1.1.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-library-1.1.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/dev/jmock-2.5.1.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/dev/jmock-junit4-2.5.1.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/dev/jmock-legacy-2.5.1.jar!/" />
     </CLASSES>
-    <JAVADOC />
-    <SOURCES />
+    <JAVADOC/>
+    <SOURCES>
+      <root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-core-1.1.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-library-1.1.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/dev/jmock-2.5.1.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/dev/jmock-junit4-2.5.1.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/dev/jmock-legacy-2.5.1.jar!/" />
+    </SOURCES>
   </library>
 </component>
\ No newline at end of file
index 6a6ef6bc66af6d0aadba29e6bec6e4d21bc3eb44..9e0e25ca9c94efeac34831ffe1b41c3756d547dd 100644 (file)
@@ -695,13 +695,13 @@ public class CompileServerManager implements ApplicationComponent{
 
     @Override
     public void sessionTerminated() {
-      String statusMessage = "Auto make completed";
+      String statusMessage = null/*"Auto make completed"*/;
       switch (myBuildStatus) {
         case SUCCESS:
-          statusMessage = "Auto make completed successfully";
+          //statusMessage = "Auto make completed successfully";
           break;
         case UP_TO_DATE:
-          statusMessage = "All files are up-to-date";
+          //statusMessage = "All files are up-to-date";
           break;
         case ERRORS:
           statusMessage = "Auto make completed with errors";
@@ -710,9 +710,11 @@ public class CompileServerManager implements ApplicationComponent{
           statusMessage = "Auto make has been canceled";
           break;
       }
-      final Notification notification = CompilerManager.NOTIFICATION_GROUP.createNotification(statusMessage, MessageType.INFO);
-      if (!myProject.isDisposed()) {
-        notification.notify(myProject);
+      if (statusMessage != null) {
+        final Notification notification = CompilerManager.NOTIFICATION_GROUP.createNotification(statusMessage, MessageType.INFO);
+        if (!myProject.isDisposed()) {
+          notification.notify(myProject);
+        }
       }
     }
 
index 027b82b25641fc1e7be06df2cc3541b30508c70a..f5569d5bdb1f54b4ae9bfcfb37b114926fe5bef7 100644 (file)
@@ -73,22 +73,20 @@ public class DebuggerManagerThreadImpl extends InvokeAndWaitThread<DebuggerComma
     }
   }
 
-  public void pushBack(DebuggerCommandImpl managerCommand) {
-    if(myEvents.isClosed()) {
+  public boolean pushBack(DebuggerCommandImpl managerCommand) {
+    final boolean pushed = super.pushBack(managerCommand);
+    if (!pushed) {
       managerCommand.notifyCancelled();
     }
-    else {
-      super.pushBack(managerCommand);
-    }
+    return pushed;
   }
 
-  public void schedule(DebuggerCommandImpl managerCommand) {
-    if(myEvents.isClosed()) {
+  public boolean schedule(DebuggerCommandImpl managerCommand) {
+    final boolean scheduled = super.schedule(managerCommand);
+    if (!scheduled) {
       managerCommand.notifyCancelled();
     }
-    else {
-      super.schedule(managerCommand);
-    }
+    return scheduled;
   }
 
   /**
index d222c97888d99534da56c8966b7d72ba28526938..a7bd73ae541a39293e2439de5a82cddf155332dc 100644 (file)
@@ -45,36 +45,42 @@ public class EventQueue<E> {
     }
   }
 
-  public void pushBack(@NotNull E event, int priority) {
+  public boolean pushBack(@NotNull E event, int priority) {
     if(LOG.isDebugEnabled()) {
       LOG.debug("pushBack event " + event);
     }
 
     myLock.lock();
     try {
-      assertOpen();
+      if (isClosed()) {
+        return false;
+      }
       getEventsList(priority).addFirst(event);
       myEventsAvailable.signalAll();
     }
     finally {
       myLock.unlock();
     }
+    return true;
   }
 
-  public void put(@NotNull E event, int priority) {
+  public boolean put(@NotNull E event, int priority) {
     if(LOG.isDebugEnabled()) {
       LOG.debug("put event " + event);
     }
 
     myLock.lock();
     try {
-      assertOpen();
+      if (isClosed()) {
+        return false;
+      }
       getEventsList(priority).offer(event);
       myEventsAvailable.signalAll();
     }
     finally {
       myLock.unlock();
     }
+    return true;
   }
 
   private LinkedList<E> getEventsList(final int priority) {
@@ -84,7 +90,6 @@ public class EventQueue<E> {
   public void close(){
     myLock.lock();
     try {
-      assertOpen();
       myIsClosed = true;
       myEventsAvailable.signalAll();
     }
@@ -93,10 +98,6 @@ public class EventQueue<E> {
     }
   }
 
-  private void assertOpen() {
-    if (myIsClosed) throw new AssertionError("Already closed");
-  }
-
   private E getEvent() throws EventQueueClosedException {
     myLock.lock();
     try {
index be0cd485b30bd22f48b4d060c43b8ea371425628..d58b663f522a70d0b17455255538565dd901e503 100644 (file)
@@ -19,4 +19,8 @@ package com.intellij.debugger.impl;
  * @author lex
  */
 public class EventQueueClosedException extends Exception {
+  @Override
+  public Throwable fillInStackTrace() {
+    return this;
+  }
 }
index 3278e59f1764cb32351f9790a8788bd2b2c9d812..3576c86b4f65052a0c2337c56f8b55d50865e674 100644 (file)
@@ -28,12 +28,12 @@ public abstract class InvokeAndWaitThread<E extends DebuggerTask> extends Invoke
    * !!! Do not remove this code !!!
    * Otherwise it will be impossible to override schedule method
    */
-  public void schedule(E e) {
-    super.schedule(e);
+  public boolean schedule(E e) {
+    return super.schedule(e);
   }
 
-  public void pushBack(E e) {
-    super.pushBack(e);
+  public boolean pushBack(E e) {
+    return super.pushBack(e);
   }
 
   public void invokeAndWait(final E runnable) {
index b3ddf3a90ed25e0adabdd4b37896ed3e49fa4195..e8835275f907f86126fb4f53df3455e8dde96149 100644 (file)
@@ -172,18 +172,18 @@ public abstract class InvokeThread<E extends PrioritizedTask> {
     return request != null? request.getOwner() : null;
   }
 
-  public void schedule(E r) {
+  public boolean schedule(E r) {
     if(LOG.isDebugEnabled()) {
       LOG.debug("schedule " + r + " in " + this);
     }
-    myEvents.put(r, r.getPriority().ordinal());
+    return myEvents.put(r, r.getPriority().ordinal());
   }
 
-  public void pushBack(E r) {
+  public boolean pushBack(E r) {
     if(LOG.isDebugEnabled()) {
       LOG.debug("pushBack " + r + " in " + this);
     }
-    myEvents.pushBack(r, r.getPriority().ordinal());
+    return myEvents.pushBack(r, r.getPriority().ordinal());
   }
 
   protected void switchToRequest(WorkerThreadRequest newWorkerThread) {
index 1f9444abfad166526cbdc92db508691190ca9a48..69d02d7782563bbbedcf8f706f509a0b178e7870 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.execution.junit.RefactoringListeners;
 import com.intellij.execution.process.OSProcessHandler;
 import com.intellij.execution.runners.ExecutionEnvironment;
 import com.intellij.execution.util.JavaParametersUtil;
+import com.intellij.execution.util.ProgramParametersUtil;
 import com.intellij.openapi.components.PathMacroManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.extensions.Extensions;
@@ -31,7 +32,6 @@ import com.intellij.openapi.module.Module;
 import com.intellij.openapi.options.SettingsEditor;
 import com.intellij.openapi.options.SettingsEditorGroup;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.DefaultJDOMExternalizer;
 import com.intellij.openapi.util.InvalidDataException;
@@ -138,19 +138,13 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
   }
 
   public void checkConfiguration() throws RuntimeConfigurationException {
-    if (ALTERNATIVE_JRE_PATH_ENABLED){
-      if (ALTERNATIVE_JRE_PATH == null ||
-          ALTERNATIVE_JRE_PATH.length() == 0 ||
-          !JavaSdkImpl.checkForJre(ALTERNATIVE_JRE_PATH)){
-        throw new RuntimeConfigurationWarning(ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", ALTERNATIVE_JRE_PATH));
-      }
-    }
+    JavaParametersUtil.checkAlternativeJRE(this);
     final JavaRunConfigurationModule configurationModule = getConfigurationModule();
     final PsiClass psiClass = configurationModule.checkModuleAndClassName(MAIN_CLASS_NAME, ExecutionBundle.message("no.main.class.specified.error.text"));
     if (!PsiMethodUtil.hasMainMethod(psiClass)) {
       throw new RuntimeConfigurationWarning(ExecutionBundle.message("main.method.not.found.in.class.error.message", MAIN_CLASS_NAME));
     }
-
+    ProgramParametersUtil.checkWorkingDirectoryExist(this, getProject(), configurationModule.getModule());
     JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this);
   }
 
index bb8f62966e2164cf53a8fd07fd9f2bf2299b28d0..e19d2f9d9e6c50deb77a61c58f72414cb96c0d67 100644 (file)
@@ -17,9 +17,11 @@ package com.intellij.execution.util;
 
 import com.intellij.execution.CantRunException;
 import com.intellij.execution.CommonJavaRunConfigurationParameters;
+import com.intellij.execution.ExecutionBundle;
 import com.intellij.execution.JavaExecutionUtil;
 import com.intellij.execution.configurations.JavaParameters;
 import com.intellij.execution.configurations.RunConfigurationModule;
+import com.intellij.execution.configurations.RuntimeConfigurationWarning;
 import com.intellij.execution.configurations.SimpleJavaParameters;
 import com.intellij.execution.junit.JUnitUtil;
 import com.intellij.openapi.module.Module;
@@ -122,4 +124,15 @@ public class JavaParametersUtil {
     if (jdk == null) throw CantRunException.noJdkConfigured();
     return jdk;
   }
+
+  public static void checkAlternativeJRE(CommonJavaRunConfigurationParameters configuration) throws RuntimeConfigurationWarning {
+    if (configuration.isAlternativeJrePathEnabled()) {
+      if (configuration.getAlternativeJrePath() == null ||
+          configuration.getAlternativeJrePath().length() == 0 ||
+          !JavaSdk.checkForJre(configuration.getAlternativeJrePath())) {
+        throw new RuntimeConfigurationWarning(
+          ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", configuration.getAlternativeJrePath()));
+      }
+    }
+  }
 }
index bb416ccb404748fc2119543a4fd40885a475f193..2739fdea8d4a7cb568e2ff61186b84c30971f291 100644 (file)
@@ -39,8 +39,12 @@ public class ProjectJdksEditor extends DialogWrapper {
 
 
   public ProjectJdksEditor(final Sdk jdk, Project project, Component parent) {
+    this(jdk, parent, new ProjectJdksConfigurable(project));
+  }
+  
+  public ProjectJdksEditor(final Sdk jdk, Component parent, ProjectJdksConfigurable configurable) {
     super(parent, true);
-    myConfigurable = new ProjectJdksConfigurable(project);
+    myConfigurable = configurable;
     SwingUtilities.invokeLater(new Runnable(){
       public void run() {
         myConfigurable.selectNodeInTree(jdk != null ? jdk.getName() : null);
index e70b585dac5bf7b6feb17e8d6476e8a971528f3e..97807b9292df2a62d2deaea78ccff1d948e8b877 100644 (file)
@@ -18,7 +18,6 @@ package com.intellij.openapi.roots.ui.configuration;
 import com.intellij.ide.DataManager;
 import com.intellij.ide.util.projectWizard.ProjectJdkListRenderer;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
-import com.intellij.openapi.application.ApplicationBundle;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectBundle;
 import com.intellij.openapi.projectRoots.Sdk;
@@ -47,8 +46,7 @@ import java.util.Comparator;
  * @author Eugene Zhuravlev
  * @since May 18, 2005
  */
-class JdkComboBox extends ComboBoxWithWidePopup {
-  private final JButton myEditButton = new JButton(ApplicationBundle.message("button.edit"));
+public class JdkComboBox extends ComboBoxWithWidePopup {
 
   public JdkComboBox(@NotNull final ProjectSdksModel jdkModel) {
     super(new JdkComboBoxModel(jdkModel));
@@ -101,17 +99,22 @@ class JdkComboBox extends ComboBoxWithWidePopup {
     return minSize;
   }
 
-  public JButton createSetupButton(final Project project, final ProjectSdksModel jdksModel, final JdkComboBoxItem firstItem) {
-    return createSetupButton(project, jdksModel, firstItem, null, false);
+  public void setSetupButton(final JButton setUpButton,
+                                final Project project,
+                                final ProjectSdksModel jdksModel,
+                                final JdkComboBoxItem firstItem,
+                                @Nullable final Condition<Sdk> additionalSetup,
+                                final boolean moduleJdkSetup) {
+    setSetupButton(setUpButton, project, jdksModel, firstItem, additionalSetup,
+                   ProjectBundle.message("project.roots.set.up.jdk.title", moduleJdkSetup ? 1 : 2));
   }
 
-
-  public JButton createSetupButton(final Project project,
-                                   final ProjectSdksModel jdksModel,
-                                   final JdkComboBoxItem firstItem,
-                                   @Nullable final Condition<Sdk> additionalSetup,
-                                   final boolean moduleJdkSetup) {
-    final JButton setUpButton = new JButton(ApplicationBundle.message("button.new"));
+  public void setSetupButton(final JButton setUpButton,
+                                final Project project,
+                                final ProjectSdksModel jdksModel,
+                                final JdkComboBoxItem firstItem,
+                                @Nullable final Condition<Sdk> additionalSetup,
+                                final String actionGroupTitle) {
     setUpButton.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
         final JdkListConfigurable configurable = JdkListConfigurable.getInstance(project);
@@ -129,16 +132,16 @@ class JdkComboBox extends ComboBoxWithWidePopup {
           }
         });
         JBPopupFactory.getInstance()
-          .createActionGroupPopup(ProjectBundle.message("project.roots.set.up.jdk.title", moduleJdkSetup ? 1 : 2), group,
-                                  DataManager.getInstance().getDataContext(JdkComboBox.this), JBPopupFactory.ActionSelectionAid.MNEMONICS, false)
+          .createActionGroupPopup(actionGroupTitle, group,
+                                  DataManager.getInstance().getDataContext(JdkComboBox.this), JBPopupFactory.ActionSelectionAid.MNEMONICS,
+                                  false)
           .showUnderneathOf(setUpButton);
       }
     });
-    return setUpButton;
   }
 
-  public void appendEditButton(final Project project, final JPanel panel, GridBagConstraints gc, final Computable<Sdk> retrieveJDK){
-    myEditButton.addActionListener(new ActionListener() {
+  public void setEditButton(final JButton editButton, final Project project, final Computable<Sdk> retrieveJDK){
+    editButton.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
         final Sdk projectJdk = retrieveJDK.compute();
         if (projectJdk != null) {
@@ -146,17 +149,17 @@ class JdkComboBox extends ComboBoxWithWidePopup {
         }
       }
     });
-    addActionListener(new ActionListener(){
+    addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
         final JdkComboBoxItem selectedItem = getSelectedItem();
         if (selectedItem instanceof ProjectJdkComboBoxItem) {
-          myEditButton.setEnabled(ProjectStructureConfigurable.getInstance(project).getProjectJdksModel().getProjectSdk() != null);
-        } else {
-          myEditButton.setEnabled(!(selectedItem instanceof InvalidJdkComboBoxItem) && selectedItem != null && selectedItem.getJdk() != null);
+          editButton.setEnabled(ProjectStructureConfigurable.getInstance(project).getProjectJdksModel().getProjectSdk() != null);
+        }
+        else {
+          editButton.setEnabled(!(selectedItem instanceof InvalidJdkComboBoxItem) && selectedItem != null && selectedItem.getJdk() != null);
         }
       }
     });
-    panel.add(myEditButton, gc);
   }
 
   public JdkComboBoxItem getSelectedItem() {
@@ -260,6 +263,11 @@ class JdkComboBox extends ComboBoxWithWidePopup {
       return myJdk;
     }
 
+    @Nullable
+    public String getSdkName() {
+      return myJdk != null ? myJdk.getName() : null;
+    }
+    
     public String toString() {
       return myJdk.getName();
     }
@@ -286,15 +294,19 @@ class JdkComboBox extends ComboBoxWithWidePopup {
   }
 
   private static class InvalidJdkComboBoxItem extends JdkComboBoxItem {
-    private final String myName;
+    private final String mySdkName;
 
     public InvalidJdkComboBoxItem(String name) {
       super(null);
-      myName = ProjectBundle.message("jdk.combo.box.invalid.item", name);
+      mySdkName = name;
+    }
+
+    public String getSdkName() {
+      return mySdkName;
     }
 
     public String toString() {
-      return myName;
+      return ProjectBundle.message("jdk.combo.box.invalid.item", mySdkName);
     }
   }
 }
index 718f923efcea41898c1a2910c603a4261faaa2af..3dd421d20568b150cadee48acdcd7386618b7876 100644 (file)
@@ -17,6 +17,7 @@
 package com.intellij.openapi.roots.ui.configuration;
 
 import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationBundle;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectBundle;
@@ -119,17 +120,18 @@ public abstract class ModuleJdkConfigurable implements Disposable {
                                                          GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
                                                          new Insets(6, 6, 12, 0), 0, 0));
     final Project project = getRootModel().getModule().getProject();
-    final JButton setUpButton = myCbModuleJdk
-      .createSetupButton(project, myJdksModel, new JdkComboBox.ProjectJdkComboBoxItem(), new Condition<Sdk>(){
+    final JButton setUpButton = new JButton(ApplicationBundle.message("button.new"));
+    myCbModuleJdk
+      .setSetupButton(setUpButton, project, myJdksModel, new JdkComboBox.ProjectJdkComboBoxItem(), new Condition<Sdk>() {
         public boolean value(Sdk jdk) {
           final Sdk projectJdk = myJdksModel.getProjectSdk();
-          if (projectJdk == null){
+          if (projectJdk == null) {
             final int res =
               Messages.showYesNoDialog(myJdkPanel,
                                        ProjectBundle.message("project.roots.no.jdk.on.project.message"),
-                                       ProjectBundle.message("project.roots.no.jdk.on.projecct.title"),
+                                       ProjectBundle.message("project.roots.no.jdk.on.project.title"),
                                        Messages.getInformationIcon());
-            if (res == DialogWrapper.OK_EXIT_CODE){
+            if (res == DialogWrapper.OK_EXIT_CODE) {
               myJdksModel.setProjectSdk(jdk);
               return true;
             }
@@ -140,12 +142,16 @@ public abstract class ModuleJdkConfigurable implements Disposable {
     myJdkPanel.add(setUpButton, new GridBagConstraints(2, 0, 1, 1, 0, 0,
                                                        GridBagConstraints.WEST, GridBagConstraints.NONE,
                                                        new Insets(0, 4, 7, 0), 0, 0));
-    myCbModuleJdk.appendEditButton(getRootModel().getModule().getProject(), myJdkPanel, new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 1.0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 7, 0), 0, 0) , new Computable<Sdk>() {
+    final JButton editButton = new JButton(ApplicationBundle.message("button.edit"));
+    myCbModuleJdk.setEditButton(editButton, getRootModel().getModule().getProject(), new Computable<Sdk>() {
       @Nullable
       public Sdk compute() {
         return getRootModel().getSdk();
       }
     });
+    myJdkPanel.add(editButton,
+                   new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 1.0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE,
+                                          new Insets(0, 4, 7, 0), 0, 0));
   }
 
   private void clearCaches() {
index 54a36d3c569f6d58359aee78a02e3635c33ef075..ade16cb422a535e9588d20f463e21c75e9ed56cf 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.intellij.openapi.roots.ui.configuration;
 
+import com.intellij.openapi.application.ApplicationBundle;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.options.UnnamedConfigurable;
 import com.intellij.openapi.project.Project;
@@ -90,14 +91,19 @@ public class ProjectJdkConfigurable implements UnnamedConfigurable {
       });
       myJdkPanel.add(new JLabel(ProjectBundle.message("module.libraries.target.jdk.project.radio")), new GridBagConstraints(0, 0, 3, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 4, 0), 0, 0));
       myJdkPanel.add(myCbProjectJdk, new GridBagConstraints(0, 1, 1, 1, 0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0));
-      final JButton setUpButton = myCbProjectJdk.createSetupButton(myProject, myJdksModel, new JdkComboBox.NoneJdkComboBoxItem());
+      final JButton setUpButton = new JButton(ApplicationBundle.message("button.new"));
+      myCbProjectJdk.setSetupButton(setUpButton, myProject, myJdksModel, new JdkComboBox.NoneJdkComboBoxItem(), null, false);
       myJdkPanel.add(setUpButton, new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0));
-      myCbProjectJdk.appendEditButton(myProject, myJdkPanel, new GridBagConstraints(GridBagConstraints.RELATIVE, 1, 1, 1, 1.0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0), new Computable<Sdk>() {
+      final JButton editButton = new JButton(ApplicationBundle.message("button.edit"));
+      myCbProjectJdk.setEditButton(editButton, myProject, new Computable<Sdk>() {
         @Nullable
         public Sdk compute() {
           return myJdksModel.getProjectSdk();
         }
       });
+
+      myJdkPanel.add(editButton, new GridBagConstraints(GridBagConstraints.RELATIVE, 1, 1, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
+                                                            GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0));
     }
     return myJdkPanel;
   }
index 456a15a004ea43337fbf164234bdc60fd7439c95..ac6d5cd9ca80f09324f82166c7c8a69207092aeb 100644 (file)
@@ -57,13 +57,16 @@ public class ProjectJdksConfigurable extends MasterDetailsComponent {
 
   private final ProjectSdksModel myProjectJdksModel;
   private final Project myProject;
-  @NonNls 
+  @NonNls
   private static final String SPLITTER_PROPORTION = "project.jdk.splitter";
 
   public ProjectJdksConfigurable(Project project) {
-    super();
+    this(project, ProjectStructureConfigurable.getInstance(project).getProjectJdksModel());
+  }
+
+  public ProjectJdksConfigurable(Project project, ProjectSdksModel sdksModel) {
     myProject = project;
-    myProjectJdksModel = ProjectStructureConfigurable.getInstance(project).getProjectJdksModel();
+    myProjectJdksModel = sdksModel;
     initTree();
   }
 
index a549c928659ca97725e173722ae4367b75e9a873..fa4ec428ed8643a6dec6f17dc71bda46640bcfa7 100644 (file)
@@ -72,7 +72,8 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
     if (delegate instanceof PsiTypeLookupItem) {
       fillTypeArgs = !isRawTypeExpected(context, (PsiTypeLookupItem)delegate) &&
                      psiClass.getTypeParameters().length > 0 &&
-                     ((PsiTypeLookupItem)delegate).calcGenerics(position).isEmpty();
+                     ((PsiTypeLookupItem)delegate).calcGenerics(position).isEmpty() &&
+                     context.getCompletionChar() != '(';
       delegate.handleInsert(context);
       PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting(context.getFile().getViewProvider());
     }
@@ -99,7 +100,7 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
       editor.getDocument().insertString(offset, " {}");
       editor.getCaretModel().moveToOffset(offset + 2);
 
-      if (fillTypeArgs && promptTypeArgs(context, context.getOffset(insideRef))) return;
+      if (fillTypeArgs && JavaCompletionUtil.promptTypeArgs(context, context.getOffset(insideRef))) return;
 
       context.setLaterRunnable(generateAnonymousBody(editor, context.getFile()));
     }
@@ -116,7 +117,7 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
       if (mySmart) {
         FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW);
       }
-      if (fillTypeArgs && promptTypeArgs(context, context.getOffset(insideRef))) return;
+      if (fillTypeArgs && JavaCompletionUtil.promptTypeArgs(context, context.getOffset(insideRef))) return;
     }
   }
 
@@ -136,23 +137,6 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
     return false;
   }
 
-  static boolean promptTypeArgs(InsertionContext context, int offset) {
-    if (offset < 0) {
-      return false;
-    }
-
-    OffsetKey key = context.trackOffset(offset, false);
-    PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
-    offset = context.getOffset(key);
-    if (offset < 0) {
-      return false;
-    }
-
-    context.getDocument().insertString(offset, "<>");
-    context.getEditor().getCaretModel().moveToOffset(offset + 1);
-    return true;
-  }
-
   public static boolean insertParentheses(InsertionContext context,
                                           LookupItem delegate,
                                           final PsiClass psiClass,
index e93f0c426919f9c586f851aa279ba32cb6bab525..12f1ec79ad7bfa98ac908142d0fbafa1b1aa0007 100644 (file)
@@ -125,8 +125,8 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
       }
     }
 
-    if (fillTypeArgs) {
-      ConstructorInsertHandler.promptTypeArgs(context, context.getOffset(refEnd));
+    if (fillTypeArgs && context.getCompletionChar() != '(') {
+      JavaCompletionUtil.promptTypeArgs(context, context.getOffset(refEnd));
     }
   }
 
index 9000a39a6bd1682eb63f9841f0be621336f385e1..d876f0ad9ba88929b31a19e5f58ff7f3d91603f9 100644 (file)
@@ -44,6 +44,7 @@ import com.intellij.psi.filters.ElementFilter;
 import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
 import com.intellij.psi.filters.element.ExcludeSillyAssignment;
 import com.intellij.psi.html.HtmlTag;
+import com.intellij.psi.impl.source.PostprocessReformattingAspect;
 import com.intellij.psi.impl.source.PsiImmediateClassType;
 import com.intellij.psi.javadoc.PsiDocToken;
 import com.intellij.psi.scope.BaseScopeProcessor;
@@ -909,4 +910,21 @@ public class JavaCompletionUtil {
     }
     return !hasAccessibleInnerClass(psiClass, position);
   }
+
+  public static boolean promptTypeArgs(InsertionContext context, int offset) {
+    if (offset < 0) {
+      return false;
+    }
+
+    OffsetKey key = context.trackOffset(offset, false);
+    PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
+    offset = context.getOffset(key);
+    if (offset < 0) {
+      return false;
+    }
+
+    context.getDocument().insertString(offset, "<>");
+    context.getEditor().getCaretModel().moveToOffset(offset + 1);
+    return true;
+  }
 }
index 2f41b69c8368fe31c1f89fb619226eaf4d9a92fb..65bc73d12b8abdb6427e37114bcc3842a9082c9f 100644 (file)
@@ -43,6 +43,7 @@ import java.util.List;
  */
 public class JavaAnonymousClassesNodeProvider implements FileStructureNodeProvider<JavaAnonymousClassTreeElement>, PropertyOwner {
   public static final String ID = "SHOW_ANONYMOUS";
+  public static final String JAVA_ANONYMOUS_PROPERTY_NAME = "java.anonymous.provider";
 
   @Override
   public Collection<JavaAnonymousClassTreeElement> provideNodes(TreeElement node) {
@@ -87,6 +88,6 @@ public class JavaAnonymousClassesNodeProvider implements FileStructureNodeProvid
   @NotNull
   @Override
   public String getPropertyName() {
-    return "java.anonymous.provider";
+    return JAVA_ANONYMOUS_PROPERTY_NAME;
   }
 }
index abc477fed6fec160e1fc49ec585df0fca8f45634..5d06e931eab2fb1138f2231879a0e1a5c279b05f 100644 (file)
@@ -17,7 +17,10 @@ package com.intellij.refactoring.memberPullUp;
 
 import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
 import com.intellij.psi.*;
+import com.intellij.psi.statistics.StatisticsInfo;
+import com.intellij.psi.statistics.StatisticsManager;
 import com.intellij.refactoring.HelpID;
 import com.intellij.refactoring.JavaRefactoringSettings;
 import com.intellij.refactoring.RefactoringBundle;
@@ -57,6 +60,7 @@ public class PullUpDialog extends RefactoringDialog {
   private List<MemberInfo> myMemberInfos;
   private DocCommentPanel myJavaDocPanel;
   private JComboBox myClassCombo;
+  private static final String PULL_UP_STATISTICS_KEY = "pull.up##";
 
   public interface Callback {
     boolean checkConflicts(PullUpDialog dialog);
@@ -127,11 +131,10 @@ public class PullUpDialog extends RefactoringDialog {
     myClassCombo.setRenderer(new ClassCellRenderer(myClassCombo.getRenderer()));
     classComboLabel.setText(RefactoringBundle.message("pull.up.members.to", UsageViewUtil.getLongName(myClass)));
     classComboLabel.setLabelFor(myClassCombo);
-
-    PsiClass nearestBase = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false);
+    final PsiClass preselection = getPreselection();
     int indexToSelect = 0;
-    if (nearestBase != null) {
-      indexToSelect = mySuperClasses.indexOf(nearestBase);
+    if (preselection != null) {
+      indexToSelect = mySuperClasses.indexOf(preselection);
     }
     myClassCombo.setSelectedIndex(indexToSelect);
     myClassCombo.addItemListener(new ItemListener() {
@@ -152,6 +155,27 @@ public class PullUpDialog extends RefactoringDialog {
     return panel;
   }
 
+  private PsiClass getPreselection() {
+    PsiClass preselection = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false);
+
+    final String statKey = PULL_UP_STATISTICS_KEY + myClass.getQualifiedName();
+    for (StatisticsInfo info : StatisticsManager.getInstance().getAllValues(statKey)) {
+      final String superClassName = info.getValue();
+      PsiClass superClass = null;
+      for (PsiClass aClass : mySuperClasses) {
+        if (Comparing.strEqual(superClassName, aClass.getQualifiedName())) {
+          superClass = aClass;
+          break;
+        }
+      }
+      if (superClass != null && StatisticsManager.getInstance().getUseCount(info) > 0) {
+        preselection = superClass;
+        break;
+      }
+    }
+    return preselection;
+  }
+
   protected void doHelpAction() {
     HelpManager.getInstance().invokeHelp(HelpID.MEMBERS_PULL_UP);
   }
@@ -168,7 +192,9 @@ public class PullUpDialog extends RefactoringDialog {
   protected void doAction() {
     if (!myCallback.checkConflicts(this)) return;
     JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy();
-
+    StatisticsManager
+            .getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), getSuperClass().getQualifiedName()));
+    
     invokeRefactoring(new PullUpHelper(myClass, getSuperClass(), getSelectedMemberInfos(),
                                                new DocCommentPolicy(getJavaDocPolicy())));
     close(OK_EXIT_CODE);
diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoClosingWhenChoosingWithParenBeforeIdentifier.java b/java/java-tests/testData/codeInsight/completion/normal/NoClosingWhenChoosingWithParenBeforeIdentifier.java
new file mode 100644 (file)
index 0000000..e9682a8
--- /dev/null
@@ -0,0 +1,5 @@
+class Foo {
+  {
+    toS<caret>xxx
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoClosingWhenChoosingWithParenBeforeIdentifier_after.java b/java/java-tests/testData/codeInsight/completion/normal/NoClosingWhenChoosingWithParenBeforeIdentifier_after.java
new file mode 100644 (file)
index 0000000..489d121
--- /dev/null
@@ -0,0 +1,5 @@
+class Foo {
+  {
+    toString(<caret>xxx
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoGenericsWhenChoosingWithParen.java b/java/java-tests/testData/codeInsight/completion/normal/NoGenericsWhenChoosingWithParen.java
new file mode 100644 (file)
index 0000000..221d428
--- /dev/null
@@ -0,0 +1,5 @@
+class Foo {
+  {
+    new Hash<caret>
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoGenericsWhenChoosingWithParen_after.java b/java/java-tests/testData/codeInsight/completion/normal/NoGenericsWhenChoosingWithParen_after.java
new file mode 100644 (file)
index 0000000..0bb51b1
--- /dev/null
@@ -0,0 +1,7 @@
+import java.util.HashMap;
+
+class Foo {
+  {
+    new HashMap(<caret>)
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/fileStructure/selection/Constructor.java b/java/java-tests/testData/fileStructure/selection/Constructor.java
new file mode 100644 (file)
index 0000000..55a5f02
--- /dev/null
@@ -0,0 +1,7 @@
+class Constructor {
+  int num1;
+  int num2;
+
+  Constructor() {<caret>}
+  void foo() {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/fileStructure/selection/Constructor.tree b/java/java-tests/testData/fileStructure/selection/Constructor.tree
new file mode 100644 (file)
index 0000000..92a1b45
--- /dev/null
@@ -0,0 +1,6 @@
+-Constructor.java
+ -Constructor
+  [Constructor()]
+  foo():void
+  num1:int
+  num2:int
\ No newline at end of file
diff --git a/java/java-tests/testData/fileStructure/selection/Field.java b/java/java-tests/testData/fileStructure/selection/Field.java
new file mode 100644 (file)
index 0000000..35e5fea
--- /dev/null
@@ -0,0 +1,7 @@
+class Field {
+  int num1;
+  int <caret>num2;
+
+  Field() {}
+  void foo() {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/fileStructure/selection/Field.tree b/java/java-tests/testData/fileStructure/selection/Field.tree
new file mode 100644 (file)
index 0000000..1008b5f
--- /dev/null
@@ -0,0 +1,6 @@
+-Field.java
+ -Field
+  Field()
+  foo():void
+  num1:int
+  [num2:int]
diff --git a/java/java-tests/testData/fileStructure/selection/InsideClass.java b/java/java-tests/testData/fileStructure/selection/InsideClass.java
new file mode 100644 (file)
index 0000000..5fc06c0
--- /dev/null
@@ -0,0 +1,7 @@
+class InsideClass {
+  int num1;
+  int num2;
+  <caret>
+  InsideClass() {}
+  void foo() {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/fileStructure/selection/InsideClass.tree b/java/java-tests/testData/fileStructure/selection/InsideClass.tree
new file mode 100644 (file)
index 0000000..96d30ca
--- /dev/null
@@ -0,0 +1,6 @@
+-InsideClass.java
+ -[InsideClass]
+  InsideClass()
+  foo():void
+  num1:int
+  num2:int
\ No newline at end of file
diff --git a/java/java-tests/testData/fileStructure/selection/Method.java b/java/java-tests/testData/fileStructure/selection/Method.java
new file mode 100644 (file)
index 0000000..01e47e1
--- /dev/null
@@ -0,0 +1,7 @@
+class Method {
+  int num1;
+  int num2;
+
+  Method() {}
+  void foo() {<caret>}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/fileStructure/selection/Method.tree b/java/java-tests/testData/fileStructure/selection/Method.tree
new file mode 100644 (file)
index 0000000..5e868f2
--- /dev/null
@@ -0,0 +1,6 @@
+-Method.java
+ -Method
+  Method()
+  [foo():void]
+  num1:int
+  num2:int
\ No newline at end of file
index dc148649b4f321f98197714d8e0de93075afce1a..9e74675a1ec28e54155a5e44c4d16e7287914833 100644 (file)
@@ -1258,4 +1258,16 @@ public class ListUtils {
     }
   }
 
+  public void testNoGenericsWhenChoosingWithParen() {
+    configure()
+    myFixture.type 'Ma('
+    checkResult()
+  }
+
+  public void testNoClosingWhenChoosingWithParenBeforeIdentifier() {
+    configure()
+    myFixture.type '('
+    checkResult()
+  }
+
 }
diff --git a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureSelectionTest.java b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureSelectionTest.java
new file mode 100644 (file)
index 0000000..84e9714
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.fileStructure;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class JavaFileStructureSelectionTest extends JavaFileStructureTestCase {
+  @Override
+  protected String getTestDataFolderName() {
+    return "selection";
+  }
+
+  public void testField() throws Exception {checkTree();}
+  public void testMethod() throws Exception {checkTree();}
+  public void testConstructor() throws Exception {checkTree();}
+  public void testInsideClass() throws Exception {checkTree();}
+}
diff --git a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureTestCase.java b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureTestCase.java
new file mode 100644 (file)
index 0000000..0753206
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.fileStructure;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.ide.structureView.impl.java.JavaAnonymousClassesNodeProvider;
+import com.intellij.ide.util.FileStructurePopup;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.testFramework.FileStructureTestBase;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public abstract class JavaFileStructureTestCase extends FileStructureTestBase {
+  private boolean myShowAnonymousByDefault;
+
+  protected abstract String getTestDataFolderName();
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    myShowAnonymousByDefault = PropertiesComponent.getInstance().getBoolean(getAnonymousPropertyName(), false);
+  }
+
+  @Override
+  protected String getFileExtension() {
+    return "java";
+  }
+
+  @Override
+  public void tearDown() throws Exception {
+    PropertiesComponent.getInstance().setValue(getAnonymousPropertyName(), Boolean.toString(myShowAnonymousByDefault));
+    super.tearDown();
+  }
+
+  private static String getAnonymousPropertyName() {
+    return FileStructurePopup.getPropertyName(JavaAnonymousClassesNodeProvider.JAVA_ANONYMOUS_PROPERTY_NAME);
+  }
+
+  @Override
+  protected String getBasePath() {
+    return JavaTestUtil.getRelativeJavaTestDataPath() + "/fileStructure/" + getTestDataFolderName();
+  }
+}
index 0d3d9a82aac5631987fa8abc4110f98dbba33abe..f0742ba9bcdbdbef490f0131fb410f03a2071472 100644 (file)
@@ -3,9 +3,10 @@ package org.jetbrains.jps.incremental.groovy;
 
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Consumer;
 import com.intellij.util.SystemProperties;
 import groovy.util.CharsetToolkit;
-import org.jetbrains.annotations.Nullable;
 import org.jetbrains.ether.dependencyView.Callbacks;
 import org.jetbrains.ether.dependencyView.Mappings;
 import org.jetbrains.groovy.compiler.rt.GroovyCompilerWrapper;
@@ -14,7 +15,6 @@ import org.jetbrains.jps.Module;
 import org.jetbrains.jps.ModuleChunk;
 import org.jetbrains.jps.incremental.*;
 import org.jetbrains.jps.incremental.java.JavaBuilder;
-import org.jetbrains.jps.incremental.messages.BuildMessage;
 import org.jetbrains.jps.incremental.messages.CompilerMessage;
 import org.jetbrains.jps.incremental.messages.FileGeneratedEvent;
 import org.jetbrains.jps.incremental.messages.ProgressMessage;
@@ -23,6 +23,7 @@ import org.jetbrains.jps.server.ClasspathBootstrap;
 import org.objectweb.asm.ClassReader;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.*;
 
 /**
@@ -45,63 +46,29 @@ public class GroovyBuilder extends ModuleLevelBuilder {
 
   public ModuleLevelBuilder.ExitCode build(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
     ExitCode exitCode = ExitCode.OK;
-    final List<File> toCompile = new ArrayList<File>();
     try {
-      context.processFilesToRecompile(chunk, new FileProcessor() {
-        @Override
-        public boolean apply(Module module, File file, String sourceRoot) throws Exception {
-          final String path = file.getPath();
-          if (isGroovyFile(path)) { //todo file type check
-            toCompile.add(file);
-          }
-          return true;
-        }
-      });
-
+      final List<File> toCompile = collectChangedFiles(context, chunk);
       if (toCompile.isEmpty()) {
         return exitCode;
       }
 
-      final Set<String> cp = new LinkedHashSet<String>();
-      //groovy_rt.jar
-      // IMPORTANT! must be the first in classpath
-      cp.add(ClasspathBootstrap.getResourcePath(GroovyCompilerWrapper.class).getPath());
-
-      for (File file : context.getProjectPaths().getClasspathFiles(chunk, ClasspathKind.compile(context.isCompilingTests()), false)) {
-        cp.add(FileUtil.toCanonicalPath(file.getPath()));
-      }
-      for (File file : context.getProjectPaths().getClasspathFiles(chunk, ClasspathKind.runtime(context.isCompilingTests()), false)) {
-        cp.add(FileUtil.toCanonicalPath(file.getPath()));
-      }
-
-      final File tempFile = FileUtil.createTempFile("ideaGroovyToCompile", ".txt", true);
-      final Module representativeModule = chunk.getModules().iterator().next();
-      File moduleOutputDir = context.getProjectPaths().getModuleOutputDir(representativeModule, context.isCompilingTests());
-      final File dir = myForStubs ? FileUtil.createTempDirectory(/*new File("/tmp/stubs/"), */"groovyStubs", null) : moduleOutputDir;
-      assert dir != null;
+      String moduleOutput = getModuleOutput(context, chunk);
+      String compilerOutput = getCompilerOutput(context, moduleOutput);
 
       final Set<String> toCompilePaths = new LinkedHashSet<String>();
       for (File file : toCompile) {
         toCompilePaths.add(FileUtil.toSystemIndependentName(file.getPath()));
       }
       
-      String moduleOutputPath = FileUtil.toCanonicalPath(moduleOutputDir.getPath());
-      if (!moduleOutputPath.endsWith("/")) {
-        moduleOutputPath += "/";
-      }
-      Map<String, String> class2Src = buildClassToSourceMap(chunk, context, toCompilePaths, moduleOutputPath);
+      Map<String, String> class2Src = buildClassToSourceMap(chunk, context, toCompilePaths, moduleOutput);
 
       String ideCharset = chunk.getProject().getProjectCharset();
       String encoding = !Comparing.equal(CharsetToolkit.getDefaultSystemCharset().name(), ideCharset) ? ideCharset : null;
       List<String> patchers = Collections.emptyList(); //todo patchers
-      GroovycOSProcessHandler.fillFileWithGroovycParameters(
-        tempFile, FileUtil.toCanonicalPath(dir.getPath()), toCompilePaths, FileUtil.toSystemDependentName(moduleOutputPath), class2Src, encoding, patchers
+      final File tempFile = GroovycOSProcessHandler.fillFileWithGroovycParameters(
+        compilerOutput, toCompilePaths, FileUtil.toSystemDependentName(moduleOutput), class2Src, encoding, patchers
       );
 
-      if (myForStubs) {
-        JavaBuilder.addTempSourcePathRoot(context, dir);
-      }
-
       // todo CompilerUtil.addLocaleOptions()
       //todo different outputs in a chunk
       //todo xmx
@@ -109,71 +76,30 @@ public class GroovyBuilder extends ModuleLevelBuilder {
       final List<String> cmd = ExternalProcessUtil.buildJavaCommandLine(
         SystemProperties.getJavaHome() + "/bin/java",
         "org.jetbrains.groovy.compiler.rt.GroovycRunner",
-        Collections.<String>emptyList(), new ArrayList<String>(cp),
+        Collections.<String>emptyList(), new ArrayList<String>(generateClasspath(context, chunk)),
         Arrays.asList("-Xmx384m"/*, "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5239"*/),
         Arrays.<String>asList(myForStubs ? "stubs" : "groovyc", tempFile.getPath())
       );
 
       List<GroovycOSProcessHandler.OutputItem> successfullyCompiled = Collections.emptyList();
       try {
-        final Process process = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()]));
-        GroovycOSProcessHandler handler = new GroovycOSProcessHandler(process, null) {
+        final Process process = Runtime.getRuntime().exec(ArrayUtil.toStringArray(cmd));
+        GroovycOSProcessHandler handler = GroovycOSProcessHandler.runGroovyc(process, new Consumer<String>() {
           @Override
-          protected void updateStatus(@Nullable String status) {
-            context.processMessage(new ProgressMessage(status == null ? GROOVY_COMPILER_IN_OPERATION : status));
+          public void consume(String s) {
+            context.processMessage(new ProgressMessage(s));
           }
-        };
-        handler.startNotify();
-        handler.waitFor();
+        });
 
         successfullyCompiled = handler.getSuccessfullyCompiled();
 
-        final List<CompilerMessage> messages = handler.getCompilerMessages();
-        for (CompilerMessage message : messages) {
+        for (CompilerMessage message : handler.getCompilerMessages()) {
           context.processMessage(message);
         }
-
-        boolean hasMessages = !messages.isEmpty();
-
-        final StringBuffer unparsedBuffer = handler.getStdErr();
-        if (unparsedBuffer.length() != 0) {
-          context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.INFO, unparsedBuffer.toString()));
-        }
-
-        final int exitValue = handler.getProcess().exitValue();
-        if (!hasMessages && exitValue != 0) {
-          context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Internal groovyc error: code " + exitValue));
-        }
       }
       finally {
         if (!myForStubs) {
-          final Mappings delta = context.createDelta();
-          final List<File> successfullyCompiledFiles = new ArrayList<File>();
-          if (!successfullyCompiled.isEmpty()) {
-
-            final Callbacks.Backend callback = delta.getCallback();
-            final FileGeneratedEvent generatedEvent = new FileGeneratedEvent();
-
-            for (GroovycOSProcessHandler.OutputItem item : successfullyCompiled) {
-              final String sourcePath = FileUtil.toSystemIndependentName(item.sourcePath);
-              final String outputPath = FileUtil.toSystemIndependentName(item.outputPath);
-              final RootDescriptor moduleAndRoot = context.getModuleAndRoot(new File(sourcePath));
-              if (moduleAndRoot != null) {
-                final String moduleName = moduleAndRoot.module.getName().toLowerCase(Locale.US);
-                context.getDataManager().getSourceToOutputMap(moduleName, moduleAndRoot.isTestRoot).appendData(sourcePath, outputPath);
-              }
-              callback.associate(outputPath, Callbacks.getDefaultLookup(sourcePath), new ClassReader(FileUtil.loadFileBytes(new File(outputPath))));
-              successfullyCompiledFiles.add(new File(sourcePath));
-
-              generatedEvent.add(moduleOutputPath, FileUtil.getRelativePath(moduleOutputPath, outputPath, '/'));
-            }
-
-            context.processMessage(generatedEvent);
-          }
-
-
-          final boolean needSecondPass = updateMappings(context, delta, chunk, toCompile, successfullyCompiledFiles);
-          if (needSecondPass) {
+          if (updateDependencies(context, chunk, toCompile, moduleOutput, successfullyCompiled)) {
             exitCode = ExitCode.ADDITIONAL_PASS_REQUIRED;
           }
         }
@@ -186,6 +112,85 @@ public class GroovyBuilder extends ModuleLevelBuilder {
     }
   }
 
+  private static String getModuleOutput(CompileContext context, ModuleChunk chunk) {
+    final Module representativeModule = chunk.getModules().iterator().next();
+    File moduleOutputDir = context.getProjectPaths().getModuleOutputDir(representativeModule, context.isCompilingTests());
+    assert moduleOutputDir != null;
+    String moduleOutputPath = FileUtil.toCanonicalPath(moduleOutputDir.getPath());
+    return moduleOutputPath.endsWith("/") ? moduleOutputPath : moduleOutputPath + "/";
+  }
+
+  private String getCompilerOutput(CompileContext context, String moduleOutputDir) throws IOException {
+    final File dir = myForStubs ? FileUtil.createTempDirectory("groovyStubs", null) : new File(moduleOutputDir);
+    if (myForStubs) {
+      JavaBuilder.addTempSourcePathRoot(context, dir);
+    }
+    return FileUtil.toCanonicalPath(dir.getPath());
+  }
+
+  private static List<File> collectChangedFiles(CompileContext context, ModuleChunk chunk) throws Exception {
+    final List<File> toCompile = new ArrayList<File>();
+    context.processFilesToRecompile(chunk, new FileProcessor() {
+      @Override
+      public boolean apply(Module module, File file, String sourceRoot) throws Exception {
+        final String path = file.getPath();
+        if (isGroovyFile(path)) { //todo file type check
+          toCompile.add(file);
+        }
+        return true;
+      }
+    });
+    return toCompile;
+  }
+
+  private boolean updateDependencies(CompileContext context,
+                                  ModuleChunk chunk,
+                                  List<File> toCompile,
+                                  String moduleOutputPath,
+                                  List<GroovycOSProcessHandler.OutputItem> successfullyCompiled) throws Exception {
+    final Mappings delta = context.createDelta();
+    final List<File> successfullyCompiledFiles = new ArrayList<File>();
+    if (!successfullyCompiled.isEmpty()) {
+
+      final Callbacks.Backend callback = delta.getCallback();
+      final FileGeneratedEvent generatedEvent = new FileGeneratedEvent();
+
+      for (GroovycOSProcessHandler.OutputItem item : successfullyCompiled) {
+        final String sourcePath = FileUtil.toSystemIndependentName(item.sourcePath);
+        final String outputPath = FileUtil.toSystemIndependentName(item.outputPath);
+        final RootDescriptor moduleAndRoot = context.getModuleAndRoot(new File(sourcePath));
+        if (moduleAndRoot != null) {
+          final String moduleName = moduleAndRoot.module.getName().toLowerCase(Locale.US);
+          context.getDataManager().getSourceToOutputMap(moduleName, moduleAndRoot.isTestRoot).appendData(sourcePath, outputPath);
+        }
+        callback.associate(outputPath, Callbacks.getDefaultLookup(sourcePath), new ClassReader(FileUtil.loadFileBytes(new File(outputPath))));
+        successfullyCompiledFiles.add(new File(sourcePath));
+
+        generatedEvent.add(moduleOutputPath, FileUtil.getRelativePath(moduleOutputPath, outputPath, '/'));
+      }
+
+      context.processMessage(generatedEvent);
+    }
+
+
+    return updateMappings(context, delta, chunk, toCompile, successfullyCompiledFiles);
+  }
+
+  private static List<String> generateClasspath(CompileContext context, ModuleChunk chunk) {
+    final Set<String> cp = new LinkedHashSet<String>();
+    //groovy_rt.jar
+    // IMPORTANT! must be the first in classpath
+    cp.add(ClasspathBootstrap.getResourcePath(GroovyCompilerWrapper.class).getPath());
+
+    for (File file : context.getProjectPaths().getClasspathFiles(chunk, ClasspathKind.compile(context.isCompilingTests()), false)) {
+      cp.add(FileUtil.toCanonicalPath(file.getPath()));
+    }
+    for (File file : context.getProjectPaths().getClasspathFiles(chunk, ClasspathKind.runtime(context.isCompilingTests()), false)) {
+      cp.add(FileUtil.toCanonicalPath(file.getPath()));
+    }
+    return new ArrayList<String>(cp);
+  }
+
   private static boolean isGroovyFile(String path) {
     return path.endsWith(".groovy") || path.endsWith(".gpp");
   }
index 87a1ec8c22db8107368f23a18e409ac40e0c8999..02bd682eec39a27b19129ced41c532f6cf29c1f7 100644 (file)
@@ -20,7 +20,9 @@ import com.intellij.execution.process.BaseOSProcessHandler;
 import com.intellij.execution.process.ProcessOutputTypes;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.Consumer;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.groovy.compiler.rt.GroovycRunner;
@@ -42,9 +44,11 @@ public class GroovycOSProcessHandler extends BaseOSProcessHandler {
   private final StringBuffer stdErr = new StringBuffer();
 
   private static final Logger LOG = Logger.getInstance("org.jetbrains.jps.incremental.groovy.GroovycOSProcessHandler");
+  private final Consumer<String> myStatusUpdater;
 
-  public GroovycOSProcessHandler(Process process, String s) {
-    super(process, s, null);
+  private GroovycOSProcessHandler(Process process, Consumer<String> statusUpdater) {
+    super(process, null, null);
+    myStatusUpdater = statusUpdater;
   }
 
   public void notifyTextAvailable(final String text, final Key outputType) {
@@ -69,7 +73,9 @@ public class GroovycOSProcessHandler extends BaseOSProcessHandler {
 
   private final StringBuffer outputBuffer = new StringBuffer();
 
-  protected void updateStatus(@Nullable String status) { }
+  protected void updateStatus(@Nullable String status) {
+    myStatusUpdater.consume(status == null ? GROOVY_COMPILER_IN_OPERATION : status);
+  }
 
   private void parseOutput(String text) {
     final String trimmed = text.trim();
@@ -175,19 +181,46 @@ public class GroovycOSProcessHandler extends BaseOSProcessHandler {
     return toRecompileFiles;
   }
 
+  public boolean shouldRetry() {
+    if (getProcess().exitValue() != 0) {
+      return true;
+    }
+    for (CompilerMessage message : compilerMessages) {
+      if (message.getKind() == BuildMessage.Kind.ERROR) {
+        return true;
+      }
+    }
+    if (getStdErr().length() > 0) {
+      return true;
+    }
+    return false;
+  }
+
   public List<CompilerMessage> getCompilerMessages() {
-    return compilerMessages;
+    ArrayList<CompilerMessage> messages = new ArrayList<CompilerMessage>(compilerMessages);
+    final StringBuffer unparsedBuffer = getStdErr();
+    if (unparsedBuffer.length() != 0) {
+      messages.add(new CompilerMessage("Groovyc", BuildMessage.Kind.INFO, unparsedBuffer.toString()));
+    }
+
+    final int exitValue = getProcess().exitValue();
+    if (messages.isEmpty() && exitValue != 0) {
+      messages.add(new CompilerMessage("Groovyc", BuildMessage.Kind.ERROR, "Internal groovyc error: code " + exitValue));
+    }
+
+    return messages;
   }
 
   public StringBuffer getStdErr() {
     return stdErr;
   }
 
-  public static void fillFileWithGroovycParameters(File tempFile,
-                                                   final String outputDir,
+  public static File fillFileWithGroovycParameters(final String outputDir,
                                                    final Collection<String> changedSources,
                                                    String finalOutput,
                                                    Map<String, String> class2Src, @Nullable final String encoding, List<String> patchers) throws IOException {
+    File tempFile = FileUtil.createTempFile("ideaGroovyToCompile", ".txt", true);
+
     final Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempFile)));
     try {
       for (String file : changedSources) {
@@ -222,6 +255,15 @@ public class GroovycOSProcessHandler extends BaseOSProcessHandler {
     finally {
       writer.close();
     }
+    return tempFile;
+  }
+
+  public static GroovycOSProcessHandler runGroovyc(Process process, Consumer<String> updater) {
+    GroovycOSProcessHandler processHandler = new GroovycOSProcessHandler(process, updater);
+
+    processHandler.startNotify();
+    processHandler.waitFor();
+    return processHandler;
   }
 
   public static class OutputItem {
index d33d8e63f52bd8cc18f9af2e5e8d5f473502af02..3fe04627663897ea1f66538e2b4cab98c5cb770a 100644 (file)
@@ -53,6 +53,7 @@ public class CompilerMessage extends BuildMessage {
     return myCompilerName;
   }
 
+  @Nullable
   public String getSourcePath() {
     return mySourcePath;
   }
index 5d40326f4de8cf925080392ddcfee0626a6a0cb1..243e8ba487f5e393f95ab358112eafc189d2e1ca 100644 (file)
 package com.intellij.openapi.vfs;
 
 import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream;
+import com.intellij.openapi.util.io.FileUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.util.HashSet;
 import java.util.Set;
@@ -180,4 +182,14 @@ public class VfsUtilCore {
     }
     visitor.afterChildrenVisited(file);
   }
+
+  public static String loadText(@NotNull VirtualFile file) throws IOException{
+    InputStreamReader reader = new InputStreamReader(file.getInputStream(), file.getCharset());
+    try {
+      return new String(FileUtil.loadText(reader, (int)file.getLength()));
+    }
+    finally {
+      reader.close();
+    }
+  }
 }
index e5e2ffd8acf55e0100199db5f485435cabf0289a..8ce543e7f688c3bdabbcc4947eafa1b587f5c8b5 100644 (file)
  */
 package com.intellij.codeInsight.completion.util;
 
-import com.intellij.codeInsight.TailType;
 import com.intellij.codeInsight.completion.InsertHandler;
 import com.intellij.codeInsight.completion.InsertionContext;
 import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.PsiWhiteSpace;
@@ -58,22 +58,22 @@ public abstract class ParenthesesInsertHandler<T extends LookupElement> implemen
 
   private final boolean mySpaceBeforeParentheses;
   private final boolean mySpaceBetweenParentheses;
-  private final boolean myInsertRightParenthesis;
+  private final boolean myMayInsertRightParenthesis;
   private final boolean myAllowParametersOnNextLine;
 
   protected ParenthesesInsertHandler(final boolean spaceBeforeParentheses,
                                      final boolean spaceBetweenParentheses,
-                                     final boolean insertRightParenthesis) {
-    this(spaceBeforeParentheses, spaceBetweenParentheses, insertRightParenthesis, false);
+                                     final boolean mayInsertRightParenthesis) {
+    this(spaceBeforeParentheses, spaceBetweenParentheses, mayInsertRightParenthesis, false);
   }
 
   protected ParenthesesInsertHandler(boolean spaceBeforeParentheses,
                                      boolean spaceBetweenParentheses,
-                                     boolean insertRightParenthesis,
+                                     boolean mayInsertRightParenthesis,
                                      boolean allowParametersOnNextLine) {
     mySpaceBeforeParentheses = spaceBeforeParentheses;
     mySpaceBetweenParentheses = spaceBetweenParentheses;
-    myInsertRightParenthesis = insertRightParenthesis;
+    myMayInsertRightParenthesis = mayInsertRightParenthesis;
     myAllowParametersOnNextLine = allowParametersOnNextLine;
   }
 
@@ -138,7 +138,15 @@ public abstract class ParenthesesInsertHandler<T extends LookupElement> implemen
       editor.getCaretModel().moveToOffset(context.getTailOffset());
     }
 
-    if (!myInsertRightParenthesis) return;
+    if (!myMayInsertRightParenthesis) return;
+
+    if (context.getCompletionChar() == '(') {
+      //todo use BraceMatchingUtil.isPairedBracesAllowedBeforeTypeInFileType
+      int tail = context.getTailOffset();
+      if (tail < document.getTextLength() && StringUtil.isJavaIdentifierPart(document.getCharsSequence().charAt(tail))) {
+        return;
+      }
+    }
 
     document.insertString(context.getTailOffset(), getSpace(mySpaceBetweenParentheses) + ")");
     if (!putCaretInside) {
index d5057096f40fa1be43de363a2a78c1874213eb33..2f7adf63a796c6f45ab9802fde8b34e5aadd5596 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.execution.util;
 
 import com.intellij.execution.CommonProgramRunConfigurationParameters;
 import com.intellij.execution.configurations.ModuleBasedConfiguration;
+import com.intellij.execution.configurations.RuntimeConfigurationWarning;
 import com.intellij.execution.configurations.SimpleProgramParameters;
 import com.intellij.openapi.components.PathMacroManager;
 import com.intellij.openapi.module.Module;
@@ -26,6 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.PathUtil;
 import org.jetbrains.annotations.Nullable;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -36,6 +38,19 @@ public class ProgramParametersUtil {
 
     parameters.getProgramParametersList().addParametersString(configuration.getProgramParameters());
 
+    parameters.setWorkingDirectory(getWorkingDir(configuration, project, module));
+
+    parameters.setupEnvs(configuration.getEnvs(), configuration.isPassParentEnvs());
+    if (parameters.getEnv() != null) {
+      Map<String, String> expanded = new HashMap<String, String>();
+      for (Map.Entry<String, String> each : parameters.getEnv().entrySet()) {
+        expanded.put(each.getKey(), expandPath(each.getValue(), module, project));
+      }
+      parameters.setEnv(expanded);
+    }
+  }
+
+  public static String getWorkingDir(CommonProgramRunConfigurationParameters configuration, Project project, Module module) {
     String workingDirectory = configuration.getWorkingDirectory();
     VirtualFile baseDir = project.getBaseDir();
 
@@ -46,15 +61,14 @@ public class ProgramParametersUtil {
     if (!FileUtil.isAbsolute(workingDirectory) && baseDir != null) {
       workingDirectory = baseDir.getPath() + "/" + workingDirectory;
     }
-    parameters.setWorkingDirectory(workingDirectory);
+    return workingDirectory;
+  }
 
-    parameters.setupEnvs(configuration.getEnvs(), configuration.isPassParentEnvs());
-    if (parameters.getEnv() != null) {
-      Map<String, String> expanded = new HashMap<String, String>();
-      for (Map.Entry<String, String> each : parameters.getEnv().entrySet()) {
-        expanded.put(each.getKey(), expandPath(each.getValue(), module, project));
-      }
-      parameters.setEnv(expanded);
+  public static void checkWorkingDirectoryExist(CommonProgramRunConfigurationParameters configuration, Project project, Module module)
+    throws RuntimeConfigurationWarning {
+    final String workingDir = getWorkingDir(configuration, project, module);
+    if (!new File(workingDir).exists()) {
+      throw new RuntimeConfigurationWarning("Working directory '" + workingDir + "' doesn't exist");
     }
   }
 
index 9d885b1e49d8444373a55afe5be95360ddb19f78..39dbe47a25aa718e29a96fad3c3096a5d0bdbf93 100644 (file)
@@ -424,7 +424,8 @@ public class FileStructurePopup implements Disposable {
     }
   }
 
-  public void selectPsiElement(PsiElement element) {
+  @Nullable
+  public FilteringTreeStructure.FilteringNode selectPsiElement(PsiElement element) {
     Set<PsiElement> parents = getAllParents(element);
 
     FilteringTreeStructure.FilteringNode node = (FilteringTreeStructure.FilteringNode)myAbstractTreeBuilder.getRootElement();
@@ -443,11 +444,11 @@ public class FileStructurePopup implements Disposable {
         if (myAbstractTreeBuilder.getSelectedElements().isEmpty()) {
           TreeUtil.selectFirstNode(myTree);
         }
-        return;
-
+        return node;
       }
     }
     TreeUtil.selectFirstNode(myTree);
+    return null;
   }
 
   private static Set<PsiElement> getAllParents(PsiElement element) {
@@ -721,7 +722,7 @@ public class FileStructurePopup implements Disposable {
     }
   }
 
-  private static String getPropertyName(String propertyName) {
+  public static String getPropertyName(String propertyName) {
     return propertyName + ".file.structure.state";
   }
 
index b923084c275d554e4804199a4f18d048880f395b..c90b321c1e3dff2a6a40631025bc4b2f0953c840 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.intellij.openapi.roots.impl;
 
+import com.intellij.openapi.extensions.ExtensionPointName;
 import com.intellij.openapi.projectRoots.ProjectJdkTable;
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.roots.ModuleJdkOrderEntry;
@@ -29,6 +30,7 @@ import org.jdom.Attribute;
 import org.jdom.Element;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * @author dsl
@@ -62,8 +64,7 @@ public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implement
 
     final String jdkName = jdkNameAttribute.getValue();
     final String jdkType = element.getAttributeValue(JDK_TYPE_ATTR);
-    final ProjectJdkTable projectJdkTable = ProjectJdkTable.getInstance();
-    final Sdk jdkByName = projectJdkTable.findJdk(jdkName, jdkType);
+    final Sdk jdkByName = findJdk(jdkName, jdkType);
     if (jdkByName == null) {
       init(null, jdkName, jdkType);
     }
@@ -72,6 +73,26 @@ public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implement
     }
   }
 
+  public abstract static class SdkFinder {
+    private static final ExtensionPointName<SdkFinder> EP_NAME = ExtensionPointName.create("com.intellij.sdkFinder");
+
+    @Nullable
+    public Sdk findSdk(String name, String sdkType) {
+      return null;
+    }
+  }
+
+  @Nullable
+  private static Sdk findJdk(final String jdkName, final String jdkType) {
+    for (SdkFinder sdkFinder : SdkFinder.EP_NAME.getExtensions()) {
+      final Sdk sdk = sdkFinder.findSdk(jdkName, jdkType);
+      if (sdk != null) {
+        return sdk;
+      }
+    }
+    final ProjectJdkTable projectJdkTable = ProjectJdkTable.getInstance();
+    return projectJdkTable.findJdk(jdkName, jdkType);
+  }
 
 
   private ModuleJdkOrderEntryImpl(ModuleJdkOrderEntryImpl that, RootModelImpl rootModel, ProjectRootManagerImpl projectRootManager) {
index 43423a3599326a448abfe5bbde0bc7795a08f4d9..96560cad40a8996ccd1825a2e6de87b3029d3fa4 100644 (file)
@@ -3688,7 +3688,7 @@ public class AbstractTreeUi {
   }
 
   public void userSelect(final Object[] elements, final Runnable onDone, final boolean addToSelection, boolean scroll) {
-    _select(elements, onDone, addToSelection, true, false, scroll, false, true, true);
+    _select(elements, onDone, addToSelection, true, false, scroll, false, true, !ApplicationManager.getApplication().isUnitTestMode());
   }
 
   void _select(final Object[] elements,
index a5b1c3829e79dbc34d4e4588dc79e402017a822b..59b2e017a6454991bfc6528a9459d8185d2b2f81 100644 (file)
@@ -45,16 +45,6 @@ import java.util.*;
 public class VfsUtil extends VfsUtilCore {
   private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.VfsUtil");
 
-  public static String loadText(@NotNull VirtualFile file) throws IOException{
-    InputStreamReader reader = new InputStreamReader(file.getInputStream(), file.getCharset());
-    try {
-      return new String(FileUtil.loadText(reader, (int)file.getLength()));
-    }
-    finally {
-      reader.close();
-    }
-  }
-
   public static void saveText(@NotNull VirtualFile file, @NotNull String text) throws IOException {
     Charset charset = file.getCharset();
     file.setBinaryContent(text.getBytes(charset.name()));
index 786ecdf73791f12bc32c73903e5c120e99538769..7a3fce1253bc2fc95d4883f4dd655b31893e3e13 100644 (file)
@@ -241,7 +241,7 @@ public class FilteringTreeStructure extends AbstractTreeStructure {
     }
 
     public Object[] getEqualityObjects() {
-      return NONE;
+      return new Object[]{myDelegate};
     }
 
     @Override
index f8c6d21f2ce5ece05aa8aa8758247084d71f7b9f..98d69abbf08c2d23cb0c79cbacab2cc553846dff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1040,9 +1040,9 @@ public class FSRecords implements Forceable {
   }
 
   private static void checkFileIsValid(int fileId) {
-    assert fileId > 0 : "assert fileId > 0 failed";
+    assert fileId > 0 : fileId;
     // TODO: This assertion is a bit timey, will remove when bug is caught.
-    assert (getFlags(fileId) & FREE_RECORD_FLAG) == 0 : "Trying to find an attribute of deleted page";
+    assert (getFlags(fileId) & FREE_RECORD_FLAG) == 0 : "Accessing attribute of a deleted page: " + fileId + ":" + getName(fileId);
   }
 
   public static int acquireFileContent(int fileId) {
index 8b853b5fa2d225cc742589fda6880e23e40ec2f7..d6dd203561832d2ace489e55bbad4c3dc36595d3 100644 (file)
@@ -528,7 +528,7 @@ exclude.from.imports.no.exclusions=No exclude patterns
 inline.elements=Inline elements:
 don.t.break.if.inline.content=Don't break if inline content:
 edit.code.folding.options=Open code folding options
-button.new=&New
+button.new=&New...
 building.include.indices=Building include indices...
 loading.include.indices=Loading include indices...
 use.external.annotations=Use &external annotations
index 694fc07924eaadd186d5da2e1b75dc0b2a691ad3..466de59f09d3037c0efd84098efe3daee064e25b 100644 (file)
@@ -295,9 +295,9 @@ module.library.display.name=Module {0, choice, 1#Library|2#Libraries}
 project.roots.library.banner.text= {1} ''{0}''
 facet.banner.text=Facet ''{0}''
 project.roots.project.banner.text=General Settings for Project ''{0}''
-project.roots.set.up.jdk.title=Set up {0, choice, 1#module|2#project} SDK
+project.roots.set.up.jdk.title=Set up {0, choice, 1#Module|2#Project} SDK
 project.roots.no.jdk.on.project.message=Set up created sdk on project?
-project.roots.no.jdk.on.projecct.title=No project sdk set up
+project.roots.no.jdk.on.project.title=Create SDK
 project.roots.jdks.node.text=JDK stands for the Java Development Kit, a software development package that is required to write, test and debug Java applications. \
   JDK also contains classes and runtime environment that are used to execute the target application. <br><br>\
   Mobile SDK contains emulator of mobile phone as well as embedded Java SDK to compile/pack/run/debug J2ME applications. <br><br>\
index cca38e9c553b38353d7d91a1df1734d3251ccc00..044b1b5cac10f74d9864d14edd86ad407da8b79f 100644 (file)
   <extensionPoint name="library.presentationProvider" interface="com.intellij.openapi.roots.libraries.LibraryPresentationProvider"/>
   <extensionPoint name="library.type" interface="com.intellij.openapi.roots.libraries.LibraryType"/>
 
+  <extensionPoint name="sdkFinder" interface="com.intellij.openapi.roots.impl.ModuleJdkOrderEntryImpl$SdkFinder"/>
+
   <extensionPoint name="lang.implementationTextSelectioner"
                   beanClass="com.intellij.lang.LanguageExtensionPoint"/>
   <extensionPoint name="lang.lineWrapStrategy"
index 38c562f6923705b6869d2a45e225975d36b7cfeb..461375ebbd1fe6188bdf6f192a928d66ea57287f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -57,7 +57,7 @@ public class SymLinkHandlingTest extends LightPlatformLangTestCase {
     assertNull(selfLinkVFile);
   }
 
-  public void testTargetIsWriteable() throws Exception {
+  public void testTargetIsWritable() throws Exception {
     if (!SystemInfo.areSymLinksSupported) return;
 
     final File targetFile = FileUtil.createTempFile("target", "");
index 3f991b0cb683a6820109ecbc489e2a3d4fc9b4a5..645d6ae0192eed63f7a558e3f86cd748daea31ee 100644 (file)
@@ -66,8 +66,8 @@ public abstract class FileStructureTestBase extends CodeInsightFixtureTestCase {
   }
 
   protected void checkTree() throws Exception {
-    final String expected = FileUtil.loadFile(new File(getTestDataPath() + "/" + getTreeFileName()));
-    Assert.assertEquals(expected, PlatformTestUtil.print(getTree(), true));
+    final String expected = FileUtil.loadFile(new File(getTestDataPath() + "/" + getTreeFileName()), true);
+    Assert.assertEquals(expected.trim(), PlatformTestUtil.print(getTree(), true).trim());
   }
 
 
@@ -78,7 +78,8 @@ public abstract class FileStructureTestBase extends CodeInsightFixtureTestCase {
         getStructure().rebuild();
         updateTree();
         TreeUtil.expandAll(getTree());
-        myPopup.selectPsiElement(getFile());
+        final FilteringTreeStructure.FilteringNode node = myPopup.selectPsiElement(myPopup.getCurrentElement(getFile()));
+        getTree().getSelectionModel().setSelectionPath(getTree().getPath(node));
       }
     });
   }
index 45ca8249e70dadf520a5a53546b4ca425ef1115b..d4e56c07982ae8da3daa5105ff6e776de0b08683 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
 import com.intellij.psi.PsiFile;
 import com.intellij.testFramework.UsefulTestCase;
 import com.intellij.testFramework.builders.EmptyModuleFixtureBuilder;
+import com.intellij.testFramework.builders.ModuleFixtureBuilder;
 import org.jetbrains.annotations.NonNls;
 
 import java.io.File;
@@ -29,7 +30,7 @@ import java.io.File;
 /**
  * @author yole
  */
-public abstract class CodeInsightFixtureTestCase extends UsefulTestCase {
+public abstract class CodeInsightFixtureTestCase<T extends ModuleFixtureBuilder> extends UsefulTestCase {
   protected CodeInsightTestFixture myFixture;
   protected Module myModule;
 
@@ -39,7 +40,7 @@ public abstract class CodeInsightFixtureTestCase extends UsefulTestCase {
 
     final TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder();
     myFixture = IdeaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
-    final EmptyModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(EmptyModuleFixtureBuilder.class);
+    final T moduleFixtureBuilder = projectBuilder.addModule(getModuleBuilderClass());
     moduleFixtureBuilder.addSourceContentRoot(myFixture.getTempDirPath());
     tuneFixture(moduleFixtureBuilder);
 
@@ -48,6 +49,10 @@ public abstract class CodeInsightFixtureTestCase extends UsefulTestCase {
     myModule = moduleFixtureBuilder.getFixture().getModule();
   }
 
+  protected Class<T> getModuleBuilderClass() {
+    return (Class<T>)EmptyModuleFixtureBuilder.class;
+  }
+  
   @Override
   protected void tearDown() throws Exception {
     myFixture.tearDown();
@@ -56,7 +61,7 @@ public abstract class CodeInsightFixtureTestCase extends UsefulTestCase {
     super.tearDown();
   }
 
-  protected void tuneFixture(final EmptyModuleFixtureBuilder moduleBuilder) {}
+  protected void tuneFixture(final T moduleBuilder) {}
 
   /**
    * Return relative path to the test data. Path is relative to the
index c48b53e30bdced41ee1714a21950d1db72a39c86..beca1196d72e2786d6edc06cd9d4164a51a46d96 100644 (file)
@@ -173,12 +173,23 @@ public class FileUtil {
 
   @NotNull
   public static String loadFile(@NotNull File file) throws IOException {
-    return loadFile(file, null);
+    return loadFile(file, null, false);
+  }
+
+  @NotNull
+  public static String loadFile(@NotNull File file, boolean convertLineSeparators) throws IOException {
+    return loadFile(file, null, convertLineSeparators);
   }
 
   @NotNull
   public static String loadFile(@NotNull File file, String encoding) throws IOException {
-    return new String(loadFileText(file, encoding));
+    return loadFile(file, encoding, false);
+  }
+
+  @NotNull
+  public static String loadFile(@NotNull File file, String encoding, boolean convertLineSeparators) throws IOException {
+    final String s = new String(loadFileText(file, encoding));
+    return convertLineSeparators ? StringUtil.convertLineSeparators(s) : s;
   }
 
   @NotNull
index b633502aefd5934f30416478d965fa205cfd95c1..db948129570d8d149549ebc8c80bc0d5cd3e69d7 100644 (file)
@@ -31,6 +31,7 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
 import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.JarFileSystem;
 import com.intellij.openapi.vfs.VfsUtil;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -45,25 +46,29 @@ import org.jetbrains.idea.eclipse.config.EclipseModuleManager;
 import org.jetbrains.idea.eclipse.importWizard.EclipseProjectFinder;
 import org.jetbrains.idea.eclipse.util.ErrorLog;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
+import java.io.*;
+import java.util.*;
+import java.util.jar.Manifest;
 import java.util.regex.PatternSyntaxException;
 
-import static org.jetbrains.idea.eclipse.conversion.EPathUtil.*;
+import static org.jetbrains.idea.eclipse.conversion.EPathUtil.expandEclipsePath2Url;
 
 public class EclipseClasspathReader {
   private final String myRootPath;
   private final Project myProject;
   @Nullable private final List<String> myCurrentRoots;
   private ContentEntry myContentEntry;
+  @Nullable private final Set<String> myModuleNames;
 
   public EclipseClasspathReader(final String rootPath, final Project project, @Nullable List<String> currentRoots) {
+    this(rootPath, project, currentRoots, null);
+  }
+
+  public EclipseClasspathReader(final String rootPath, final Project project, @Nullable List<String> currentRoots, @Nullable Set<String> moduleNames) {
     myRootPath = FileUtil.toSystemIndependentName(rootPath);
     myProject = project;
     myCurrentRoots = currentRoots;
+    myModuleNames = moduleNames;
   }
 
   public void init(ModifiableRootModel model) {
@@ -236,6 +241,7 @@ public class EclipseClasspathReader {
     }
     else if (kind.equals(EclipseXml.CON_KIND)) {
       if (path.equals(EclipseXml.ECLIPSE_PLATFORM)) {
+        readRequiredBundles(rootModel, refsToModules);
         addNamedLibrary(rootModel, unknownLibraries, exported, IdeaXml.ECLIPSE_LIBRARY, LibraryTablesRegistrar.APPLICATION_LEVEL);
       }
       else if (path.startsWith(EclipseXml.JRE_CONTAINER)) {
@@ -276,6 +282,53 @@ public class EclipseClasspathReader {
     }
   }
 
+  private void readRequiredBundles(ModifiableRootModel rootModel, Set<String> refsToModules) throws ConversionException {
+    if (myModuleNames == null) {
+      return;
+    }
+
+    final File manifestFile = new File(myRootPath, "META-INF/MANIFEST.MF");
+    if (!manifestFile.exists()) {
+      return;
+    }
+
+    InputStream in = null;
+    try {
+      in = new BufferedInputStream(new FileInputStream(manifestFile));
+      final Manifest manifest = new Manifest(in);
+      final String attributes = manifest.getMainAttributes().getValue("Require-Bundle");
+      if (!StringUtil.isEmpty(attributes)) {
+        final StringTokenizer tokenizer = new StringTokenizer(attributes, ",");
+        while (tokenizer.hasMoreTokens()) {
+          String bundle = tokenizer.nextToken().trim();
+          if (!bundle.isEmpty()) {
+            final int constraintIndex = bundle.indexOf(';');
+            if (constraintIndex != -1) {
+              bundle = bundle.substring(0, constraintIndex).trim();
+            }
+
+            if (myModuleNames.contains(bundle)) {
+              refsToModules.add(bundle);
+              rootModel.addInvalidModuleEntry(bundle);
+            }
+          }
+        }
+      }
+    }
+    catch (IOException e) {
+      throw new ConversionException(e.getMessage());
+    }
+    finally {
+      if (in != null) {
+        try {
+          in.close();
+        }
+        catch (IOException ignored) {
+        }
+      }
+    }
+  }
+
   private static int rearrangeOrderEntryOfType(ModifiableRootModel rootModel, Class<? extends OrderEntry> orderEntryClass) {
     OrderEntry[] orderEntries = rootModel.getOrderEntries();
     int moduleSourcesIdx = 0;
index aff404771e3f87d133e4168a4e5cffcfdd5fdf58..b5e1beb045d6ddda82714365148ddee3ffbcbf16 100644 (file)
@@ -50,6 +50,7 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.packaging.artifacts.ModifiableArtifactModel;
 import com.intellij.projectImport.ProjectImportBuilder;
 import com.intellij.util.Function;
+import gnu.trove.THashSet;
 import org.jdom.Element;
 import org.jdom.JDOMException;
 import org.jetbrains.annotations.NotNull;
@@ -198,12 +199,14 @@ public class EclipseImportBuilder extends ProjectImportBuilder<String> implement
       final ModifiableModuleModel moduleModel = model != null ? model : ModuleManager.getInstance(project).getModifiableModel();
       final ModifiableRootModel[] rootModels = new ModifiableRootModel[getParameters().projectsToConvert.size()];
       final Set<File> files = new HashSet<File>();
+      final Set<String> moduleNames = new THashSet<String>(getParameters().projectsToConvert.size());
       for (String path : getParameters().projectsToConvert) {
         String modulesDirectory = getParameters().converterOptions.commonModulesDirectory;
         if (modulesDirectory == null) {
           modulesDirectory = path;
         }
         final String moduleName = EclipseProjectFinder.findProjectName(path);
+        moduleNames.add(moduleName);
         final File imlFile = new File(modulesDirectory + File.separator + moduleName + IdeaXml.IML_EXT);
         if (imlFile.isFile()) {
           files.add(imlFile);
@@ -266,7 +269,7 @@ public class EclipseImportBuilder extends ProjectImportBuilder<String> implement
         rootModels[idx++] = rootModel;
 
         final File classpathFile = new File(path, EclipseXml.DOT_CLASSPATH_EXT);
-        final EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, getParameters().projectsToConvert);
+        final EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, getParameters().projectsToConvert, moduleNames);
         classpathReader.init(rootModel);
         if (classpathFile.exists()) {
           final Element classpathElement = JDOMUtil.loadDocument(classpathFile).getRootElement();
index 28396fdde88c72d3ea4ef20072af30ba4e720c96..f7bfa21ecd7cd0961068006b1333dcd55911ca03 100644 (file)
@@ -104,7 +104,7 @@ public class GitCheckoutNewBranchOperation extends GitBranchOperation {
     GitCompoundResult deleteResult = new GitCompoundResult(myProject);
     Collection<GitRepository> repositories = getSuccessfulRepositories();
     for (GitRepository repository : repositories) {
-      GitCommandResult result = Git.checkout(repository, myPreviousBranch, null);
+      GitCommandResult result = Git.checkout(repository, myPreviousBranch, null, true);
       checkoutResult.append(repository, result);
       if (result.success()) {
         deleteResult.append(repository, Git.branchDelete(repository, myNewBranchName, false));
index 9be5f1e1f0e9696e7ad5fc6080c8f42a5aa26bc7..06f93d1c923351772f41142d60ba85db8ea9848f 100644 (file)
@@ -96,7 +96,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
       GitSimpleEventDetector unmergedFiles = new GitSimpleEventDetector(GitSimpleEventDetector.Event.UNMERGED);
       GitMessageWithFilesDetector untrackedOverwrittenByCheckout = new GitMessageWithFilesDetector(UNTRACKED_FILES_OVERWRITTEN_BY, root);
 
-      GitCommandResult result = Git.checkout(repository, myStartPointReference, myNewBranch,
+      GitCommandResult result = Git.checkout(repository, myStartPointReference, myNewBranch, false,
                                              localChangesOverwrittenByCheckout, unmergedFiles, untrackedOverwrittenByCheckout);
       if (result.success()) {
         refresh(repository);
@@ -134,13 +134,14 @@ public class GitCheckoutOperation extends GitBranchOperation {
     // get all other conflicting changes
     Map<GitRepository, List<Change>> conflictingChangesInRepositories = collectLocalChangesOnAllOtherRepositories(repository);
     Set<GitRepository> otherProblematicRepositories = conflictingChangesInRepositories.keySet();
-    Collection<GitRepository> allConflictingRepositories = new ArrayList<GitRepository>(otherProblematicRepositories);
+    List<GitRepository> allConflictingRepositories = new ArrayList<GitRepository>(otherProblematicRepositories);
     allConflictingRepositories.add(repository);
     for (List<Change> changes : conflictingChangesInRepositories.values()) {
       affectedChanges.addAll(changes);
     }
 
-    if (GitWouldBeOverwrittenByCheckoutDialog.showAndGetAnswer(myProject, affectedChanges)) {
+    int smartCheckoutDecision = GitWouldBeOverwrittenByCheckoutDialog.showAndGetAnswer(myProject, affectedChanges);
+    if (smartCheckoutDecision == GitWouldBeOverwrittenByCheckoutDialog.SMART_CHECKOUT) {
       boolean smartCheckedOutSuccessfully = smartCheckout(allConflictingRepositories, myStartPointReference, myNewBranch, getIndicator());
       if (smartCheckedOutSuccessfully) {
         GitRepository[] otherRepositories = ArrayUtil.toObjectArray(otherProblematicRepositories, GitRepository.class);
@@ -156,6 +157,9 @@ public class GitCheckoutOperation extends GitBranchOperation {
         return false;
       }
     }
+    else if (smartCheckoutDecision == GitWouldBeOverwrittenByCheckoutDialog.FORCE_CHECKOUT_EXIT_CODE) {
+      return checkoutOrNotify(allConflictingRepositories, myStartPointReference, myNewBranch, true);
+    }
     else {
       fatalLocalChangesError();
       return false;
@@ -248,7 +252,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
     GitCompoundResult checkoutResult = new GitCompoundResult(myProject);
     GitCompoundResult deleteResult = new GitCompoundResult(myProject);
     for (GitRepository repository : getSuccessfulRepositories()) {
-      GitCommandResult result = Git.checkout(repository, myPreviousBranch, null);
+      GitCommandResult result = Git.checkout(repository, myPreviousBranch, null, true);
       checkoutResult.append(repository, result);
       if (result.success() && myNewBranch != null) {
         /*
@@ -310,7 +314,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
   }
 
   // stash - checkout - unstash
-  private boolean smartCheckout(@NotNull final Collection<GitRepository> repositories, @NotNull final String reference, @Nullable final String newBranch, @NotNull ProgressIndicator indicator) {
+  private boolean smartCheckout(@NotNull final List<GitRepository> repositories, @NotNull final String reference, @Nullable final String newBranch, @NotNull ProgressIndicator indicator) {
     final GitChangesSaver saver = configureSaver(reference, indicator);
 
     final AtomicBoolean result = new AtomicBoolean();
@@ -319,7 +323,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
         boolean savedSuccessfully = save(repositories, saver);
         if (savedSuccessfully) {
           try {
-            result.set(checkoutOrNotify(repositories, reference, newBranch));
+            result.set(checkoutOrNotify(repositories, reference, newBranch, false));
           } finally {
             saver.restoreLocalChanges(context);
           }
@@ -384,12 +388,11 @@ public class GitCheckoutOperation extends GitBranchOperation {
   /**
    * Checks out or shows an error message.
    */
-  private boolean checkoutOrNotify(@NotNull Collection<GitRepository> repositories,
-                                                    @NotNull String reference,
-                                                    @Nullable String newBranch) {
+  private boolean checkoutOrNotify(@NotNull List<GitRepository> repositories, 
+                                   @NotNull String reference, @Nullable String newBranch, boolean force) {
     GitCompoundResult compoundResult = new GitCompoundResult(myProject);
     for (GitRepository repository : repositories) {
-      compoundResult.append(repository, Git.checkout(repository, reference, newBranch));
+      compoundResult.append(repository, Git.checkout(repository, reference, newBranch, force));
     }
     if (compoundResult.totalSuccess()) {
       return true;
index f281e4a1f71876ffc5e6655cfbe5b552b278509b..ad60e17fcc44d31d85b4c98d6b6b85174c9cb530 100644 (file)
@@ -26,8 +26,9 @@ import git4idea.DialogManager;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
+import java.awt.event.ActionEvent;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * The dialog that is shown when the error "The following files would be overwritten by checkout" happens.
@@ -38,23 +39,26 @@ import java.util.concurrent.atomic.AtomicBoolean;
 // TODO "don't ask again" option
 class GitWouldBeOverwrittenByCheckoutDialog extends DialogWrapper {
 
+  public static final int SMART_CHECKOUT = OK_EXIT_CODE;
+  public static final int FORCE_CHECKOUT_EXIT_CODE = NEXT_USER_EXIT_CODE;
+  
   private final Project myProject;
   private final List<Change> myChanges;
 
   /**
    * @return true if smart checkout has to be performed, false if user doesn't want to checkout.
    */
-  static boolean showAndGetAnswer(@NotNull final Project project, @NotNull final List<Change> changes) {
-    final AtomicBoolean ok = new AtomicBoolean();
+  static int showAndGetAnswer(@NotNull final Project project, @NotNull final List<Change> changes) {
+    final AtomicInteger exitCode = new AtomicInteger();
     UIUtil.invokeAndWaitIfNeeded(new Runnable() {
       @Override
       public void run() {
         GitWouldBeOverwrittenByCheckoutDialog dialog = new GitWouldBeOverwrittenByCheckoutDialog(project, changes);
         DialogManager.getInstance(project).showDialog(dialog);
-        ok.set(dialog.isOK());
+        exitCode.set(dialog.getExitCode());
       }
     });
-    return ok.get();
+    return exitCode.get();
   }
 
   private GitWouldBeOverwrittenByCheckoutDialog(@NotNull Project project, @NotNull List<Change> changes) {
@@ -68,8 +72,8 @@ class GitWouldBeOverwrittenByCheckoutDialog extends DialogWrapper {
   }
 
   @Override
-  protected Action getOKAction() {
-    return super.getOKAction();
+  protected Action[] createLeftSideActions() {
+    return new Action[] {new ForceCheckoutAction() };
   }
 
   @Override
@@ -93,4 +97,17 @@ class GitWouldBeOverwrittenByCheckoutDialog extends DialogWrapper {
     return GitWouldBeOverwrittenByCheckoutDialog.class.getName();
   }
 
+
+  private class ForceCheckoutAction extends AbstractAction {
+    
+    ForceCheckoutAction() {
+      super("Force checkout");
+    }
+    
+    @Override
+    public void actionPerformed(ActionEvent e) {
+      close(FORCE_CHECKOUT_EXIT_CODE);
+    }
+  }
+
 }
index 8f47061ad11c8d85ee3f98c83293ae828bc029af..ebe5b02a9f0ee39699176f642430abc7f0d0c967 100644 (file)
@@ -138,12 +138,17 @@ public class Git {
   public static GitCommandResult checkout(@NotNull GitRepository repository,
                                           @NotNull String reference,
                                           @Nullable String newBranch,
+                                          boolean force,
                                           @NotNull GitLineHandlerListener... listeners) {
     final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECKOUT);
     h.setSilent(false);
+    if (force) {
+      h.addParameters("--force");
+    }
     if (newBranch == null) { // simply checkout
       h.addParameters(reference);
-    } else { // checkout reference as new branch
+    } 
+    else { // checkout reference as new branch
       h.addParameters("-b", newBranch, reference);
     }
     for (GitLineHandlerListener listener : listeners) {
index 8168474896d1b2f84246854e3df5a32a2f1468ee..322cdfef217f1d6902144a31c46b1dde38a9e2e0 100644 (file)
@@ -25,7 +25,6 @@ import com.intellij.compiler.impl.javaCompiler.OutputItemImpl;
 import com.intellij.compiler.make.CacheCorruptedException;
 import com.intellij.compiler.make.DependencyCache;
 import com.intellij.execution.ExecutionException;
-import com.intellij.execution.configurations.GeneralCommandLine;
 import com.intellij.execution.configurations.JavaParameters;
 import com.intellij.openapi.application.AccessToken;
 import com.intellij.openapi.application.ApplicationManager;
@@ -165,11 +164,10 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
     parameters.setMainClass(GroovycRunner.class.getName());
 
     try {
-      File fileWithParameters = FileUtil.createTempFile("toCompile", "");
       final VirtualFile finalOutputDir = getMainOutput(compileContext, module, tests);
       LOG.assertTrue(finalOutputDir != null, "No output directory for module " + module.getName() + (tests ? " tests" : " production"));
       final Charset ideCharset = EncodingProjectManager.getInstance(myProject).getDefaultCharset();
-      String encoding = !Comparing.equal(CharsetToolkit.getDefaultSystemCharset(), ideCharset) ? ideCharset.name() : null;
+      String encoding = ideCharset != null && !Comparing.equal(CharsetToolkit.getDefaultSystemCharset(), ideCharset) ? ideCharset.name() : null;
       Set<String> paths2Compile = ContainerUtil.map2Set(toCompile, new Function<VirtualFile, String>() {
         @Override
         public String fun(VirtualFile file) {
@@ -186,8 +184,8 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
         }
       }
 
-      GroovycOSProcessHandler
-        .fillFileWithGroovycParameters(fileWithParameters, outputDir.getPath(), paths2Compile, FileUtil.toSystemDependentName(finalOutputDir.getPath()),
+      File fileWithParameters = GroovycOSProcessHandler
+        .fillFileWithGroovycParameters(outputDir.getPath(), paths2Compile, FileUtil.toSystemDependentName(finalOutputDir.getPath()),
                                        class2Src, encoding, patchers);
 
       parameters.getProgramParametersList().add(forStubs ? "stubs" : "groovyc");
@@ -197,51 +195,31 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
       LOG.error(e);
     }
 
-    GroovycOSProcessHandler processHandler;
 
     try {
-      final GeneralCommandLine commandLine = JdkUtil.setupJVMCommandLine(exePath, parameters, true);
-      processHandler = new GroovycOSProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString()) {
+      Process process = JdkUtil.setupJVMCommandLine(exePath, parameters, true).createProcess();
+      GroovycOSProcessHandler processHandler = GroovycOSProcessHandler.runGroovyc(process, new Consumer<String>() {
         @Override
-        protected void updateStatus(@Nullable String status) {
-          compileContext.getProgressIndicator().setText(status == null ? GROOVY_COMPILER_IN_OPERATION : status);
+        public void consume(String s) {
+          compileContext.getProgressIndicator().setText(s);
         }
-      };
-
-      processHandler.startNotify();
-      processHandler.waitFor();
+      });
 
       final List<VirtualFile> toRecompile = new ArrayList<VirtualFile>();
-      Set<File> toRecompileFiles = processHandler.getToRecompileFiles();
-      for (File toRecompileFile : toRecompileFiles) {
+      for (File toRecompileFile : processHandler.getToRecompileFiles()) {
         final VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(toRecompileFile);
         LOG.assertTrue(vFile != null);
         toRecompile.add(vFile);
       }
 
-      final List<CompilerMessage> messages = processHandler.getCompilerMessages();
-      for (CompilerMessage compilerMessage : messages) {
-        final CompilerMessageCategory category = getMessageCategory(compilerMessage);
-
+      for (CompilerMessage compilerMessage : processHandler.getCompilerMessages()) {
         final String url = compilerMessage.getSourcePath();
-
-        compileContext.addMessage(category, compilerMessage.getMessageText(), VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(url)),
+        compileContext.addMessage(getMessageCategory(compilerMessage), compilerMessage.getMessageText(),
+                                  url == null ? null : VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(url)),
                                   (int)compilerMessage.getLine(),
                                   (int)compilerMessage.getColumn());
       }
 
-      boolean hasMessages = !messages.isEmpty();
-
-      StringBuffer unparsedBuffer = processHandler.getStdErr();
-      if (unparsedBuffer.length() != 0) {
-        compileContext.addMessage(CompilerMessageCategory.INFORMATION, unparsedBuffer.toString(), null, -1, -1);
-      }
-
-      final int exitCode = processHandler.getProcess().exitValue();
-      if (!hasMessages && exitCode != 0) {
-        compileContext.addMessage(CompilerMessageCategory.ERROR, "Internal groovyc error: code " + exitCode, null, -1, -1);
-      }
-
       List<GroovycOSProcessHandler.OutputItem> outputItems = processHandler.getSuccessfullyCompiled();
       ArrayList<OutputItem> items = new ArrayList<OutputItem>();
       if (forStubs) {
index e73b13cb07a861cffd3194746bc3af176ce6208e..bb8ee2be533a13544c5ae07e5d01d75701a6763c 100644 (file)
@@ -88,10 +88,9 @@ public class GroovyClassNameInsertHandler implements InsertHandler<JavaPsiClassR
       GroovyPsiElement place = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), GroovyPsiElement.class, false);
       JavaCompletionUtil.insertParentheses(context, item, false, place != null && GroovyCompletionUtil.hasConstructorParameters(psiClass, place));
 
-      if (context.getCompletionChar() == '<' || psiClass.hasTypeParameters()) {
-        context.getDocument().insertString(identifierEnd, "<>");
+      if (context.getCompletionChar() == '<' || psiClass.hasTypeParameters() && context.getCompletionChar() != '(') {
         context.setAddCompletionChar(false);
-        context.getEditor().getCaretModel().moveToOffset(identifierEnd + 1);
+        JavaCompletionUtil.promptTypeArgs(context, identifierEnd);
       }
     }
 
index a6d4607f9cc1ae51ea02a528c749fb52595a414a..057ab85becf0663366daf5147b691790879c2ccd 100644 (file)
 package com.intellij.execution.junit;
 
 import com.intellij.execution.CantRunException;
-import com.intellij.execution.ExecutionBundle;
 import com.intellij.execution.configurations.*;
 import com.intellij.execution.testframework.SourceScope;
+import com.intellij.execution.util.JavaParametersUtil;
+import com.intellij.execution.util.ProgramParametersUtil;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.JavaSdk;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
+import com.intellij.psi.JavaDirectoryService;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiPackage;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.GlobalSearchScopes;
 
@@ -80,14 +83,8 @@ class TestDirectory extends TestPackage {
 
   @Override
   public void checkConfiguration() throws RuntimeConfigurationException {
-    if (myConfiguration.isAlternativeJrePathEnabled()) {
-      if (myConfiguration.getAlternativeJrePath() == null ||
-          myConfiguration.getAlternativeJrePath().length() == 0 ||
-          !JavaSdk.checkForJre(myConfiguration.getAlternativeJrePath())) {
-        throw new RuntimeConfigurationWarning(
-          ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", myConfiguration.getAlternativeJrePath()));
-      }
-    }
+    JavaParametersUtil.checkAlternativeJRE(myConfiguration);
+    ProgramParametersUtil.checkWorkingDirectoryExist(myConfiguration, myConfiguration.getProject(), myConfiguration.getConfigurationModule().getModule());
     final String dirName = myConfiguration.getPersistentData().getDirName();
     if (dirName == null || dirName.isEmpty()) {
       throw new RuntimeConfigurationError("Directory is not specified");
index 7c063b6439584a7baa2870bce1bd76601f6bc322..b3a288099cb6655d9cc1cfea8d3a496fe1fe17c7 100644 (file)
@@ -36,13 +36,13 @@ import com.intellij.execution.runners.ProgramRunner;
 import com.intellij.execution.testframework.*;
 import com.intellij.execution.ui.ConsoleViewContentType;
 import com.intellij.execution.util.JavaParametersUtil;
+import com.intellij.execution.util.ProgramParametersUtil;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.JavaSdk;
 import com.intellij.openapi.projectRoots.JavaSdkType;
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
@@ -179,14 +179,8 @@ public abstract class TestObject implements JavaCommandLine {
   };
 
   public void checkConfiguration() throws RuntimeConfigurationException{
-    if (myConfiguration.isAlternativeJrePathEnabled()){
-      if (myConfiguration.getAlternativeJrePath() == null ||
-          myConfiguration.getAlternativeJrePath().length() == 0 ||
-          !JavaSdk.checkForJre(myConfiguration.getAlternativeJrePath())){
-        throw new RuntimeConfigurationWarning(
-          ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", myConfiguration.getAlternativeJrePath()));
-      }
-    }
+    JavaParametersUtil.checkAlternativeJRE(myConfiguration);
+    ProgramParametersUtil.checkWorkingDirectoryExist(myConfiguration, myConfiguration.getProject(), myConfiguration.getConfigurationModule().getModule());
   }
 
   public SourceScope getSourceScope() {
index 9021ecea90b2f8fce9be0769a628713428e94716..52bc39ee1adfb0e0e39a31577a15f044723199cd 100644 (file)
@@ -29,6 +29,8 @@ import com.intellij.execution.configurations.*;
 import com.intellij.execution.junit.RefactoringListeners;
 import com.intellij.execution.runners.ExecutionEnvironment;
 import com.intellij.execution.testframework.SourceScope;
+import com.intellij.execution.util.JavaParametersUtil;
+import com.intellij.execution.util.ProgramParametersUtil;
 import com.intellij.openapi.components.PathMacroManager;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.options.SettingsEditor;
@@ -338,6 +340,8 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
       }
     }
     JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this);
+    ProgramParametersUtil.checkWorkingDirectoryExist(this, getProject(), getConfigurationModule().getModule());
+    JavaParametersUtil.checkAlternativeJRE(this);
     //TODO add various checks here
   }
 
index c75ec170d5bfc1c8cc0a0045a7729a550d9aa7e6..08e7421d877c606e40ae6828fbc1638518686fd4 100644 (file)
@@ -211,7 +211,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
         dups.add(proxy);
       }
     }
-    final String testMethodDescriptor = result.getTestClass() + result.getMethod();
+    final String testMethodDescriptor = TestProxy.toDisplayText(result, project);
     if (startedMethods.contains(testMethodDescriptor)) {
       total++;
     }
index 6e5d96ffc4bf5451f961d269648a1d2666798cf8..baf52860e7c7a2b816573f02aba2f133d7fe9f08 100644 (file)
@@ -93,6 +93,7 @@ public class TestNGUtil
   }
 
   public static final String TEST_ANNOTATION_FQN = Test.class.getName();
+  public static final String FACTORY_ANNOTATION_FQN = Factory.class.getName();
   public static final String[] CONFIG_ANNOTATIONS_FQN = {
       Configuration.class.getName(),
       Factory.class.getName(),
@@ -199,6 +200,7 @@ public class TestNGUtil
       PsiClass psiClass = (PsiClass) element;
       for (PsiMethod method : psiClass.getAllMethods()) {
         if (AnnotationUtil.isAnnotated(method, TEST_ANNOTATION_FQN, false, true)) return true;
+        if (AnnotationUtil.isAnnotated(method, FACTORY_ANNOTATION_FQN, false, true)) return true;
         if (hasTestJavaDoc(method, checkJavadoc)) return true;
       }
     } else if (element instanceof PsiMethod) {
index bf21f20bb868d961b6c228dee23624cc9e7f7b63..916c3fcaf3d55740e265caf395596500192e8846 100644 (file)
@@ -323,48 +323,51 @@ public class ColorSampleLookupValue implements LookupValueWithUIHint, DeferredUs
 
   public static ColorSampleLookupValue[] getColors() {
     if (ourColors == null) {
-      ourColorNameToHexCodeMap = new HashMap<String, String>(25);
-      ourHexCodeToColorNameMap = new HashMap<String, String>(25);
-      List<ColorSampleLookupValue> colorsList = new LinkedList<ColorSampleLookupValue>();
-      StringTokenizer tokenizer = new StringTokenizer(systemColorsString, "\n");
-
-      while (tokenizer.hasMoreTokens()) {
-        String name = tokenizer.nextToken();
-        colorsList.add(new ColorSampleLookupValue(name, name, false));
-        tokenizer.nextToken();
-      }
-
-      tokenizer = new StringTokenizer(standardColorsString, ", \n");
-      HashMap<String, String> standardColors = new HashMap<String, String>();
-
-      while (tokenizer.hasMoreTokens()) {
-        String name = tokenizer.nextToken();
-        String value = tokenizer.nextToken();
-        standardColors.put(name, name);
-        ourColorNameToHexCodeMap.put(name, value);
-        ourHexCodeToColorNameMap.put(value, name);
-
-        colorsList.add(new ColorSampleLookupValue(name, value, true));
-      }
-
-      tokenizer = new StringTokenizer(colorsString, " \t\n");
-
-      while (tokenizer.hasMoreTokens()) {
-        String name = tokenizer.nextToken();
-        String hexValue = tokenizer.nextToken();
-
-        tokenizer.nextToken(); // skip rgb
-
-        if (!standardColors.containsKey(name)) {
-          colorsList.add(new ColorSampleLookupValue(name, hexValue, false));
-          ourColorNameToHexCodeMap.put(name, hexValue);
-          ourHexCodeToColorNameMap.put(hexValue, name);
+      synchronized (ColorSampleLookupValue.class) {
+        if (ourColors == null) {
+          ourColorNameToHexCodeMap = new HashMap<String, String>(25);
+          ourHexCodeToColorNameMap = new HashMap<String, String>(25);
+          List<ColorSampleLookupValue> colorsList = new LinkedList<ColorSampleLookupValue>();
+          StringTokenizer tokenizer = new StringTokenizer(systemColorsString, "\n");
+
+          while (tokenizer.hasMoreTokens()) {
+            String name = tokenizer.nextToken();
+            colorsList.add(new ColorSampleLookupValue(name, name, false));
+            tokenizer.nextToken();
+          }
+
+          tokenizer = new StringTokenizer(standardColorsString, ", \n");
+          HashMap<String, String> standardColors = new HashMap<String, String>();
+
+          while (tokenizer.hasMoreTokens()) {
+            String name = tokenizer.nextToken();
+            String value = tokenizer.nextToken();
+            standardColors.put(name, name);
+            ourColorNameToHexCodeMap.put(name, value);
+            ourHexCodeToColorNameMap.put(value, name);
+
+            colorsList.add(new ColorSampleLookupValue(name, value, true));
+          }
+
+          tokenizer = new StringTokenizer(colorsString, " \t\n");
+
+          while (tokenizer.hasMoreTokens()) {
+            String name = tokenizer.nextToken();
+            String hexValue = tokenizer.nextToken();
+
+            tokenizer.nextToken(); // skip rgb
+
+            if (!standardColors.containsKey(name)) {
+              colorsList.add(new ColorSampleLookupValue(name, hexValue, false));
+              ourColorNameToHexCodeMap.put(name, hexValue);
+              ourHexCodeToColorNameMap.put(hexValue, name);
+            }
+          }
+
+          colorsList.toArray(ourColors = new ColorSampleLookupValue[colorsList.size()]);
         }
       }
-
-      colorsList.toArray(ourColors = new ColorSampleLookupValue[colorsList.size()]);
     }
-
     return ourColors;
   }
 
@@ -389,12 +392,12 @@ public class ColorSampleLookupValue implements LookupValueWithUIHint, DeferredUs
     return myName == null || Character.isLowerCase(myName.charAt(0)) ? HIGHER : NORMAL;
   }
 
-  public static String getHexCodeForColorName(String colorName) {
+  public static synchronized String getHexCodeForColorName(String colorName) {
     getColors(); // to guarantee initialization
     return ourColorNameToHexCodeMap.get(colorName);
   }
 
-  public static String getColorNameForHexCode(String colorName) {
+  public static synchronized String getColorNameForHexCode(String colorName) {
     getColors(); // to guarantee initialization
     return ourHexCodeToColorNameMap.get(colorName);
   }