public void registerExtension(
      final PluginDescriptor pluginDescriptor, final Element extensionElement) {
    final PluginId pluginId = pluginDescriptor.getPluginId();

    String epName = extractEPName(extensionElement);

    ExtensionComponentAdapter adapter;
    final PicoContainer container = getPluginContainer(pluginId.getIdString());
    final ExtensionPoint extensionPoint = getExtensionPoint(epName);
    if (extensionPoint.getKind() == ExtensionPoint.Kind.INTERFACE) {
      String implClass = extensionElement.getAttributeValue("implementation");
      if (implClass == null) {
        throw new RuntimeException(
            "'implementation' attribute not specified for '"
                + epName
                + "' extension in '"
                + pluginId.getIdString()
                + "' plugin");
      }
      adapter =
          new ExtensionComponentAdapter(
              implClass,
              extensionElement,
              container,
              pluginDescriptor,
              shouldDeserializeInstance(extensionElement));
    } else {
      adapter =
          new ExtensionComponentAdapter(
              extensionPoint.getClassName(), extensionElement, container, pluginDescriptor, true);
    }
    myExtensionElement2extension.put(extensionElement, adapter);
    internalGetPluginContainer().registerComponent(adapter);
    getExtensionPoint(epName).registerExtensionAdapter(adapter);
  }
Beispiel #2
0
 private List<String> getNonOptionalDependencies(final String id) {
   List<String> result = new ArrayList<String>();
   IdeaPluginDescriptor descriptor = findPlugin(id);
   if (descriptor != null) {
     for (PluginId pluginId : descriptor.getDependentPluginIds()) {
       if (pluginId.getIdString().equals("com.intellij")) continue;
       if (!ArrayUtil.contains(pluginId, descriptor.getOptionalDependentPluginIds())) {
         result.add(pluginId.getIdString());
       }
     }
   }
   return result;
 }
 public static boolean hasNewerVersion(PluginId descr) {
   return !wasUpdated(descr)
       && (NewVersions2Plugins.containsKey(descr)
           || PluginManagerUISettings.getInstance()
               .myOutdatedPlugins
               .contains(descr.getIdString()));
 }
  private static void updateExistingPluginInfo(
      IdeaPluginDescriptor descr, IdeaPluginDescriptor existing) {
    int state = StringUtil.compareVersionNumbers(descr.getVersion(), existing.getVersion());
    final PluginId pluginId = existing.getPluginId();
    final String idString = pluginId.getIdString();
    final JDOMExternalizableStringList installedPlugins =
        PluginManagerUISettings.getInstance().getInstalledPlugins();
    if (!installedPlugins.contains(idString)
        && !((IdeaPluginDescriptorImpl) existing).isDeleted()) {
      installedPlugins.add(idString);
    }
    final PluginManagerUISettings updateSettings = PluginManagerUISettings.getInstance();
    if (state > 0
        && !PluginManager.isIncompatible(descr)
        && !updatedPlugins.contains(descr.getPluginId())) {
      NewVersions2Plugins.put(pluginId, 1);
      if (!updateSettings.myOutdatedPlugins.contains(idString)) {
        updateSettings.myOutdatedPlugins.add(idString);
      }

      final IdeaPluginDescriptorImpl plugin = (IdeaPluginDescriptorImpl) existing;
      plugin.setDownloadsCount(descr.getDownloads());
      plugin.setVendor(descr.getVendor());
      plugin.setVendorEmail(descr.getVendorEmail());
      plugin.setVendorUrl(descr.getVendorUrl());
      plugin.setUrl(descr.getUrl());

    } else {
      updateSettings.myOutdatedPlugins.remove(idString);
      if (NewVersions2Plugins.remove(pluginId) != null) {
        updatedPlugins.add(pluginId);
      }
    }
  }
  @Override
  public boolean isBundled() {
    if (PluginManagerCore.CORE_PLUGIN_ID.equals(myId.getIdString())) {
      return true;
    }

    String path;
    try {
      // to avoid paths like this /home/kb/IDEA/bin/../config/plugins/APlugin
      path = getPath().getCanonicalPath();
    } catch (IOException e) {
      path = getPath().getAbsolutePath();
    }
    Application app = ApplicationManager.getApplication();
    if (app != null && app.isInternal()) {
      if (path.startsWith(
          PathManager.getHomePath() + File.separator + "out" + File.separator + "classes")) {
        return true;
      }
      if (app.isUnitTestMode()
          && !path.startsWith(PathManager.getPluginsPath() + File.separatorChar)) {
        return true;
      }
    }

    return path.startsWith(PathManager.getPreInstalledPluginsPath());
  }
  private static boolean checkDependants(
      final IdeaPluginDescriptor pluginDescriptor,
      final Function<PluginId, IdeaPluginDescriptor> pluginId2Descriptor,
      final Condition<PluginId> check,
      final Set<PluginId> processed) {
    processed.add(pluginDescriptor.getPluginId());
    final PluginId[] dependentPluginIds = pluginDescriptor.getDependentPluginIds();
    final Set<PluginId> optionalDependencies =
        new HashSet<PluginId>(Arrays.asList(pluginDescriptor.getOptionalDependentPluginIds()));
    for (final PluginId dependentPluginId : dependentPluginIds) {
      if (processed.contains(dependentPluginId)) continue;

      // TODO[yole] should this condition be a parameter?
      if (isModuleDependency(dependentPluginId)
          && (ourAvailableModules.isEmpty()
              || ourAvailableModules.contains(dependentPluginId.getIdString()))) {
        continue;
      }
      if (!optionalDependencies.contains(dependentPluginId)) {
        if (!check.value(dependentPluginId)) {
          return false;
        }
        final IdeaPluginDescriptor dependantPluginDescriptor =
            pluginId2Descriptor.fun(dependentPluginId);
        if (dependantPluginDescriptor != null
            && !checkDependants(dependantPluginDescriptor, pluginId2Descriptor, check, processed)) {
          return false;
        }
      }
    }
    return true;
  }
  public static void handleComponentError(
      Throwable t, @Nullable String componentClassName, @Nullable ComponentConfig config) {
    if (t instanceof StartupAbortedException) {
      throw (StartupAbortedException) t;
    }

    PluginId pluginId = null;
    if (config != null) {
      pluginId = config.getPluginId();
    }
    if (pluginId == null || CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
      if (componentClassName != null) {
        pluginId = getPluginByClassName(componentClassName);
      }
    }
    if (pluginId == null || CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
      if (t instanceof PicoPluginExtensionInitializationException) {
        pluginId = ((PicoPluginExtensionInitializationException) t).getPluginId();
      }
    }

    if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
      getLogger().warn(t);

      disablePlugin(pluginId.getIdString());

      StringWriter message = new StringWriter();
      message
          .append("Plugin '")
          .append(pluginId.getIdString())
          .append("' failed to initialize and will be disabled. ");
      message
          .append(" Please restart ")
          .append(ApplicationNamesInfo.getInstance().getFullProductName())
          .append('.');
      message.append("\n\n");
      t.printStackTrace(new PrintWriter(message));
      Main.showMessage("Plugin Error", message.toString(), false);

      throw new StartupAbortedException(t).exitCode(Main.PLUGIN_ERROR).logError(false);
    } else {
      throw new StartupAbortedException("Fatal error initializing '" + componentClassName + "'", t);
    }
  }
 @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);
 }
