コード例 #1
0
  public void testRegisterThenDisposeThenRegisterAgain() {
    Disposable disposable = Disposer.newDisposable();
    Disposer.register(myRoot, disposable);

    Disposer.dispose(disposable);
    Disposer.register(myRoot, disposable);
    Disposer.register(disposable, Disposer.newDisposable());
  }
コード例 #2
0
  public void testMustNotRegisterWithAlreadyDisposed() {
    Disposable disposable = Disposer.newDisposable();
    Disposer.register(myRoot, disposable);

    Disposer.dispose(disposable);

    try {
      Disposer.register(disposable, Disposer.newDisposable());
      fail("Must not be able to register with already disposed parent");
    } catch (IncorrectOperationException ignored) {

    }
  }
コード例 #3
0
  public void addRunContentListener(final RunContentListener listener, final Executor executor) {
    final Disposable disposable = Disposer.newDisposable();
    myProject
        .getMessageBus()
        .connect(disposable)
        .subscribe(
            RUN_CONTENT_TOPIC,
            new RunContentWithExecutorListener() {
              @Override
              public void contentSelected(
                  RunContentDescriptor descriptor, @NotNull Executor executor2) {
                if (executor2.equals(executor)) {
                  listener.contentSelected(descriptor);
                }
              }

              @Override
              public void contentRemoved(
                  RunContentDescriptor descriptor, @NotNull Executor executor2) {
                if (executor2.equals(executor)) {
                  listener.contentRemoved(descriptor);
                }
              }
            });
    myListeners.put(listener, disposable);
  }
コード例 #4
0
  private boolean checkNoDifferenceAndNotify(
      DiffPanel diffPanel, DiffRequest data, final Window window, final boolean showMessage) {
    if (!diffPanel.hasDifferences() && !data.getHints().contains(HINT_ALLOW_NO_DIFFERENCES)) {
      DiffManagerImpl manager = (DiffManagerImpl) DiffManager.getInstance();
      if (!Comparing.equal(manager.getComparisonPolicy(), ComparisonPolicy.DEFAULT)) {
        ComparisonPolicy oldPolicy = manager.getComparisonPolicy();
        manager.setComparisonPolicy(ComparisonPolicy.DEFAULT);
        Disposable parentDisposable = Disposer.newDisposable();
        DiffPanel maybeDiffPanel =
            DiffManagerImpl.createDiffPanel(data, window, parentDisposable, this);
        manager.setComparisonPolicy(oldPolicy);

        boolean hasDiffs = maybeDiffPanel.hasDifferences();
        Disposer.dispose(parentDisposable);

        if (hasDiffs) return false;
      }

      if (!showMessage) {
        return true;
      }
      return !askForceOpenDiff(data);
    }
    return false;
  }
コード例 #5
0
 @Override
 public void initialize() {
   try {
     base.initialize();
   } catch (Exception ignore) {
   }
   myDisposable = Disposer.newDisposable();
   Application application = ApplicationManager.getApplication();
   if (application != null) {
     Disposer.register(application, myDisposable);
   }
   myMnemonicAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myDisposable);
   IdeEventQueue.getInstance()
       .addDispatcher(
           e -> {
             if (e instanceof KeyEvent && ((KeyEvent) e).getKeyCode() == KeyEvent.VK_ALT) {
               myAltPressed = e.getID() == KeyEvent.KEY_PRESSED;
               myMnemonicAlarm.cancelAllRequests();
               final Component focusOwner = IdeFocusManager.findInstance().getFocusOwner();
               if (focusOwner != null) {
                 myMnemonicAlarm.addRequest(() -> repaintMnemonics(focusOwner, myAltPressed), 10);
               }
             }
             return false;
           },
           myDisposable);
 }
コード例 #6
0
 @Override
 protected boolean showHint(final JComponent component) {
   boolean result = super.showHint(component);
   if (result && getType() == ValueHintType.MOUSE_OVER_HINT) {
     myDisposable = Disposer.newDisposable();
     ShortcutSet shortcut =
         ActionManager.getInstance().getAction("ShowErrorDescription").getShortcutSet();
     new DumbAwareAction() {
       @Override
       public void actionPerformed(@NotNull AnActionEvent e) {
         hideHint();
         final Point point = new Point(myPoint.x, myPoint.y + getEditor().getLineHeight());
         new XValueHint(
                 getProject(),
                 getEditor(),
                 point,
                 ValueHintType.MOUSE_CLICK_HINT,
                 myExpressionInfo,
                 myEvaluator,
                 myDebugSession)
             .invokeHint();
       }
     }.registerCustomShortcutSet(shortcut, getEditor().getContentComponent(), myDisposable);
   }
   return result;
 }
コード例 #7
0
 @Override
 public void addNotify() {
   super.addNotify();
   myGlassPane = IdeGlassPaneUtil.find(this);
   myDisposable = Disposer.newDisposable();
   myGlassPane.addMouseMotionPreprocessor(myListener, myDisposable);
   myGlassPane.addMousePreprocessor(myListener, myDisposable);
 }
コード例 #8
0
ファイル: ClasspathEditor.java プロジェクト: novokrest/JBIDEA
  public ClasspathEditor(final ModuleConfigurationState state) {
    super(state);

    final Disposable disposable = Disposer.newDisposable();

    state
        .getProject()
        .getMessageBus()
        .connect(disposable)
        .subscribe(ProjectTopics.PROJECT_ROOTS, this);
    registerDisposable(disposable);
  }
コード例 #9
0
  @Override
  public void reset() {
    if (myFilePointersDisposable != null) {
      Disposer.dispose(myFilePointersDisposable);
    }

    myFilePointersDisposable = Disposer.newDisposable();
    for (PyRootTypeProvider provider : myRootTypeProviders) {
      provider.reset(myFilePointersDisposable, this, myModule);
    }

    if (myRootTreeEditor != null) {
      ContentEntryEditor editor = myRootTreeEditor.getContentEntryEditor();
      if (editor != null) editor.update();
      myRootTreeEditor.update();
    }
  }
コード例 #10
0
ファイル: BytecodeCompiler.java プロジェクト: kazhida/kotlin
  /**
   * Creates new instance of {@link JetCoreEnvironment} instance using the arguments specified.
   *
   * @param stdlib path to "kotlin-runtime.jar", only used if not null and not empty
   * @param classpath compilation classpath, only used if not null and not empty
   * @param sourceRoots
   * @param enableInline
   * @param enableOptimization
   * @return compile environment instance
   */
  private JetCoreEnvironment env(
      String stdlib,
      String[] classpath,
      String[] externalAnnotationsPath,
      String[] sourceRoots,
      boolean enableInline,
      boolean enableOptimization) {
    CompilerConfiguration configuration =
        createConfiguration(
            stdlib,
            classpath,
            externalAnnotationsPath,
            sourceRoots,
            enableInline,
            enableOptimization);

    return JetCoreEnvironment.createForProduction(Disposer.newDisposable(), configuration);
  }
コード例 #11
0
@SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"})
public class ApplicationImpl extends ComponentManagerImpl implements ApplicationEx {
  private static final Logger LOG =
      Logger.getInstance("#com.intellij.application.impl.ApplicationImpl");
  private final ModalityState MODALITY_STATE_NONE = ModalityState.NON_MODAL;
  private final ModalityInvokator myInvokator = new ModalityInvokatorImpl();

  private final EventDispatcher<ApplicationListener> myDispatcher =
      EventDispatcher.create(ApplicationListener.class);

  private IApplicationStore myComponentStore;

  private boolean myTestModeFlag;
  private final boolean myHeadlessMode;
  private final boolean myCommandLineMode;

  private final boolean myIsInternal;
  private final String myName;

  private final ReentrantWriterPreferenceReadWriteLock myActionsLock =
      new ReentrantWriterPreferenceReadWriteLock();
  private final Stack<Class> myWriteActionsStack =
      new Stack<Class>(); // accessed from EDT only, no need to sync

  private volatile Runnable myExceptionalThreadWithReadAccessRunnable;

  private int myInEditorPaintCounter = 0;
  private long myStartTime = 0;
  @Nullable private Splash mySplash;
  private boolean myDoNotSave;
  private volatile boolean myDisposeInProgress = false;

  private int myRestartCode = 0;
  private volatile int myExitCode = 0;
  private final Disposable myLastDisposable = Disposer.newDisposable(); // will be disposed last

  private final AtomicBoolean mySaveSettingsIsInProgress = new AtomicBoolean(false);

  @SuppressWarnings({"UseOfArchaicSystemPropertyAccessors"})
  private static final int ourDumpThreadsOnLongWriteActionWaiting =
      Integer.getInteger("dump.threads.on.long.write.action.waiting", 0);

  private final ExecutorService ourThreadExecutorsService =
      new ThreadPoolExecutor(
          3,
          Integer.MAX_VALUE,
          5 * 60L,
          TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(),
          new ThreadFactory() {
            int i;

            public Thread newThread(Runnable r) {
              final Thread thread =
                  new Thread(r, "ApplicationImpl pooled thread " + i++) {
                    public void interrupt() {
                      if (LOG.isDebugEnabled()) {
                        LOG.debug("Interrupted worker, will remove from pool");
                      }
                      super.interrupt();
                    }

                    public void run() {
                      try {
                        super.run();
                      } catch (Throwable t) {
                        if (LOG.isDebugEnabled()) {
                          LOG.debug("Worker exits due to exception", t);
                        }
                      }
                    }
                  };
              thread.setPriority(Thread.NORM_PRIORITY - 1);
              return thread;
            }
          });
  private boolean myIsFiringLoadingEvent = false;
  @NonNls private static final String WAS_EVER_SHOWN = "was.ever.shown";

  private Boolean myActive;

  private static final ThreadLocal<Integer> ourEdtSafe = new ThreadLocal<Integer>();
  private static final ModalityState ANY =
      new ModalityState() {
        @Override
        public boolean dominates(@NotNull ModalityState anotherState) {
          return false;
        }

        @Override
        public String toString() {
          return "ANY";
        }
      };

  protected void bootstrapPicoContainer() {
    super.bootstrapPicoContainer();
    getPicoContainer()
        .registerComponentImplementation(
            IComponentStore.class, StoresFactory.getApplicationStoreClass());
    getPicoContainer().registerComponentImplementation(ApplicationPathMacroManager.class);
  }

  @NotNull
  public synchronized IApplicationStore getStateStore() {
    if (myComponentStore == null) {
      myComponentStore =
          (IApplicationStore) getPicoContainer().getComponentInstance(IComponentStore.class);
    }
    return myComponentStore;
  }

  @Override
  public void initializeComponent(Object component, boolean service) {
    getStateStore().initComponent(component, service);
  }

  public ApplicationImpl(
      boolean isInternal,
      boolean isUnitTestMode,
      boolean isHeadless,
      boolean isCommandLine,
      @NotNull String appName,
      Splash splash) {
    super(null);

    ApplicationManagerEx.setApplication(
        this, myLastDisposable); // reset back to null only when all components already disposed

    getPicoContainer().registerComponentInstance(Application.class, this);

    CommonBundle.assertKeyIsFound = isUnitTestMode;
    AWTExceptionHandler.register(); // do not crash AWT on exceptions
    if ((isInternal || isUnitTestMode)
        && !Comparing.equal("off", System.getProperty("idea.disposer.debug"))) {
      Disposer.setDebugMode(true);
    }
    myStartTime = System.currentTimeMillis();
    mySplash = splash;
    myName = appName;

    PluginsFacade.INSTANCE =
        new PluginsFacade() {
          public IdeaPluginDescriptor getPlugin(PluginId id) {
            return PluginManager.getPlugin(id);
          }

          public IdeaPluginDescriptor[] getPlugins() {
            return PluginManager.getPlugins();
          }
        };

    myIsInternal = isInternal;
    myTestModeFlag = isUnitTestMode;
    myHeadlessMode = isHeadless;
    myCommandLineMode = isCommandLine;

    myDoNotSave = myTestModeFlag || myHeadlessMode;

    loadApplicationComponents();

    if (myTestModeFlag) {
      registerShutdownHook();
    }

    if (!isUnitTestMode && !isHeadless) {
      Disposer.register(this, Disposer.newDisposable(), "ui");

      StartupUtil.addExternalInstanceListener(
          new Consumer<List<String>>() {
            @Override
            public void consume(final List<String> args) {
              invokeLater(
                  new Runnable() {
                    @Override
                    public void run() {
                      final Project project = CommandLineProcessor.processExternalCommandLine(args);
                      final IdeFrame frame;
                      if (project != null) {
                        frame = WindowManager.getInstance().getIdeFrame(project);
                      } else {
                        frame = WindowManager.getInstance().getAllFrames()[0];
                      }
                      ((IdeFrameImpl) frame).requestFocus();
                    }
                  });
            }
          });
    }

    final String s = System.getProperty("jb.restart.code");
    if (s != null) {
      try {
        myRestartCode = Integer.parseInt(s);
      } catch (NumberFormatException ignore) {
      }
    }

    registerFont("/fonts/Inconsolata.ttf");
  }

