| /* |
| * Copyright 2000-2014 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.jps.impl; |
| |
| import com.intellij.openapi.extensions.*; |
| import com.intellij.openapi.vfs.CharsetToolkit; |
| import com.intellij.util.containers.ContainerUtil; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.jetbrains.jps.plugin.JpsPluginManager; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.net.URL; |
| import java.util.*; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| |
| /** |
| * @author nik |
| */ |
| public class JpsIdePluginManagerImpl extends JpsPluginManager { |
| private List<PluginDescriptor> myExternalBuildPlugins = new CopyOnWriteArrayList<PluginDescriptor>(); |
| |
| public JpsIdePluginManagerImpl() { |
| ExtensionsArea rootArea = Extensions.getRootArea(); |
| //todo[nik] get rid of this check: currently this class is used in jps-builders tests instead of JpsPluginManagerImpl because platform-impl module is added to classpath via testFramework |
| if (rootArea.hasExtensionPoint(JpsPluginBean.EP_NAME.getName())) { |
| rootArea.getExtensionPoint(JpsPluginBean.EP_NAME).addExtensionPointListener(new ExtensionPointListener<JpsPluginBean>() { |
| @Override |
| public void extensionAdded(@NotNull JpsPluginBean extension, @Nullable PluginDescriptor pluginDescriptor) { |
| ContainerUtil.addIfNotNull(pluginDescriptor, myExternalBuildPlugins); |
| } |
| |
| @Override |
| public void extensionRemoved(@NotNull JpsPluginBean extension, @Nullable PluginDescriptor pluginDescriptor) { |
| } |
| }); |
| } |
| if (rootArea.hasExtensionPoint("com.intellij.compileServer.plugin")) { |
| ExtensionPoint extensionPoint = rootArea.getExtensionPoint("com.intellij.compileServer.plugin"); |
| //noinspection unchecked |
| extensionPoint.addExtensionPointListener(new ExtensionPointListener() { |
| @Override |
| public void extensionAdded(@NotNull Object extension, @Nullable PluginDescriptor pluginDescriptor) { |
| ContainerUtil.addIfNotNull(pluginDescriptor, myExternalBuildPlugins); |
| } |
| |
| @Override |
| public void extensionRemoved(@NotNull Object extension, @Nullable PluginDescriptor pluginDescriptor) { |
| } |
| }); |
| } |
| } |
| |
| @NotNull |
| @Override |
| public <T> Collection<T> loadExtensions(@NotNull Class<T> extensionClass) { |
| String resourceName = "META-INF/services/" + extensionClass.getName(); |
| Set<Class<T>> classes = new LinkedHashSet<Class<T>>(); |
| Set<ClassLoader> loaders = new LinkedHashSet<ClassLoader>(); |
| for (PluginDescriptor plugin : myExternalBuildPlugins) { |
| ContainerUtil.addIfNotNull(loaders, plugin.getPluginClassLoader()); |
| } |
| if (loaders.isEmpty()) { |
| loaders.add(getClass().getClassLoader()); |
| } |
| |
| Set<String> loadedUrls = new HashSet<String>(); |
| for (ClassLoader loader : loaders) { |
| try { |
| Enumeration<URL> resources = loader.getResources(resourceName); |
| while (resources.hasMoreElements()) { |
| URL url = resources.nextElement(); |
| if (loadedUrls.add(url.toExternalForm())) { |
| loadImplementations(url, loader, classes); |
| } |
| } |
| } |
| catch (IOException e) { |
| throw new ServiceConfigurationError("Cannot load configuration files for " + extensionClass.getName(), e); |
| } |
| } |
| List<T> extensions = new ArrayList<T>(); |
| for (Class<T> aClass : classes) { |
| try { |
| extensions.add(extensionClass.cast(aClass.newInstance())); |
| } |
| catch (Exception e) { |
| throw new ServiceConfigurationError("Class " + aClass.getName() + " cannot be instantiated", e); |
| } |
| } |
| return extensions; |
| } |
| |
| private static <T> void loadImplementations(URL url, ClassLoader loader, Set<Class<T>> result) throws IOException { |
| for (String name : loadClassNames(url)) { |
| try { |
| //noinspection unchecked |
| result.add((Class<T>)Class.forName(name, false, loader)); |
| } |
| catch (ClassNotFoundException e) { |
| throw new ServiceConfigurationError("Cannot find class " + name, e); |
| } |
| } |
| } |
| |
| private static List<String> loadClassNames(URL url) throws IOException { |
| List<String> result = new ArrayList<String>(); |
| BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), CharsetToolkit.UTF8)); |
| try { |
| String line; |
| while ((line = in.readLine()) != null) { |
| int i = line.indexOf('#'); |
| if (i >= 0) line = line.substring(0, i); |
| line = line.trim(); |
| if (!line.isEmpty()) { |
| result.add(line); |
| } |
| } |
| } |
| finally { |
| in.close(); |
| } |
| return result; |
| } |
| } |