update copyright
[fedora-idea.git] / plugins / ui-designer / src / com / intellij / uiDesigner / LoaderFactory.java
blob3a667c0da313fbe0c3b9baa583dd05e5c7ea53bd
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.uiDesigner;
18 import com.intellij.ProjectTopics;
19 import com.intellij.openapi.Disposable;
20 import com.intellij.openapi.components.ServiceManager;
21 import com.intellij.openapi.module.Module;
22 import com.intellij.openapi.module.ModuleUtil;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.roots.ModuleRootEvent;
25 import com.intellij.openapi.roots.ModuleRootListener;
26 import com.intellij.openapi.roots.ProjectRootsTraversing;
27 import com.intellij.openapi.roots.ProjectClasspathTraversing;
28 import com.intellij.openapi.util.Disposer;
29 import com.intellij.openapi.vfs.VirtualFile;
30 import com.intellij.uiDesigner.core.Spacer;
31 import com.intellij.util.PathUtil;
32 import com.intellij.util.lang.UrlClassLoader;
33 import com.intellij.util.messages.MessageBusConnection;
34 import org.jetbrains.annotations.NotNull;
36 import javax.swing.*;
37 import java.io.File;
38 import java.net.MalformedURLException;
39 import java.net.URL;
40 import java.util.*;
42 /**
43 * @author Anton Katilin
44 * @author Vladimir Kondratyev
46 public final class LoaderFactory {
47 private final Project myProject;
49 private final WeakHashMap<Module, ClassLoader> myModule2ClassLoader;
50 private ClassLoader myProjectClassLoader = null;
51 private final MessageBusConnection myConnection;
53 public static LoaderFactory getInstance(final Project project) {
54 return ServiceManager.getService(project, LoaderFactory.class);
57 public LoaderFactory(final Project project) {
58 myProject = project;
59 myModule2ClassLoader = new WeakHashMap<Module, ClassLoader>();
60 myConnection = myProject.getMessageBus().connect();
61 myConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
62 public void beforeRootsChange(final ModuleRootEvent event) {}
63 public void rootsChanged(final ModuleRootEvent event) {
64 clearClassLoaderCache();
66 });
68 Disposer.register(project, new Disposable() {
69 public void dispose() {
70 myConnection.disconnect();
71 myModule2ClassLoader.clear();
73 });
76 @NotNull public ClassLoader getLoader(final VirtualFile formFile) {
77 final Module module = ModuleUtil.findModuleForFile(formFile, myProject);
78 if (module == null) {
79 return getClass().getClassLoader();
82 return getLoader(module);
85 public ClassLoader getLoader(final Module module) {
86 final ClassLoader cachedLoader = myModule2ClassLoader.get(module);
87 if (cachedLoader != null) {
88 return cachedLoader;
91 final String runClasspath = ProjectRootsTraversing.collectRoots(module, ProjectClasspathTraversing.FULL_CLASSPATH_RECURSIVE).getPathsString();
93 final ClassLoader classLoader = createClassLoader(runClasspath);
95 myModule2ClassLoader.put(module, classLoader);
97 return classLoader;
100 @NotNull public ClassLoader getProjectClassLoader() {
101 if (myProjectClassLoader == null) {
102 final String runClasspath = ProjectRootsTraversing.collectRoots(myProject, ProjectClasspathTraversing.FULL_CLASSPATH_RECURSIVE).getPathsString();
103 myProjectClassLoader = createClassLoader(runClasspath);
105 return myProjectClassLoader;
108 private static ClassLoader createClassLoader(final String runClasspath) {
109 final ArrayList<URL> urls = new ArrayList<URL>();
110 final StringTokenizer tokenizer = new StringTokenizer(runClasspath, File.pathSeparator);
111 while (tokenizer.hasMoreTokens()) {
112 final String s = tokenizer.nextToken();
113 try {
114 urls.add(new File(s).toURI().toURL());
116 catch (Exception e) {
117 // ignore ?
121 try {
122 urls.add(new File(PathUtil.getJarPathForClass(Spacer.class)).toURI().toURL());
124 catch (MalformedURLException ignored) {
125 // ignore
128 final URL[] _urls = urls.toArray(new URL[urls.size()]);
129 return new DesignTimeClassLoader(Arrays.asList(_urls), null);
132 public void clearClassLoaderCache() {
133 // clear classes with invalid classloader from UIManager cache
134 final UIDefaults uiDefaults = UIManager.getDefaults();
135 for (Iterator it = uiDefaults.keySet().iterator(); it.hasNext();) {
136 Object key = it.next();
137 Object value = uiDefaults.get(key);
138 if (value instanceof Class) {
139 ClassLoader loader = ((Class)value).getClassLoader();
140 if (loader instanceof DesignTimeClassLoader) {
141 it.remove();
145 myModule2ClassLoader.clear();
146 myProjectClassLoader = null;
149 private static class DesignTimeClassLoader extends UrlClassLoader {
150 public DesignTimeClassLoader(final List<URL> urls, final ClassLoader parent) {
151 super(urls, parent);