  private void registerFont(String name) {
    if (isHeadlessEnvironment()) return;

    InputStream is = null;
    try {
      is = getClass().getResourceAsStream(name);
      final Font font = Font.createFont(Font.TRUETYPE_FONT, is);
      GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font);
    } catch (Exception e) {
      LOG.info(e);
    } finally {
      if (is != null) {
        try {
          is.close();
        } catch (IOException e) {
          LOG.error(e);
        }
      }
    }
  }

  private void registerShutdownHook() {
    ShutDownTracker
        .getInstance(); // Necessary to avoid creating an instance while already shutting down.

    ShutDownTracker.getInstance()
        .registerShutdownTask(
            new Runnable() {
              public void run() {
                if (isDisposed() || isDisposeInProgress()) {
                  return;
                }
                ShutDownTracker.invokeAndWait(
                    isUnitTestMode(),
                    new Runnable() {
                      public void run() {
                        if (ApplicationManager.getApplication() != ApplicationImpl.this) return;
                        try {
                          myDisposeInProgress = true;
                          saveAll();
                        } finally {
                          disposeSelf();
                        }
                      }
                    });
              }
            });
  }

  private boolean disposeSelf() {
    final CommandProcessor commandProcessor = CommandProcessor.getInstance();
    final Ref<Boolean> canClose = new Ref<Boolean>(Boolean.TRUE);
    for (final Project project : ProjectManagerEx.getInstanceEx().getOpenProjects()) {
      try {
        commandProcessor.executeCommand(
            project,
            new Runnable() {
              public void run() {
                canClose.set(ProjectUtil.closeAndDispose(project));
              }
            },
            ApplicationBundle.message("command.exit"),
            null);
      } catch (Throwable e) {
        LOG.error(e);
      }
      if (!canClose.get()) {
        myDisposeInProgress = false;
        return false;
      }
    }
    Disposer.dispose(this);

    Disposer.assertIsEmpty();
    return true;
  }

  @NotNull
  public String getName() {
    return myName;
  }

  public boolean holdsReadLock() {
    return myActionsLock.isReadLockAcquired();
  }

  @Override
  protected void handleInitComponentError(
      final Throwable ex, final boolean fatal, final String componentClassName) {
    if (PluginManager.isPluginClass(componentClassName)) {
      LOG.error(ex);
      PluginId pluginId = PluginManager.getPluginByClassName(componentClassName);
      @NonNls
      final String errorMessage =
          "Plugin "
              + pluginId.getIdString()
              + " failed to initialize and will be disabled:\n"
              + ex.getMessage()
              + "\nPlease restart "
              + ApplicationNamesInfo.getInstance().getFullProductName()
              + ".";
      PluginManager.disablePlugin(pluginId.getIdString());
      if (!myHeadlessMode) {
        JOptionPane.showMessageDialog(null, errorMessage);
      } else {
        //noinspection UseOfSystemOutOrSystemErr
        System.out.println(errorMessage);
        System.exit(1);
      }
      return; // do not call super
    }
    if (fatal) {
      LOG.error(ex);
      @NonNls
      final String errorMessage =
          "Fatal error initializing class "
              + componentClassName
              + ":\n"
              + ex.toString()
              + "\nComplete error stacktrace was written to idea.log";
      if (!myHeadlessMode) {
        JOptionPane.showMessageDialog(null, errorMessage);
      } else {
        //noinspection UseOfSystemOutOrSystemErr
        System.out.println(errorMessage);
      }
    }
    super.handleInitComponentError(ex, fatal, componentClassName);
  }

  private void loadApplicationComponents() {
    PluginManager.initPlugins(mySplash);
    final IdeaPluginDescriptor[] plugins = PluginManager.getPlugins();
    for (IdeaPluginDescriptor plugin : plugins) {
      if (PluginManager.shouldSkipPlugin(plugin)) continue;
      loadComponentsConfiguration(plugin.getAppComponents(), plugin, false);
    }
  }

  @Override
  protected synchronized Object createComponent(Class componentInterface) {
    Object component = super.createComponent(componentInterface);
    if (mySplash != null) {
      mySplash.showProgress(
          "", (float) (0.65f + myComponentsRegistry.getPercentageOfComponentsLoaded() * 0.35f));
    }
    return component;
  }

  protected MutablePicoContainer createPicoContainer() {
    return Extensions.getRootArea().getPicoContainer();
  }

  public boolean isInternal() {
    return myIsInternal;
  }

  public boolean isUnitTestMode() {
    return myTestModeFlag;
  }

  public void setUnitTestMode(boolean testModeFlag) {
    myTestModeFlag = testModeFlag;
  }

  public boolean isHeadlessEnvironment() {
    return myHeadlessMode;
  }

  public boolean isCommandLine() {
    return myCommandLineMode;
  }

  public Future<?> executeOnPooledThread(@NotNull final Runnable action) {
    return ourThreadExecutorsService.submit(
        new Runnable() {
          public void run() {
            try {
              action.run();
            } catch (ProcessCanceledException e) {
              // ignore
            } catch (Throwable t) {
              LOG.error(t);
            } finally {
              Thread.interrupted(); // reset interrupted status
            }
          }
        });
  }

  @Override
  public <T> Future<T> executeOnPooledThread(@NotNull final Callable<T> action) {
    return ourThreadExecutorsService.submit(
        new Callable<T>() {
          public T call() {
            try {
              return action.call();
            } catch (ProcessCanceledException e) {
              // ignore
            } catch (Throwable t) {
              LOG.error(t);
            } finally {
              Thread.interrupted(); // reset interrupted status
            }
            return null;
          }
        });
  }

  private static Thread ourDispatchThread = null;

  public boolean isDispatchThread() {
    return EventQueue.isDispatchThread();
  }

  @NotNull
  public ModalityInvokator getInvokator() {
    return myInvokator;
  }

  public void invokeLater(@NotNull final Runnable runnable) {
    myInvokator.invokeLater(runnable);
  }

  public void invokeLater(@NotNull final Runnable runnable, @NotNull final Condition expired) {
    myInvokator.invokeLater(runnable, expired);
  }

  public void invokeLater(@NotNull final Runnable runnable, @NotNull final ModalityState state) {
    myInvokator.invokeLater(runnable, state);
  }

  public void invokeLater(
      @NotNull final Runnable runnable,
      @NotNull final ModalityState state,
      @NotNull final Condition expired) {
    myInvokator.invokeLater(runnable, state, expired);
  }

  public void load(String path) throws IOException, InvalidDataException {
    getStateStore().setOptionsPath(path);
    getStateStore().setConfigPath(PathManager.getConfigPath());
    myIsFiringLoadingEvent = true;
    try {
      fireBeforeApplicationLoaded();
    } finally {
      myIsFiringLoadingEvent = false;
    }

    loadComponentRoamingTypes();

    HeavyProcessLatch.INSTANCE.processStarted();
    try {
      getStateStore().load();
    } catch (StateStorageException e) {
      throw new IOException(e.getMessage());
    } finally {
      HeavyProcessLatch.INSTANCE.processFinished();
    }
  }

  @Override
  protected <T> T getComponentFromContainer(final Class<T> interfaceClass) {
    if (myIsFiringLoadingEvent) {
      return null;
    }
    return super.getComponentFromContainer(interfaceClass);
  }

  private static void loadComponentRoamingTypes() {
    ExtensionPoint<RoamingTypeExtensionPointBean> point =
        Extensions.getRootArea().getExtensionPoint("com.intellij.ComponentRoamingType");
    final RoamingTypeExtensionPointBean[] componentRoamingTypes = point.getExtensions();

    for (RoamingTypeExtensionPointBean object : componentRoamingTypes) {

      assert object.componentName != null;
      assert object.roamingType != null;

      final RoamingType type = RoamingType.valueOf(object.roamingType);

      assert type != null;

      ComponentRoamingManager.getInstance().setRoamingType(object.componentName, type);
    }
  }

  private void fireBeforeApplicationLoaded() {
    ExtensionPoint<ApplicationLoadListener> point =
        Extensions.getRootArea().getExtensionPoint("com.intellij.ApplicationLoadListener");
    final ApplicationLoadListener[] objects = point.getExtensions();
    for (ApplicationLoadListener object : objects) {
      try {
        object.beforeApplicationLoaded(this);
      } catch (Exception e) {
        LOG.error(e);
      }
    }
  }

  public void dispose() {
    fireApplicationExiting();

    ShutDownTracker.getInstance().ensureStopperThreadsFinished();

    disposeComponents();

    ourThreadExecutorsService.shutdownNow();
    myComponentStore = null;
    super.dispose();
    Disposer.dispose(myLastDisposable); // dispose it last
  }

  private final Object lock = new Object();

  private void makeChangesVisibleToEDT() {
    synchronized (lock) {
      lock.hashCode();
    }
  }

  public boolean runProcessWithProgressSynchronously(
      @NotNull final Runnable process,
      @NotNull String progressTitle,
      boolean canBeCanceled,
      Project project) {
    return runProcessWithProgressSynchronously(
        process, progressTitle, canBeCanceled, project, null);
  }

  public boolean runProcessWithProgressSynchronously(
      @NotNull final Runnable process,
      @NotNull final String progressTitle,
      final boolean canBeCanceled,
      @Nullable final Project project,
      final JComponent parentComponent) {
    return runProcessWithProgressSynchronously(
        process, progressTitle, canBeCanceled, project, parentComponent, null);
  }

  public boolean runProcessWithProgressSynchronously(
      @NotNull final Runnable process,
      @NotNull final String progressTitle,
      final boolean canBeCanceled,
      @Nullable final Project project,
      final JComponent parentComponent,
      final String cancelText) {
    assertIsDispatchThread();

    if (myExceptionalThreadWithReadAccessRunnable != null
        || ApplicationManager.getApplication().isUnitTestMode()
        || ApplicationManager.getApplication().isHeadlessEnvironment()) {
      try {
        ProgressManager.getInstance().runProcess(process, new EmptyProgressIndicator());
      } catch (ProcessCanceledException e) {
        // ok to ignore.
        return false;
      }
      return true;
    }

    final ProgressWindow progress =
        new ProgressWindow(canBeCanceled, false, project, parentComponent, cancelText);
    progress.setTitle(progressTitle);

    try {
      myExceptionalThreadWithReadAccessRunnable = process;
      final boolean[] threadStarted = {false};
      SwingUtilities.invokeLater(
          new Runnable() {
            public void run() {
              if (myExceptionalThreadWithReadAccessRunnable != process) {
                LOG.error(
                    "myExceptionalThreadWithReadAccessRunnable != process, process = "
                        + myExceptionalThreadWithReadAccessRunnable);
              }

              executeOnPooledThread(
                  new Runnable() {
                    public void run() {
                      if (myExceptionalThreadWithReadAccessRunnable != process) {
                        LOG.error(
                            "myExceptionalThreadWithReadAccessRunnable != process, process = "
                                + myExceptionalThreadWithReadAccessRunnable);
                      }

                      final boolean old = setExceptionalThreadWithReadAccessFlag(true);
                      LOG.assertTrue(isReadAccessAllowed());
                      try {
                        ProgressManager.getInstance().runProcess(process, progress);
                      } catch (ProcessCanceledException e) {
                        progress.cancel();
                        // ok to ignore.
                      } catch (RuntimeException e) {
                        progress.cancel();
                        throw e;
                      } finally {
                        setExceptionalThreadWithReadAccessFlag(old);
                        makeChangesVisibleToEDT();
                      }
                    }
                  });
              threadStarted[0] = true;
            }
          });

      progress.startBlocking();

      LOG.assertTrue(threadStarted[0]);
      LOG.assertTrue(!progress.isRunning());
    } finally {
      myExceptionalThreadWithReadAccessRunnable = null;
      makeChangesVisibleToEDT();
    }

    return !progress.isCanceled();
  }

  public boolean isInModalProgressThread() {
    if (myExceptionalThreadWithReadAccessRunnable == null || !isExceptionalThreadWithReadAccess()) {
      return false;
    }
    ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
    return progressIndicator.isModal()
        && ((ProgressIndicatorEx) progressIndicator).isModalityEntered();
  }

  public void invokeAndWait(@NotNull Runnable runnable, @NotNull ModalityState modalityState) {
    if (isDispatchThread()) {
      LOG.error("invokeAndWait must not be called from event queue thread");
      runnable.run();
      return;
    }

    if (isExceptionalThreadWithReadAccess()) { // OK if we're in exceptional thread.
      LaterInvocator.invokeAndWait(runnable, modalityState);
      return;
    }

    if (myActionsLock.isReadLockAcquired()) {
      LOG.error("Calling invokeAndWait from read-action leads to possible deadlock.");
    }

    LaterInvocator.invokeAndWait(runnable, modalityState);
  }

  @NotNull
  public ModalityState getCurrentModalityState() {
    Object[] entities = LaterInvocator.getCurrentModalEntities();
    return entities.length > 0 ? new ModalityStateEx(entities) : getNoneModalityState();
  }

  @NotNull
  public ModalityState getModalityStateForComponent(@NotNull Component c) {
    Window window = c instanceof Window ? (Window) c : SwingUtilities.windowForComponent(c);
    if (window == null) return getNoneModalityState(); // ?
    return LaterInvocator.modalityStateForWindow(window);
  }

  @Override
  public ModalityState getAnyModalityState() {
    return ANY;
  }

  @NotNull
  public ModalityState getDefaultModalityState() {
    if (EventQueue.isDispatchThread()) {
      return getCurrentModalityState();
    } else {
      ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
      return progress == null ? getNoneModalityState() : progress.getModalityState();
    }
  }

  @NotNull
  public ModalityState getNoneModalityState() {
    return MODALITY_STATE_NONE;
  }

  public long getStartTime() {
    return myStartTime;
  }

  public long getIdleTime() {
    return IdeEventQueue.getInstance().getIdleTime();
  }

  public void exit() {
    exit(false);
  }

  public void exit(final boolean force) {
    exit(force, true);
  }

  public void exit(final boolean force, final boolean allowListenersToCancel) {
    if (!force && getDefaultModalityState() != ModalityState.NON_MODAL) {
      return;
    }

    Runnable runnable =
        new Runnable() {
          public void run() {
            if (!force && !showConfirmation()) {
              saveAll();
              myExitCode = 0;
              return;
            }

            getMessageBus().syncPublisher(AppLifecycleListener.TOPIC).appClosing();
            myDisposeInProgress = true;

            FileDocumentManager.getInstance().saveAllDocuments();

            saveSettings();

            if (!canExit() && allowListenersToCancel) {
              myExitCode = 0;
              return;
            }

            final boolean success = disposeSelf();
            if (!success || isUnitTestMode()) {
              myExitCode = 0;
              return;
            }

            System.exit(myExitCode);
          }
        };

    if (!isDispatchThread()) {
      invokeLater(runnable, ModalityState.NON_MODAL);
    } else {
      runnable.run();
    }
  }

  private static boolean showConfirmation() {
    final boolean hasUnsafeBgTasks = ProgressManager.getInstance().hasUnsafeProgressIndicator();

    DialogWrapper.DoNotAskOption option =
        new DialogWrapper.DoNotAskOption() {
          @Override
          public boolean isToBeShown() {
            return GeneralSettings.getInstance().isConfirmExit();
          }

          @Override
          public void setToBeShown(boolean value, int exitCode) {
            GeneralSettings.getInstance().setConfirmExit(value);
          }

          @Override
          public boolean canBeHidden() {
            return !hasUnsafeBgTasks;
          }

          @Override
          public boolean shouldSaveOptionsOnCancel() {
            return false;
          }

          @Override
          public String getDoNotShowMessage() {
            return "Do not ask me again";
          }
        };

    if (hasUnsafeBgTasks || option.isToBeShown()) {
      String message =
          ApplicationBundle.message(
              hasUnsafeBgTasks ? "exit.confirm.prompt.tasks" : "exit.confirm.prompt",
              ApplicationNamesInfo.getInstance().getFullProductName());

      if (DialogWrapper.OK_EXIT_CODE
          != Messages.showYesNoDialog(
              message,
              ApplicationBundle.message("exit.confirm.title"),
              ApplicationBundle.message("command.exit"),
              "Cancel",
              Messages.getQuestionIcon(),
              option)) {
        return false;
      }
    }
    return true;
  }

  private boolean canExit() {
    for (ApplicationListener applicationListener : myDispatcher.getListeners()) {
      if (!applicationListener.canExitApplication()) {
        return false;
      }
    }

    ProjectManagerEx projectManager = (ProjectManagerEx) ProjectManager.getInstance();
    Project[] projects = projectManager.getOpenProjects();
    for (Project project : projects) {
      if (!projectManager.canClose(project)) {
        return false;
      }
    }

    return true;
  }

  public void runReadAction(@NotNull final Runnable action) {
    final AccessToken token = acquireReadActionLockImpl(false);

    try {
      action.run();
    } finally {
      token.finish();
    }
  }

  private static final ThreadLocal<Boolean> exceptionalThreadWithReadAccessFlag =
      new ThreadLocal<Boolean>();

  private static boolean isExceptionalThreadWithReadAccess() {
    Boolean flag = exceptionalThreadWithReadAccessFlag.get();
    return flag == Boolean.TRUE;
  }

  public static boolean setExceptionalThreadWithReadAccessFlag(boolean flag) {
    boolean old = isExceptionalThreadWithReadAccess();
    if (flag) {
      exceptionalThreadWithReadAccessFlag.set(Boolean.TRUE);
    } else {
      exceptionalThreadWithReadAccessFlag.remove();
    }
    return old;
  }

  public <T> T runReadAction(@NotNull final Computable<T> computation) {
    final AccessToken token = acquireReadActionLockImpl(false);

    try {
      return computation.compute();
    } finally {
      token.finish();
    }
  }

  public void runWriteAction(@NotNull final Runnable action) {
    final AccessToken token = acquireWriteActionLock(action.getClass());
    try {
      action.run();
    } finally {
      token.finish();
    }
  }

  public <T> T runWriteAction(@NotNull final Computable<T> computation) {
    final AccessToken token = acquireWriteActionLock(computation.getClass());
    try {
      return computation.compute();
    } finally {
      token.finish();
    }
  }

  public boolean hasWriteAction(@Nullable Class<?> actionClass) {
    assertCanRunWriteAction();

    for (int i = myWriteActionsStack.size() - 1; i >= 0; i--) {
      Class action = myWriteActionsStack.get(i);
      if (actionClass == action
          || action != null && ReflectionCache.isAssignable(actionClass, action)) return true;
    }
    return false;
  }

  public void assertReadAccessAllowed() {
    if (myHeadlessMode) return;
    if (!isReadAccessAllowed()) {
      LOG.error(
          "Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())",
          "Current thread: " + describe(Thread.currentThread()),
          "Our dispatch thread:" + describe(ourDispatchThread),
          "SystemEventQueueThread: " + describe(getEventQueueThread()));
    }
  }

  @NonNls
  private static String describe(Thread o) {
    if (o == null) return "null";
    return o.toString() + " " + System.identityHashCode(o);
  }

  @Nullable
  private static Thread getEventQueueThread() {
    EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
    try {
      Method method = EventQueue.class.getDeclaredMethod("getDispatchThread");
      method.setAccessible(true);
      return (Thread) method.invoke(eventQueue);
    } catch (Exception e1) {
      // ok
    }
    return null;
  }

  public boolean isReadAccessAllowed() {
    Thread currentThread = Thread.currentThread();
    return ourDispatchThread == currentThread
        || isExceptionalThreadWithReadAccess()
        || myActionsLock.isReadLockAcquired()
        || myActionsLock.isWriteLockAcquired()
        || isDispatchThread();
  }

  private static void assertCanRunWriteAction() {
    assertIsDispatchThread("Write access is allowed from event dispatch thread only");
  }

  public void assertIsDispatchThread() {
    assertIsDispatchThread("Access is allowed from event dispatch thread only.");
  }

  private static void assertIsDispatchThread(String message) {
    if (ShutDownTracker.isShutdownHookRunning()) return;
    final Thread currentThread = Thread.currentThread();
    if (ourDispatchThread == currentThread) return;

    if (EventQueue.isDispatchThread()) {
      ourDispatchThread = currentThread;
    }
    if (ourDispatchThread == currentThread) return;

    Integer safeCounter = ourEdtSafe.get();
    if (safeCounter != null && safeCounter > 0) return;

    LOG.error(
        message,
        "Current thread: " + describe(Thread.currentThread()),
        "Our dispatch thread:" + describe(ourDispatchThread),
        "SystemEventQueueThread: " + describe(getEventQueueThread()));
  }

  public void runEdtSafeAction(@NotNull Runnable runnable) {
    Integer value = ourEdtSafe.get();
    if (value == null) {
      value = Integer.valueOf(0);
    }

    ourEdtSafe.set(value + 1);

    try {
      runnable.run();
    } finally {
      int newValue = ourEdtSafe.get() - 1;
      ourEdtSafe.set(newValue >= 1 ? newValue : null);
    }
  }

  public void assertIsDispatchThread(@Nullable final JComponent component) {
    if (component == null) return;

    Thread curThread = Thread.currentThread();
    if (ourDispatchThread == curThread) {
      return;
    }

    if (Boolean.TRUE.equals(component.getClientProperty(WAS_EVER_SHOWN))) {
      assertIsDispatchThread();
    } else {
      final JRootPane root = component.getRootPane();
      if (root != null) {
        component.putClientProperty(WAS_EVER_SHOWN, Boolean.TRUE);
        assertIsDispatchThread();
      }
    }
  }

  public void assertTimeConsuming() {
    if (myTestModeFlag || myHeadlessMode || ShutDownTracker.isShutdownHookRunning()) return;
    LOG.assertTrue(
        !isDispatchThread(), "This operation is time consuming and must not be called on EDT");
  }

  public boolean tryRunReadAction(@NotNull Runnable action) {
    /**
     * if we are inside read action, do not try to acquire read lock again since it will deadlock if
     * there is a pending writeAction see {@link
     * com.intellij.util.concurrency.ReentrantWriterPreferenceReadWriteLock#allowReader()}
     */
    boolean mustAcquire = !isReadAccessAllowed();

    if (mustAcquire) {
      LOG.assertTrue(
          myTestModeFlag || !Thread.holdsLock(PsiLock.LOCK),
          "Thread must not hold PsiLock while performing readAction");
      try {
        if (!myActionsLock.readLock().attempt(0)) return false;
      } catch (InterruptedException e) {
        throw new RuntimeInterruptedException(e);
      }
    }

    try {
      action.run();
    } finally {
      if (mustAcquire) {
        myActionsLock.readLock().release();
      }
    }
    return true;
  }

  public boolean tryToApplyActivationState(boolean active, Window window) {
    final Component frame = UIUtil.findUltimateParent(window);

    if (frame instanceof IdeFrame) {
      final IdeFrame ideFrame = (IdeFrame) frame;
      if (isActive() != active) {
        myActive = Boolean.valueOf(active);
        System.setProperty("idea.active", myActive.toString());
        ApplicationActivationListener publisher =
            getMessageBus().syncPublisher(ApplicationActivationListener.TOPIC);
        if (active) {
          publisher.applicationActivated(ideFrame);
        } else {
          publisher.applicationDeactivated(ideFrame);
        }
        return true;
      }
    }

    return false;
  }

  public boolean isActive() {
    if (isUnitTestMode()) return true;

    if (myActive == null) {
      Window active = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
      return active != null;
    }

    return myActive;
  }

  @Override
  public AccessToken acquireReadActionLock() {
    return acquireReadActionLockImpl(true);
  }

  private AccessToken acquireReadActionLockImpl(boolean explicit) {
    /**
     * if we are inside read action, do not try to acquire read lock again since it will deadlock if
     * there is a pending writeAction see {@link
     * com.intellij.util.concurrency.ReentrantWriterPreferenceReadWriteLock#allowReader()}
     */
    if (isReadAccessAllowed()) return AccessToken.EMPTY_ACCESS_TOKEN;

    return new ReadAccessToken(explicit);
  }

  @Override
  public AccessToken acquireWriteActionLock(Class clazz) {
    return new WriteAccessToken(clazz);
  }

  private class WriteAccessToken extends AccessToken {
    private final Class clazz;

    public WriteAccessToken(Class _clazz) {
      clazz = _clazz;
      assertCanRunWriteAction();

      ActivityTracker.getInstance().inc();
      fireBeforeWriteActionStart(_clazz);
      final AtomicBoolean stopped = new AtomicBoolean(false);

      if (ourDumpThreadsOnLongWriteActionWaiting > 0) {
        executeOnPooledThread(
            new Runnable() {
              @Override
              public void run() {
                while (!stopped.get()) {
                  try {
                    Thread.sleep(ourDumpThreadsOnLongWriteActionWaiting);
                    if (!stopped.get()) {
                      PerformanceWatcher.getInstance().dumpThreads(true);
                    }
                  } catch (InterruptedException ignored) {
                  }
                }
              }
            });
      }

      LOG.assertTrue(
          myActionsLock.isWriteLockAcquired(Thread.currentThread())
              || !Thread.holdsLock(PsiLock.LOCK),
          "Thread must not hold PsiLock while performing writeAction");
      try {
        myActionsLock.writeLock().acquire();
        acquired();
      } catch (InterruptedException e) {
        throw new RuntimeInterruptedException(e);
      }
      stopped.set(true);

      myWriteActionsStack.push(_clazz);

      fireWriteActionStarted(_clazz);
    }

    @Override
    public void finish() {
      try {
        fireWriteActionFinished(clazz);

        myWriteActionsStack.pop();
      } finally {
        myActionsLock.writeLock().release();
        released();
      }
    }
  }

  private class ReadAccessToken extends AccessToken {
    private final boolean myExplicit;

    ReadAccessToken(boolean explicit) {
      myExplicit = explicit;
      LOG.assertTrue(
          !Thread.holdsLock(PsiLock.LOCK),
          "Thread must not hold PsiLock while performing readAction");
      try {
        myActionsLock.readLock().acquire();
        if (myExplicit) acquired();
      } catch (InterruptedException e) {
        throw new RuntimeInterruptedException(e);
      }
    }

    @Override
    public void finish() {
      myActionsLock.readLock().release();
      if (myExplicit) released();
    }
  }

  public void assertWriteAccessAllowed() {
    LOG.assertTrue(
        isWriteAccessAllowed(),
        "Write access is allowed inside write-action only (see com.intellij.openapi.application.Application.runWriteAction())");
  }

  public boolean isWriteAccessAllowed() {
    return myActionsLock.isWriteLockAcquired(Thread.currentThread());
  }

  public void editorPaintStart() {
    myInEditorPaintCounter++;
  }

  public void editorPaintFinish() {
    myInEditorPaintCounter--;
    LOG.assertTrue(myInEditorPaintCounter >= 0);
  }

  public void addApplicationListener(@NotNull ApplicationListener l) {
    myDispatcher.addListener(l);
  }

  public void addApplicationListener(@NotNull ApplicationListener l, @NotNull Disposable parent) {
    myDispatcher.addListener(l, parent);
  }

  public void removeApplicationListener(@NotNull ApplicationListener l) {
    myDispatcher.removeListener(l);
  }

  private void fireApplicationExiting() {
    myDispatcher.getMulticaster().applicationExiting();
  }

  private void fireBeforeWriteActionStart(Class action) {
    myDispatcher.getMulticaster().beforeWriteActionStart(action);
  }

  private void fireWriteActionStarted(Class action) {
    myDispatcher.getMulticaster().writeActionStarted(action);
  }

  private void fireWriteActionFinished(Class action) {
    myDispatcher.getMulticaster().writeActionFinished(action);
  }

  public void _saveSettings() { // public for testing purposes
    if (mySaveSettingsIsInProgress.compareAndSet(false, true)) {
      try {
        StoreUtil.doSave(getStateStore());
      } catch (final Throwable ex) {
        if (isUnitTestMode()) {
          System.out.println("Saving application settings failed");
          ex.printStackTrace();
        } else {
          LOG.info("Saving application settings failed", ex);
          invokeLater(
              new Runnable() {
                public void run() {
                  if (ex instanceof PluginException) {
                    final PluginException pluginException = (PluginException) ex;
                    PluginManager.disablePlugin(pluginException.getPluginId().getIdString());
                    Messages.showMessageDialog(
                        "The plugin "
                            + pluginException.getPluginId()
                            + " failed to save settings and has been disabled. Please restart "
                            + ApplicationNamesInfo.getInstance().getFullProductName(),
                        CommonBundle.getErrorTitle(),
                        Messages.getErrorIcon());
                  } else {
                    Messages.showMessageDialog(
                        ApplicationBundle.message(
                            "application.save.settings.error", ex.getLocalizedMessage()),
                        CommonBundle.getErrorTitle(),
                        Messages.getErrorIcon());
                  }
                }
              });
        }
      } finally {
        mySaveSettingsIsInProgress.set(false);
      }
    }
  }

  public void saveSettings() {
    if (myDoNotSave) return;
    _saveSettings();
  }

  public void saveAll() {
    if (myDoNotSave) return;

    FileDocumentManager.getInstance().saveAllDocuments();

    Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
    for (Project openProject : openProjects) {
      ProjectEx project = (ProjectEx) openProject;
      project.save();
    }

    saveSettings();
  }

  public void doNotSave() {
    doNotSave(true);
  }

  public void doNotSave(boolean value) {
    myDoNotSave = value;
  }

  public boolean isDoNotSave() {
    return myDoNotSave;
  }

  public <T> T[] getExtensions(final ExtensionPointName<T> extensionPointName) {
    return Extensions.getRootArea().getExtensionPoint(extensionPointName).getExtensions();
  }

  public boolean isDisposeInProgress() {
    return myDisposeInProgress;
  }

  public boolean isRestartCapable() {
    return SystemInfo.isWindows || SystemInfo.isMacOSSnowLeopard || myRestartCode > 0;
  }

  public void restart() {
    if (SystemInfo.isWindows) {
      Win32Restarter.restart();
    } else if (SystemInfo.isMacOSSnowLeopard) {
      MacRestarter.restart();
    } else if (myRestartCode > 0) {
      myExitCode = myRestartCode;
      exit(true);
    } else {
      exit(true);
    }
  }

  public boolean isSaving() {
    if (getStateStore().isSaving()) return true;
    Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
    for (Project openProject : openProjects) {
      ProjectEx project = (ProjectEx) openProject;
      if (project.getStateStore().isSaving()) return true;
    }

    return false;
  }

  @Override
  protected boolean logSlowComponents() {
    return super.logSlowComponents() || ApplicationInfoImpl.getShadowInstance().isEAP();
  }

  @TestOnly
  public void setDisposeInProgress(boolean disposeInProgress) {
    myDisposeInProgress = disposeInProgress;
  }

  @NonNls
  @Override
  public String toString() {
    return "Application"
        + (isDisposed() ? " (Disposed)" : "")
        + (isUnitTestMode() ? " (Unit test)" : "")
        + (isInternal() ? " (Internal)" : "")
        + (isHeadlessEnvironment() ? " (Headless)" : "")
        + (isCommandLine() ? " (Command line)" : "");
  }
}
コード例 #12
0
  public ApplicationImpl(
      boolean isInternal,
      boolean isUnitTestMode,
      boolean isHeadless,
      boolean isCommandLine,
      @NotNull String appName,
      Splash splash) {
    super(null);

    ApplicationManagerEx.setApplication(
        this, myLastDisposable); // reset back to null only when all components already disposed

    getPicoContainer().registerComponentInstance(Application.class, this);

    CommonBundle.assertKeyIsFound = isUnitTestMode;
    AWTExceptionHandler.register(); // do not crash AWT on exceptions
    if ((isInternal || isUnitTestMode)
        && !Comparing.equal("off", System.getProperty("idea.disposer.debug"))) {
      Disposer.setDebugMode(true);
    }
    myStartTime = System.currentTimeMillis();
    mySplash = splash;
    myName = appName;

    PluginsFacade.INSTANCE =
        new PluginsFacade() {
          public IdeaPluginDescriptor getPlugin(PluginId id) {
            return PluginManager.getPlugin(id);
          }

          public IdeaPluginDescriptor[] getPlugins() {
            return PluginManager.getPlugins();
          }
        };

    myIsInternal = isInternal;
    myTestModeFlag = isUnitTestMode;
    myHeadlessMode = isHeadless;
    myCommandLineMode = isCommandLine;

    myDoNotSave = myTestModeFlag || myHeadlessMode;

    loadApplicationComponents();

    if (myTestModeFlag) {
      registerShutdownHook();
    }

    if (!isUnitTestMode && !isHeadless) {
      Disposer.register(this, Disposer.newDisposable(), "ui");

      StartupUtil.addExternalInstanceListener(
          new Consumer<List<String>>() {
            @Override
            public void consume(final List<String> args) {
              invokeLater(
                  new Runnable() {
                    @Override
                    public void run() {
                      final Project project = CommandLineProcessor.processExternalCommandLine(args);
                      final IdeFrame frame;
                      if (project != null) {
                        frame = WindowManager.getInstance().getIdeFrame(project);
                      } else {
                        frame = WindowManager.getInstance().getAllFrames()[0];
                      }
                      ((IdeFrameImpl) frame).requestFocus();
                    }
                  });
            }
          });
    }

    final String s = System.getProperty("jb.restart.code");
    if (s != null) {
      try {
        myRestartCode = Integer.parseInt(s);
      } catch (NumberFormatException ignore) {
      }
    }

    registerFont("/fonts/Inconsolata.ttf");
  }
