Loading modules from plugin.xml using extensions framework. Updated JNIWrapper to the latest version.

This commit is contained in:
Alexander Kireyev
2005-02-08 21:45:47 +03:00
parent 0066878df6
commit 0aac91265d
13 changed files with 185 additions and 71 deletions
@@ -45,7 +45,7 @@ public class ExtensionComponentAdapter extends ConstructorInjectionComponentAdap
readerConfigurator.configureReader(xStream);
}
xStream.alias(myExtensionElement.getName(), componentInstance.getClass());
myComponentInstance = xStream.unmarshal(new JDomReader(myExtensionElement), componentInstance);
myComponentInstance = xStream.unmarshal(new JDomExtensionsReader(myExtensionElement), componentInstance);
}
else {
myComponentInstance = myExtensionElement;
Binary file not shown.
+1
View File
@@ -28,6 +28,7 @@
</library>
</orderEntry>
<orderEntry type="library" name="tools" level="application" />
<orderEntry type="module" module-name="extensions" exported="" />
<orderEntryProperties />
</component>
</module>
@@ -7,9 +7,10 @@ package com.intellij.openapi.module;
import com.intellij.openapi.components.ComponentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.extensions.AreaInstance;
import com.intellij.pom.PomModule;
public interface Module extends ComponentManager {
public interface Module extends ComponentManager, AreaInstance {
Module[] EMPTY_ARRAY = new Module[0];
VirtualFile getModuleFile();
@@ -6,6 +6,7 @@ package com.intellij.openapi.project;
import com.intellij.openapi.components.ComponentManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.extensions.AreaInstance;
import com.intellij.pom.PomModel;
@@ -13,7 +14,7 @@ import com.intellij.pom.PomModel;
/**
* Project interface class.
*/
public interface Project extends ComponentManager {
public interface Project extends ComponentManager, AreaInstance {
VirtualFile getProjectFile();
String getName();
/**
@@ -1,14 +1,17 @@
<idea-plugin>
<idea-plugin version="2">
<name>ConditionalOperatorConverter</name>
<description>Intention to convert a conditional operator into if</description>
<version>1.3</version>
<vendor>JetBrains</vendor>
<idea-version min="4.0" max="4.5"/>
<project-components>
<component>
<implementation-class>com.intellij.codeInsight.intention.ConditionalOperatorConvertor</implementation-class>
<extensions xmlns="com.intellij.plugins">
<component area="PROJECT">
<implementation>com.intellij.codeInsight.intention.ConditionalOperatorConvertor</implementation>
<!--<options>-->
<!-- <option name="internal" value="true"/>-->
<!--</options>-->
</component>
</project-components>
</extensions>
</idea-plugin>
@@ -4,8 +4,10 @@ import com.intellij.ide.plugins.cl.IdeaClassLoader;
import com.intellij.ide.plugins.cl.PluginClassLoader;
import com.intellij.ide.startup.StartupActionScriptManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.extensions.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.graph.CachingSemiGraph;
import com.intellij.util.graph.DFSTBuilder;
@@ -35,6 +37,7 @@ import java.util.zip.ZipFile;
public class PluginManager {
//Logger is lasy-initialized in order not to use it outside the appClassLoader
private static Logger ourLogger = null;
public static final String COMPONENT_EXTENSION_POINT = "com.intellij.plugins.component";
private static Logger getLogger() {
if (ourLogger == null) {
@@ -74,31 +77,78 @@ public class PluginManager {
*/
public static PluginDescriptor[] getPlugins() {
if (ourPlugins == null) {
final PluginDescriptor[] pluginDescriptors = loadDescriptors();
initializePlugins();
final Map<String, PluginDescriptor> idToDescriptorMap = new HashMap<String, PluginDescriptor>();
for (int idx = 0; idx < pluginDescriptors.length; idx++) {
final PluginDescriptor descriptor = pluginDescriptors[idx];
idToDescriptorMap.put(descriptor.getId(), descriptor);
}
// sort descriptors according to plugin dependencies
Arrays.sort(pluginDescriptors, getPluginDescriptorComparator(idToDescriptorMap));
final Class callerClass = Reflection.getCallerClass(1);
final ClassLoader parentLoader = callerClass.getClassLoader();
for (int idx = 0; idx < pluginDescriptors.length; idx++) {
final PluginDescriptor pluginDescriptor = pluginDescriptors[idx];
final List classPath = pluginDescriptor.getClassPath();
final String[] dependentPluginIds = pluginDescriptor.getDependentPluginIds();
final ClassLoader[] parentLoaders = dependentPluginIds.length > 0? getParentLoaders(idToDescriptorMap, dependentPluginIds): new ClassLoader[] {parentLoader};
final PluginClassLoader pluginClassLoader = createPluginClassLoader((File[])classPath.toArray(new File[classPath.size()]), pluginDescriptor.getName(), parentLoaders, pluginDescriptor.getPath());
pluginDescriptor.setLoader(pluginClassLoader);
}
ourPlugins = pluginDescriptors;
}
return ourPlugins;
}
private static void initializePlugins() {
if (!shouldLoadPlugins()) return;
configureExtensions();
final PluginDescriptor[] pluginDescriptors = loadDescriptors();
final Map<String, PluginDescriptor> idToDescriptorMap = new HashMap<String, PluginDescriptor>();
for (int idx = 0; idx < pluginDescriptors.length; idx++) {
final PluginDescriptor descriptor = pluginDescriptors[idx];
idToDescriptorMap.put(descriptor.getId(), descriptor);
}
// sort descriptors according to plugin dependencies
Arrays.sort(pluginDescriptors, getPluginDescriptorComparator(idToDescriptorMap));
final Class callerClass = Reflection.getCallerClass(1);
final ClassLoader parentLoader = callerClass.getClassLoader();
for (int idx = 0; idx < pluginDescriptors.length; idx++) {
final PluginDescriptor pluginDescriptor = pluginDescriptors[idx];
final List classPath = pluginDescriptor.getClassPath();
final String[] dependentPluginIds = pluginDescriptor.getDependentPluginIds();
final ClassLoader[] parentLoaders = dependentPluginIds.length > 0? getParentLoaders(idToDescriptorMap, dependentPluginIds): new ClassLoader[] {parentLoader};
final PluginClassLoader pluginClassLoader = createPluginClassLoader((File[])classPath.toArray(new File[classPath.size()]), pluginDescriptor.getName(), parentLoaders, pluginDescriptor.getPath());
pluginDescriptor.setLoader(pluginClassLoader);
pluginDescriptor.registerExtensions();
}
ourPlugins = pluginDescriptors;
}
private static void configureExtensions() {
Extensions.setLogProvider(new IdeaLogProvider());
Extensions.registerAreaClass("PROJECT", null);
Extensions.registerAreaClass("MODULE", "PROJECT");
Extensions.getRootArea().registerExtensionPoint(COMPONENT_EXTENSION_POINT, ComponentDescriptor.class.getName());
Extensions.getRootArea().getExtensionPoint(Extensions.AREA_LISTENER_EXTENSION_POINT).registerExtension(new AreaListener() {
public void areaCreated(String areaClass, AreaInstance areaInstance) {
if ("PROJECT".equals(areaClass) || "MODULE".equals(areaClass)) {
Extensions.getArea(areaInstance).registerExtensionPoint(COMPONENT_EXTENSION_POINT, ComponentDescriptor.class.getName());
}
}
public void areaDisposing(String areaClass, AreaInstance areaInstance) {
}
}, LoadingOrder.FIRST);
}
public static boolean shouldLoadPlugins() {
try {
// no plugins during bootstrap
Class.forName("com.intellij.openapi.extensions.Extensions");
}
catch (ClassNotFoundException e) {
return false;
}
final String loadPlugins = System.getProperty("idea.load.plugins");
return ApplicationManagerEx.getApplicationEx() != null && !ApplicationManagerEx.getApplicationEx().isUnitTestMode() && (loadPlugins == null || "true".equals(loadPlugins));
}
public static boolean shouldLoadPlugin(PluginDescriptor descriptor) {
final String loadPluginCategory = System.getProperty("idea.load.plugins.category");
return loadPluginCategory == null || loadPluginCategory.equals(descriptor.getCategory());
}
private static Comparator<PluginDescriptor> getPluginDescriptorComparator(Map<String, PluginDescriptor> idToDescriptorMap) {
final Graph<String> graph = createPluginIdGraph(idToDescriptorMap);
final DFSTBuilder<String> builder = new DFSTBuilder<String>(graph);
@@ -259,6 +309,12 @@ public class PluginManager {
message.insert(0, "Problems found loading plugins:\n");
return message.toString();
}
for (Iterator<PluginDescriptor> iterator = result.iterator(); iterator.hasNext();) {
PluginDescriptor descriptor = iterator.next();
if (!shouldLoadPlugins() || !shouldLoadPlugin(descriptor)) {
iterator.remove();
}
}
return null;
}
@@ -586,4 +642,30 @@ public class PluginManager {
public static String getPluginByClassName (String className) {
return ourPluginClasses != null? ourPluginClasses.get(className) : null;
}
private static class IdeaLogProvider implements LogProvider {
public void error(String message) {
getLogger().error(message);
}
public void error(String message, Throwable t) {
getLogger().error(message, t);
}
public void error(Throwable t) {
getLogger().error(t);
}
public void warn(String message) {
getLogger().info(message);
}
public void warn(String message, Throwable t) {
getLogger().info(message, t);
}
public void warn(Throwable t) {
getLogger().info(t);
}
}
}
@@ -14,10 +14,10 @@ import java.io.IOException;
public interface ApplicationEx extends Application {
/**
* Loads the application configuration from the specified path
*
*
* @param optionsPath Path to /config folder
* @throws IOException
* @throws InvalidDataException
* @throws IOException
* @throws InvalidDataException
*/
void load(String optionsPath) throws IOException, InvalidDataException;
@@ -25,8 +25,6 @@ public interface ApplicationEx extends Application {
boolean isAspectJSupportEnabled();
boolean shouldLoadPlugins();
String getComponentsDescriptor();
String getName();
@@ -37,8 +35,6 @@ public interface ApplicationEx extends Application {
void doNotSave();
boolean shouldLoadPlugin(PluginDescriptor descriptor);
boolean runProcessWithProgressSynchronously(Runnable process,
String progressTitle,
boolean canBeCanceled,
@@ -30,6 +30,9 @@ import com.intellij.openapi.project.impl.convertors.Convertor34;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.AreaInstance;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.util.ArrayUtil;
import com.intellij.util.concurrency.ReentrantWriterPreferenceReadWriteLock;
@@ -120,14 +123,19 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
return myName;
}
protected void initComponents() {
initComponentsFromExtensions(Extensions.getRootArea());
super.initComponents();
}
private void loadApplicationComponents() {
loadComponentsConfiguration(APPLICATION_LAYER);
if (shouldLoadPlugins()) {
if (PluginManager.shouldLoadPlugins()) {
final PluginDescriptor[] plugins = PluginManager.getPlugins();
for (int i = 0; i < plugins.length; i++) {
PluginDescriptor plugin = plugins[i];
if (!shouldLoadPlugin(plugin)) continue;
if (!PluginManager.shouldLoadPlugin(plugin)) continue;
final Element appComponents = plugin.getAppComponents();
if (appComponents != null) {
loadComponentsConfiguration(appComponents, plugin);
@@ -148,16 +156,6 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
return myAspectJSupportEnabled || isUnitTestMode();
}
public boolean shouldLoadPlugins() {
final String loadPlugins = System.getProperty("idea.load.plugins");
return !isUnitTestMode() && (loadPlugins == null || "true".equals(loadPlugins));
}
public boolean shouldLoadPlugin(PluginDescriptor descriptor) {
final String loadPluginCategory = System.getProperty("idea.load.plugins.category");
return loadPluginCategory == null || loadPluginCategory.equals(descriptor.getCategory());
}
private static Thread ourDispatchThread = null;
public boolean isDispatchThread() {
@@ -175,7 +173,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
}
if (ourDispatchThread == currentThread) return true;
if (ourDispatchThread != null && !ourDispatchThread.isAlive()) {
ourDispatchThread = null;
return isDispatchThread(currentThread);
@@ -386,18 +384,18 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
disposeComponents();
}
}
public boolean runProcessWithProgressSynchronously(final Runnable process,
String progressTitle,
boolean canBeCanceled,
Project project) {
return runProcessWithProgressSynchronously(process, progressTitle, canBeCanceled, project, true);
}
public boolean runProcessWithProgressSynchronously(final Runnable process,
String progressTitle,
boolean canBeCanceled,
Project project,
Project project,
boolean smoothProgress) {
assertIsDispatchThread();
@@ -1,21 +1,24 @@
package com.intellij.openapi.components.impl;
import com.intellij.diagnostic.PluginException;
import com.intellij.ide.plugins.ComponentDescriptor;
import com.intellij.ide.plugins.PluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.application.ex.DecodeDefaultsUtil;
import com.intellij.openapi.components.BaseComponent;
import com.intellij.openapi.components.SettingsSavingComponent;
import com.intellij.openapi.components.LoadCancelledException;
import com.intellij.openapi.components.SettingsSavingComponent;
import com.intellij.openapi.components.ex.ComponentManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.util.*;
import com.intellij.util.containers.HashMap;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Document;
import org.picocontainer.*;
import org.picocontainer.defaults.*;
import com.intellij.util.containers.HashMap;
import java.io.IOException;
import java.io.InputStream;
@@ -173,7 +176,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
synchronized (this) {
myInitializingComponents.remove(component);
myInitializedComponents.put(interfaceClass, component);
}
}
}
return (T)component;
}
@@ -363,6 +366,37 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
return myPicoContainer;
}
protected void initComponentsFromExtensions(final ExtensionsArea extensionsArea) {
final ComponentDescriptor[] componentDescriptors =
(ComponentDescriptor[])extensionsArea.getExtensionPoint(PluginManager.COMPONENT_EXTENSION_POINT).getExtensions();
for (int i = 0; i < componentDescriptors.length; i++) {
ComponentDescriptor descriptor = componentDescriptors[i];
final Map<String, String> options = descriptor.getOptionsMap();
if (isComponentSuitable(options)) {
ClassLoader loader = findLoader(descriptor.getPluginName());
try {
registerComponent(Class.forName(descriptor.getInterface(), true, loader), Class.forName(descriptor.getImplementation(), true, loader), options, true,
isTrue(options, "lazy"));
}
catch (Exception e) {
LOG.error(new PluginException(e, PluginManager.getPlugin(descriptor.getPluginName())));
}
catch (Error e) {
LOG.error(new PluginException(e, PluginManager.getPlugin(descriptor.getPluginName())));
}
}
}
}
private ClassLoader findLoader(final String pluginName) {
ClassLoader loader = PluginManager.getPlugin(pluginName).getLoader();
if (loader == null) {
loader = getClass().getClassLoader();
}
return loader;
}
protected static class InvalidComponentDataException extends RuntimeException {
public InvalidComponentDataException(InvalidDataException exception) {
super(exception);
@@ -524,7 +558,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
throws PicoIntrospectionException,
AssignabilityRegistrationException,
NotConcreteRegistrationException {
DecoratingComponentAdapter initializingAdapter = new DecoratingComponentAdapter(new ConstructorInjectionComponentAdapter(componentKey, componentImplementation, parameters, true)) {
public Object getComponentInstance(PicoContainer picoContainer) throws PicoInitializationException, PicoIntrospectionException {
Object componentInstance = super.getComponentInstance(picoContainer);
@@ -21,6 +21,8 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
import com.intellij.openapi.extensions.AreaInstance;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.pom.PomModel;
import com.intellij.pom.PomModule;
import com.intellij.pom.core.impl.PomModuleImpl;
@@ -56,6 +58,7 @@ public class ModuleImpl extends BaseFileConfigurable implements Module {
super(false, pathMacros);
myProject = project;
myPomModel = pomModel;
Extensions.instantiateArea("MODULE", this, project);
init(filePath);
}
@@ -79,12 +82,12 @@ public class ModuleImpl extends BaseFileConfigurable implements Module {
public void loadModuleComponents() {
loadComponentsConfiguration(MODULE_LAYER);
ApplicationEx app = ApplicationManagerEx.getApplicationEx();
if (app.shouldLoadPlugins()) {
if (PluginManager.shouldLoadPlugins()) {
final PluginDescriptor[] plugins = PluginManager.getPlugins();
for (int i = 0; i < plugins.length; i++) {
PluginDescriptor plugin = plugins[i];
if (!app.shouldLoadPlugin(plugin)) continue;
if (!PluginManager.shouldLoadPlugin(plugin)) continue;
final Element moduleComponents = plugin.getModuleComponents();
if (moduleComponents != null) {
loadComponentsConfiguration(moduleComponents, plugin);
@@ -35,6 +35,8 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.AreaInstance;
import com.intellij.pom.PomModel;
import com.intellij.util.ArrayUtil;
import org.jdom.Document;
@@ -50,7 +52,7 @@ import java.util.*;
/**
*
*/
public class ProjectImpl extends BaseFileConfigurable implements ProjectEx {
public class ProjectImpl extends BaseFileConfigurable implements ProjectEx, AreaInstance {
private static final Logger LOG = Logger.getInstance("#com.intellij.project.impl.ProjectImpl");
private ProjectManagerImpl myManager;
@@ -85,6 +87,8 @@ public class ProjectImpl extends BaseFileConfigurable implements ProjectEx {
myOptimiseTestLoadSpeed = isOptimiseTestLoadSpeed;
Extensions.instantiateArea("PROJECT", this, null);
getPicoContainer().registerComponentInstance(Project.class, this);
myManager = manager;
@@ -139,12 +143,11 @@ public class ProjectImpl extends BaseFileConfigurable implements ProjectEx {
public void loadProjectComponents() {
loadComponentsConfiguration(PROJECT_LAYER);
ApplicationEx app = ApplicationManagerEx.getApplicationEx();
if (app.shouldLoadPlugins()) {
if (PluginManager.shouldLoadPlugins()) {
final PluginDescriptor[] plugins = PluginManager.getPlugins();
for (int i = 0; i < plugins.length; i++) {
PluginDescriptor plugin = plugins[i];
if (!app.shouldLoadPlugin(plugin)) continue;
if (!PluginManager.shouldLoadPlugin(plugin)) continue;
final Element projectComponents = plugin.getProjectComponents();
if (projectComponents != null) {
loadComponentsConfiguration(projectComponents, plugin);
@@ -61,10 +61,6 @@ public class MockApplication extends UserDataHolderBase implements ApplicationEx
return true;
}
public boolean shouldLoadPlugins() {
return false;
}
public BaseComponent getComponent(String name) {
return null;
}
@@ -124,10 +120,6 @@ public class MockApplication extends UserDataHolderBase implements ApplicationEx
public void doNotSave() {
}
public boolean shouldLoadPlugin(PluginDescriptor descriptor) {
return false;
}
public boolean runProcessWithProgressSynchronously(Runnable process,
String progressTitle,
boolean canBeCanceled,