Beispiel #9
0
 @Nullable
 IdeaPluginDescriptor findPlugin(String id) {
   for (IdeaPluginDescriptor pluginDescriptor : myAllPlugins) {
     PluginId pluginId = pluginDescriptor.getPluginId();
     if (pluginId != null && StringUtil.equals(pluginId.getIdString(), id)) {
       return pluginDescriptor;
     }
   }
   return null;
 }
  /** Should be called whenever a new plugin is installed or an existing one is updated. */
  public void onPluginInstall(@NotNull IdeaPluginDescriptor descriptor) {
    PluginId id = descriptor.getPluginId();
    boolean existing = PluginManager.isPluginInstalled(id);

    synchronized (myLock) {
      myOutdatedPlugins.remove(id.getIdString());
      if (existing) {
        myUpdatedPlugins.put(id, descriptor);
      } else {
        myInstalledPlugins.put(id, descriptor);
      }
    }
  }
  /**
   * Should be called whenever a list of plugins is loaded from a repository to check if there is an
   * updated version.
   */
  public void onDescriptorDownload(@NotNull IdeaPluginDescriptor descriptor) {
    PluginId id = descriptor.getPluginId();
    IdeaPluginDescriptor existing = PluginManager.getPlugin(id);
    if (existing == null
        || (existing.isBundled() && !existing.allowBundledUpdate())
        || wasUpdated(id)) {
      return;
    }

    boolean supersedes =
        !PluginManagerCore.isIncompatible(descriptor)
            && (PluginDownloader.compareVersionsSkipBroken(existing, descriptor.getVersion()) > 0
                || PluginManagerCore.isIncompatible(existing));

    String idString = id.getIdString();

    synchronized (myLock) {
      if (supersedes) {
        myOutdatedPlugins.add(idString);
      } else {
        myOutdatedPlugins.remove(idString);
      }
    }
  }
 public static boolean isModuleDependency(final PluginId dependentPluginId) {
   return dependentPluginId.getIdString().startsWith(MODULE_DEPENDENCY_PREFIX);
 }
    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
      final Component orig =
          super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
      if (myPluginDescriptor != null) {
        myNameLabel.setText(myPluginDescriptor.getName());
        final PluginId pluginId = myPluginDescriptor.getPluginId();
        final String idString = pluginId.getIdString();
        if (myPluginDescriptor.isBundled()) {
          myBundledLabel.setText("Bundled");
        } else {
          final String host = myPlugin2host.get(idString);
          if (host != null) {
            String presentableUrl = VfsUtil.urlToPath(host);
            final int idx = presentableUrl.indexOf('/');
            if (idx > -1) {
              presentableUrl = presentableUrl.substring(0, idx);
            }
            myBundledLabel.setText("From " + presentableUrl);
          } else {
            if (PluginManagerUISettings.getInstance().getInstalledPlugins().contains(idString)) {
              myBundledLabel.setText("From repository");
            } else {
              myBundledLabel.setText("Custom");
            }
          }
        }
        if (myPluginDescriptor instanceof IdeaPluginDescriptorImpl
            && ((IdeaPluginDescriptorImpl) myPluginDescriptor).isDeleted()) {
          myNameLabel.setIcon(AllIcons.Actions.Clean);
        } else if (hasNewerVersion(pluginId)) {
          myNameLabel.setIcon(AllIcons.Nodes.Pluginobsolete);
          myPanel.setToolTipText("Newer version of the plugin is available");
        } else {
          myNameLabel.setIcon(AllIcons.Nodes.Plugin);
        }

        final Color fg = orig.getForeground();
        final Color bg = orig.getBackground();
        final Color grayedFg = isSelected ? fg : Color.GRAY;

        myPanel.setBackground(bg);
        myNameLabel.setBackground(bg);
        myBundledLabel.setBackground(bg);

        myNameLabel.setForeground(fg);
        final boolean wasUpdated = wasUpdated(pluginId);
        if (wasUpdated || PluginManager.getPlugin(pluginId) == null) {
          if (!isSelected) {
            myNameLabel.setForeground(FileStatus.COLOR_ADDED);
          }
          if (wasUpdated) {
            myPanel.setToolTipText(
                "Plugin was updated to the newest version. Changes will be available after restart");
          } else {
            myPanel.setToolTipText("Plugin will be activated after restart.");
          }
        }
        myBundledLabel.setForeground(grayedFg);

        final Set<PluginId> required = myDependentToRequiredListMap.get(pluginId);
        if (required != null && required.size() > 0) {
          myNameLabel.setForeground(Color.RED);

          final StringBuilder s = new StringBuilder();
          if (myEnabled.get(pluginId) == null) {
            s.append("Plugin was not loaded.\n");
          }
          if (required.contains(PluginId.getId("com.intellij.modules.ultimate"))) {
            s.append("The plugin requires IntelliJ IDEA Ultimate");
          } else {
            s.append("Required plugin").append(required.size() == 1 ? " \"" : "s \"");
            s.append(
                StringUtil.join(
                    required,
                    new Function<PluginId, String>() {
                      @Override
                      public String fun(final PluginId id) {
                        final IdeaPluginDescriptor plugin = PluginManager.getPlugin(id);
                        return plugin == null ? id.getIdString() : plugin.getName();
                      }
                    },
                    ","));

            s.append(required.size() == 1 ? "\" is not enabled!" : "\" are not enabled!");
          }
          myPanel.setToolTipText(s.toString());
        }

        if (PluginManager.isIncompatible(myPluginDescriptor)) {
          myPanel.setToolTipText(
              IdeBundle.message(
                  "plugin.manager.incompatible.tooltip.warning",
                  ApplicationNamesInfo.getInstance().getFullProductName()));
          myNameLabel.setForeground(Color.red);
        }
      }

      return myPanel;
    }
  private static boolean prepareToInstall(
      final PluginNode pluginNode,
      final List<PluginId> pluginIds,
      List<IdeaPluginDescriptor> allPlugins)
      throws IOException {
    // check for dependent plugins at first.
    if (pluginNode.getDepends() != null && pluginNode.getDepends().size() > 0) {
      // prepare plugins list for install

      final PluginId[] optionalDependentPluginIds = pluginNode.getOptionalDependentPluginIds();
      final List<PluginNode> depends = new ArrayList<PluginNode>();
      final List<PluginNode> optionalDeps = new ArrayList<PluginNode>();
      for (int i = 0; i < pluginNode.getDepends().size(); i++) {
        PluginId depPluginId = pluginNode.getDepends().get(i);

        if (PluginManager.isPluginInstalled(depPluginId)
            || PluginManager.isModuleDependency(depPluginId)
            || (pluginIds != null && pluginIds.contains(depPluginId))) {
          //  ignore installed or installing plugins
          continue;
        }

        PluginNode depPlugin = new PluginNode(depPluginId);
        depPlugin.setSize("-1");
        depPlugin.setName(depPluginId.getIdString()); // prevent from exceptions

        if (optionalDependentPluginIds != null
            && ArrayUtil.indexOf(optionalDependentPluginIds, depPluginId) != -1) {
          if (isPluginInRepo(depPluginId, allPlugins)) {
            optionalDeps.add(depPlugin);
          }
        } else {
          depends.add(depPlugin);
        }
      }

      if (depends.size() > 0) { // has something to install prior installing the plugin
        final boolean[] proceed = new boolean[1];
        final StringBuffer buf = new StringBuffer();
        for (PluginNode depend : depends) {
          buf.append(depend.getName()).append(",");
        }
        try {
          GuiUtils.runOrInvokeAndWait(
              new Runnable() {
                public void run() {
                  proceed[0] =
                      Messages.showYesNoDialog(
                              IdeBundle.message(
                                  "plugin.manager.dependencies.detected.message",
                                  depends.size(),
                                  buf.substring(0, buf.length() - 1)),
                              IdeBundle.message("plugin.manager.dependencies.detected.title"),
                              Messages.getWarningIcon())
                          == DialogWrapper.OK_EXIT_CODE;
                }
              });
        } catch (Exception e) {
          return false;
        }
        if (proceed[0]) {
          if (!prepareToInstall(depends, allPlugins)) {
            return false;
          }
        } else {
          return false;
        }
      }

      if (optionalDeps.size() > 0) {
        final StringBuffer buf = new StringBuffer();
        for (PluginNode depend : optionalDeps) {
          buf.append(depend.getName()).append(",");
        }
        final boolean[] proceed = new boolean[1];
        try {
          GuiUtils.runOrInvokeAndWait(
              new Runnable() {
                public void run() {
                  proceed[0] =
                      Messages.showYesNoDialog(
                              IdeBundle.message(
                                  "plugin.manager.optional.dependencies.detected.message",
                                  optionalDeps.size(),
                                  buf.substring(0, buf.length() - 1)),
                              IdeBundle.message("plugin.manager.dependencies.detected.title"),
                              Messages.getWarningIcon())
                          == DialogWrapper.OK_EXIT_CODE;
                }
              });
        } catch (Exception e) {
          return false;
        }
        if (proceed[0]) {
          if (!prepareToInstall(optionalDeps, allPlugins)) {
            return false;
          }
        }
      }
    }

    synchronized (PluginManager.lock) {
      final PluginDownloader downloader = PluginDownloader.createDownloader(pluginNode);
      if (downloader.prepareToInstall(ProgressManager.getInstance().getProgressIndicator())) {
        downloader.install();
        pluginNode.setStatus(PluginNode.STATUS_DOWNLOADED);
      } else {
        return false;
      }
    }

    return true;
  }
 public boolean hasNewerVersion(@NotNull PluginId id) {
   synchronized (myLock) {
     return !wasUpdated(id) && myOutdatedPlugins.contains(id.getIdString());
   }
 }
  @Nullable
  static String filterBadPlugins(
      List<? extends IdeaPluginDescriptor> result, final Map<String, String> disabledPluginNames) {
    final Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap =
        new HashMap<PluginId, IdeaPluginDescriptor>();
    final StringBuffer message = new StringBuffer();
    boolean pluginsWithoutIdFound = false;
    for (Iterator<? extends IdeaPluginDescriptor> it = result.iterator(); it.hasNext(); ) {
      final IdeaPluginDescriptor descriptor = it.next();
      final PluginId id = descriptor.getPluginId();
      if (id == null) {
        pluginsWithoutIdFound = true;
      }
      if (idToDescriptorMap.containsKey(id)) {
        message.append("<br>");
        message.append(IdeBundle.message("message.duplicate.plugin.id"));
        message.append(id);
        it.remove();
      } else if (descriptor.isEnabled()) {
        idToDescriptorMap.put(id, descriptor);
      }
    }
    addModulesAsDependents(idToDescriptorMap);
    final List<String> disabledPluginIds = new ArrayList<String>();
    final LinkedHashSet<String> faultyDescriptors = new LinkedHashSet<String>();
    for (final Iterator<? extends IdeaPluginDescriptor> it = result.iterator(); it.hasNext(); ) {
      final IdeaPluginDescriptor pluginDescriptor = it.next();
      checkDependants(
          pluginDescriptor,
          new Function<PluginId, IdeaPluginDescriptor>() {
            @Override
            public IdeaPluginDescriptor fun(final PluginId pluginId) {
              return idToDescriptorMap.get(pluginId);
            }
          },
          new Condition<PluginId>() {
            @Override
            public boolean value(final PluginId pluginId) {
              if (!idToDescriptorMap.containsKey(pluginId)) {
                pluginDescriptor.setEnabled(false);
                if (!pluginId.getIdString().startsWith(MODULE_DEPENDENCY_PREFIX)) {
                  faultyDescriptors.add(pluginId.getIdString());
                  disabledPluginIds.add(pluginDescriptor.getPluginId().getIdString());
                  message.append("<br>");
                  final String name = pluginDescriptor.getName();
                  final IdeaPluginDescriptor descriptor = idToDescriptorMap.get(pluginId);
                  String pluginName;
                  if (descriptor == null) {
                    pluginName = pluginId.getIdString();
                    if (disabledPluginNames.containsKey(pluginName)) {
                      pluginName = disabledPluginNames.get(pluginName);
                    }
                  } else {
                    pluginName = descriptor.getName();
                  }

                  message.append(
                      getDisabledPlugins().contains(pluginId.getIdString())
                          ? IdeBundle.message("error.required.plugin.disabled", name, pluginName)
                          : IdeBundle.message(
                              "error.required.plugin.not.installed", name, pluginName));
                }
                it.remove();
                return false;
              }
              return true;
            }
          });
    }
    if (!disabledPluginIds.isEmpty()) {
      myPlugins2Disable = disabledPluginIds;
      myPlugins2Enable = faultyDescriptors;
      message.append("<br>");
      message.append("<br>").append("<a href=\"" + DISABLE + "\">Disable ");
      if (disabledPluginIds.size() == 1) {
        final PluginId pluginId2Disable = PluginId.getId(disabledPluginIds.iterator().next());
        message.append(
            idToDescriptorMap.containsKey(pluginId2Disable)
                ? idToDescriptorMap.get(pluginId2Disable).getName()
                : pluginId2Disable.getIdString());
      } else {
        message.append("not loaded plugins");
      }
      message.append("</a>");
      boolean possibleToEnable = true;
      for (String descriptor : faultyDescriptors) {
        if (disabledPluginNames.get(descriptor) == null) {
          possibleToEnable = false;
          break;
        }
      }
      if (possibleToEnable) {
        message
            .append("<br>")
            .append("<a href=\"" + ENABLE + "\">Enable ")
            .append(
                faultyDescriptors.size() == 1
                    ? disabledPluginNames.get(faultyDescriptors.iterator().next())
                    : " all necessary plugins")
            .append("</a>");
      }
      message.append("<br>").append("<a href=\"" + EDIT + "\">Open plugin manager</a>");
    }
    if (pluginsWithoutIdFound) {
      message.append("<br>");
      message.append(IdeBundle.message("error.plugins.without.id.found"));
    }
    if (message.length() > 0) {
      message.insert(0, IdeBundle.message("error.problems.found.loading.plugins"));
      return message.toString();
    }
    return null;
  }
 /**
  * @deprecated if more settings are needed for this plugin, you should create a {@link
  *     com.intellij.openapi.components.PersistentStateComponent} and store all the settings in a
  *     separate file without the prefix on the property name.
  */
 @Deprecated
 private static String getSettingsPrefix() {
   PluginId pluginId = PluginManager.getPluginByClassName(MTTheme.class.getName());
   return pluginId == null ? "com.chrisrm.idea.MaterialThemeUI" : pluginId.getIdString();
 }