コード例 #13
0
/** @author peter */
public class DomFileDescriptionTest extends DomHardCoreTestCase {
  private XmlFile myFooElementFile;
  private XmlFile myBarElementFile;
  private Disposable myDisposable = Disposer.newDisposable();

  @Override
  protected void setUp() throws Exception {
    super.setUp();

    myFooElementFile = (XmlFile) createFile("a.xml", "<a/>");

    getDomManager()
        .registerFileDescription(
            new MockDomFileDescription<>(FooElement.class, "a", myFooElementFile), myDisposable);

    myBarElementFile = (XmlFile) createFile("b.xml", "<b/>");

    getDomManager()
        .registerFileDescription(
            new DomFileDescription<BarElement>(BarElement.class, "b") {
              @Override
              public boolean isMyFile(@NotNull final XmlFile file, final Module module) {
                String text = myFooElementFile.getText();
                return text.contains("239");
              }

              @Override
              public boolean isAutomaticHighlightingEnabled() {
                return false;
              }
            },
            myDisposable);

    assertResultsAndClear();
  }

  @Override
  public void tearDown() throws Exception {
    try {
      Disposer.dispose(myDisposable);
    } finally {
      myFooElementFile = null;
      myBarElementFile = null;

      super.tearDown();
    }
  }

  public void testNoInitialDomnessInB() throws Throwable {
    assertFalse(getDomManager().isDomFile(myBarElementFile));
    assertNull(getDomManager().getFileElement(myBarElementFile));
  }

  public void testIsDomValue() throws Throwable {
    final XmlFile file = (XmlFile) createFile("a.xml", "<b>42</b>");
    getDomManager()
        .registerFileDescription(
            new DomFileDescription<MyElement>(MyElement.class, "b") {

              @Override
              public boolean isMyFile(@NotNull final XmlFile file, final Module module) {
                return /*super.isMyFile(file, module) && */ file.getText().contains("239");
              }
            },
            myDisposable);

    assertFalse(getDomManager().isDomFile(file));
    assertNull(getDomManager().getFileElement(file));

    new WriteCommandAction(getProject()) {
      @Override
      protected void run(@NotNull Result result) throws Throwable {
        file.getDocument().getRootTag().getValue().setText("239");
      }
    }.execute();
    assertTrue(getDomManager().isDomFile(file));
    final DomFileElementImpl<MyElement> root = getDomManager().getFileElement(file);
    assertNotNull(root);
    final MyElement child = root.getRootElement().getChild();
    assertTrue(root.isValid());
    assertTrue(child.isValid());

    new WriteCommandAction(getProject()) {
      @Override
      protected void run(@NotNull Result result) throws Throwable {
        file.getDocument().getRootTag().getValue().setText("57121");
      }
    }.execute();
    assertFalse(getDomManager().isDomFile(file));
    assertNull(getDomManager().getFileElement(file));
    assertFalse(root.isValid());
    assertFalse(child.isValid());
  }

  public void testCopyFileDescriptionFromOriginalFile() throws Throwable {
    final XmlFile file = (XmlFile) createFile("a.xml", "<b>42</b>");

    getDomManager()
        .registerFileDescription(
            new MockDomFileDescription<>(MyElement.class, "b", file), myDisposable);
    ApplicationManager.getApplication()
        .runWriteAction(
            () -> {
              file.setName("b.xml");
            });

    assertTrue(getDomManager().isDomFile(file));
    final XmlFile copy = (XmlFile) file.copy();
    assertTrue(getDomManager().isDomFile(copy));
    assertFalse(getDomManager().getFileElement(file).equals(getDomManager().getFileElement(copy)));
  }

  public void testDependantFileDescriptionCauseStackOverflow() throws Throwable {
    final XmlFile interestingFile = (XmlFile) createFile("a.xml", "<b>42</b>");

    getDomManager()
        .registerFileDescription(
            new MockDomFileDescription<>(MyElement.class, "b", (XmlFile) null), myDisposable);
    for (int i = 0; i < 239; i++) {
      getDomManager()
          .registerFileDescription(
              new MockDomFileDescription<AbstractElement>(
                  AbstractElement.class, "b", (XmlFile) null) {
                @Override
                @NotNull
                public Set getDependencyItems(final XmlFile file) {
                  getDomManager().isDomFile(interestingFile);
                  return super.getDependencyItems(file);
                }
              },
              myDisposable);
    }

    getDomManager().isDomFile(interestingFile);
  }

  public void testCheckNamespace() throws Throwable {
    getDomManager()
        .registerFileDescription(
            new DomFileDescription<NamespacedElement>(NamespacedElement.class, "xxx", "bar") {

              @Override
              protected void initializeFileDescription() {
                registerNamespacePolicy("foo", "bar");
              }
            },
            myDisposable);

    final PsiFile file = createFile("xxx.xml", "<xxx/>");
    assertFalse(getDomManager().isDomFile(file));

    new WriteCommandAction(getProject()) {
      @Override
      protected void run(@NotNull Result result) throws Throwable {
        ((XmlFile) file).getDocument().getRootTag().setAttribute("xmlns", "bar");
      }
    }.execute();

    assertTrue(getDomManager().isDomFile(file));
  }

  public void testCheckDtdPublicId() throws Throwable {
    getDomManager()
        .registerFileDescription(
            new DomFileDescription<NamespacedElement>(NamespacedElement.class, "xxx", "bar") {

              @Override
              protected void initializeFileDescription() {
                registerNamespacePolicy("foo", "bar");
              }
            },
            myDisposable);

    final PsiFile file = createFile("xxx.xml", "<xxx/>");
    assertFalse(getDomManager().isDomFile(file));

    new WriteCommandAction(getProject()) {
      @Override
      protected void run(@NotNull Result result) throws Throwable {
        final Document document = getDocument(file);
        document.insertString(
            0, "<!DOCTYPE xxx PUBLIC \"bar\" \"http://java.sun.com/dtd/ejb-jar_2_0.dtd\">\n");
        commitDocument(document);
      }
    }.execute();

    assertTrue(getDomManager().isDomFile(file));
  }

  public void testChangeCustomDomness() throws Throwable {
    getDomManager()
        .registerFileDescription(
            new DomFileDescription<MyElement>(MyElement.class, "xxx") {
              @Override
              public boolean isMyFile(@NotNull final XmlFile file, @Nullable final Module module) {
                return file.getText().contains("foo");
              }
            },
            myDisposable);
    final XmlFile file = (XmlFile) createFile("xxx.xml", "<xxx zzz=\"foo\"><boy/><boy/><xxx/>");
    final MyElement boy =
        getDomManager().getFileElement(file, MyElement.class).getRootElement().getBoys().get(0);
    new WriteCommandAction(getProject()) {
      @Override
      protected void run(@NotNull Result result) throws Throwable {
        file.getDocument().getRootTag().setAttribute("zzz", "bar");
      }
    }.execute();
    assertFalse(getDomManager().isDomFile(file));
    assertFalse(boy.isValid());
  }

  public interface AbstractElement extends GenericDomValue<String> {
    GenericAttributeValue<String> getAttr();
  }

  public interface FooElement extends AbstractElement {}

  public interface BarElement extends AbstractElement {}

  public interface ZipElement extends AbstractElement {}

  public interface MyElement extends DomElement {

    MyElement getChild();

    List<MyElement> getBoys();
  }

