summaryrefslogtreecommitdiff
path: root/platform/core-impl/src/com/intellij/ide
diff options
context:
space:
mode:
Diffstat (limited to 'platform/core-impl/src/com/intellij/ide')
-rw-r--r--platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java13
-rw-r--r--platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java55
-rw-r--r--platform/core-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java112
3 files changed, 154 insertions, 26 deletions
diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java
index 3094304a02cb..a6b957c0c508 100644
--- a/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java
+++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java
@@ -15,7 +15,6 @@
*/
package com.intellij.ide.plugins;
-import com.intellij.ide.IdeBundle;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.util.containers.HashMap;
import gnu.trove.TObjectIntHashMap;
@@ -32,7 +31,7 @@ public class PluginDescriptorComparator implements Comparator<IdeaPluginDescript
private final TObjectIntHashMap<PluginId> myIdToNumberMap = new TObjectIntHashMap<PluginId>();
private int myAvailableNumber = 1;
- public PluginDescriptorComparator(IdeaPluginDescriptor[] descriptors) throws Exception{
+ public PluginDescriptorComparator(IdeaPluginDescriptor[] descriptors){
final Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap = new HashMap<PluginId, IdeaPluginDescriptor>();
for (final IdeaPluginDescriptor descriptor : descriptors) {
idToDescriptorMap.put(descriptor.getPluginId(), descriptor);
@@ -46,18 +45,20 @@ public class PluginDescriptorComparator implements Comparator<IdeaPluginDescript
}
}
- private void assignNumbers(PluginId id, Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap, Stack<PluginId> visited) throws Exception {
+ private void assignNumbers(PluginId id, Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap, Stack<PluginId> visited){
visited.push(id);
try {
final IdeaPluginDescriptor ideaPluginDescriptor = idToDescriptorMap.get(id);
- if (ideaPluginDescriptor == null) {
- // missing optional dependency
+ if (ideaPluginDescriptor == null || !ideaPluginDescriptor.isEnabled()) {
+ // missing optional dependency or already disabled due to cycles
return;
}
final PluginId[] parentIds = ideaPluginDescriptor.getDependentPluginIds();
for (final PluginId parentId : parentIds) {
if (visited.contains(parentId)) {
- throw new Exception(IdeBundle.message("error.plugins.should.not.have.cyclic.dependencies") + id + "->" + parentId + "->...->" + id);
+ //disable plugins in the cycle
+ ideaPluginDescriptor.setEnabled(false);
+ break;
}
}
for (PluginId parentId1 : parentIds) {
diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
index cf2d45ad4945..8f4fd771ebdd 100644
--- a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
+++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
@@ -25,10 +25,7 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.ExtensionAreas;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.*;
-import com.intellij.openapi.util.BuildNumber;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.util.io.ZipFileCache;
@@ -479,8 +476,10 @@ public class PluginManagerCore {
}
static void prepareLoadingPluginsErrorMessage(final String errorMessage) {
- if (errorMessage != null) {
- if (!ApplicationManager.getApplication().isHeadlessEnvironment() && !ApplicationManager.getApplication().isUnitTestMode()) {
+ if (!StringUtil.isEmptyOrSpaces(errorMessage)) {
+ if (ApplicationManager.getApplication() != null
+ && !ApplicationManager.getApplication().isHeadlessEnvironment()
+ && !ApplicationManager.getApplication().isUnitTestMode()) {
if (myPluginError == null) {
myPluginError = errorMessage;
}
@@ -499,6 +498,7 @@ public class PluginManagerCore {
}
}
+ @Deprecated
static Comparator<IdeaPluginDescriptor> getPluginDescriptorComparator(Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap) {
final Graph<PluginId> graph = createPluginIdGraph(idToDescriptorMap);
final DFSTBuilder<PluginId> builder = new DFSTBuilder<PluginId>(graph);
@@ -549,6 +549,7 @@ public class PluginManagerCore {
}));
}
+ @Deprecated
static IdeaPluginDescriptorImpl[] findCorePlugin(IdeaPluginDescriptorImpl[] pluginDescriptors) {
for (IdeaPluginDescriptorImpl descriptor : pluginDescriptors) {
if (CORE_PLUGIN_ID.equals(descriptor.getPluginId().getIdString())) {
@@ -820,7 +821,7 @@ public class PluginManagerCore {
message.insert(0, IdeBundle.message("error.problems.found.loading.plugins"));
return message.toString();
}
- return null;
+ return "";
}
static void loadDescriptorsFromClassPath(@NotNull List<IdeaPluginDescriptorImpl> result, @Nullable StartupProgress progress) {
@@ -900,14 +901,7 @@ public class PluginManagerCore {
loadDescriptorsFromClassPath(result, fromSources ? progress : null);
IdeaPluginDescriptorImpl[] pluginDescriptors = result.toArray(new IdeaPluginDescriptorImpl[result.size()]);
- try {
- Arrays.sort(pluginDescriptors, new PluginDescriptorComparator(pluginDescriptors));
- }
- catch (Exception e) {
- prepareLoadingPluginsErrorMessage(IdeBundle.message("error.plugins.were.not.loaded", e.getMessage()));
- getLogger().info(e);
- return findCorePlugin(pluginDescriptors);
- }
+ Arrays.sort(pluginDescriptors, new PluginDescriptorComparator(pluginDescriptors));
return pluginDescriptors;
}
@@ -1090,12 +1084,13 @@ public class PluginManagerCore {
String errorMessage = filterBadPlugins(result, disabledPluginNames);
if (!brokenPluginsList.isEmpty()) {
- errorMessage = "Following plugins are incompatible with current IDE build: " + StringUtil.join(brokenPluginsList, ", ")
- + "<br>\n" + StringUtil.notNullize(errorMessage);
+ if (!StringUtil.isEmptyOrSpaces(errorMessage)) {
+ errorMessage += "<br>";
+ }
+ errorMessage += "Following plugins are incompatible with current IDE build: " + StringUtil.join(brokenPluginsList, ", ")
+ + "<br>\n" + StringUtil.notNullize(errorMessage);
}
- prepareLoadingPluginsErrorMessage(errorMessage);
-
final Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap = new HashMap<PluginId, IdeaPluginDescriptorImpl>();
for (final IdeaPluginDescriptorImpl descriptor : result) {
idToDescriptorMap.put(descriptor.getPluginId(), descriptor);
@@ -1112,8 +1107,28 @@ public class PluginManagerCore {
mergeOptionalConfigs(idToDescriptorMap);
addModulesAsDependents(idToDescriptorMap);
+ final Graph<PluginId> graph = createPluginIdGraph(idToDescriptorMap);
+ final DFSTBuilder<PluginId> builder = new DFSTBuilder<PluginId>(graph);
+ if (!builder.isAcyclic()) {
+ final Couple<PluginId> circularDependency = builder.getCircularDependency();
+ final PluginId id = circularDependency.getFirst();
+ final PluginId parentId = circularDependency.getSecond();
+ if (!StringUtil.isEmptyOrSpaces(errorMessage)) {
+ errorMessage += "<br>";
+ }
+ errorMessage += IdeBundle.message("error.plugins.should.not.have.cyclic.dependencies") + id + "->" + parentId + "->...->" + id;
+ }
+
+ prepareLoadingPluginsErrorMessage(errorMessage);
+
+ final Comparator<PluginId> idComparator = builder.comparator();
// sort descriptors according to plugin dependencies
- Collections.sort(result, getPluginDescriptorComparator(idToDescriptorMap));
+ Collections.sort(result, new Comparator<IdeaPluginDescriptor>() {
+ @Override
+ public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
+ return idComparator.compare(o1.getPluginId(), o2.getPluginId());
+ }
+ });
for (int i = 0; i < result.size(); i++) {
ourId2Index.put(result.get(i).getPluginId(), i);
diff --git a/platform/core-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java b/platform/core-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java
new file mode 100644
index 000000000000..a743569b1798
--- /dev/null
+++ b/platform/core-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.util;
+
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class PropertiesComponentImpl extends PropertiesComponent implements PersistentStateComponent<Element> {
+ private final Map<String, String> myMap = new LinkedHashMap<String, String>();
+ @NonNls private static final String ELEMENT_PROPERTY = "property";
+ @NonNls private static final String ATTRIBUTE_NAME = "name";
+ @NonNls private static final String ATTRIBUTE_VALUE = "value";
+
+ @NotNull
+ public String getComponentName() {
+ return "PropertiesComponent";
+ }
+
+ PropertiesComponentImpl() {
+ }
+
+ @Override
+ public Element getState() {
+ Element parentNode = new Element("state");
+ for (final String key : myMap.keySet()) {
+ String value = myMap.get(key);
+ if (value != null) {
+ Element element = new Element(ELEMENT_PROPERTY);
+ element.setAttribute(ATTRIBUTE_NAME, key);
+ element.setAttribute(ATTRIBUTE_VALUE, value);
+ parentNode.addContent(element);
+ }
+ }
+ return parentNode;
+ }
+
+ @Override
+ public void loadState(final Element parentNode) {
+ myMap.clear();
+ for (Element e : parentNode.getChildren(ELEMENT_PROPERTY)) {
+ String name = e.getAttributeValue(ATTRIBUTE_NAME);
+ if (name != null) {
+ myMap.put(name, e.getAttributeValue(ATTRIBUTE_VALUE));
+ }
+ }
+ }
+
+ @Override
+ public String getValue(String name) {
+ return myMap.get(name);
+ }
+
+ @Override
+ public void setValue(String name, String value) {
+ myMap.put(name, value);
+ }
+
+ @Override
+ public void setValue(@NotNull String name, @NotNull String value, @NotNull String defaultValue) {
+ if (value.equals(defaultValue)) {
+ myMap.remove(name);
+ }
+ else {
+ myMap.put(name, value);
+ }
+ }
+
+ @Override
+ public void unsetValue(String name) {
+ myMap.remove(name);
+ }
+
+ @Override
+ public boolean isValueSet(String name) {
+ return myMap.containsKey(name);
+ }
+
+ @Override
+ public String[] getValues(@NonNls String name) {
+ final String value = getValue(name);
+ return value != null ? value.split("\n") : null;
+ }
+
+ @Override
+ public void setValues(@NonNls String name, String[] values) {
+ if (values == null) {
+ setValue(name, null);
+ }
+ else {
+ setValue(name, StringUtil.join(values, "\n"));
+ }
+ }
+} \ No newline at end of file