  @Namespace("foo")
  public interface NamespacedElement extends DomElement {}
}
コード例 #14
0
public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
    implements EditorOptionsProvider {
  private HashMap<String, MyColorScheme> mySchemes;
  private MyColorScheme mySelectedScheme;
  public static final String DIFF_GROUP = ApplicationBundle.message("title.diff");
  public static final String FILE_STATUS_GROUP = ApplicationBundle.message("title.file.status");
  public static final String SCOPES_GROUP = ApplicationBundle.message("title.scope.based");

  private boolean mySomeSchemesDeleted = false;
  private Map<ColorAndFontPanelFactory, InnerSearchableConfigurable> mySubPanelFactories;

  private SchemesPanel myRootSchemesPanel;

  private boolean myInitResetCompleted = false;
  private boolean myInitResetInvoked = false;

  private boolean myRevertChangesCompleted = false;

  private boolean myApplyCompleted = false;
  private boolean myDisposeCompleted = false;
  private final Disposable myDisposable = Disposer.newDisposable();
  private static final Logger LOG =
      Logger.getInstance("#com.intellij.application.options.colors.ColorAndFontOptions");

  @Override
  public boolean isModified() {
    boolean listModified = isSchemeListModified();
    boolean schemeModified = isSomeSchemeModified();

    if (listModified || schemeModified) {
      myApplyCompleted = false;
    }

    return listModified;
  }

  private boolean isSchemeListModified() {
    if (mySomeSchemesDeleted) return true;

    if (!mySelectedScheme
        .getName()
        .equals(EditorColorsManager.getInstance().getGlobalScheme().getName())) return true;

    for (MyColorScheme scheme : mySchemes.values()) {
      if (scheme.isNew()) return true;
    }

    return false;
  }

  private boolean isSomeSchemeModified() {
    for (MyColorScheme scheme : mySchemes.values()) {
      if (scheme.isModified()) return true;
    }
    return false;
  }

  public EditorColorsScheme selectScheme(@NotNull String name) {
    mySelectedScheme = getScheme(name);
    return mySelectedScheme;
  }

  private MyColorScheme getScheme(String name) {
    return mySchemes.get(name);
  }

  public EditorColorsScheme getSelectedScheme() {
    return mySelectedScheme;
  }

  public EditorColorsScheme getOriginalSelectedScheme() {
    return mySelectedScheme == null ? null : mySelectedScheme.getOriginalScheme();
  }

  public EditorSchemeAttributeDescriptor[] getCurrentDescriptions() {
    return mySelectedScheme.getDescriptors();
  }

  public static boolean isReadOnly(@NotNull final EditorColorsScheme scheme) {
    return ((MyColorScheme) scheme).isReadOnly();
  }

  @NotNull
  public String[] getSchemeNames() {
    List<MyColorScheme> schemes = new ArrayList<MyColorScheme>(mySchemes.values());
    Collections.sort(
        schemes,
        new Comparator<MyColorScheme>() {
          @Override
          public int compare(@NotNull MyColorScheme o1, @NotNull MyColorScheme o2) {
            if (isReadOnly(o1) && !isReadOnly(o2)) return -1;
            if (!isReadOnly(o1) && isReadOnly(o2)) return 1;

            return o1.getName().compareToIgnoreCase(o2.getName());
          }
        });

    List<String> names = new ArrayList<String>(schemes.size());
    for (MyColorScheme scheme : schemes) {
      names.add(scheme.getName());
    }

    return ArrayUtil.toStringArray(names);
  }

  @NotNull
  public Collection<EditorColorsScheme> getSchemes() {
    return new ArrayList<EditorColorsScheme>(mySchemes.values());
  }

  public void saveSchemeAs(String name) {
    MyColorScheme scheme = mySelectedScheme;
    if (scheme == null) return;

    EditorColorsScheme clone = (EditorColorsScheme) scheme.getOriginalScheme().clone();

    scheme.apply(clone);

    clone.setName(name);
    MyColorScheme newScheme = new MyColorScheme(clone);
    initScheme(newScheme);

    newScheme.setIsNew();

    mySchemes.put(name, newScheme);
    selectScheme(newScheme.getName());
    resetSchemesCombo(null);
  }

  public void addImportedScheme(@NotNull final EditorColorsScheme imported) {
    MyColorScheme newScheme = new MyColorScheme(imported);
    initScheme(newScheme);

    mySchemes.put(imported.getName(), newScheme);
    selectScheme(newScheme.getName());
    resetSchemesCombo(null);
  }

  public void removeScheme(String name) {
    if (mySelectedScheme.getName().equals(name)) {
      //noinspection HardCodedStringLiteral
      selectScheme("Default");
    }

    boolean deletedNewlyCreated = false;

    MyColorScheme toDelete = mySchemes.get(name);

    if (toDelete != null) {
      deletedNewlyCreated = toDelete.isNew();
    }

    mySchemes.remove(name);
    resetSchemesCombo(null);
    mySomeSchemesDeleted = mySomeSchemesDeleted || !deletedNewlyCreated;
  }

  @Override
  public void apply() throws ConfigurationException {
    if (myApplyCompleted) {
      return;
    }
    try {
      EditorColorsManager myColorsManager = EditorColorsManager.getInstance();

      myColorsManager.removeAllSchemes();
      for (MyColorScheme scheme : mySchemes.values()) {
        if (!scheme.isDefault()) {
          scheme.apply();
          myColorsManager.addColorsScheme(scheme.getOriginalScheme());
        }
      }

      EditorColorsScheme originalScheme = mySelectedScheme.getOriginalScheme();
      myColorsManager.setGlobalScheme(originalScheme);
      if (originalScheme != null
          && DarculaLaf.NAME.equals(originalScheme.getName())
          && !UIUtil.isUnderDarcula()) {
        int ok =
            Messages.showYesNoDialog(
                "Darcula color scheme has been set for editors. Would you like to set Darcula as default Look and Feel?",
                "Darcula Look and Feel",
                Messages.getQuestionIcon());
        if (ok == Messages.YES) {
          LafManager.getInstance().setCurrentLookAndFeel(new DarculaLookAndFeelInfo());
          DarculaInstaller.install();
        }
      }
      applyChangesToEditors();

      reset();
    } finally {
      myApplyCompleted = true;
    }
  }

  private static void applyChangesToEditors() {
    EditorFactory.getInstance().refreshAllEditors();

    TodoConfiguration.getInstance().colorSettingsChanged();
    Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
    for (Project openProject : openProjects) {
      FileStatusManager.getInstance(openProject).fileStatusesChanged();
      DaemonCodeAnalyzer.getInstance(openProject).restart();
    }
  }

  private boolean myIsReset = false;

  private void resetSchemesCombo(Object source) {
    myIsReset = true;
    try {
      myRootSchemesPanel.resetSchemesCombo(source);
      if (mySubPanelFactories != null) {
        for (NewColorAndFontPanel subPartialConfigurable : getPanels()) {
          subPartialConfigurable.reset(source);
        }
      }
    } finally {
      myIsReset = false;
    }
  }

  @Override
  public JComponent createComponent() {
    if (myRootSchemesPanel == null) {
      ensureSchemesPanel();
    }
    return myRootSchemesPanel;
  }

  @Override
  public boolean hasOwnContent() {
    return true;
  }

  @NotNull
  @Override
  public Configurable[] buildConfigurables() {
    myDisposeCompleted = false;
    initAll();

    List<ColorAndFontPanelFactory> panelFactories = createPanelFactories();

    List<Configurable> result = new ArrayList<Configurable>();
    mySubPanelFactories =
        new LinkedHashMap<ColorAndFontPanelFactory, InnerSearchableConfigurable>(
            panelFactories.size());
    for (ColorAndFontPanelFactory panelFactory : panelFactories) {
      mySubPanelFactories.put(panelFactory, new InnerSearchableConfigurable(panelFactory));
    }

    result.addAll(new ArrayList<SearchableConfigurable>(mySubPanelFactories.values()));
    return result.toArray(new Configurable[result.size()]);
  }

  @NotNull
  private Set<NewColorAndFontPanel> getPanels() {
    Set<NewColorAndFontPanel> result = new HashSet<NewColorAndFontPanel>();
    for (InnerSearchableConfigurable configurable : mySubPanelFactories.values()) {
      NewColorAndFontPanel panel = configurable.getSubPanelIfInitialized();
      if (panel != null) {
        result.add(panel);
      }
    }
    return result;
  }

  protected List<ColorAndFontPanelFactory> createPanelFactories() {
    List<ColorAndFontPanelFactory> result = new ArrayList<ColorAndFontPanelFactory>();
    result.add(new FontConfigurableFactory());

    List<ColorAndFontPanelFactory> extensions = new ArrayList<ColorAndFontPanelFactory>();
    extensions.add(new ConsoleFontConfigurableFactory());
    ColorSettingsPage[] pages = ColorSettingsPages.getInstance().getRegisteredPages();
    for (final ColorSettingsPage page : pages) {
      extensions.add(
          new ColorAndFontPanelFactoryEx() {
            @Override
            @NotNull
            public NewColorAndFontPanel createPanel(@NotNull ColorAndFontOptions options) {
              final SimpleEditorPreview preview = new SimpleEditorPreview(options, page);
              return NewColorAndFontPanel.create(
                  preview, page.getDisplayName(), options, null, page);
            }

            @Override
            @NotNull
            public String getPanelDisplayName() {
              return page.getDisplayName();
            }

            @Override
            public DisplayPriority getPriority() {
              if (page instanceof DisplayPrioritySortable) {
                return ((DisplayPrioritySortable) page).getPriority();
              }
              return DisplayPriority.LANGUAGE_SETTINGS;
            }
          });
    }
    Collections.addAll(extensions, Extensions.getExtensions(ColorAndFontPanelFactory.EP_NAME));
    Collections.sort(
        extensions,
        new Comparator<ColorAndFontPanelFactory>() {
          @Override
          public int compare(ColorAndFontPanelFactory f1, ColorAndFontPanelFactory f2) {
            if (f1 instanceof DisplayPrioritySortable) {
              if (f2 instanceof DisplayPrioritySortable) {
                int result =
                    ((DisplayPrioritySortable) f1)
                        .getPriority()
                        .compareTo(((DisplayPrioritySortable) f2).getPriority());
                if (result != 0) return result;
              } else {
                return 1;
              }
            } else if (f2 instanceof DisplayPrioritySortable) {
              return -1;
            }
            return f1.getPanelDisplayName().compareToIgnoreCase(f2.getPanelDisplayName());
          }
        });
    result.addAll(extensions);

    result.add(new DiffColorsPageFactory());
    result.add(new FileStatusColorsPageFactory());
    result.add(new ScopeColorsPageFactory());

    return result;
  }

  private static class FontConfigurableFactory implements ColorAndFontPanelFactory {
    @Override
    @NotNull
    public NewColorAndFontPanel createPanel(@NotNull ColorAndFontOptions options) {
      FontEditorPreview previewPanel = new FontEditorPreview(options, true);
      return new NewColorAndFontPanel(
          new SchemesPanel(options), new FontOptions(options), previewPanel, "Font", null, null) {
        @Override
        public boolean containsFontOptions() {
          return true;
        }
      };
    }

    @Override
    @NotNull
    public String getPanelDisplayName() {
      return "Font";
    }
  }

  private static class ConsoleFontConfigurableFactory implements ColorAndFontPanelFactoryEx {
    @Override
    @NotNull
    public NewColorAndFontPanel createPanel(@NotNull ColorAndFontOptions options) {
      FontEditorPreview previewPanel =
          new FontEditorPreview(options, false) {
            @Override
            protected EditorColorsScheme updateOptionsScheme(EditorColorsScheme selectedScheme) {
              return ConsoleViewUtil.updateConsoleColorScheme(selectedScheme);
            }
          };
      return new NewColorAndFontPanel(
          new SchemesPanel(options),
          new ConsoleFontOptions(options),
          previewPanel,
          "Font",
          null,
          null) {
        @Override
        public boolean containsFontOptions() {
          return true;
        }
      };
    }

    @Override
    @NotNull
    public String getPanelDisplayName() {
      return "Console Font";
    }

    @NotNull
    @Override
    public DisplayPriority getPriority() {
      return DisplayPriority.COMMON_SETTINGS;
    }
  }

  private class DiffColorsPageFactory implements ColorAndFontPanelFactory {
    @Override
    @NotNull
    public NewColorAndFontPanel createPanel(@NotNull ColorAndFontOptions options) {
      final DiffOptionsPanel optionsPanel = new DiffOptionsPanel(options);
      SchemesPanel schemesPanel = new SchemesPanel(options);
      PreviewPanel previewPanel;
      try {
        final DiffPreviewPanel diffPreviewPanel = new DiffPreviewPanel(myDisposable);
        diffPreviewPanel.setMergeRequest(null);
        schemesPanel.addListener(
            new ColorAndFontSettingsListener.Abstract() {
              @Override
              public void schemeChanged(final Object source) {
                diffPreviewPanel.setColorScheme(getSelectedScheme());
                optionsPanel.updateOptionsList();
                diffPreviewPanel.updateView();
              }
            });
        previewPanel = diffPreviewPanel;
      } catch (FilesTooBigForDiffException e) {
        LOG.info(e);
        previewPanel = new PreviewPanel.Empty();
      }

      return new NewColorAndFontPanel(
          schemesPanel, optionsPanel, previewPanel, DIFF_GROUP, null, null);
    }

    @Override
    @NotNull
    public String getPanelDisplayName() {
      return DIFF_GROUP;
    }
  }

  private void initAll() {
    EditorColorsManager colorsManager = EditorColorsManager.getInstance();
    EditorColorsScheme[] allSchemes = colorsManager.getAllSchemes();

    mySchemes = new HashMap<String, MyColorScheme>();
    for (EditorColorsScheme allScheme : allSchemes) {
      MyColorScheme schemeDelegate = new MyColorScheme(allScheme);
      initScheme(schemeDelegate);
      mySchemes.put(schemeDelegate.getName(), schemeDelegate);
    }

    mySelectedScheme = mySchemes.get(EditorColorsManager.getInstance().getGlobalScheme().getName());
    assert mySelectedScheme != null
        : EditorColorsManager.getInstance().getGlobalScheme().getName()
            + "; myschemes="
            + mySchemes;
  }

  private static void initScheme(@NotNull MyColorScheme scheme) {
    List<EditorSchemeAttributeDescriptor> descriptions =
        new ArrayList<EditorSchemeAttributeDescriptor>();
    initPluggedDescriptions(descriptions, scheme);
    initDiffDescriptors(descriptions, scheme);
    initFileStatusDescriptors(descriptions, scheme);
    initScopesDescriptors(descriptions, scheme);

    scheme.setDescriptors(
        descriptions.toArray(new EditorSchemeAttributeDescriptor[descriptions.size()]));
  }

  private static void initPluggedDescriptions(
      @NotNull List<EditorSchemeAttributeDescriptor> descriptions, @NotNull MyColorScheme scheme) {
    ColorSettingsPage[] pages = ColorSettingsPages.getInstance().getRegisteredPages();
    for (ColorSettingsPage page : pages) {
      initDescriptions(page, descriptions, scheme);
    }
    for (ColorAndFontDescriptorsProvider provider :
        Extensions.getExtensions(ColorAndFontDescriptorsProvider.EP_NAME)) {
      initDescriptions(provider, descriptions, scheme);
    }
  }

  private static void initDescriptions(
      @NotNull ColorAndFontDescriptorsProvider provider,
      @NotNull List<EditorSchemeAttributeDescriptor> descriptions,
      @NotNull MyColorScheme scheme) {
    String group = provider.getDisplayName();
    List<AttributesDescriptor> attributeDescriptors =
        ColorSettingsUtil.getAllAttributeDescriptors(provider);
    for (AttributesDescriptor descriptor : attributeDescriptors) {
      addSchemedDescription(
          descriptions,
          descriptor.getDisplayName(),
          group,
          descriptor.getKey(),
          scheme,
          null,
          null);
    }

    ColorDescriptor[] colorDescriptors = provider.getColorDescriptors();
    for (ColorDescriptor descriptor : colorDescriptors) {
      ColorKey back =
          descriptor.getKind() == ColorDescriptor.Kind.BACKGROUND ? descriptor.getKey() : null;
      ColorKey fore =
          descriptor.getKind() == ColorDescriptor.Kind.FOREGROUND ? descriptor.getKey() : null;
      addEditorSettingDescription(
          descriptions, descriptor.getDisplayName(), group, back, fore, scheme);
    }
  }

  private static void initDiffDescriptors(
      @NotNull List<EditorSchemeAttributeDescriptor> descriptions, @NotNull MyColorScheme scheme) {
    DiffOptionsPanel.addSchemeDescriptions(descriptions, scheme);
  }

  private static void initFileStatusDescriptors(
      @NotNull List<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {

    FileStatus[] statuses = FileStatusFactory.getInstance().getAllFileStatuses();

    for (FileStatus fileStatus : statuses) {
      addEditorSettingDescription(
          descriptions,
          fileStatus.getText(),
          FILE_STATUS_GROUP,
          null,
          fileStatus.getColorKey(),
          scheme);
    }
  }

  private static void initScopesDescriptors(
      @NotNull List<EditorSchemeAttributeDescriptor> descriptions, @NotNull MyColorScheme scheme) {
    Set<Pair<NamedScope, NamedScopesHolder>> namedScopes =
        new THashSet<Pair<NamedScope, NamedScopesHolder>>(
            new TObjectHashingStrategy<Pair<NamedScope, NamedScopesHolder>>() {
              @Override
              public int computeHashCode(
                  @NotNull final Pair<NamedScope, NamedScopesHolder> object) {
                return object.getFirst().getName().hashCode();
              }

              @Override
              public boolean equals(
                  @NotNull final Pair<NamedScope, NamedScopesHolder> o1,
                  @NotNull final Pair<NamedScope, NamedScopesHolder> o2) {
                return o1.getFirst().getName().equals(o2.getFirst().getName());
              }
            });
    Project[] projects = ProjectManager.getInstance().getOpenProjects();
    for (Project project : projects) {
      DependencyValidationManagerImpl validationManager =
          (DependencyValidationManagerImpl) DependencyValidationManager.getInstance(project);
      List<Pair<NamedScope, NamedScopesHolder>> cachedScopes =
          validationManager.getScopeBasedHighlightingCachedScopes();
      namedScopes.addAll(cachedScopes);
    }

    List<Pair<NamedScope, NamedScopesHolder>> list =
        new ArrayList<Pair<NamedScope, NamedScopesHolder>>(namedScopes);

    Collections.sort(
        list,
        new Comparator<Pair<NamedScope, NamedScopesHolder>>() {
          @Override
          public int compare(
              @NotNull final Pair<NamedScope, NamedScopesHolder> o1,
              @NotNull final Pair<NamedScope, NamedScopesHolder> o2) {
            return o1.getFirst().getName().compareToIgnoreCase(o2.getFirst().getName());
          }
        });
    for (Pair<NamedScope, NamedScopesHolder> pair : list) {
      NamedScope namedScope = pair.getFirst();
      String name = namedScope.getName();
      TextAttributesKey textAttributesKey = ScopeAttributesUtil.getScopeTextAttributeKey(name);
      if (scheme.getAttributes(textAttributesKey) == null) {
        scheme.setAttributes(textAttributesKey, new TextAttributes());
      }
      NamedScopesHolder holder = pair.getSecond();

      PackageSet value = namedScope.getValue();
      String toolTip = holder.getDisplayName() + (value == null ? "" : ": " + value.getText());
      addSchemedDescription(
          descriptions, name, SCOPES_GROUP, textAttributesKey, scheme, holder.getIcon(), toolTip);
    }
  }

  private static void addEditorSettingDescription(
      @NotNull List<EditorSchemeAttributeDescriptor> array,
      String name,
      String group,
      @Nullable ColorKey backgroundKey,
      @Nullable ColorKey foregroundKey,
      EditorColorsScheme scheme) {
    String type = null;
    if (foregroundKey != null) {
      type = foregroundKey.getExternalName();
    } else {
      if (backgroundKey != null) {
        type = backgroundKey.getExternalName();
      }
    }
    ColorAndFontDescription descr =
        new EditorSettingColorDescription(name, group, backgroundKey, foregroundKey, type, scheme);
    array.add(descr);
  }

  private static void addSchemedDescription(
      @NotNull List<EditorSchemeAttributeDescriptor> array,
      String name,
      String group,
      @NotNull TextAttributesKey key,
      @NotNull MyColorScheme scheme,
      Icon icon,
      String toolTip) {
    ColorAndFontDescription descr =
        new SchemeTextAttributesDescription(name, group, key, scheme, icon, toolTip);
    array.add(descr);
  }

  @Override
  public String getDisplayName() {
    return ApplicationBundle.message("title.colors.and.fonts");
  }

  private void revertChanges() {
    if (isSchemeListModified() || isSomeSchemeModified()) {
      myRevertChangesCompleted = false;
    }

    if (!myRevertChangesCompleted) {
      ensureSchemesPanel();

      try {
        resetImpl();
      } finally {
        myRevertChangesCompleted = true;
      }
    }
  }

  private void resetImpl() {
    mySomeSchemesDeleted = false;
    initAll();
    resetSchemesCombo(null);
  }

  @Override
  public synchronized void reset() {
    if (!myInitResetInvoked) {
      try {
        super.reset();
        if (!myInitResetCompleted) {
          ensureSchemesPanel();

          try {
            resetImpl();
          } finally {
            myInitResetCompleted = true;
          }
        }
      } finally {
        myInitResetInvoked = true;
      }

    } else {
      revertChanges();
    }
  }

  public synchronized void resetFromChild() {
    if (!myInitResetCompleted) {
      ensureSchemesPanel();

      try {
        resetImpl();
      } finally {
        myInitResetCompleted = true;
      }
    }
  }

  private void ensureSchemesPanel() {
    if (myRootSchemesPanel == null) {
      myRootSchemesPanel = new SchemesPanel(this);

      myRootSchemesPanel.addListener(
          new ColorAndFontSettingsListener.Abstract() {
            @Override
            public void schemeChanged(final Object source) {
              if (!myIsReset) {
                resetSchemesCombo(source);
              }
            }
          });
    }
  }

  @Override
  public void disposeUIResources() {
    try {
      if (!myDisposeCompleted) {
        try {
          super.disposeUIResources();
          Disposer.dispose(myDisposable);
          if (myRootSchemesPanel != null) {
            myRootSchemesPanel.disposeUIResources();
          }
        } finally {
          myDisposeCompleted = true;
        }
      }
    } finally {
      mySubPanelFactories = null;

      myInitResetCompleted = false;
      myInitResetInvoked = false;
      myRevertChangesCompleted = false;

      myApplyCompleted = false;
      myRootSchemesPanel = null;
    }
  }

  public boolean currentSchemeIsReadOnly() {
    return isReadOnly(mySelectedScheme);
  }

  public boolean currentSchemeIsShared() {
    return ColorSettingsUtil.isSharedScheme(mySelectedScheme);
  }

  private static class SchemeTextAttributesDescription extends TextAttributesDescription {
    @NotNull private final TextAttributes myAttributesToApply;
    @NotNull private final TextAttributesKey key;
    private TextAttributes myFallbackAttributes;
    private Pair<ColorSettingsPage, AttributesDescriptor> myBaseAttributeDescriptor;
    private boolean myIsInheritedInitial = false;

    private SchemeTextAttributesDescription(
        String name,
        String group,
        @NotNull TextAttributesKey key,
        @NotNull MyColorScheme scheme,
        Icon icon,
        String toolTip) {
      super(name, group, getInitialAttributes(scheme, key).clone(), key, scheme, icon, toolTip);
      this.key = key;
      myAttributesToApply = getInitialAttributes(scheme, key);
      TextAttributesKey fallbackKey = key.getFallbackAttributeKey();
      if (fallbackKey != null) {
        myFallbackAttributes = scheme.getAttributes(fallbackKey);
        myBaseAttributeDescriptor =
            ColorSettingsPages.getInstance().getAttributeDescriptor(fallbackKey);
        if (myBaseAttributeDescriptor == null) {
          myBaseAttributeDescriptor =
              new Pair<ColorSettingsPage, AttributesDescriptor>(
                  null, new AttributesDescriptor(fallbackKey.getExternalName(), fallbackKey));
        }
      }
      myIsInheritedInitial = isInherited(scheme);
      setInherited(myIsInheritedInitial);
      initCheckedStatus();
    }

    @NotNull
    private static TextAttributes getInitialAttributes(
        @NotNull MyColorScheme scheme, @NotNull TextAttributesKey key) {
      TextAttributes attributes = scheme.getAttributes(key);
      return attributes != null ? attributes : new TextAttributes();
    }

    private boolean isInherited(@NotNull MyColorScheme scheme) {
      TextAttributes attributes = scheme.getAttributes(key);
      TextAttributesKey fallbackKey = key.getFallbackAttributeKey();
      if (fallbackKey != null && !scheme.containsKey(key)) {
        TextAttributes fallbackAttributes = scheme.getAttributes(fallbackKey);
        if (attributes != null && attributes == fallbackAttributes) {
          return true;
        }
      }
      return false;
    }

    @Override
    public void apply(EditorColorsScheme scheme) {
      if (scheme == null) scheme = getScheme();
      scheme.setAttributes(key, isInherited() ? new TextAttributes() : getTextAttributes());
    }

    @Override
    public boolean isModified() {
      return !Comparing.equal(myAttributesToApply, getTextAttributes())
          || myIsInheritedInitial != isInherited();
    }

    @Override
    public boolean isErrorStripeEnabled() {
      return true;
    }

    @Nullable
    @Override
    public TextAttributes getBaseAttributes() {
      return myFallbackAttributes;
    }

    @Nullable
    @Override
    public Pair<ColorSettingsPage, AttributesDescriptor> getBaseAttributeDescriptor() {
      return myBaseAttributeDescriptor;
    }

    @Override
    public void setInherited(boolean isInherited) {
      super.setInherited(isInherited);
    }
  }

  private static class GetSetColor {
    private final ColorKey myKey;
    private final EditorColorsScheme myScheme;
    private boolean isModified = false;
    private Color myColor;

    private GetSetColor(ColorKey key, EditorColorsScheme scheme) {
      myKey = key;
      myScheme = scheme;
      myColor = myScheme.getColor(myKey);
    }

    public Color getColor() {
      return myColor;
    }

    public void setColor(Color col) {
      if (getColor() == null || !getColor().equals(col)) {
        isModified = true;
        myColor = col;
      }
    }

    public void apply(EditorColorsScheme scheme) {
      if (scheme == null) scheme = myScheme;
      scheme.setColor(myKey, myColor);
    }

    public boolean isModified() {
      return isModified;
    }
  }

  private static class EditorSettingColorDescription extends ColorAndFontDescription {
    private GetSetColor myGetSetForeground;
    private GetSetColor myGetSetBackground;

    private EditorSettingColorDescription(
        String name,
        String group,
        ColorKey backgroundKey,
        ColorKey foregroundKey,
        String type,
        EditorColorsScheme scheme) {
      super(name, group, type, scheme, null, null);
      if (backgroundKey != null) {
        myGetSetBackground = new GetSetColor(backgroundKey, scheme);
      }
      if (foregroundKey != null) {
        myGetSetForeground = new GetSetColor(foregroundKey, scheme);
      }
      initCheckedStatus();
    }

    @Override
    public int getFontType() {
      return 0;
    }

    @Override
    public void setFontType(int type) {}

    @Override
    public Color getExternalEffectColor() {
      return null;
    }

    @Override
    public void setExternalEffectColor(Color color) {}

    @Override
    public void setExternalEffectType(EffectType type) {}

    @NotNull
    @Override
    public EffectType getExternalEffectType() {
      return EffectType.LINE_UNDERSCORE;
    }

    @Override
    public Color getExternalForeground() {
      if (myGetSetForeground == null) {
        return null;
      }
      return myGetSetForeground.getColor();
    }

    @Override
    public void setExternalForeground(Color col) {
      if (myGetSetForeground == null) {
        return;
      }
      myGetSetForeground.setColor(col);
    }

    @Override
    public Color getExternalBackground() {
      if (myGetSetBackground == null) {
        return null;
      }
      return myGetSetBackground.getColor();
    }

    @Override
    public void setExternalBackground(Color col) {
      if (myGetSetBackground == null) {
        return;
      }
      myGetSetBackground.setColor(col);
    }

    @Override
    public Color getExternalErrorStripe() {
      return null;
    }

    @Override
    public void setExternalErrorStripe(Color col) {}

    @Override
    public boolean isFontEnabled() {
      return false;
    }

    @Override
    public boolean isForegroundEnabled() {
      return myGetSetForeground != null;
    }

    @Override
    public boolean isBackgroundEnabled() {
      return myGetSetBackground != null;
    }

    @Override
    public boolean isEffectsColorEnabled() {
      return false;
    }

    @Override
    public boolean isModified() {
      return myGetSetBackground != null && myGetSetBackground.isModified()
          || myGetSetForeground != null && myGetSetForeground.isModified();
    }

    @Override
    public void apply(EditorColorsScheme scheme) {
      if (myGetSetBackground != null) {
        myGetSetBackground.apply(scheme);
      }
      if (myGetSetForeground != null) {
        myGetSetForeground.apply(scheme);
      }
    }
  }

  @Override
  @NotNull
  public String getHelpTopic() {
    return "reference.settingsdialog.IDE.editor.colors";
  }

  private static class MyColorScheme extends EditorColorsSchemeImpl {

    private EditorSchemeAttributeDescriptor[] myDescriptors;
    private String myName;
    private boolean myIsNew = false;

    private MyColorScheme(@NotNull EditorColorsScheme parentScheme) {
      super(parentScheme, DefaultColorSchemesManager.getInstance());
      parentScheme.getFontPreferences().copyTo(getFontPreferences());
      setLineSpacing(parentScheme.getLineSpacing());

      parentScheme.getConsoleFontPreferences().copyTo(getConsoleFontPreferences());
      setConsoleLineSpacing(parentScheme.getConsoleLineSpacing());

      setQuickDocFontSize(parentScheme.getQuickDocFontSize());
      myName = parentScheme.getName();
      if (parentScheme instanceof ExternalizableScheme) {
        getExternalInfo().copy(((ExternalizableScheme) parentScheme).getExternalInfo());
      }
      initFonts();
    }

    @Override
    public String getName() {
      return myName;
    }

    @Override
    public void setName(String name) {
      myName = name;
    }

    public void setDescriptors(EditorSchemeAttributeDescriptor[] descriptors) {
      myDescriptors = descriptors;
    }

    public EditorSchemeAttributeDescriptor[] getDescriptors() {
      return myDescriptors;
    }

    public boolean isDefault() {
      return myParentScheme instanceof DefaultColorsScheme;
    }

    public boolean isReadOnly() {
      return myParentScheme instanceof ReadOnlyColorsScheme;
    }

    public boolean isModified() {
      if (isFontModified() || isConsoleFontModified()) return true;

      for (EditorSchemeAttributeDescriptor descriptor : myDescriptors) {
        if (descriptor.isModified()) {
          return true;
        }
      }

      return false;
    }

    private boolean isFontModified() {
      if (!getFontPreferences().equals(myParentScheme.getFontPreferences())) return true;
      if (getLineSpacing() != myParentScheme.getLineSpacing()) return true;
      return getQuickDocFontSize() != myParentScheme.getQuickDocFontSize();
    }

    private boolean isConsoleFontModified() {
      if (!getConsoleFontPreferences().equals(myParentScheme.getConsoleFontPreferences()))
        return true;
      return getConsoleLineSpacing() != myParentScheme.getConsoleLineSpacing();
    }

    public void apply() {
      apply(myParentScheme);
    }

    public void apply(@NotNull EditorColorsScheme scheme) {
      scheme.setFontPreferences(getFontPreferences());
      scheme.setLineSpacing(myLineSpacing);
      scheme.setQuickDocFontSize(getQuickDocFontSize());
      scheme.setConsoleFontPreferences(getConsoleFontPreferences());
      scheme.setConsoleLineSpacing(getConsoleLineSpacing());

      for (EditorSchemeAttributeDescriptor descriptor : myDescriptors) {
        descriptor.apply(scheme);
      }
    }

    @Override
    public Object clone() {
      return null;
    }

    public EditorColorsScheme getOriginalScheme() {
      return myParentScheme;
    }

    public void setIsNew() {
      myIsNew = true;
    }

    public boolean isNew() {
      return myIsNew;
    }

    @NotNull
    @Override
    public String toString() {
      return "temporary scheme for " + myName;
    }
  }

  @Override
  @NotNull
  public String getId() {
    return getHelpTopic();
  }

  @Override
  @Nullable
  public Runnable enableSearch(final String option) {
    return null;
  }

  @Nullable
  public InnerSearchableConfigurable findSubConfigurable(@NotNull final Class pageClass) {
    if (mySubPanelFactories == null) {
      buildConfigurables();
    }
    for (Map.Entry<ColorAndFontPanelFactory, InnerSearchableConfigurable> entry :
        mySubPanelFactories.entrySet()) {
      if (pageClass.isInstance(entry.getValue().createPanel().getSettingsPage())) {
        return entry.getValue();
      }
    }
    return null;
  }

  @Nullable
  public NewColorAndFontPanel findPage(String pageName) {
    if (mySubPanelFactories == null) {
      buildConfigurables();
    }
    for (InnerSearchableConfigurable configurable : mySubPanelFactories.values()) {
      if (configurable.getDisplayName().equals(pageName)) {
        return configurable.createPanel();
      }
    }
    return null;
  }

  private class InnerSearchableConfigurable
      implements SearchableConfigurable, OptionsContainingConfigurable, NoScroll {
    private NewColorAndFontPanel mySubPanel;
    private boolean mySubInitInvoked = false;
    @NotNull private final ColorAndFontPanelFactory myFactory;

    private InnerSearchableConfigurable(@NotNull ColorAndFontPanelFactory factory) {
      myFactory = factory;
    }

    @NotNull
    @Override
    @Nls
    public String getDisplayName() {
      return myFactory.getPanelDisplayName();
    }

    public NewColorAndFontPanel getSubPanelIfInitialized() {
      return mySubPanel;
    }

    private NewColorAndFontPanel createPanel() {
      if (mySubPanel == null) {
        mySubPanel = myFactory.createPanel(ColorAndFontOptions.this);
        mySubPanel.reset(this);
        mySubPanel.addSchemesListener(
            new ColorAndFontSettingsListener.Abstract() {
              @Override
              public void schemeChanged(final Object source) {
                if (!myIsReset) {
                  resetSchemesCombo(source);
                }
              }
            });

        mySubPanel.addDescriptionListener(
            new ColorAndFontSettingsListener.Abstract() {
              @Override
              public void fontChanged() {
                for (NewColorAndFontPanel panel : getPanels()) {
                  panel.updatePreview();
                }
              }
            });
      }
      return mySubPanel;
    }

    @Override
    public String getHelpTopic() {
      return null;
    }

    @Override
    public JComponent createComponent() {
      return createPanel().getPanel();
    }

    @Override
    public boolean isModified() {
      createPanel();
      for (MyColorScheme scheme : mySchemes.values()) {
        if (mySubPanel.containsFontOptions()) {
          if (scheme.isFontModified() || scheme.isConsoleFontModified()) {
            myRevertChangesCompleted = false;
            return true;
          }
        } else {
          for (EditorSchemeAttributeDescriptor descriptor : scheme.getDescriptors()) {
            if (mySubPanel.contains(descriptor) && descriptor.isModified()) {
              myRevertChangesCompleted = false;
              return true;
            }
          }
        }
      }

      return false;
    }

    @Override
    public void apply() throws ConfigurationException {
      ColorAndFontOptions.this.apply();
    }

    @Override
    public void reset() {
      if (!mySubInitInvoked) {
        if (!myInitResetCompleted) {
          resetFromChild();
        }
        mySubInitInvoked = true;
      } else {
        revertChanges();
      }
    }

    @Override
    public void disposeUIResources() {
      if (mySubPanel != null) {
        mySubPanel.disposeUIResources();
        mySubPanel = null;
      }
    }

    @Override
    @NotNull
    public String getId() {
      return ColorAndFontOptions.this.getId() + "." + getDisplayName();
    }

    @Override
    public Runnable enableSearch(final String option) {
      return createPanel().showOption(option);
    }

    @NotNull
    @Override
    public Set<String> processListOptions() {
      return createPanel().processListOptions();
    }

    @NotNull
    @NonNls
    @Override
    public String toString() {
      return "Color And Fonts for " + getDisplayName();
    }
  }
}
コード例 #15
0
public class BreakpointsDialog extends DialogWrapper {
  @NotNull private Project myProject;

  private Object myInitialBreakpoint;
  private List<BreakpointPanelProvider> myBreakpointsPanelProviders;

  private BreakpointItemsTreeController myTreeController;

  JLabel temp = new JLabel();

  private MasterController myMasterController =
      new MasterController() {
        @Override
        public ItemWrapper[] getSelectedItems() {
          final List<BreakpointItem> res = myTreeController.getSelectedBreakpoints();
          return res.toArray(new ItemWrapper[res.size()]);
        }

        @Override
        public JLabel getPathLabel() {
          return temp;
        }
      };

  private final DetailController myDetailController = new DetailController(myMasterController);

  private Collection<BreakpointItem> myBreakpointItems = new ArrayList<BreakpointItem>();

  private final List<XBreakpointGroupingRule> myRulesAvailable =
      new ArrayList<XBreakpointGroupingRule>();

  private Set<XBreakpointGroupingRule> myRulesEnabled =
      new TreeSet<XBreakpointGroupingRule>(
          new Comparator<XBreakpointGroupingRule>() {
            @Override
            public int compare(XBreakpointGroupingRule o1, XBreakpointGroupingRule o2) {
              final int res = o2.getPriority() - o1.getPriority();
              return res != 0 ? res : (o1.getId().compareTo(o2.getId()));
            }
          });
  private Disposable myListenerDisposable = Disposer.newDisposable();
  private List<ToggleActionButton> myToggleRuleActions = new ArrayList<ToggleActionButton>();

  private XBreakpointManagerImpl getBreakpointManager() {
    return (XBreakpointManagerImpl) XDebuggerManager.getInstance(myProject).getBreakpointManager();
  }

  protected BreakpointsDialog(
      @NotNull Project project,
      Object breakpoint,
      @NotNull List<BreakpointPanelProvider> providers) {
    super(project);
    myProject = project;
    myBreakpointsPanelProviders = providers;
    myInitialBreakpoint = breakpoint;

    collectGroupingRules();

    collectItems();

    setTitle("Breakpoints");
    setModal(false);
    init();
    setOKButtonText("Done");
  }

  private String getSplitterProportionKey() {
    return getDimensionServiceKey() + ".splitter";
  }

  @Nullable
  @Override
  protected JComponent createCenterPanel() {
    JPanel mainPanel = new JPanel(new BorderLayout());

    JBSplitter splitPane = new JBSplitter(0.3f);
    splitPane.setSplitterProportionKey(getSplitterProportionKey());

    splitPane.setFirstComponent(createMasterView());
    splitPane.setSecondComponent(createDetailView());

    mainPanel.add(splitPane, BorderLayout.CENTER);

    return mainPanel;
  }

  private JComponent createDetailView() {
    DetailViewImpl detailView = new DetailViewImpl(myProject);
    myDetailController.setDetailView(detailView);

    return detailView;
  }

  void collectItems() {
    if (!myBreakpointsPanelProviders.isEmpty()) {
      myBreakpointItems.clear();
      for (BreakpointPanelProvider panelProvider : myBreakpointsPanelProviders) {
        panelProvider.provideBreakpointItems(myProject, myBreakpointItems);
      }
    }
  }

  void initSelection(Collection<BreakpointItem> breakpoints) {
    boolean found = false;
    for (BreakpointItem breakpoint : breakpoints) {
      if (breakpoint.getBreakpoint() == myInitialBreakpoint) {
        myTreeController.selectBreakpointItem(breakpoint, null);
        found = true;
        break;
      }
    }

    if (!found && !breakpoints.isEmpty()) {
      myTreeController.selectFirstBreakpointItem();
    }
  }

  @Nullable
  @Override
  protected String getDimensionServiceKey() {
    return getClass().getName();
  }

  @NotNull
  @Override
  protected Action[] createActions() {
    return new Action[] {getOKAction()};
  }

  private class ToggleBreakpointGroupingRuleEnabledAction extends ToggleActionButton {
    private XBreakpointGroupingRule myRule;

    public ToggleBreakpointGroupingRuleEnabledAction(XBreakpointGroupingRule rule) {
      super(rule.getPresentableName(), rule.getIcon());
      myRule = rule;
      getTemplatePresentation().setText(rule.getPresentableName());
    }

    @Override
    public boolean isSelected(AnActionEvent e) {
      return myRulesEnabled.contains(myRule);
    }

    @Override
    public void setSelected(AnActionEvent e, boolean state) {
      if (state) {
        myRulesEnabled.add(myRule);
      } else {
        myRulesEnabled.remove(myRule);
      }
      myTreeController.setGroupingRules(myRulesEnabled);
    }
  }

  private JComponent createMasterView() {
    myTreeController = new BreakpointItemsTreeController(myRulesEnabled);
    JTree tree = new BreakpointsCheckboxTree(myProject, myTreeController);

    new AnAction("BreakpointDialog.GoToSource") {
      @Override
      public void actionPerformed(AnActionEvent e) {
        navigate();
        close(OK_EXIT_CODE);
      }
    }.registerCustomShortcutSet(
        new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)), tree);

    new AnAction("BreakpointDialog.ShowSource") {
      @Override
      public void actionPerformed(AnActionEvent e) {
        navigate();
      }
    }.registerCustomShortcutSet(
        ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(),
        tree);

    tree.addMouseListener(
        new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent event) {
            if (event.getClickCount() == 2
                && UIUtil.isActionClick(event, MouseEvent.MOUSE_CLICKED)
                && !UIUtil.isSelectionButtonDown(event)
                && !event.isConsumed()) {
              navigate();
              close(OK_EXIT_CODE);
            }
          }
        });

    final DefaultActionGroup breakpointTypes = new DefaultActionGroup();
    for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
      breakpointTypes.addAll(provider.getAddBreakpointActions(myProject));
    }

    ToolbarDecorator decorator =
        ToolbarDecorator.createDecorator(tree)
            .setAddAction(
                new AnActionButtonRunnable() {
                  @Override
                  public void run(AnActionButton button) {
                    JBPopupFactory.getInstance()
                        .createActionGroupPopup(
                            null,
                            breakpointTypes,
                            DataManager.getInstance().getDataContext(button.getContextComponent()),
                            JBPopupFactory.ActionSelectionAid.NUMBERING,
                            false)
                        .show(button.getPreferredPopupPoint());
                  }
                })
            .setRemoveAction(
                new AnActionButtonRunnable() {
                  @Override
                  public void run(AnActionButton button) {
                    myTreeController.removeSelectedBreakpoints(myProject);
                  }
                })
            .setRemoveActionUpdater(
                new AnActionButtonUpdater() {
                  @Override
                  public boolean isEnabled(AnActionEvent e) {
                    boolean enabled = false;
                    final ItemWrapper[] items = myMasterController.getSelectedItems();
                    for (ItemWrapper item : items) {
                      if (item.allowedToRemove()) {
                        enabled = true;
                      }
                    }
                    return enabled;
                  }
                });

    for (ToggleActionButton action : myToggleRuleActions) {
      decorator.addExtraAction(action);
    }

    JPanel decoratedTree = decorator.createPanel();
    myTreeController.setTreeView(tree);

    myDetailController.setTree(tree);

    myTreeController.buildTree(myBreakpointItems);

    initSelection(myBreakpointItems);

    final BreakpointPanelProvider.BreakpointsListener listener =
        new BreakpointPanelProvider.BreakpointsListener() {
          @Override
          public void breakpointsChanged() {
            collectItems();
            myTreeController.rebuildTree(myBreakpointItems);
          }
        };

    for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
      provider.addListener(listener, myProject, myListenerDisposable);
    }

    return decoratedTree;
  }

  private void navigate() {
    List<BreakpointItem> breakpoints = myTreeController.getSelectedBreakpoints();
    if (!breakpoints.isEmpty()) {
      breakpoints.get(0).navigate(true);
    }
  }

  @Nullable
  @Override
  public JComponent getPreferredFocusedComponent() {
    return myTreeController.getTreeView();
  }

  private void collectGroupingRules() {
    for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
      provider.createBreakpointsGroupingRules(myRulesAvailable);
    }

    myRulesEnabled.clear();
    XBreakpointsDialogState settings = (getBreakpointManager()).getBreakpointsDialogSettings();

    for (XBreakpointGroupingRule rule : myRulesAvailable) {
      if (rule.isAlwaysEnabled()
          || (settings != null && settings.getSelectedGroupingRules().contains(rule.getId()))) {
        myRulesEnabled.add(rule);
      }
    }

    for (XBreakpointGroupingRule rule : myRulesAvailable) {
      if (!rule.isAlwaysEnabled()) {
        myToggleRuleActions.add(new ToggleBreakpointGroupingRuleEnabledAction(rule));
      }
    }
  }

  private void saveBreakpointsDialogState() {
    final XBreakpointsDialogState dialogState = new XBreakpointsDialogState();
    final List<XBreakpointGroupingRule> rulesEnabled =
        ContainerUtil.filter(
            myRulesEnabled,
            new Condition<XBreakpointGroupingRule>() {
              @Override
              public boolean value(XBreakpointGroupingRule rule) {
                return !rule.isAlwaysEnabled();
              }
            });

    dialogState.setSelectedGroupingRules(
        new HashSet<String>(
            ContainerUtil.map(
                rulesEnabled,
                new Function<XBreakpointGroupingRule, String>() {
                  @Override
                  public String fun(XBreakpointGroupingRule rule) {
                    return rule.getId();
                  }
                })));
    getBreakpointManager().setBreakpointsDialogSettings(dialogState);
  }

  @Override
  protected void dispose() {
    Disposer.dispose(myListenerDisposable);
    saveBreakpointsDialogState();
    super.dispose();
  }
}
  @Override
  public boolean executeTask(
      DataContext context,
      RunConfiguration configuration,
      ExecutionEnvironment env,
      ExternalSystemBeforeRunTask beforeRunTask) {

    final ExternalSystemTaskExecutionSettings executionSettings =
        beforeRunTask.getTaskExecutionSettings();

    final List<ExternalTaskPojo> tasks = ContainerUtilRt.newArrayList();
    for (String taskName : executionSettings.getTaskNames()) {
      tasks.add(new ExternalTaskPojo(taskName, executionSettings.getExternalProjectPath(), null));
    }
    if (tasks.isEmpty()) return true;

    final Pair<ProgramRunner, ExecutionEnvironment> pair =
        ExternalSystemUtil.createRunner(
            executionSettings, DefaultRunExecutor.EXECUTOR_ID, myProject, mySystemId);

    if (pair == null) return false;

    final ProgramRunner runner = pair.first;
    final ExecutionEnvironment environment = pair.second;
    environment.setExecutionId(env.getExecutionId());

    final Semaphore targetDone = new Semaphore();
    final Ref<Boolean> result = new Ref<Boolean>(false);
    final Disposable disposable = Disposer.newDisposable();

    final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
    final String executorId = executor.getId();

    myProject
        .getMessageBus()
        .connect(disposable)
        .subscribe(
            ExecutionManager.EXECUTION_TOPIC,
            new ExecutionAdapter() {
              public void processStartScheduled(
                  final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
                if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                  targetDone.down();
                }
              }

              public void processNotStarted(
                  final String executorIdLocal,
                  @NotNull final ExecutionEnvironment environmentLocal) {
                if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                  targetDone.up();
                }
              }

              public void processStarted(
                  final String executorIdLocal,
                  @NotNull final ExecutionEnvironment environmentLocal,
                  @NotNull final ProcessHandler handler) {
                if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                  handler.addProcessListener(
                      new ProcessAdapter() {
                        public void processTerminated(ProcessEvent event) {
                          result.set(event.getExitCode() == 0);
                          targetDone.up();
                          environmentLocal.getContentToReuse();
                        }
                      });
                }
              }
            });

    try {
      ApplicationManager.getApplication()
          .invokeAndWait(
              new Runnable() {
                @Override
                public void run() {
                  try {
                    runner.execute(environment);
                  } catch (ExecutionException e) {
                    targetDone.up();
                    LOG.error(e);
                  }
                }
              },
              ModalityState.NON_MODAL);
    } catch (Exception e) {
      LOG.error(e);
      Disposer.dispose(disposable);
      return false;
    }

    targetDone.waitFor();
    Disposer.dispose(disposable);

    return result.get();
  }
コード例 #17
0
// Made public and non-final for Fabrique
public class IdeRootPane extends JRootPane implements UISettingsListener {
  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.IdeRootPane");

  /** Toolbar and status bar. */
  private JComponent myToolbar;

  private IdeStatusBarImpl myStatusBar;

  private final Box myNorthPanel = Box.createVerticalBox();
  private final List<IdeRootPaneNorthExtension> myNorthComponents =
      new ArrayList<IdeRootPaneNorthExtension>();

  /** Current <code>ToolWindowsPane</code>. If there is no such pane then this field is null. */
  private ToolWindowsPane myToolWindowsPane;

  private final MyUISettingsListenerImpl myUISettingsListener;
  private JPanel myContentPane;
  private final ActionManager myActionManager;
  private final UISettings myUISettings;

  private static WelcomeScreen myWelcomeScreen;
  private static Component myWelcomePane;
  private final boolean myGlassPaneInitialized;
  private final IdeGlassPaneImpl myGlassPane;

  private final Application myApplication;
  private MemoryUsagePanel myMemoryWidget;
  private final StatusBarCustomComponentFactory[] myStatusBarCustomComponentFactories;
  private final Disposable myDisposable = Disposer.newDisposable();

  IdeRootPane(
      ActionManagerEx actionManager,
      UISettings uiSettings,
      DataManager dataManager,
      final Application application,
      final String[] commandLineArgs,
      IdeFrame frame) {
    myActionManager = actionManager;
    myUISettings = uiSettings;

    updateToolbar();
    myContentPane.add(myNorthPanel, BorderLayout.NORTH);

    myStatusBarCustomComponentFactories =
        application.getExtensions(StatusBarCustomComponentFactory.EP_NAME);
    myApplication = application;

    createStatusBar(frame);

    updateStatusBarVisibility();

    myContentPane.add(myStatusBar, BorderLayout.SOUTH);

    myUISettingsListener = new MyUISettingsListenerImpl();
    setJMenuBar(new IdeMenuBar(actionManager, dataManager));

    final Ref<Boolean> willOpenProject = new Ref<Boolean>(Boolean.FALSE);
    final AppLifecycleListener lifecyclePublisher =
        application.getMessageBus().syncPublisher(AppLifecycleListener.TOPIC);
    lifecyclePublisher.appFrameCreated(commandLineArgs, willOpenProject);
    LOG.info(
        "App initialization took "
            + (System.nanoTime() - PluginManager.startupStart) / 1000000
            + " ms");
    PluginManager.dumpPluginClassStatistics();
    if (!willOpenProject.get()) {
      showWelcomeScreen();
      lifecyclePublisher.welcomeScreenDisplayed();
    }

    myGlassPane = new IdeGlassPaneImpl(this);
    setGlassPane(myGlassPane);
    myGlassPaneInitialized = true;

    myGlassPane.setVisible(false);
    Disposer.register(application, myDisposable);
  }

  private void showWelcomeScreen() {
    myWelcomeScreen = new WelcomeScreen(this);
    Disposer.register(myDisposable, myWelcomeScreen);
    myWelcomePane = myWelcomeScreen.getWelcomePanel();
    myContentPane.add(myWelcomePane);
    updateToolbarVisibility();
  }

  public void setGlassPane(final Component glass) {
    if (myGlassPaneInitialized)
      throw new IllegalStateException("Setting of glass pane for IdeFrame is prohibited");
    super.setGlassPane(glass);
  }

  /** Invoked when enclosed frame is being shown. */
  public final void addNotify() {
    super.addNotify();
    myUISettings.addUISettingsListener(myUISettingsListener, myDisposable);
  }

  /** Invoked when enclosed frame is being disposed. */
  public final void removeNotify() {
    Disposer.dispose(myDisposable);
    super.removeNotify();
  }

  /**
   * Sets current tool windows pane (panel where all tool windows are located). If <code>
   * toolWindowsPane</code> is <code>null</code> then the method just removes the current tool
   * windows pane.
   */
  final void setToolWindowsPane(@Nullable final ToolWindowsPane toolWindowsPane) {
    final JComponent contentPane = (JComponent) getContentPane();
    if (myToolWindowsPane != null) {
      contentPane.remove(myToolWindowsPane);
    }

    hideWelcomeScreen(contentPane);

    myToolWindowsPane = toolWindowsPane;
    if (myToolWindowsPane != null) {
      contentPane.add(myToolWindowsPane, BorderLayout.CENTER);
    } else if (!myApplication.isDisposeInProgress()) {
      showWelcomeScreen();
    }

    contentPane.revalidate();
  }

  private void hideWelcomeScreen(JComponent contentPane) {
    if (myWelcomePane != null) {
      Disposer.dispose(myWelcomeScreen);
      contentPane.remove(myWelcomePane);
      myWelcomeScreen = null;
      myWelcomePane = null;
      updateToolbarVisibility();
    }
  }

  protected final Container createContentPane() {
    myContentPane = new JPanel(new BorderLayout());
    myContentPane.setBackground(Color.GRAY);

    return myContentPane;
  }

  void updateToolbar() {
    if (myToolbar != null) {
      myNorthPanel.remove(myToolbar);
    }
    myToolbar = createToolbar();
    myNorthPanel.add(myToolbar);
    updateToolbarVisibility();
    myContentPane.revalidate();
  }

  void updateMainMenuActions() {
    ((IdeMenuBar) menuBar).updateMenuActions();
    menuBar.repaint();
  }

  private JComponent createToolbar() {
    ActionGroup group =
        (ActionGroup)
            CustomActionsSchema.getInstance().getCorrectedAction(IdeActions.GROUP_MAIN_TOOLBAR);
    final ActionToolbar toolBar =
        myActionManager.createActionToolbar(ActionPlaces.MAIN_TOOLBAR, group, true);
    toolBar.setLayoutPolicy(ActionToolbar.WRAP_LAYOUT_POLICY);

    DefaultActionGroup menuGroup = new DefaultActionGroup();
    menuGroup.add(new ViewToolbarAction());
    menuGroup.add(new CustomizeUIAction());
    PopupHandler.installUnknownPopupHandler(toolBar.getComponent(), menuGroup, myActionManager);

    return toolBar.getComponent();
  }

  private void createStatusBar(IdeFrame frame) {
    myUISettings.addUISettingsListener(this, myApplication);

    myStatusBar = new IdeStatusBarImpl();
    myStatusBar.install(frame);

    myMemoryWidget = new MemoryUsagePanel();

    if (myStatusBarCustomComponentFactories != null) {
      for (final StatusBarCustomComponentFactory<JComponent> componentFactory :
          myStatusBarCustomComponentFactories) {
        final JComponent c = componentFactory.createComponent(myStatusBar);
        myStatusBar.addWidget(
            new CustomStatusBarWidget() {
              public JComponent getComponent() {
                return c;
              }

              @NotNull
              public String ID() {
                return c.getClass().getSimpleName();
              }

              public WidgetPresentation getPresentation(@NotNull PlatformType type) {
                return null;
              }

              public void install(@NotNull StatusBar statusBar) {}

              public void dispose() {
                componentFactory.disposeComponent(myStatusBar, c);
              }
            },
            "before " + MemoryUsagePanel.WIDGET_ID);
      }
    }

    myStatusBar.addWidget(myMemoryWidget);
    myStatusBar.addWidget(
        new IdeMessagePanel(MessagePool.getInstance()), "before " + MemoryUsagePanel.WIDGET_ID);

    setMemoryIndicatorVisible(myUISettings.SHOW_MEMORY_INDICATOR);
  }

  void setMemoryIndicatorVisible(final boolean visible) {
    if (myMemoryWidget != null) {
      myMemoryWidget.setShowing(visible);
      if (!SystemInfo.isMac) {
        myStatusBar.setBorder(BorderFactory.createEmptyBorder(1, 4, 0, visible ? 0 : 2));
      }
    }
  }

  @Nullable
  final StatusBar getStatusBar() {
    return myStatusBar;
  }

  private void updateToolbarVisibility() {
    myToolbar.setVisible(myUISettings.SHOW_MAIN_TOOLBAR && myWelcomeScreen == null);
  }

  private void updateStatusBarVisibility() {
    myStatusBar.setVisible(myUISettings.SHOW_STATUS_BAR);
  }

  public void installNorthComponents(final Project project) {
    ContainerUtil.addAll(
        myNorthComponents, Extensions.getExtensions(IdeRootPaneNorthExtension.EP_NAME, project));
    for (IdeRootPaneNorthExtension northComponent : myNorthComponents) {
      myNorthPanel.add(northComponent.getComponent());
      northComponent.uiSettingsChanged(myUISettings);
    }
  }

  public void deinstallNorthComponents() {
    for (IdeRootPaneNorthExtension northComponent : myNorthComponents) {
      myNorthPanel.remove(northComponent.getComponent());
      Disposer.dispose(northComponent);
    }
    myNorthComponents.clear();
  }

  public IdeRootPaneNorthExtension findByName(String name) {
    for (IdeRootPaneNorthExtension northComponent : myNorthComponents) {
      if (Comparing.strEqual(name, northComponent.getKey())) {
        return northComponent;
      }
    }
    return null;
  }

  public void uiSettingsChanged(UISettings source) {
    setMemoryIndicatorVisible(source.SHOW_MEMORY_INDICATOR);
  }

  private final class MyUISettingsListenerImpl implements UISettingsListener {
    public final void uiSettingsChanged(final UISettings source) {
      updateToolbarVisibility();
      updateStatusBarVisibility();
      for (IdeRootPaneNorthExtension component : myNorthComponents) {
        component.uiSettingsChanged(source);
      }
    }
  }

  public boolean isOptimizedDrawingEnabled() {
    return !myGlassPane.hasPainters() && myGlassPane.getComponentCount() == 0;
  }
}
コード例 #18
0
  public ApplicationImpl(
      boolean isInternal,
      boolean isUnitTestMode,
      boolean isHeadless,
      boolean isCommandLine,
      @NotNull String appName) {
    super(null);

    getPicoContainer().registerComponentInstance(Application.class, this);

    CommonBundle.assertKeyIsFound = isUnitTestMode;

    if ((isInternal || isUnitTestMode)
        && !Comparing.equal("off", System.getProperty("idea.disposer.debug"))) {
      Disposer.setDebugMode(true);
    }
    myStartTime = System.currentTimeMillis();
    myName = appName;
    ApplicationManagerEx.setApplication(this);

    PluginsFacade.INSTANCE =
        new PluginsFacade() {
          public IdeaPluginDescriptor getPlugin(PluginId id) {
            return PluginManager.getPlugin(id);
          }

          public IdeaPluginDescriptor[] getPlugins() {
            return PluginManager.getPlugins();
          }
        };

    if (!isUnitTestMode && !isHeadless) {
      Toolkit.getDefaultToolkit().getSystemEventQueue().push(IdeEventQueue.getInstance());
      if (Patches.SUN_BUG_ID_6209673) {
        RepaintManager.setCurrentManager(new IdeRepaintManager());
      }
      IconLoader.activate();
    }

    myIsInternal = isInternal;
    myTestModeFlag = isUnitTestMode;
    myHeadlessMode = isHeadless;
    myCommandLineMode = isCommandLine;

    loadApplicationComponents();

    if (myTestModeFlag) {
      registerShutdownHook();
    }

    if (!isUnitTestMode && !isHeadless) {
      Disposer.register(this, Disposer.newDisposable(), "ui");

      StartupUtil.addExternalInstanceListener(
          new Consumer<List<String>>() {
            @Override
            public void consume(final List<String> args) {
              invokeLater(
                  new Runnable() {
                    @Override
                    public void run() {
                      final Project project = CommandLineProcessor.processExternalCommandLine(args);
                      final IdeFrame frame;
                      if (project != null) {
                        frame = WindowManager.getInstance().getIdeFrame(project);
                      } else {
                        frame = WindowManager.getInstance().getAllFrames()[0];
                      }
                      ((IdeFrameImpl) frame).requestFocus();
                    }
                  });
            }
          });
    }

    final String s = System.getProperty("jb.restart.code");
    if (s != null) {
      try {
        myRestartCode = Integer.parseInt(s);
      } catch (NumberFormatException ignore) {
      }
    }
  }
コード例 #19
0
/** @author dsl */
public class LibraryImpl extends TraceableDisposable
    implements LibraryEx.ModifiableModelEx, LibraryEx {
  private static final Logger LOG =
      Logger.getInstance("#com.intellij.openapi.roots.impl.impl.LibraryImpl");
  @NonNls public static final String LIBRARY_NAME_ATTR = "name";
  @NonNls public static final String LIBRARY_TYPE_ATTR = "type";
  @NonNls public static final String ROOT_PATH_ELEMENT = "root";
  @NonNls public static final String ELEMENT = "library";
  @NonNls public static final String PROPERTIES_ELEMENT = "properties";
  private static final SkipDefaultValuesSerializationFilters SERIALIZATION_FILTERS =
      new SkipDefaultValuesSerializationFilters();
  private String myName;
  private final LibraryTable myLibraryTable;
  private final Map<OrderRootType, VirtualFilePointerContainer> myRoots;
  private final JarDirectories myJarDirectories = new JarDirectories();
  private final LibraryImpl mySource;
  private PersistentLibraryKind<?> myKind;
  private LibraryProperties myProperties;

  private final MyRootProviderImpl myRootProvider = new MyRootProviderImpl();
  private final ModifiableRootModel myRootModel;
  private boolean myDisposed;
  private final Disposable myPointersDisposable = Disposer.newDisposable();
  private final JarDirectoryWatcher myRootsWatcher =
      JarDirectoryWatcherFactory.getInstance().createWatcher(myJarDirectories, myRootProvider);

  LibraryImpl(LibraryTable table, Element element, ModifiableRootModel rootModel)
      throws InvalidDataException {
    this(
        table,
        rootModel,
        null,
        element.getAttributeValue(LIBRARY_NAME_ATTR),
        (PersistentLibraryKind<?>)
            LibraryKind.findById(element.getAttributeValue(LIBRARY_TYPE_ATTR)));
    readProperties(element);
    myJarDirectories.readExternal(element);
    readRoots(element);
    myRootsWatcher.updateWatchedRoots();
  }

  LibraryImpl(
      String name,
      @Nullable final PersistentLibraryKind<?> kind,
      LibraryTable table,
      ModifiableRootModel rootModel) {
    this(table, rootModel, null, name, kind);
    if (kind != null) {
      myProperties = kind.createDefaultProperties();
    }
  }

  private LibraryImpl(
      @NotNull LibraryImpl from, LibraryImpl newSource, ModifiableRootModel rootModel) {
    this(from.myLibraryTable, rootModel, newSource, from.myName, from.myKind);
    assert !from.isDisposed();
    if (from.myKind != null && from.myProperties != null) {
      myProperties = myKind.createDefaultProperties();
      //noinspection unchecked
      myProperties.loadState(from.myProperties.getState());
    }
    for (OrderRootType rootType : getAllRootTypes()) {
      final VirtualFilePointerContainer thisContainer = myRoots.get(rootType);
      final VirtualFilePointerContainer thatContainer = from.myRoots.get(rootType);
      thisContainer.addAll(thatContainer);
    }
    myJarDirectories.copyFrom(from.myJarDirectories);
  }

  // primary
  private LibraryImpl(
      LibraryTable table,
      ModifiableRootModel rootModel,
      LibraryImpl newSource,
      String name,
      @Nullable final PersistentLibraryKind<?> kind) {
    super(new Throwable());
    myLibraryTable = table;
    myRootModel = rootModel;
    mySource = newSource;
    myKind = kind;
    myName = name;
    // init roots depends on my myKind
    myRoots = initRoots();
    Disposer.register(this, myRootsWatcher);
  }

  private Set<OrderRootType> getAllRootTypes() {
    Set<OrderRootType> rootTypes = new HashSet<OrderRootType>();
    rootTypes.addAll(Arrays.asList(OrderRootType.getAllTypes()));
    if (myKind != null) {
      rootTypes.addAll(Arrays.asList(myKind.getAdditionalRootTypes()));
    }
    return rootTypes;
  }

  @Override
  public void dispose() {
    if (isDisposed()) {
      throwDisposalError("Already disposed:");
    }
    myDisposed = true;
    kill(null);
  }

  @Override
  public boolean isDisposed() {
    return myDisposed;
  }

  @Override
  public String getName() {
    return myName;
  }

  @Override
  @NotNull
  public String[] getUrls(@NotNull OrderRootType rootType) {
    assert !isDisposed();
    final VirtualFilePointerContainer result = myRoots.get(rootType);
    return result.getUrls();
  }

  @Override
  @NotNull
  public VirtualFile[] getFiles(@NotNull OrderRootType rootType) {
    assert !isDisposed();
    final List<VirtualFile> expanded = new ArrayList<VirtualFile>();
    for (VirtualFile file : myRoots.get(rootType).getFiles()) {
      if (file.isDirectory()) {
        if (myJarDirectories.contains(rootType, file.getUrl())) {
          collectJarFiles(file, expanded, myJarDirectories.isRecursive(rootType, file.getUrl()));
          continue;
        }
      }
      expanded.add(file);
    }
    return VfsUtilCore.toVirtualFileArray(expanded);
  }

  public static void collectJarFiles(
      final VirtualFile dir, final List<VirtualFile> container, final boolean recursively) {
    VfsUtilCore.visitChildrenRecursively(
        dir,
        new VirtualFileVisitor(SKIP_ROOT, (recursively ? null : ONE_LEVEL_DEEP)) {
          @Override
          public boolean visitFile(@NotNull VirtualFile file) {
            final VirtualFile jarRoot = StandardFileSystems.getJarRootForLocalFile(file);
            if (jarRoot != null) {
              container.add(jarRoot);
              return false;
            }
            return true;
          }
        });
  }

  @Override
  public void setName(String name) {
    LOG.assertTrue(isWritable());
    myName = name;
  }

  /* you have to commit modifiable model or dispose it by yourself! */
  @Override
  @NotNull
  public ModifiableModel getModifiableModel() {
    assert !isDisposed();
    return new LibraryImpl(this, this, myRootModel);
  }

  @Override
  public Library cloneLibrary(RootModelImpl rootModel) {
    LOG.assertTrue(myLibraryTable == null);
    final LibraryImpl clone = new LibraryImpl(this, null, rootModel);
    clone.myRootsWatcher.updateWatchedRoots();
    return clone;
  }

  @Override
  public List<String> getInvalidRootUrls(OrderRootType type) {
    if (myDisposed) return Collections.emptyList();

    final List<VirtualFilePointer> pointers = myRoots.get(type).getList();
    List<String> invalidPaths = null;
    for (VirtualFilePointer pointer : pointers) {
      if (!pointer.isValid()) {
        if (invalidPaths == null) {
          invalidPaths = new SmartList<String>();
        }
        invalidPaths.add(pointer.getUrl());
      }
    }
    return invalidPaths == null ? Collections.<String>emptyList() : invalidPaths;
  }

  @Override
  public void setProperties(LibraryProperties properties) {
    LOG.assertTrue(isWritable());
    myProperties = properties;
  }

  @Override
  @NotNull
  public RootProvider getRootProvider() {
    return myRootProvider;
  }

  private Map<OrderRootType, VirtualFilePointerContainer> initRoots() {
    Disposer.register(this, myPointersDisposable);

    Map<OrderRootType, VirtualFilePointerContainer> result =
        new HashMap<OrderRootType, VirtualFilePointerContainer>(4);

    for (OrderRootType rootType : getAllRootTypes()) {
      result.put(
          rootType, VirtualFilePointerManager.getInstance().createContainer(myPointersDisposable));
    }

    return result;
  }

  @Override
  public void readExternal(Element element) throws InvalidDataException {
    readName(element);
    readProperties(element);
    readRoots(element);
    myJarDirectories.readExternal(element);
    myRootsWatcher.updateWatchedRoots();
  }

  private void readProperties(Element element) {
    final String typeId = element.getAttributeValue(LIBRARY_TYPE_ATTR);
    if (typeId == null) return;

    myKind = (PersistentLibraryKind<?>) LibraryKind.findById(typeId);
    if (myKind == null) return;

    myProperties = myKind.createDefaultProperties();
    final Element propertiesElement = element.getChild(PROPERTIES_ELEMENT);
    if (propertiesElement != null) {
      ComponentSerializationUtil.loadComponentState(myProperties, propertiesElement);
    }
  }

  private void readName(Element element) {
    myName = element.getAttributeValue(LIBRARY_NAME_ATTR);
  }

  private void readRoots(Element element) throws InvalidDataException {
    for (OrderRootType rootType : getAllRootTypes()) {
      final Element rootChild = element.getChild(rootType.name());
      if (rootChild == null) {
        continue;
      }
      VirtualFilePointerContainer roots = myRoots.get(rootType);
      roots.readExternal(rootChild, ROOT_PATH_ELEMENT);
    }
  }

  // TODO<rv> Remove the next two methods as a temporary solution. Sort in OrderRootType.
  //
  public static List<OrderRootType> sortRootTypes(Collection<OrderRootType> rootTypes) {
    List<OrderRootType> allTypes = new ArrayList<OrderRootType>(rootTypes);
    Collections.sort(
        allTypes,
        new Comparator<OrderRootType>() {
          @Override
          public int compare(final OrderRootType o1, final OrderRootType o2) {
            return getSortKey(o1).compareTo(getSortKey(o2));
          }
        });
    return allTypes;
  }

  private static String getSortKey(OrderRootType orderRootType) {
    if (orderRootType instanceof PersistentOrderRootType) {
      return ((PersistentOrderRootType) orderRootType).getSdkRootName();
    }
    if (orderRootType instanceof OrderRootType.DocumentationRootType) {
      return ((OrderRootType.DocumentationRootType) orderRootType).getSdkRootName();
    }
    return "";
  }

  @Override
  public void writeExternal(Element rootElement) throws WriteExternalException {
    LOG.assertTrue(!isDisposed(), "Already disposed!");

    Element element = new Element(ELEMENT);
    if (myName != null) {
      element.setAttribute(LIBRARY_NAME_ATTR, myName);
    }
    if (myKind != null) {
      element.setAttribute(LIBRARY_TYPE_ATTR, myKind.getKindId());
      final Object state = myProperties.getState();
      if (state != null) {
        final Element propertiesElement = XmlSerializer.serialize(state, SERIALIZATION_FILTERS);
        if (propertiesElement != null
            && (!propertiesElement.getContent().isEmpty()
                || !propertiesElement.getAttributes().isEmpty())) {
          element.addContent(propertiesElement.setName(PROPERTIES_ELEMENT));
        }
      }
    }
    ArrayList<OrderRootType> storableRootTypes = new ArrayList<OrderRootType>();
    storableRootTypes.addAll(Arrays.asList(OrderRootType.getAllTypes()));
    if (myKind != null) {
      storableRootTypes.addAll(Arrays.asList(myKind.getAdditionalRootTypes()));
    }
    for (OrderRootType rootType : sortRootTypes(storableRootTypes)) {
      final VirtualFilePointerContainer roots = myRoots.get(rootType);
      if (roots.size() == 0 && rootType.skipWriteIfEmpty()) continue; // compatibility iml/ipr
      final Element rootTypeElement = new Element(rootType.name());
      roots.writeExternal(rootTypeElement, ROOT_PATH_ELEMENT);
      element.addContent(rootTypeElement);
    }
    myJarDirectories.writeExternal(element);
    rootElement.addContent(element);
  }

  private boolean isWritable() {
    return mySource != null;
  }

  @Nullable
  @Override
  public PersistentLibraryKind<?> getKind() {
    return myKind;
  }

  @Override
  public LibraryProperties getProperties() {
    return myProperties;
  }

  @Override
  public void setKind(PersistentLibraryKind<?> kind) {
    LOG.assertTrue(isWritable());
    LOG.assertTrue(
        myKind == null || myKind == kind,
        "Library kind cannot be changed from " + myKind + " to " + kind);
    myKind = kind;
  }

  @Override
  public void addRoot(@NotNull String url, @NotNull OrderRootType rootType) {
    LOG.assertTrue(isWritable());
    assert !isDisposed();

    final VirtualFilePointerContainer container = myRoots.get(rootType);
    container.add(url);
  }

  @Override
  public void addRoot(@NotNull VirtualFile file, @NotNull OrderRootType rootType) {
    LOG.assertTrue(isWritable());
    assert !isDisposed();

    final VirtualFilePointerContainer container = myRoots.get(rootType);
    container.add(file);
  }

  @Override
  public void addJarDirectory(@NotNull final String url, final boolean recursive) {
    addJarDirectory(url, recursive, JarDirectories.DEFAULT_JAR_DIRECTORY_TYPE);
  }

  @Override
  public void addJarDirectory(@NotNull final VirtualFile file, final boolean recursive) {
    addJarDirectory(file, recursive, JarDirectories.DEFAULT_JAR_DIRECTORY_TYPE);
  }

  @Override
  public void addJarDirectory(
      @NotNull final String url, final boolean recursive, @NotNull OrderRootType rootType) {
    assert !isDisposed();
    LOG.assertTrue(isWritable());
    final VirtualFilePointerContainer container = myRoots.get(rootType);
    container.add(url);
    myJarDirectories.add(rootType, url, recursive);
  }

  @Override
  public void addJarDirectory(
      @NotNull final VirtualFile file, final boolean recursive, @NotNull OrderRootType rootType) {
    assert !isDisposed();
    LOG.assertTrue(isWritable());
    final VirtualFilePointerContainer container = myRoots.get(rootType);
    container.add(file);
    myJarDirectories.add(rootType, file.getUrl(), recursive);
  }

  @Override
  public boolean isJarDirectory(@NotNull final String url) {
    return isJarDirectory(url, JarDirectories.DEFAULT_JAR_DIRECTORY_TYPE);
  }

  @Override
  public boolean isJarDirectory(@NotNull final String url, @NotNull final OrderRootType rootType) {
    return myJarDirectories.contains(rootType, url);
  }

  @Override
  public boolean isValid(@NotNull final String url, @NotNull final OrderRootType rootType) {
    final VirtualFilePointerContainer container = myRoots.get(rootType);
    final VirtualFilePointer fp = container.findByUrl(url);
    return fp != null && fp.isValid();
  }

  @Override
  public boolean removeRoot(@NotNull String url, @NotNull OrderRootType rootType) {
    assert !isDisposed();
    LOG.assertTrue(isWritable());
    final VirtualFilePointerContainer container = myRoots.get(rootType);
    final VirtualFilePointer byUrl = container.findByUrl(url);
    if (byUrl != null) {
      container.remove(byUrl);
      myJarDirectories.remove(rootType, url);
      return true;
    }
    return false;
  }

  @Override
  public void moveRootUp(@NotNull String url, @NotNull OrderRootType rootType) {
    assert !isDisposed();
    LOG.assertTrue(isWritable());
    final VirtualFilePointerContainer container = myRoots.get(rootType);
    container.moveUp(url);
  }

  @Override
  public void moveRootDown(@NotNull String url, @NotNull OrderRootType rootType) {
    assert !isDisposed();
    LOG.assertTrue(isWritable());
    final VirtualFilePointerContainer container = myRoots.get(rootType);
    container.moveDown(url);
  }

  @Override
  public boolean isChanged() {
    return !mySource.equals(this);
  }

  private boolean areRootsChanged(final LibraryImpl that) {
    return !that.equals(this);
    // final OrderRootType[] allTypes = OrderRootType.getAllTypes();
    // for (OrderRootType type : allTypes) {
    //  final String[] urls = getUrls(type);
    //  final String[] thatUrls = that.getUrls(type);
    //  if (urls.length != thatUrls.length) {
    //    return true;
    //  }
    //  for (int idx = 0; idx < urls.length; idx++) {
    //    final String url = urls[idx];
    //    final String thatUrl = thatUrls[idx];
    //    if (!Comparing.equal(url, thatUrl)) {
    //      return true;
    //    }
    //    final Boolean jarDirRecursive = myJarDirectories.get(url);
    //    final Boolean sourceJarDirRecursive = that.myJarDirectories.get(thatUrl);
    //    if (jarDirRecursive == null ? sourceJarDirRecursive != null :
    // !jarDirRecursive.equals(sourceJarDirRecursive)) {
    //      return true;
    //    }
    //  }
    // }
    // return false;
  }

  public Library getSource() {
    return mySource;
  }

  @Override
  public void commit() {
    assert !isDisposed();
    mySource.commit(this);
    Disposer.dispose(this);
  }

  private void commit(@NotNull LibraryImpl fromModel) {
    if (myLibraryTable != null) {
      ApplicationManager.getApplication().assertWriteAccessAllowed();
    }
    if (!Comparing.equal(fromModel.myName, myName)) {
      myName = fromModel.myName;
      if (myLibraryTable instanceof LibraryTableBase) {
        ((LibraryTableBase) myLibraryTable).fireLibraryRenamed(this);
      }
    }
    myKind = fromModel.getKind();
    myProperties = fromModel.myProperties;
    if (areRootsChanged(fromModel)) {
      disposeMyPointers();
      copyRootsFrom(fromModel);
      myJarDirectories.copyFrom(fromModel.myJarDirectories);
      myRootsWatcher.updateWatchedRoots();
      myRootProvider.fireRootSetChanged();
    }
  }

  private void copyRootsFrom(LibraryImpl fromModel) {
    myRoots.clear();
    for (Map.Entry<OrderRootType, VirtualFilePointerContainer> entry :
        fromModel.myRoots.entrySet()) {
      OrderRootType rootType = entry.getKey();
      VirtualFilePointerContainer container = entry.getValue();
      VirtualFilePointerContainer clone = container.clone(myPointersDisposable);
      myRoots.put(rootType, clone);
    }
  }

  private void disposeMyPointers() {
    for (VirtualFilePointerContainer container :
        new THashSet<VirtualFilePointerContainer>(myRoots.values())) {
      container.killAll();
    }
    Disposer.dispose(myPointersDisposable);
    Disposer.register(this, myPointersDisposable);
  }

  private class MyRootProviderImpl extends RootProviderBaseImpl {
    @Override
    @NotNull
    public String[] getUrls(@NotNull OrderRootType rootType) {
      Set<String> originalUrls =
          new LinkedHashSet<String>(Arrays.asList(LibraryImpl.this.getUrls(rootType)));
      for (VirtualFile file : getFiles(rootType)) { // Add those expanded with jar directories.
        originalUrls.add(file.getUrl());
      }
      return ArrayUtil.toStringArray(originalUrls);
    }

    @Override
    @NotNull
    public VirtualFile[] getFiles(@NotNull final OrderRootType rootType) {
      return LibraryImpl.this.getFiles(rootType);
    }
  }

  @Override
  public LibraryTable getTable() {
    return myLibraryTable;
  }

  public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    final LibraryImpl library = (LibraryImpl) o;

    if (!myJarDirectories.equals(library.myJarDirectories)) return false;
    if (myName != null ? !myName.equals(library.myName) : library.myName != null) return false;
    if (myRoots != null ? !myRoots.equals(library.myRoots) : library.myRoots != null) return false;
    if (myKind != null ? !myKind.equals(library.myKind) : library.myKind != null) return false;
    if (myProperties != null
        ? !myProperties.equals(library.myProperties)
        : library.myProperties != null) return false;

    return true;
  }

  public int hashCode() {
    int result = myName != null ? myName.hashCode() : 0;
    result = 31 * result + (myRoots != null ? myRoots.hashCode() : 0);
    result = 31 * result + (myJarDirectories != null ? myJarDirectories.hashCode() : 0);
    return result;
  }

  @NonNls
  @Override
  public String toString() {
    return "Library: name:" + myName + "; jars:" + myJarDirectories + "; roots:" + myRoots.values();
  }

  @Nullable("will return non-null value only for module level libraries")
  public Module getModule() {
    return myRootModel == null ? null : myRootModel.getModule();
  }
}
コード例 #20
0
public class JBOptionButton extends JButton implements MouseMotionListener, Weighted {
  private final Insets myDownIconInsets = JBUI.insets(0, 6, 0, 4);

  private Rectangle myMoreRec;
  private Rectangle myMoreRecMouse;
  private Action[] myOptions;

  private JPopupMenu myUnderPopup;
  private JPopupMenu myAbovePopup;
  private boolean myPopupIsShowing;

  private String myOptionTooltipText;

  private Set<OptionInfo> myOptionInfos = new HashSet<OptionInfo>();
  private boolean myOkToProcessDefaultMnemonics = true;

  private IdeGlassPane myGlassPane;
  private final Disposable myDisposable = Disposer.newDisposable();

  public JBOptionButton(Action action, Action[] options) {
    super(action);
    myOptions = options;
    myMoreRec =
        new Rectangle(
            0,
            0,
            AllIcons.General.ArrowDown.getIconWidth(),
            AllIcons.General.ArrowDown.getIconHeight());

    myUnderPopup = fillMenu(true);
    myAbovePopup = fillMenu(false);
    enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
  }

  @Override
  public void addNotify() {
    super.addNotify();
    if (!ScreenUtil.isStandardAddRemoveNotify(this)) return;
    myGlassPane = IdeGlassPaneUtil.find(this);
    if (myGlassPane != null) {
      myGlassPane.addMouseMotionPreprocessor(this, myDisposable);
    }
  }

  @Override
  public void removeNotify() {
    super.removeNotify();
    if (!ScreenUtil.isStandardAddRemoveNotify(this)) return;
    Disposer.dispose(myDisposable);
  }

  @Override
  public double getWeight() {
    return 0.5;
  }

  @Override
  public void mouseDragged(MouseEvent e) {}

  @Override
  public void mouseMoved(MouseEvent e) {
    final MouseEvent event = SwingUtilities.convertMouseEvent(e.getComponent(), e, getParent());
    final boolean insideRec = getBounds().contains(event.getPoint());
    boolean buttonsNotPressed =
        (e.getModifiersEx()
                & (InputEvent.BUTTON1_DOWN_MASK
                    | InputEvent.BUTTON2_DOWN_MASK
                    | InputEvent.BUTTON3_DOWN_MASK))
            == 0;
    if (!myPopupIsShowing && insideRec && buttonsNotPressed) {
      showPopup(null, false);
    } else if (myPopupIsShowing && !insideRec) {
      final Component over =
          SwingUtilities.getDeepestComponentAt(e.getComponent(), e.getX(), e.getY());
      JPopupMenu popup = myUnderPopup.isShowing() ? myUnderPopup : myAbovePopup;
      if (over != null && popup.isShowing()) {
        final Rectangle rec = new Rectangle(popup.getLocationOnScreen(), popup.getSize());
        int delta = 15;
        rec.x -= delta;
        rec.width += delta * 2;
        rec.y -= delta;
        rec.height += delta * 2;

        final Point eventPoint = e.getPoint();
        SwingUtilities.convertPointToScreen(eventPoint, e.getComponent());

        if (rec.contains(eventPoint)) {
          return;
        }
      }

      closePopup();
    }
  }

  @Override
  public Dimension getPreferredSize() {
    final Dimension size = super.getPreferredSize();
    size.width += (myMoreRec.width + myDownIconInsets.left + myDownIconInsets.right);
    size.height += (myDownIconInsets.top + myDownIconInsets.bottom);
    return size;
  }

  @Override
  public void doLayout() {
    super.doLayout();

    Insets insets = getInsets();
    myMoreRec.x = getSize().width - myMoreRec.width - insets.right + 8;
    myMoreRec.y = (getHeight() / 2 - myMoreRec.height / 2);

    myMoreRecMouse = new Rectangle(myMoreRec.x - 8, 0, getWidth() - myMoreRec.x, getHeight());
  }

  @Override
  public String getToolTipText(MouseEvent event) {
    if (myMoreRec.x < event.getX()) {
      return myOptionTooltipText;
    } else {
      return super.getToolTipText(event);
    }
  }

  @Override
  protected void processMouseEvent(MouseEvent e) {
    if (myMoreRecMouse.contains(e.getPoint())) {
      if (e.getID() == MouseEvent.MOUSE_PRESSED) {
        if (!myPopupIsShowing) {
          togglePopup();
        }
      }
    } else {
      super.processMouseEvent(e);
    }
  }

  public void togglePopup() {
    if (myPopupIsShowing) {
      closePopup();
    } else {
      showPopup(null, false);
    }
  }

  public void showPopup(final Action actionToSelect, final boolean ensureSelection) {
    if (myPopupIsShowing) return;

    myPopupIsShowing = true;
    final Point loc = getLocationOnScreen();
    final Rectangle screen = ScreenUtil.getScreenRectangle(loc);
    final Dimension popupSize = myUnderPopup.getPreferredSize();
    final Rectangle intersection =
        screen.intersection(new Rectangle(new Point(loc.x, loc.y + getHeight()), popupSize));
    final boolean above = intersection.height < popupSize.height;
    int y = above ? getY() - popupSize.height : getY() + getHeight();

    final JPopupMenu popup = above ? myAbovePopup : myUnderPopup;

    final Ref<PopupMenuListener> listener = new Ref<PopupMenuListener>();
    listener.set(
        new PopupMenuListener() {
          @Override
          public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}

          @Override
          public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            if (popup != null && listener.get() != null) {
              popup.removePopupMenuListener(listener.get());
            }
            SwingUtilities.invokeLater(
                new Runnable() {
                  @Override
                  public void run() {
                    myPopupIsShowing = false;
                  }
                });
          }

          @Override
          public void popupMenuCanceled(PopupMenuEvent e) {}
        });
    popup.addPopupMenuListener(listener.get());
    popup.show(this, 0, y);

    SwingUtilities.invokeLater(
        new Runnable() {
          @Override
          public void run() {
            if (popup == null || !popup.isShowing() || !myPopupIsShowing) return;

            Action selection = actionToSelect;
            if (selection == null && myOptions.length > 0 && ensureSelection) {
              selection = getAction();
            }

            if (selection == null) return;

            final MenuElement[] elements = popup.getSubElements();
            for (MenuElement eachElement : elements) {
              if (eachElement instanceof JMenuItem) {
                JMenuItem eachItem = (JMenuItem) eachElement;
                if (selection.equals(eachItem.getAction())) {
                  final MenuSelectionManager mgr = MenuSelectionManager.defaultManager();
                  final MenuElement[] path = new MenuElement[2];
                  path[0] = popup;
                  path[1] = eachItem;
                  mgr.setSelectedPath(path);
                  break;
                }
              }
            }
          }
        });
  }

  public void closePopup() {
    myUnderPopup.setVisible(false);
    myAbovePopup.setVisible(false);
  }

  private JPopupMenu fillMenu(boolean under) {
    final JPopupMenu result = new JBPopupMenu();

    if (under && myOptions.length > 0) {
      final JMenuItem mainAction = new JBMenuItem(getAction());
      configureItem(getMenuInfo(getAction()), mainAction);
      result.add(mainAction);
      result.addSeparator();
    }

    for (Action each : myOptions) {
      if (getAction() == each) continue;
      final OptionInfo info = getMenuInfo(each);
      final JMenuItem eachItem = new JBMenuItem(each);

      configureItem(info, eachItem);
      result.add(eachItem);
    }

    if (!under && myOptions.length > 0) {
      result.addSeparator();
      final JMenuItem mainAction = new JBMenuItem(getAction());
      configureItem(getMenuInfo(getAction()), mainAction);
      result.add(mainAction);
    }

    return result;
  }

  private void configureItem(OptionInfo info, JMenuItem eachItem) {
    eachItem.setText(info.myPlainText);
    if (info.myMnemonic >= 0) {
      eachItem.setMnemonic(info.myMnemonic);
      eachItem.setDisplayedMnemonicIndex(info.myMnemonicIndex);
    }
    myOptionInfos.add(info);
  }

  public boolean isOkToProcessDefaultMnemonics() {
    return myOkToProcessDefaultMnemonics;
  }

  public static class OptionInfo {

    String myPlainText;
    int myMnemonic;
    int myMnemonicIndex;
    JBOptionButton myButton;
    Action myAction;

    OptionInfo(
        String plainText, int mnemonic, int mnemonicIndex, JBOptionButton button, Action action) {
      myPlainText = plainText;
      myMnemonic = mnemonic;
      myMnemonicIndex = mnemonicIndex;
      myButton = button;
      myAction = action;
    }

    public String getPlainText() {
      return myPlainText;
    }

    public int getMnemonic() {
      return myMnemonic;
    }

    public int getMnemonicIndex() {
      return myMnemonicIndex;
    }

    public JBOptionButton getButton() {
      return myButton;
    }

    public Action getAction() {
      return myAction;
    }
  }

  private OptionInfo getMenuInfo(Action each) {
    final String text = (String) each.getValue(Action.NAME);
    int mnemonic = -1;
    int mnemonicIndex = -1;
    StringBuilder plainText = new StringBuilder();
    for (int i = 0; i < text.length(); i++) {
      char ch = text.charAt(i);
      if (ch == '&' || ch == '_') {
        if (i + 1 < text.length()) {
          final char mnemonicsChar = text.charAt(i + 1);
          mnemonic = Character.toUpperCase(mnemonicsChar);
          mnemonicIndex = i;
        }
        continue;
      }
      plainText.append(ch);
    }

    return new OptionInfo(plainText.toString(), mnemonic, mnemonicIndex, this, each);
  }

  public Set<OptionInfo> getOptionInfos() {
    return myOptionInfos;
  }

  @Override
  protected void paintChildren(Graphics g) {
    super.paintChildren(g);
    boolean dark = UIUtil.isUnderDarcula();
    int off = dark ? 6 : 0;
    AllIcons.General.ArrowDown.paintIcon(this, g, myMoreRec.x - off, myMoreRec.y);
    if (dark) return;

    final Insets insets = getInsets();
    int y1 = myMoreRec.y - 2;
    int y2 = getHeight() - insets.bottom - 2;

    if (y1 < getInsets().top) {
      y1 = insets.top;
    }

    final int x = myMoreRec.x - 4;
    UIUtil.drawDottedLine(((Graphics2D) g), x, y1, x, y2, null, Color.darkGray);
  }

  public void setOptionTooltipText(String text) {
    myOptionTooltipText = text;
  }

  public void setOkToProcessDefaultMnemonics(boolean ok) {
    myOkToProcessDefaultMnemonics = ok;
  }
}
コード例 #21
0
  @Override
  public boolean executeTask(
      final DataContext dataContext,
      RunConfiguration configuration,
      final ExecutionEnvironment env,
      RunConfigurableBeforeRunTask task) {
    RunnerAndConfigurationSettings settings = task.getSettings();
    if (settings == null) {
      return false;
    }
    final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
    final String executorId = executor.getId();
    ExecutionEnvironmentBuilder builder =
        ExecutionEnvironmentBuilder.createOrNull(executor, settings);
    if (builder == null) {
      return false;
    }
    final ExecutionEnvironment environment = builder.build();
    environment.setExecutionId(env.getExecutionId());
    if (!ExecutionTargetManager.canRun(settings, env.getExecutionTarget())) {
      return false;
    }

    if (!environment.getRunner().canRun(executorId, environment.getRunProfile())) {
      return false;
    } else {
      final Semaphore targetDone = new Semaphore();
      final Ref<Boolean> result = new Ref<Boolean>(false);
      final Disposable disposable = Disposer.newDisposable();

      myProject
          .getMessageBus()
          .connect(disposable)
          .subscribe(
              ExecutionManager.EXECUTION_TOPIC,
              new ExecutionAdapter() {
                @Override
                public void processStartScheduled(
                    final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
                  if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                    targetDone.down();
                  }
                }

                @Override
                public void processNotStarted(
                    final String executorIdLocal,
                    @NotNull final ExecutionEnvironment environmentLocal) {
                  if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                    targetDone.up();
                  }
                }

                @Override
                public void processStarted(
                    final String executorIdLocal,
                    @NotNull final ExecutionEnvironment environmentLocal,
                    @NotNull final ProcessHandler handler) {
                  if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                    handler.addProcessListener(
                        new ProcessAdapter() {
                          @Override
                          public void processTerminated(ProcessEvent event) {
                            result.set(event.getExitCode() == 0);
                            targetDone.up();
                          }
                        });
                  }
                }
              });

      try {
        ApplicationManager.getApplication()
            .invokeAndWait(
                new Runnable() {
                  @Override
                  public void run() {
                    try {
                      environment.getRunner().execute(environment);
                    } catch (ExecutionException e) {
                      targetDone.up();
                      LOG.error(e);
                    }
                  }
                },
                ModalityState.NON_MODAL);
      } catch (Exception e) {
        LOG.error(e);
        Disposer.dispose(disposable);
        return false;
      }

      targetDone.waitFor();
      Disposer.dispose(disposable);

      return result.get();
    }
  }