diff --git a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java index 4d12c4bf6255..05280434f3d0 100644 --- a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java +++ b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java @@ -17,7 +17,6 @@ package com.intellij.ide; import com.intellij.util.lang.UrlClassLoader; -import javax.swing.*; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; @@ -29,31 +28,19 @@ import java.util.List; public class Bootstrap { private static final String PLUGIN_MANAGER = "com.intellij.ide.plugins.PluginManager"; - private Bootstrap() {} + private Bootstrap() { } - public static void main(final String[] args, final String mainClass, final String methodName) { + public static void main(String[] args, String mainClass, String methodName) throws Exception { main(args, mainClass, methodName, new ArrayList()); } - public static void main(final String[] args, final String mainClass, final String methodName, final List classpathElements) { - final UrlClassLoader newClassLoader = ClassloaderUtil.initClassloader(classpathElements); - try { - WindowsCommandLineProcessor.ourMirrorClass = Class.forName(WindowsCommandLineProcessor.class.getName(), true, newClassLoader); + public static void main(String[] args, String mainClass, String methodName, List classpathElements) throws Exception { + UrlClassLoader newClassLoader = ClassloaderUtil.initClassloader(classpathElements); + WindowsCommandLineProcessor.ourMirrorClass = Class.forName(WindowsCommandLineProcessor.class.getName(), true, newClassLoader); - final Class klass = Class.forName(PLUGIN_MANAGER, true, newClassLoader); - - final Method startMethod = klass.getDeclaredMethod("start", String.class, String.class, String[].class); - startMethod.setAccessible(true); - startMethod.invoke(null, mainClass, methodName, args); - } - catch (Exception e) { - if ("true".equals(System.getProperty("java.awt.headless"))) { - //noinspection UseOfSystemOutOrSystemErr - e.printStackTrace(System.err); - } - else { - JOptionPane.showMessageDialog(null, e.getClass().getName() + ": " + e.getMessage(), "Error starting IntelliJ Platform", JOptionPane.ERROR_MESSAGE); - } - } + Class klass = Class.forName(PLUGIN_MANAGER, true, newClassLoader); + Method startMethod = klass.getDeclaredMethod("start", String.class, String.class, String[].class); + startMethod.setAccessible(true); + startMethod.invoke(null, mainClass, methodName, args); } } \ No newline at end of file diff --git a/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java b/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java index d31e2383c4fb..6d6f715d026d 100644 --- a/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java +++ b/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java @@ -30,7 +30,6 @@ import com.intellij.util.lang.UrlClassLoader; import com.intellij.util.text.StringTokenizer; import org.jetbrains.annotations.NonNls; -import javax.swing.*; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -44,76 +43,33 @@ import java.util.regex.Pattern; public class ClassloaderUtil extends ClassUtilCore { @NonNls public static final String PROPERTY_IGNORE_CLASSPATH = "ignore.classpath"; - @SuppressWarnings({"HardCodedStringLiteral"}) - private static final String ERROR = "Error"; - private ClassloaderUtil() {} public static Logger getLogger() { return Logger.getInstance("ClassloaderUtil"); } - public static UrlClassLoader initClassloader(final List classpathElements) { + public static UrlClassLoader initClassloader(final List classpathElements) throws Exception { PathManager.loadProperties(); - try { - addParentClasspath(classpathElements); - addIDEALibraries(classpathElements); - addAdditionalClassPath(classpathElements); - } - catch (IllegalArgumentException e) { - if (Main.isHeadless()) { - getLogger().error(e); - } else { - JOptionPane - .showMessageDialog(JOptionPane.getRootFrame(), e.getMessage(), ERROR, JOptionPane.INFORMATION_MESSAGE); - } - System.exit(1); - } - catch (MalformedURLException e) { - if (Main.isHeadless()) { - getLogger().error(e.getMessage()); - } else { - JOptionPane - .showMessageDialog(JOptionPane.getRootFrame(), e.getMessage(), ERROR, JOptionPane.INFORMATION_MESSAGE); - } - System.exit(1); - } + addParentClasspath(classpathElements); + addIDEALibraries(classpathElements); + addAdditionalClassPath(classpathElements); filterClassPath(classpathElements); + UrlClassLoader newClassLoader = new UrlClassLoader(classpathElements, null, true, true); - UrlClassLoader newClassLoader = null; - try { - newClassLoader = new UrlClassLoader(classpathElements, null, true, true); - - // prepare plugins - if (!isLoadingOfExternalPluginsDisabled()) { - try { - StartupActionScriptManager.executeActionScript(); - } - catch (IOException e) { - final String errorMessage = "Error executing plugin installation script: " + e.getMessage(); - if (Main.isHeadless()) { - System.out.println(errorMessage); - } else { - JOptionPane - .showMessageDialog(JOptionPane.getRootFrame(), errorMessage, ERROR, JOptionPane.INFORMATION_MESSAGE); - } - } + // prepare plugins + if (!isLoadingOfExternalPluginsDisabled()) { + try { + StartupActionScriptManager.executeActionScript(); } - - Thread.currentThread().setContextClassLoader(newClassLoader); - - } - catch (Exception e) { - Logger logger = getLogger(); - if (logger == null) { - e.printStackTrace(System.err); - } - else { - logger.error(e); + catch (IOException e) { + Main.showMessage("Plugin Installation Error", e); } } + + Thread.currentThread().setContextClassLoader(newClassLoader); return newClassLoader; } diff --git a/platform/bootstrap/src/com/intellij/idea/Main.java b/platform/bootstrap/src/com/intellij/idea/Main.java index 499f5ec1b583..182946c2c786 100644 --- a/platform/bootstrap/src/com/intellij/idea/Main.java +++ b/platform/bootstrap/src/com/intellij/idea/Main.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.idea; import com.intellij.ide.Bootstrap; @@ -21,102 +20,99 @@ import com.intellij.openapi.application.PathManager; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.util.ArrayUtilRt; +import com.intellij.util.ExceptionUtil; import com.intellij.util.Restarter; -import org.jetbrains.annotations.NonNls; import javax.swing.*; import java.awt.*; import java.io.File; import java.io.IOException; -import java.io.PrintWriter; +import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; +@SuppressWarnings({"UseOfSystemOutOrSystemErr", "MethodNamesDifferingOnlyByCase"}) public class Main { + public static final int UPDATE_FAILED = 1; + public static final int STARTUP_EXCEPTION = 2; + public static final int STARTUP_IMPOSSIBLE = 3; + public static final int LICENSE_ERROR = 4; + public static final int PLUGIN_ERROR = 5; + private static boolean isHeadless; + private static boolean isCommandLine; - private Main() { - } + private Main() { } - @SuppressWarnings("MethodNamesDifferingOnlyByCase") public static void main(final String[] args) { - isHeadless = isHeadless(args); - if (isHeadless) { + setFlags(args); + + if (isHeadless()) { System.setProperty("java.awt.headless", Boolean.TRUE.toString()); } - else if (GraphicsEnvironment.isHeadless()) { - throw new HeadlessException("Unable to detect graphics environment"); - } + else { + if (GraphicsEnvironment.isHeadless()) { + throw new HeadlessException("Unable to detect graphics environment"); + } - if (!isHeadless) { try { installPatch(); } - catch (IOException e) { - e.printStackTrace(); - - File log = null; - try { - log = FileUtilRt.createTempFile("patch", ".log", false); - PrintWriter writer = new PrintWriter(log); - try { - e.printStackTrace(writer); - } - finally { - writer.close(); - } - } - catch (IOException ignore) { - ignore.printStackTrace(); - } - - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } - catch (Throwable ignore) { - } - String message = e.getMessage() - + "\n" + (log == null ? "Log cannot be saved" : "Log is saved in " + log) - + "\n\nPlease download and install update manually" ; - JOptionPane.showMessageDialog(null, message, "Cannot Apply Patch", JOptionPane.ERROR_MESSAGE); + catch (Throwable t) { + showMessage("Update Failed", t); + System.exit(UPDATE_FAILED); } } - Bootstrap.main(args, Main.class.getName() + "Impl", "start"); - } - - public static boolean isHeadless(final String[] args) { - final Boolean forceEnabledHeadlessMode = Boolean.valueOf(System.getProperty("java.awt.headless")); - - @NonNls final String antAppCode = "ant"; - @NonNls final String duplocateCode = "duplocate"; - @NonNls final String traverseUI = "traverseUI"; - if (args.length == 0) { - return false; + try { + Bootstrap.main(args, Main.class.getName() + "Impl", "start"); + } + catch (Throwable t) { + showMessage("Start Failed", t); + System.exit(STARTUP_EXCEPTION); } - final String firstArg = args[0]; - return forceEnabledHeadlessMode || - Comparing.strEqual(firstArg, antAppCode) || - Comparing.strEqual(firstArg, duplocateCode) || - Comparing.strEqual(firstArg, traverseUI) || - (firstArg.length() < 20 && firstArg.endsWith("inspect")); - } - - public static boolean isUITraverser(final String[] args) { - return args.length > 0 && Comparing.strEqual(args[0], "traverseUI"); - } - - public static boolean isCommandLine(final String[] args) { - if (isHeadless(args)) return true; - @NonNls final String diffAppCode = "diff"; - return args.length > 0 && Comparing.strEqual(args[0], diffAppCode); } public static boolean isHeadless() { return isHeadless; } + public static boolean isCommandLine() { + return isCommandLine; + } + + public static void setFlags(String[] args) { + isHeadless = isHeadless(args); + isCommandLine = isCommandLine(args); + } + + private static boolean isHeadless(String[] args) { + if (GraphicsEnvironment.isHeadless()) { + return true; + } + + if (args.length == 0) { + return false; + } + + String firstArg = args[0]; + return Comparing.strEqual(firstArg, "ant") || + Comparing.strEqual(firstArg, "duplocate") || + Comparing.strEqual(firstArg, "traverseUI") || + (firstArg.length() < 20 && firstArg.endsWith("inspect")); + } + + private static boolean isCommandLine(String[] args) { + if (isHeadless()) return true; + return args.length > 0 && Comparing.strEqual(args[0], "diff"); + } + + public static boolean isUITraverser(final String[] args) { + return args.length > 0 && Comparing.strEqual(args[0], "traverseUI"); + } + private static void installPatch() throws IOException { String platform = System.getProperty("idea.platform.prefix", "idea"); String patchFileName = ("jetbrains.patch.jar." + platform).toLowerCase(); @@ -124,28 +120,67 @@ public class Main { File copyPatchFile = new File(System.getProperty("java.io.tmpdir"), patchFileName + "_copy"); // always delete previous patch copy - if (!FileUtilRt.delete(copyPatchFile)) throw new IOException("Cannot create temporary patch file"); + if (!FileUtilRt.delete(copyPatchFile)) { + throw new IOException("Cannot create temporary patch file"); + } - if (!originalPatchFile.exists()) return; + if (!originalPatchFile.exists()) { + return; + } if (!originalPatchFile.renameTo(copyPatchFile) || !FileUtilRt.delete(originalPatchFile)) { throw new IOException("Cannot create temporary patch file"); } - List args = new ArrayList(); - if (SystemInfo.isWindows) { - args.add(Restarter.createTempExecutable(new File(PathManager.getBinPath(), "vistalauncher.exe")).getPath()); + int status = 0; + if (Restarter.isSupported()) { + List args = new ArrayList(); + + if (SystemInfo.isWindows) { + File launcher = new File(PathManager.getBinPath(), "VistaLauncher.exe"); + args.add(Restarter.createTempExecutable(launcher).getPath()); + } + + Collections.addAll(args, + System.getProperty("java.home") + "/bin/java", + "-Xmx500m", + "-classpath", + copyPatchFile.getPath(), + "com.intellij.updater.Runner", + "install", + PathManager.getHomePath()); + + status = Restarter.scheduleRestart(ArrayUtilRt.toStringArray(args)); + } + else { + String message = "Patch update is not supported - please do it manually"; + showMessage("Update Error", message, true); } - Collections.addAll(args, - System.getProperty("java.home") + "/bin/java", - "-Xmx500m", - "-classpath", - copyPatchFile.getPath(), - "com.intellij.updater.Runner", - "install", - PathManager.getHomePath()); + System.exit(status); + } - System.exit(Restarter.scheduleRestart(args.toArray(new String[args.size()]))); + public static void showMessage(String title, Throwable t) { + String message = "Internal exception, please report to http://youtrack.jetbrains.com\n\n" + ExceptionUtil.getThrowableText(t); + showMessage(title, message, true); + } + + public static void showMessage(String title, String message, boolean error) { + if (isCommandLine()) { + PrintStream stream = error ? System.err : System.out; + stream.println(title + ": " + message); + } + else { + try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } + catch (Throwable ignore) { } + + JTextPane textPane = new JTextPane(); + textPane.setEditable(false); + textPane.setText(message.replaceAll("\t", " ")); + textPane.setBackground(UIManager.getColor("Panel.background")); + + int type = error ? JOptionPane.ERROR_MESSAGE : JOptionPane.INFORMATION_MESSAGE; + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), textPane, title, type); + } } } diff --git a/platform/core-api/src/com/intellij/diagnostic/PluginException.java b/platform/core-api/src/com/intellij/diagnostic/PluginException.java index 3d4e5da85f75..3a520ebc466c 100644 --- a/platform/core-api/src/com/intellij/diagnostic/PluginException.java +++ b/platform/core-api/src/com/intellij/diagnostic/PluginException.java @@ -19,11 +19,8 @@ import com.intellij.openapi.extensions.PluginId; import org.jetbrains.annotations.NonNls; /** - * Created by IntelliJ IDEA. - * User: stathik - * Date: Jan 8, 2004 - * Time: 3:06:43 PM - * To change this template use Options | File Templates. + * @author stathik + * @since Jan 8, 2004 */ public class PluginException extends RuntimeException { private final PluginId myPluginId; diff --git a/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java b/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java index 83270ac75ea8..a33f22150dae 100644 --- a/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java @@ -105,21 +105,10 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements try { myComponentsRegistry.loadClasses(); - final Class[] componentInterfaces = myComponentsRegistry.getComponentInterfaces(); + Class[] componentInterfaces = myComponentsRegistry.getComponentInterfaces(); for (Class componentInterface : componentInterfaces) { ProgressIndicatorProvider.checkCanceled(); - try { - createComponent(componentInterface); - } - catch (StateStorageException e) { - throw e; - } - catch (ProcessCanceledException e) { - throw e; - } - catch(Exception e) { - LOG.error(e); - } + createComponent(componentInterface); } } finally { @@ -209,35 +198,12 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements return null; } - private void initComponent(Object component) { - final ProgressIndicator indicator = getProgressIndicator(); - if (indicator != null) { - indicator.checkCanceled(); - } - - try { - initializeComponent(component, false); - if (component instanceof BaseComponent) { - ((BaseComponent)component).initComponent(); - } - } - catch (StateStorageException e) { - throw e; - } - catch (ProcessCanceledException e) { - throw e; - } - catch (Throwable ex) { - handleInitComponentError(ex, false, component.getClass().getName(), null); - } - } - @Nullable protected static ProgressIndicator getProgressIndicator() { return ProgressIndicatorProvider.getGlobalProgressIndicator(); } - protected double getPercentageOfComponentsLoaded() { + protected float getPercentageOfComponentsLoaded() { return myComponentsRegistry.getPercentageOfComponentsLoaded(); } @@ -245,8 +211,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements public void initializeComponent(Object component, boolean service) { } - - protected void handleInitComponentError(final Throwable ex, final boolean fatal, final String componentClassName, ComponentConfig config) { + protected void handleInitComponentError(Throwable ex, String componentClassName, ComponentConfig config) { LOG.error(ex); } @@ -358,7 +323,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements getComponents(); } - protected void loadComponentsConfiguration(ComponentConfig[] components, @Nullable final PluginDescriptor descriptor, final boolean defaultProject) { + protected void loadComponentsConfiguration(ComponentConfig[] components, @Nullable PluginDescriptor descriptor, boolean defaultProject) { myConfigurator.loadComponentsConfiguration(components, descriptor, defaultProject); } @@ -426,7 +391,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements protected class ComponentsRegistry { private final Map myInterfaceToLockMap = new THashMap(); private final Map myInterfaceToClassMap = new THashMap(); - private final ArrayList myComponentInterfaces = new ArrayList(); // keeps order of component's registration + private final List myComponentInterfaces = new ArrayList(); // keeps order of component's registration private final Map myNameToComponent = new THashMap(); private final List myComponentConfigs = new ArrayList(); private final List myImplementations = new ArrayList(); @@ -452,7 +417,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements interfaceClass : Class.forName(config.getImplementationClass(), true, loader); if (myInterfaceToClassMap.get(interfaceClass) != null) { - throw new ComponentAlreadyRegisteredException(interfaceClass); + throw new RuntimeException("Component already registered: " + interfaceClass.getName()); } getPicoContainer().registerComponent(new ComponentConfigComponentAdapter(config, implementationClass)); @@ -460,17 +425,8 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements myComponentClassToConfig.put(implementationClass, config); myComponentInterfaces.add(interfaceClass); } - catch (ComponentAlreadyRegisteredException ex) { - throw new Error(ex); - } - catch (Throwable e) { - handleInitComponentError(e, false, null, config); - } - } - - private class ComponentAlreadyRegisteredException extends Exception { - private ComponentAlreadyRegisteredException(Class interfaceClass) { - super(interfaceClass.getName() + " component already registered"); + catch (Throwable t) { + handleInitComponentError(t, null, config); } } @@ -492,8 +448,8 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements return myInterfaceToClassMap.containsKey(interfaceClass); } - public double getPercentageOfComponentsLoaded() { - return ((double)myImplementations.size()) / myComponentConfigs.size(); + public float getPercentageOfComponentsLoaded() { + return ((float)myImplementations.size()) / myComponentConfigs.size(); } private void registerComponentInstance(final Object component) { @@ -565,57 +521,66 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements public ComponentConfigComponentAdapter(final ComponentConfig config, Class implementationClass) { myConfig = config; + final String componentKey = config.getInterfaceClass(); myDelegate = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(componentKey, implementationClass, null, true)) { - @Override - public Object getComponentInstance(PicoContainer picoContainer) throws PicoInitializationException, PicoIntrospectionException { - Object componentInstance = null; - try { - long startTime = myInitialized ? 0 : System.nanoTime(); - componentInstance = super.getComponentInstance(picoContainer); - - if (!myInitialized) { - if (myInitializing) { - if (myConfig.pluginDescriptor != null) { - LOG.error(new PluginException("Cyclic component initialization: " + componentKey, myConfig.pluginDescriptor.getPluginId())); - } - else { - LOG.error(new Throwable("Cyclic component initialization: " + componentKey)); - } - } - - try { - myInitializing = true; - myComponentsRegistry.registerComponentInstance(componentInstance); - initComponent(componentInstance); - long endTime = System.nanoTime(); - long ms = (endTime - startTime) / 1000000; - if (ms > 10) { - if (logSlowComponents()) { - LOG.info(componentInstance.getClass().getName() + " initialized in " + ms + " ms"); - } - } - } - finally { - myInitializing = false; - } - - myInitialized = true; - } - } - catch (ProcessCanceledException e) { - throw e; - } - catch (StateStorageException e) { - throw e; - } - catch (Throwable t) { - handleInitComponentError(t, componentInstance == null, componentKey, config); - } - return componentInstance; + @Override + public Object getComponentInstance(PicoContainer picoContainer) throws PicoInitializationException, PicoIntrospectionException { + ProgressIndicator indicator = getProgressIndicator(); + if (indicator != null) { + indicator.checkCanceled(); } - }; + Object componentInstance = null; + try { + long startTime = myInitialized ? 0 : System.nanoTime(); + + componentInstance = super.getComponentInstance(picoContainer); + + if (!myInitialized) { + if (myInitializing) { + if (myConfig.pluginDescriptor != null) { + LOG.error(new PluginException("Cyclic component initialization: " + componentKey, myConfig.pluginDescriptor.getPluginId())); + } + else { + LOG.error(new Throwable("Cyclic component initialization: " + componentKey)); + } + } + + try { + myInitializing = true; + myComponentsRegistry.registerComponentInstance(componentInstance); + + initializeComponent(componentInstance, false); + if (componentInstance instanceof BaseComponent) { + ((BaseComponent)componentInstance).initComponent(); + } + + long ms = (System.nanoTime() - startTime) / 1000000; + if (ms > 10 && logSlowComponents()) { + LOG.info(componentInstance.getClass().getName() + " initialized in " + ms + " ms"); + } + } + finally { + myInitializing = false; + } + + myInitialized = true; + } + } + catch (ProcessCanceledException e) { + throw e; + } + catch (StateStorageException e) { + throw e; + } + catch (Throwable t) { + handleInitComponentError(t, componentKey, config); + } + + return componentInstance; + } + }; } @Override @@ -625,27 +590,23 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements @Override public Class getComponentImplementation() { - return getDelegate().getComponentImplementation(); + return myDelegate.getComponentImplementation(); } @Override public Object getComponentInstance(final PicoContainer container) throws PicoInitializationException, PicoIntrospectionException { - return getDelegate().getComponentInstance(container); + return myDelegate.getComponentInstance(container); } @Override public void verify(final PicoContainer container) throws PicoIntrospectionException { - getDelegate().verify(container); + myDelegate.verify(container); } @Override public void accept(final PicoVisitor visitor) { visitor.visitComponentAdapter(this); - getDelegate().accept(visitor); - } - - private ComponentAdapter getDelegate() { - return myDelegate; + myDelegate.accept(visitor); } } } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/DefaultIdeaErrorLogger.java b/platform/platform-impl/src/com/intellij/diagnostic/DefaultIdeaErrorLogger.java index 139d3eaa2e47..3488bce03487 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/DefaultIdeaErrorLogger.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/DefaultIdeaErrorLogger.java @@ -16,7 +16,6 @@ package com.intellij.diagnostic; import com.intellij.notification.Notification; -import com.intellij.notification.NotificationDisplayType; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; @@ -35,13 +34,14 @@ import java.lang.reflect.InvocationTargetException; * @author kir */ public class DefaultIdeaErrorLogger implements ErrorLogger { - private static boolean ourOomOccured = false; + private static boolean ourOomOccurred = false; private static boolean ourLoggerBroken = false; - private static boolean mappingFailedNotificationPosted = false; + private static boolean ourMappingFailedNotificationPosted = false; + @NonNls private static final String FATAL_ERROR_NOTIFICATION_PROPERTY = "idea.fatal.error.notification"; @NonNls private static final String DISABLED_VALUE = "disabled"; @NonNls private static final String ENABLED_VALUE = "enabled"; - @NonNls private static final String PARAM_PERMGEN = "PermGen"; + @NonNls private static final String PARAM_PERM_GEN = "PermGen"; public boolean canHandle(IdeaLoggingEvent event) { if (ourLoggerBroken) return false; @@ -56,7 +56,7 @@ public class DefaultIdeaErrorLogger implements ErrorLogger { return notificationEnabled || showPluginError || ApplicationManagerEx.getApplicationEx().isInternal() || - isOOMError(event.getThrowable()) || + isOOMError(event.getThrowable()) || event.getThrowable() instanceof MappingFailedException; } catch (LinkageError e) { @@ -68,13 +68,8 @@ public class DefaultIdeaErrorLogger implements ErrorLogger { } } - /** - * @noinspection CallToPrintStackTrace - */ public void handle(IdeaLoggingEvent event) { - if (ourLoggerBroken) { - return; - } + if (ourLoggerBroken) return; try { Throwable throwable = event.getThrowable(); @@ -84,11 +79,11 @@ public class DefaultIdeaErrorLogger implements ErrorLogger { else if (throwable instanceof MappingFailedException) { processMappingFailed(event); } - else if (!ourOomOccured) { + else if (!ourOomOccurred) { MessagePool messagePool = MessagePool.getInstance(); LogMessage message = messagePool.addIdeFatalMessage(event); if (message != null && ApplicationManager.getApplication() != null) { - notifyUi(messagePool, message); + ErrorNotifier.notifyUi(message, messagePool); } } } @@ -99,14 +94,9 @@ public class DefaultIdeaErrorLogger implements ErrorLogger { //noinspection AssignmentToStaticFieldFromInstanceMethod ourLoggerBroken = true; } - e.printStackTrace(); } } - private static void notifyUi(MessagePool messagePool, LogMessage message) { - ErrorNotifier.notifyUi(message, messagePool); - } - private static boolean isOOMError(Throwable throwable) { return throwable instanceof OutOfMemoryError || (throwable instanceof VirtualMachineError && @@ -114,17 +104,13 @@ public class DefaultIdeaErrorLogger implements ErrorLogger { throwable.getMessage().contains("CodeCache")); } - /** - * @noinspection CallToPrintStackTrace - */ private static void processOOMError(final Throwable throwable) throws InterruptedException, InvocationTargetException { - ourOomOccured = true; - throwable.printStackTrace(); + ourOomOccurred = true; SwingUtilities.invokeAndWait(new Runnable() { public void run() { String message = throwable.getMessage(); - OutOfMemoryDialog.MemoryKind k = message != null && message.contains(PARAM_PERMGEN) + OutOfMemoryDialog.MemoryKind k = message != null && message.contains(PARAM_PERM_GEN) ? OutOfMemoryDialog.MemoryKind.PERM_GEN : message != null && message.contains("CodeCache") ? OutOfMemoryDialog.MemoryKind.CODE_CACHE @@ -135,13 +121,13 @@ public class DefaultIdeaErrorLogger implements ErrorLogger { } private static void processMappingFailed(final IdeaLoggingEvent event) throws InterruptedException, InvocationTargetException { - if (!mappingFailedNotificationPosted && SystemInfo.isWindows && SystemInfo.is32Bit) { - mappingFailedNotificationPosted = true; - final String exceptionMessage = event.getThrowable().getMessage(); - final String text = exceptionMessage + - "
Possible cause: unable to allocate continuous memory chunk of necessary size.
Reducing JVM's maximum heap size (-Xmx) may help."; - Notifications.Bus.notify(new Notification("Memory", "Memory Mapping Failed", text, NotificationType.WARNING), NotificationDisplayType.BALLOON, null); + if (!ourMappingFailedNotificationPosted && SystemInfo.isWindows && SystemInfo.is32Bit) { + ourMappingFailedNotificationPosted = true; + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") String exceptionMessage = event.getThrowable().getMessage(); + String text = exceptionMessage + + "
Possible cause: unable to allocate continuous memory chunk of necessary size.
" + + "Reducing JVM maximum heap size (-Xmx) may help."; + Notifications.Bus.notify(new Notification("Memory", "Memory Mapping Failed", text, NotificationType.WARNING), null); } } - } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java index 2ce3a3c4fe4f..5c9f61efba7d 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java @@ -13,16 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.ide.plugins; import com.intellij.ide.ClassUtilCore; import com.intellij.ide.IdeBundle; +import com.intellij.idea.Main; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; -import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ApplicationNamesInfo; +import com.intellij.openapi.components.ComponentConfig; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.progress.ProcessCanceledException; @@ -30,7 +32,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.util.ArrayUtil; -import com.intellij.util.ExceptionUtil; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,12 +41,11 @@ import javax.swing.*; import javax.swing.event.HyperlinkEvent; import java.io.IOException; import java.lang.reflect.Method; -import java.util.*; +import java.util.List; /** * @author mike */ -@SuppressWarnings({"UseOfSystemOutOrSystemErr", "CallToPrintStackTrace"}) // No logger is loaded at this time so we have to use these. public class PluginManager extends PluginManagerCore { @NonNls public static final String INSTALLED_TXT = "installed.txt"; @@ -55,93 +56,103 @@ public class PluginManager extends PluginManagerCore { /** * Called via reflection */ - @SuppressWarnings({"UnusedDeclaration"}) + @SuppressWarnings({"UnusedDeclaration", "HardCodedStringLiteral", "finally"}) protected static void start(final String mainClass, final String methodName, final String[] args) { startupStart = System.nanoTime(); - try { - //noinspection HardCodedStringLiteral - ThreadGroup threadGroup = new ThreadGroup("Idea Thread Group") { - @Override - public void uncaughtException(Thread t, Throwable e) { - if (!(e instanceof ProcessCanceledException)) { - PluginManagerCore.getLogger().error(e); - } - } - }; - Runnable runnable = new Runnable() { - @Override - public void run() { + Main.setFlags(args); + + if (!Main.isHeadless()) { + UIUtil.initDefaultLAF(); + } + + ThreadGroup threadGroup = new ThreadGroup("Idea Thread Group") { + @Override + public void uncaughtException(Thread t, Throwable e) { + if (e instanceof StartupAbortedException) { + StartupAbortedException se = (StartupAbortedException)e; try { - ClassUtilCore.clearJarURLCache(); - - Class aClass = Class.forName(mainClass); - Method method = aClass.getDeclaredMethod(methodName, ArrayUtil.EMPTY_STRING_ARRAY.getClass()); - method.setAccessible(true); - - //noinspection RedundantArrayCreation - method.invoke(null, new Object[]{args}); + if (se.logError()) { + if (Logger.isInitialized()) { + getLogger().error(e); + } + Main.showMessage("Start Failed", e); + } } - catch (Exception e) { - e.printStackTrace(System.err); - String message = "Error while accessing " + mainClass + "." + methodName + " with arguments: " + Arrays.asList(args); - if ("true".equals(System.getProperty("java.awt.headless"))) { - //noinspection UseOfSystemOutOrSystemErr - System.err.println(message); - } - else { - JOptionPane.showMessageDialog(null, message + ": " + e.getClass().getName() + ": " + e.getMessage() + "\n" + ExceptionUtil.getThrowableText(e), "Error starting IntelliJ Platform", JOptionPane.ERROR_MESSAGE); - } + finally { + System.exit(se.exitCode()); } } - }; - //noinspection HardCodedStringLiteral - new Thread(threadGroup, runnable, "Idea Main Thread").start(); - } - catch (Exception e) { - PluginManagerCore.getLogger().error(e); - } + if (!(e instanceof ProcessCanceledException)) { + getLogger().error(e); + } + } + }; + + Runnable runnable = new Runnable() { + @Override + public void run() { + try { + ClassUtilCore.clearJarURLCache(); + + Class aClass = Class.forName(mainClass); + Method method = aClass.getDeclaredMethod(methodName, ArrayUtil.EMPTY_STRING_ARRAY.getClass()); + method.setAccessible(true); + Object[] argsArray = {args}; + method.invoke(null, argsArray); + } + catch (Throwable t) { + throw new StartupAbortedException(t); + } + } + }; + + new Thread(threadGroup, runnable, "Idea Main Thread").start(); } public static void reportPluginError() { if (myPluginError != null) { - Notifications.Bus.notify(new Notification(IdeBundle.message("title.plugin.error"), IdeBundle.message("title.plugin.error"), - myPluginError, NotificationType.ERROR, new NotificationListener() { - @Override - public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { - notification.expire(); - final String description = event.getDescription(); - if (EDIT.equals(description)) { - final PluginManagerConfigurable configurable = new PluginManagerConfigurable(PluginManagerUISettings.getInstance()); - IdeFrame ideFrame = WindowManagerEx.getInstanceEx().findFrameFor(null); - ShowSettingsUtil.getInstance().editConfigurable((JFrame)ideFrame, configurable); - return; - } - final List disabledPlugins = PluginManagerCore.getDisabledPlugins(); - if (myPlugins2Disable != null && DISABLE.equals(description)) { - for (String pluginId : myPlugins2Disable) { - if (!disabledPlugins.contains(pluginId)) { - disabledPlugins.add(pluginId); - } - } - } else if (myPlugins2Enable != null && ENABLE.equals(description)) { - disabledPlugins.removeAll(myPlugins2Enable); - } - try { - PluginManagerCore.saveDisabledPlugins(disabledPlugins, false); - } - catch (IOException ignore) { - } - myPlugins2Enable = null; - myPlugins2Disable = null; + String message = IdeBundle.message("title.plugin.error"); + Notifications.Bus.notify(new Notification(message, message, myPluginError, NotificationType.ERROR, new NotificationListener() { + @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") + @Override + public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { + notification.expire(); + + String description = event.getDescription(); + if (EDIT.equals(description)) { + PluginManagerConfigurable configurable = new PluginManagerConfigurable(PluginManagerUISettings.getInstance()); + IdeFrame ideFrame = WindowManagerEx.getInstanceEx().findFrameFor(null); + ShowSettingsUtil.getInstance().editConfigurable((JFrame)ideFrame, configurable); + return; } - })); + + List disabledPlugins = getDisabledPlugins(); + if (myPlugins2Disable != null && DISABLE.equals(description)) { + for (String pluginId : myPlugins2Disable) { + if (!disabledPlugins.contains(pluginId)) { + disabledPlugins.add(pluginId); + } + } + } + else if (myPlugins2Enable != null && ENABLE.equals(description)) { + disabledPlugins.removeAll(myPlugins2Enable); + } + + try { + saveDisabledPlugins(disabledPlugins, false); + } + catch (IOException ignore) { } + + myPlugins2Enable = null; + myPlugins2Disable = null; + } + })); myPluginError = null; } } - public static boolean isPluginInstalled(PluginId id) { return getPlugin(id) != null; } @@ -157,24 +168,59 @@ public class PluginManager extends PluginManagerCore { return null; } - public static void disableIncompatiblePlugin(final Object cause, final Throwable ex) { - final PluginId pluginId = getPluginByClassName(cause.getClass().getName()); - if (pluginId != null && !ApplicationManager.getApplication().isHeadlessEnvironment()) { - final boolean success = PluginManagerCore.disablePlugin(pluginId.getIdString()); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), - "Incompatible plugin detected: " + pluginId.getIdString() + - (success ? "\nThe plugin has been disabled" : ""), - "Plugin Manager", - JOptionPane.ERROR_MESSAGE); - } - }); + public static void handleComponentError(Throwable t, String componentClassName, ComponentConfig config) { + if (t instanceof StartupAbortedException) { + throw (StartupAbortedException)t; + } + + PluginId pluginId = config != null ? config.getPluginId() : getPluginByClassName(componentClassName); + + if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) { + getLogger().warn(t); + + disablePlugin(pluginId.getIdString()); + + String message = + "Plugin '" + pluginId.getIdString() + "' failed to initialize and will be disabled\n" + + "(reason: " + t.getMessage() + ")\n\n" + + ApplicationNamesInfo.getInstance().getFullProductName() + " will be restarted."; + Main.showMessage("Plugin Error", message, false); + + throw new StartupAbortedException(t).exitCode(Main.PLUGIN_ERROR).logError(false); } else { - // should never happen - throw new RuntimeException(ex); + throw new StartupAbortedException("Fatal error initializing '" + componentClassName + "'", t); + } + } + + public static class StartupAbortedException extends RuntimeException { + private int exitCode = Main.STARTUP_EXCEPTION; + private boolean logError = true; + + public StartupAbortedException(Throwable cause) { + super(cause); + } + + public StartupAbortedException(String message, Throwable cause) { + super(message, cause); + } + + public int exitCode() { + return exitCode; + } + + public StartupAbortedException exitCode(int exitCode) { + this.exitCode = exitCode; + return this; + } + + public boolean logError() { + return logError; + } + + public StartupAbortedException logError(boolean logError) { + this.logError = logError; + return this; } } } diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java index 1641c8dd7838..4604d57a6777 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java @@ -18,12 +18,12 @@ package com.intellij.idea; import com.intellij.ExtensionPoints; import com.intellij.Patches; import com.intellij.concurrency.JobScheduler; -import com.intellij.diagnostic.PluginException; import com.intellij.ide.AppLifecycleListener; import com.intellij.ide.CommandLineProcessor; import com.intellij.ide.IdeEventQueue; import com.intellij.ide.IdeRepaintManager; import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.notification.NotificationDisplayType; import com.intellij.notification.NotificationGroup; import com.intellij.notification.NotificationType; @@ -36,10 +36,12 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.updateSettings.impl.UpdateChecker; import com.intellij.openapi.updateSettings.impl.UpdateSettings; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.impl.SystemDock; @@ -54,7 +56,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.File; -import java.io.IOException; import java.util.Arrays; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -79,14 +80,15 @@ public class IdeaApplication { myArgs = args; boolean isInternal = Boolean.valueOf(System.getProperty(IDEA_IS_INTERNAL_PROPERTY)).booleanValue(); - if (Main.isCommandLine(args)) { - boolean headless = Main.isHeadless(args); - if (!headless) patchSystem(); + boolean headless = Main.isHeadless(); + if (!headless) { + patchSystem(); + } + + if (Main.isCommandLine()) { new CommandLineApplication(isInternal, false, headless); } else { - patchSystem(); - Splash splash = null; if (myArgs.length == 0) { myStarter = getStarter(); @@ -159,15 +161,16 @@ public class IdeaApplication { protected ApplicationStarter getStarter() { if (myArgs.length > 0) { - PluginManager.getPlugins(); + PluginManagerCore.getPlugins(); ExtensionPoint point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.APPLICATION_STARTER); - final ApplicationStarter[] starters = point.getExtensions(); + ApplicationStarter[] starters = point.getExtensions(); String key = myArgs[0]; for (ApplicationStarter o : starters) { if (Comparing.equal(o.getCommandName(), key)) return o; } } + return new IdeStarter(); } @@ -175,17 +178,9 @@ public class IdeaApplication { return ourInstance; } - public void run() { + public void run() throws Exception { ApplicationEx app = ApplicationManagerEx.getApplicationEx(); - try { - app.load(PathManager.getOptionsPath()); - } - catch (IOException e) { - e.printStackTrace(); - } - catch (InvalidDataException e) { - e.printStackTrace(); - } + app.load(PathManager.getOptionsPath()); myStarter.main(myArgs); myStarter = null; //GC it @@ -252,36 +247,28 @@ public class IdeaApplication { @Override public void main(String[] args) { - SystemDock.updateMenu(); + // Event queue should not be changed during initialization of application components. // It also cannot be changed before initialization of application components because IdeEventQueue uses other // application components. So it is proper to perform replacement only here. ApplicationEx app = ApplicationManagerEx.getApplicationEx(); - // app.setupIdeQueue(IdeEventQueue.getInstance()); WindowManagerImpl windowManager = (WindowManagerImpl)WindowManager.getInstance(); + IdeEventQueue.getInstance().setWindowManager(windowManager); - try { - IdeEventQueue.getInstance().setWindowManager(windowManager); + Ref willOpenProject = new Ref(Boolean.FALSE); + AppLifecycleListener lifecyclePublisher = app.getMessageBus().syncPublisher(AppLifecycleListener.TOPIC); + lifecyclePublisher.appFrameCreated(args, willOpenProject); - final Ref willOpenProject = new Ref(Boolean.FALSE); - final AppLifecycleListener lifecyclePublisher = app.getMessageBus().syncPublisher(AppLifecycleListener.TOPIC); - lifecyclePublisher.appFrameCreated(args, willOpenProject); - LOG.info("App initialization took " + (System.nanoTime() - PluginManager.startupStart) / 1000000 + " ms"); - PluginManager.dumpPluginClassStatistics(); - if (!willOpenProject.get()) { - WelcomeFrame.showNow(); - lifecyclePublisher.welcomeScreenDisplayed(); - } - else { - windowManager.showFrame(); - } + LOG.info("App initialization took " + (System.nanoTime() - PluginManager.startupStart) / 1000000 + " ms"); + PluginManagerCore.dumpPluginClassStatistics(); + + if (!willOpenProject.get()) { + WelcomeFrame.showNow(); + lifecyclePublisher.welcomeScreenDisplayed(); } - catch (PluginException e) { - Messages.showErrorDialog("Plugin " + e.getPluginId() + " couldn't be loaded, the IDE will now exit.\n" + - "See the full details in the log.\n" + - e.getMessage(), "Plugin Error"); - System.exit(-1); + else { + windowManager.showFrame(); } app.invokeLater(new Runnable() { @@ -321,7 +308,6 @@ public class IdeaApplication { } }, ModalityState.NON_MODAL); } - } private void loadProject() { diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java b/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java index 6f075573a6a2..17de69c30b7c 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java @@ -44,7 +44,6 @@ public class IdeaLogger extends Logger { public static String ourLastActionId = ""; - private final org.apache.log4j.Logger myLogger; /** If not null - it means that errors occurred and it is the first of them. */ public static Exception ourErrorsOccurred; @@ -59,25 +58,24 @@ public class IdeaLogger extends Logger { static { InputStream stream = Logger.class.getResourceAsStream(COMPILATION_TIMESTAMP_RESOURCE_NAME); if (stream != null) { - LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream)); try { - String s = reader.readLine(); - if (s != null) { - ourCompilationTimestamp = s.trim(); - } - } - catch (IOException ignored) { - } - finally { + LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream)); try { - stream.close(); + String s = reader.readLine(); + if (s != null) { + ourCompilationTimestamp = s.trim(); + } } - catch (IOException ignored) { + finally { + reader.close(); } } + catch (IOException ignored) { } } } + private final org.apache.log4j.Logger myLogger; + IdeaLogger(org.apache.log4j.Logger logger) { myLogger = logger; } @@ -134,9 +132,6 @@ public class IdeaLogger extends Logger { myLogger.error(message + (!detailString.isEmpty() ? "\nDetails: " + detailString : ""), t); logErrorHeader(); - if (t != null && t.getCause() != null) { - myLogger.error("Original exception: ", t.getCause()); - } } private void logErrorHeader() { diff --git a/platform/platform-impl/src/com/intellij/idea/SocketLock.java b/platform/platform-impl/src/com/intellij/idea/SocketLock.java index d77b870c7112..d2b0fbf09b7d 100644 --- a/platform/platform-impl/src/com/intellij/idea/SocketLock.java +++ b/platform/platform-impl/src/com/intellij/idea/SocketLock.java @@ -88,7 +88,7 @@ public class SocketLock { if (mySocket == null) { if (!myIsDialogShown) { final String productName = ApplicationNamesInfo.getInstance().getProductName(); - if (StartupUtil.isHeadless()) { //team server inspections + if (Main.isHeadless()) { //team server inspections throw new RuntimeException("Only one instance of " + productName + " can be run at a time."); } @NonNls final String pathToLogFile = PathManager.getLogPath() + "/idea.log file".replace('/', File.separatorChar); diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index c05df8fdb349..28ee2fbfe8c2 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -15,10 +15,11 @@ */ package com.intellij.idea; -import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.ide.startupWizard.StartupWizard; import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.application.ApplicationNamesInfo; +import com.intellij.openapi.application.ConfigImportHelper; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.application.impl.ApplicationInfoImpl; @@ -28,6 +29,7 @@ import com.intellij.openapi.util.SystemInfoRt; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.win32.IdeaWin32; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.AppUIUtil; import com.intellij.util.Consumer; import com.intellij.util.EnvironmentUtil; import com.intellij.util.SystemProperties; @@ -41,7 +43,6 @@ import javax.swing.*; import java.io.File; import java.io.InputStream; import java.lang.management.ManagementFactory; -import java.lang.management.RuntimeMXBean; import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; @@ -54,8 +55,6 @@ public class StartupUtil { public static final boolean NO_SNAPPY = SystemProperties.getBooleanProperty("idea.no.snappy", false); - static boolean isHeadless; - private static SocketLock ourLock; private static String myDefaultLAF; @@ -73,17 +72,55 @@ public class StartupUtil { return !Arrays.asList(args).contains(NO_SPLASH); } + /** @deprecated use {@link Main#isHeadless()} (to remove in IDEA 14) */ + @SuppressWarnings("unused") public static boolean isHeadless() { - return isHeadless; + return Main.isHeadless(); } - private static void showError(final String title, final String message) { - if (isHeadless()) { - //noinspection UseOfSystemOutOrSystemErr - System.out.println(message); + public synchronized static void addExternalInstanceListener(Consumer> consumer) { + ourLock.setActivateListener(consumer); + } + + interface AppStarter { + void start(boolean newConfigFolder); + } + + static void prepareAndStart(String[] args, AppStarter appStarter) { + boolean newConfigFolder = false; + + if (!Main.isHeadless()) { + AppUIUtil.updateFrameClass(); + AppUIUtil.updateWindowIcon(JOptionPane.getRootFrame()); + AppUIUtil.registerBundledFonts(); + + newConfigFolder = PathManager.ensureConfigFolderExists(true); + if (newConfigFolder) { + ConfigImportHelper.importConfigsTo(PathManager.getConfigPath()); + } } - else { - JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), message, title, JOptionPane.ERROR_MESSAGE); + + boolean canStart = checkJdkVersion() && checkSystemFolders() && lockSystemFolders(args); // note: uses config folder! + if (!canStart) { + System.exit(Main.STARTUP_IMPOSSIBLE); + } + + Logger.setFactory(LoggerFactory.getInstance()); + Logger log = Logger.getInstance(Main.class); + startLogging(log); + fixProcessEnvironment(log); + loadSystemLibraries(log); + + appStarter.start(newConfigFolder); + } + + static void runStartupWizard() { + final List pages = ApplicationInfoImpl.getShadowInstance().getPluginChooserPages(); + if (!pages.isEmpty()) { + final StartupWizard startupWizard = new StartupWizard(pages); + startupWizard.setCancelText("Skip"); + startupWizard.show(); + PluginManagerCore.invalidatePlugins(); } } @@ -97,17 +134,9 @@ public class StartupUtil { Class.forName("com.sun.jdi.Field"); } catch (ClassNotFoundException e) { - showError("Error", "'tools.jar' is not in " + ApplicationNamesInfo.getInstance().getProductName() + " classpath.\n" + - "Please ensure JAVA_HOME points to JDK rather than JRE."); - return false; - } - } - - if (!"true".equals(System.getProperty("idea.no.jdk.check"))) { - final String version = System.getProperty("java.version"); - if (!SystemInfo.isJavaVersionAtLeast("1.6")) { - showError("Java Version Mismatch", "The JDK version is " + version + ".\n" + - ApplicationNamesInfo.getInstance().getProductName() + " requires JDK 1.6 or higher."); + String message = "'tools.jar' seems to be not in " + ApplicationNamesInfo.getInstance().getProductName() + " classpath.\n" + + "Please ensure JAVA_HOME points to JDK rather than JRE."; + Main.showMessage("JDK Required", message, true); return false; } } @@ -117,18 +146,20 @@ public class StartupUtil { private synchronized static boolean checkSystemFolders() { final String configPath = PathManager.getConfigPath(); - if (configPath == null || !new File(configPath).isDirectory()) { - showError("Invalid config path", "Config path '" + configPath + "' is invalid.\n" + - "If you have modified the 'idea.config.path' property please make sure it is correct,\n" + - "otherwise please re-install the IDE."); + if (!new File(configPath).isDirectory()) { + String message = "Config path '" + configPath + "' is invalid.\n" + + "If you have modified the 'idea.config.path' property please make sure it is correct,\n" + + "otherwise please re-install the IDE."; + Main.showMessage("Invalid Config Path", message, true); return false; } final String systemPath = PathManager.getSystemPath(); if (systemPath == null || !new File(systemPath).isDirectory()) { - showError("Invalid system path", "System path '" + systemPath + "' is invalid.\n" + - "If you have modified the 'idea.system.path' property please make sure it is correct,\n" + - "otherwise please re-install the IDE."); + String message = "System path '" + systemPath + "' is invalid.\n" + + "If you have modified the 'idea.system.path' property please make sure it is correct,\n" + + "otherwise please re-install the IDE."; + Main.showMessage("Invalid System Path", message, true); return false; } @@ -146,8 +177,9 @@ public class StartupUtil { } if (activateStatus != SocketLock.ActivateStatus.NO_INSTANCE) { - if (isHeadless() || activateStatus == SocketLock.ActivateStatus.CANNOT_ACTIVATE) { - showError("Error", "Only one instance of " + ApplicationNamesInfo.getInstance().getFullProductName() + " can be run at a time."); + if (Main.isHeadless() || activateStatus == SocketLock.ActivateStatus.CANNOT_ACTIVATE) { + String message = "Only one instance of " + ApplicationNamesInfo.getInstance().getFullProductName() + " can be run at a time."; + Main.showMessage("Too Many Instances", message, true); } return false; } @@ -155,38 +187,16 @@ public class StartupUtil { return true; } - static boolean checkStartupPossible(String[] args) { - return checkJdkVersion() && - checkSystemFolders() && - lockSystemFolders(args); - } - - static void runStartupWizard() { - final List pages = ApplicationInfoImpl.getShadowInstance().getPluginChooserPages(); - if (!pages.isEmpty()) { - final StartupWizard startupWizard = new StartupWizard(pages); - startupWizard.setCancelText("Skip"); - startupWizard.show(); - PluginManager.invalidatePlugins(); - } - } - - public synchronized static void addExternalInstanceListener(Consumer> consumer) { - ourLock.setActivateListener(consumer); - } - - - static void fixProcessEnvironment(Logger log) { + private static void fixProcessEnvironment(Logger log) { boolean envReady = EnvironmentUtil.isEnvironmentReady(); // trigger environment loading if (!envReady) { log.info("initializing environment"); } } - private static final String JAVA_IO_TEMP_DIR = "java.io.tmpdir"; - static void loadSystemLibraries(final Logger log) { + private static void loadSystemLibraries(final Logger log) { // load JNA and Snappy in own temp directory - to avoid collisions and work around no-exec /tmp final File ideaTempDir = new File(PathManager.getSystemPath(), "tmp"); if (!(ideaTempDir.mkdirs() || ideaTempDir.exists())) { @@ -231,7 +241,7 @@ public class StartupUtil { IdeaWin32.isAvailable(); // logging is done there } - if (SystemInfo.isWin2kOrNewer && !isHeadless) { + if (SystemInfo.isWin2kOrNewer && !Main.isHeadless()) { try { System.loadLibrary(SystemInfo.isAMD64 ? "focusKiller64" : "focusKiller"); log.info("Using \"FocusKiller\" library to prevent focus stealing."); @@ -280,28 +290,25 @@ public class StartupUtil { loadNativeLibrary.invoke(null, loaderClass); } - public static void startLogging(final Logger log) { + private static void startLogging(final Logger log) { Runtime.getRuntime().addShutdownHook(new Thread("Shutdown hook - logging") { public void run() { - log.info( - "------------------------------------------------------ IDE SHUTDOWN ------------------------------------------------------"); + log.info("------------------------------------------------------ IDE SHUTDOWN ------------------------------------------------------"); } }); - log.info( - "------------------------------------------------------ IDE STARTED ------------------------------------------------------"); + log.info("------------------------------------------------------ IDE STARTED ------------------------------------------------------"); - final ApplicationInfo appInfo = ApplicationInfoImpl.getShadowInstance(); - final ApplicationNamesInfo namesInfo = ApplicationNamesInfo.getInstance(); + ApplicationInfo appInfo = ApplicationInfoImpl.getShadowInstance(); + ApplicationNamesInfo namesInfo = ApplicationNamesInfo.getInstance(); log.info("IDE: " + namesInfo.getFullProductName() + " (build #" + appInfo.getBuild() + ", " + DateFormatUtilRt.formatBuildDate(appInfo.getBuildDate()) + ")"); log.info("OS: " + SystemInfoRt.OS_NAME + " (" + SystemInfoRt.OS_VERSION + ")"); - log.info("JRE: " + System.getProperty("java.runtime.version", "-") + " (" + System.getProperty("java.vendor", "-") + ")"); log.info("JVM: " + System.getProperty("java.vm.version", "-") + " (" + System.getProperty("java.vm.vendor", "-") + ")"); - RuntimeMXBean RuntimemxBean = ManagementFactory.getRuntimeMXBean(); - List arguments = RuntimemxBean.getInputArguments(); - - if (arguments != null) log.info("JVM Args: " + StringUtil.join(arguments, " ")); + List arguments = ManagementFactory.getRuntimeMXBean().getInputArguments(); + if (arguments != null) { + log.info("JVM Args: " + StringUtil.join(arguments, " ")); + } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 48d8b85b133d..f092d21e0e43 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -22,6 +22,7 @@ import com.intellij.diagnostic.PluginException; import com.intellij.ide.*; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.idea.StartupUtil; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.*; @@ -37,7 +38,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProcessCanceledException; @@ -89,8 +89,8 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application private static final Logger LOG = Logger.getInstance("#com.intellij.application.impl.ApplicationImpl"); private final ModalityState MODALITY_STATE_NONE = ModalityState.NON_MODAL; - // about writer preference: the way the java.util.concurrent.locks.ReentrantReadWriteLock.NonfairSync is implemented, the - // writer thread will be always at the queue head and therefore, java.util.concurrent.locks.ReentrantReadWriteLock.NonfairSync.readerShouldBlock() + // about writer preference: the way the j.u.c.l.ReentrantReadWriteLock.NonfairSync is implemented, the + // writer thread will be always at the queue head and therefore, j.u.c.l.ReentrantReadWriteLock.NonfairSync.readerShouldBlock() // will return true if the write action is pending, exactly as we need private final ReentrantReadWriteLock myLock = new ReentrantReadWriteLock(false); @@ -361,55 +361,25 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application } @Override - protected void handleInitComponentError(final Throwable ex, final boolean fatal, final String componentClassName, ComponentConfig config) { - if (myHandlingInitComponentError) { - return; - } - myHandlingInitComponentError = true; - try { - PluginId pluginId = config == null ? PluginManager.getPluginByClassName(componentClassName) : config.getPluginId(); - if (pluginId != null) { - LOG.warn(ex); - @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 if (!isUnitTestMode()) { - //noinspection UseOfSystemOutOrSystemErr - System.out.println(errorMessage); - System.exit(1); - } - return; // do not call super + protected void handleInitComponentError(Throwable t, String componentClassName, ComponentConfig config) { + if (!myHandlingInitComponentError) { + myHandlingInitComponentError = true; + try { + PluginManager.handleComponentError(t, componentClassName, config); } - if (fatal) { - LOG.error(ex); - @NonNls final String errorMessage = "Fatal error initializing class " + componentClassName + ":\n" + - StringUtil.trimLog(ex.toString(), 239) + - "\nComplete error stacktrace was written to " + PathManager.getLogPath() + "/idea.log"; - if (!myHeadlessMode) { - JOptionPane.showMessageDialog(null, errorMessage); - } - else { - //noinspection UseOfSystemOutOrSystemErr - System.out.println(errorMessage); - } + finally { + myHandlingInitComponentError = false; } - super.handleInitComponentError(ex, fatal, componentClassName, config); - } - finally { - myHandlingInitComponentError = false; } } private void loadApplicationComponents() { - PluginManager.initPlugins(mySplash); - final IdeaPluginDescriptor[] plugins = PluginManager.getPlugins(); + PluginManagerCore.initPlugins(mySplash); + IdeaPluginDescriptor[] plugins = PluginManagerCore.getPlugins(); for (IdeaPluginDescriptor plugin : plugins) { - if (PluginManager.shouldSkipPlugin(plugin)) continue; - loadComponentsConfiguration(plugin.getAppComponents(), plugin, false); + if (!PluginManagerCore.shouldSkipPlugin(plugin)) { + loadComponentsConfiguration(plugin.getAppComponents(), plugin, false); + } } } @@ -417,7 +387,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application protected synchronized Object createComponent(Class componentInterface) { Object component = super.createComponent(componentInterface); if (mySplash != null) { - mySplash.showProgress("", (float)(0.65f + getPercentageOfComponentsLoaded() * 0.35f)); + mySplash.showProgress("", 0.65f + getPercentageOfComponentsLoaded() * 0.35f); } return component; } @@ -1440,7 +1410,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application public void run() { if (ex instanceof PluginException) { final PluginException pluginException = (PluginException)ex; - PluginManager.disablePlugin(pluginException.getPluginId().getIdString()); + PluginManagerCore.disablePlugin(pluginException.getPluginId().getIdString()); Messages.showMessageDialog("The plugin " + pluginException.getPluginId() + " failed to save settings and has been disabled. Please restart " + diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java index fd6e291e0b27..0ff8fe8b00fd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java @@ -149,12 +149,12 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME } }; - for (final FileTypeFactory factory : Extensions.getExtensions(FileTypeFactory.FILE_TYPE_FACTORY_EP)) { + for (FileTypeFactory factory : Extensions.getExtensions(FileTypeFactory.FILE_TYPE_FACTORY_EP)) { try { factory.createFileTypes(consumer); } - catch (final Error ex) { - PluginManager.disableIncompatiblePlugin(factory, ex); + catch (Throwable t) { + PluginManager.handleComponentError(t, factory.getClass().getName(), null); } } } @@ -191,7 +191,6 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME } return null; - } @Override @@ -218,7 +217,6 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME } return new Document(root); - } @Override diff --git a/platform/platform-main/src/com/intellij/idea/MainImpl.java b/platform/platform-main/src/com/intellij/idea/MainImpl.java index 0faeeb706a0a..32660d97733a 100644 --- a/platform/platform-main/src/com/intellij/idea/MainImpl.java +++ b/platform/platform-main/src/com/intellij/idea/MainImpl.java @@ -15,77 +15,42 @@ */ package com.intellij.idea; -import com.intellij.openapi.application.ApplicationInfo; -import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.application.ConfigImportHelper; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.application.impl.ApplicationInfoImpl; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.SystemInfoRt; -import com.intellij.ui.AppUIUtil; +import com.intellij.ide.plugins.PluginManager; import com.intellij.util.PlatformUtils; -import com.intellij.util.text.DateFormatUtilRt; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.PlatformUtilsCore; import javax.swing.*; -@SuppressWarnings({"HardCodedStringLiteral", "UseOfSystemOutOrSystemErr", "UnusedDeclaration"}) +@SuppressWarnings({"UnusedDeclaration"}) public class MainImpl { - private static final String LOG_CATEGORY = "#com.intellij.idea.Main"; - private MainImpl() { } /** * Called from PluginManager via reflection. */ protected static void start(final String[] args) { - System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, PlatformUtils.getPlatformPrefix(PlatformUtils.COMMUNITY_PREFIX)); + System.setProperty(PlatformUtilsCore.PLATFORM_PREFIX_KEY, PlatformUtils.getPlatformPrefix(PlatformUtils.COMMUNITY_PREFIX)); - StartupUtil.isHeadless = Main.isHeadless(args); - if (!StartupUtil.isHeadless) { - AppUIUtil.updateFrameClass(); - AppUIUtil.updateWindowIcon(JOptionPane.getRootFrame()); - AppUIUtil.registerBundledFonts(); - - UIUtil.initDefaultLAF(); - - final boolean isNewConfigFolder = PathManager.ensureConfigFolderExists(true); - if (isNewConfigFolder) { - ConfigImportHelper.importConfigsTo(PathManager.getConfigPath()); - } - } - - if (!StartupUtil.checkStartupPossible(args)) { // It uses config folder! - System.exit(-1); - } - - Logger.setFactory(LoggerFactory.getInstance()); - - final Logger LOG = Logger.getInstance(LOG_CATEGORY); - - StartupUtil.startLogging(LOG); - - _main(args); - } - - protected static void _main(final String[] args) { - // http://weblogs.java.net/blog/shan_man/archive/2005/06/improved_drag_g.html - System.setProperty("sun.swing.enableImprovedDragGesture", ""); - - Logger LOG = Logger.getInstance(LOG_CATEGORY); - StartupUtil.fixProcessEnvironment(LOG); - StartupUtil.loadSystemLibraries(LOG); - - startApplication(args); - } - - private static void startApplication(final String[] args) { - final IdeaApplication app = new IdeaApplication(args); - //noinspection SSBasedInspection - SwingUtilities.invokeLater(new Runnable() { - public void run() { - app.run(); + StartupUtil.prepareAndStart(args, new StartupUtil.AppStarter() { + @Override + public void start(boolean newConfigFolder) { + final IdeaApplication app = new IdeaApplication(args); + //noinspection SSBasedInspection + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + try { + app.run(); + } + catch (PluginManager.StartupAbortedException e) { + throw e; + } + catch (Throwable t) { + throw new PluginManager.StartupAbortedException(t); + } + } + }); } }); } -} \ No newline at end of file +} diff --git a/platform/util/src/com/intellij/openapi/diagnostic/Logger.java b/platform/util/src/com/intellij/openapi/diagnostic/Logger.java index 7a07bec9ae5e..bac5d8cab2cf 100644 --- a/platform/util/src/com/intellij/openapi/diagnostic/Logger.java +++ b/platform/util/src/com/intellij/openapi/diagnostic/Logger.java @@ -26,17 +26,23 @@ public abstract class Logger { Logger getLoggerInstance(String category); } - public static Factory ourFactory = new Factory() { + private static class DefaultFactory implements Factory { @Override public Logger getLoggerInstance(String category) { return new DefaultLogger(category); } - }; + } + + public static Factory ourFactory = new DefaultFactory(); public static void setFactory(Factory factory) { ourFactory = factory; } + public static boolean isInitialized() { + return !(ourFactory instanceof DefaultFactory); + } + public static Logger getInstance(@NonNls String category) { return ourFactory.getLoggerInstance(category); } @@ -48,9 +54,29 @@ public abstract class Logger { public abstract boolean isDebugEnabled(); public abstract void debug(@NonNls String message); + public abstract void debug(@Nullable Throwable t); + public abstract void debug(@NonNls String message, @Nullable Throwable t); + public void info(@NotNull Throwable t) { + info(t.getMessage(), t); + } + + public abstract void info(@NonNls String message); + + public abstract void info(@NonNls String message, @Nullable Throwable t); + + public void warn(@NonNls String message) { + warn(message, null); + } + + public void warn(@NotNull Throwable t) { + warn(t.getMessage(), t); + } + + public abstract void warn(@NonNls String message, @Nullable Throwable t); + public void error(@NonNls String message) { error(message, new Throwable(), ArrayUtil.EMPTY_STRING_ARRAY); } @@ -70,27 +96,8 @@ public abstract class Logger { error(t.getMessage(), t, ArrayUtil.EMPTY_STRING_ARRAY); } - public void warn(@NonNls String message) { - warn(message, null); - } - - public void warn(@NotNull Throwable t) { - warn(t.getMessage(), t); - } - - public abstract void error(@NonNls String message, @Nullable Throwable t, @NonNls @NotNull String... details); - public abstract void info(@NonNls String message); - - public abstract void info(@NonNls String message, @Nullable Throwable t); - - public abstract void warn(@NonNls String message, @Nullable Throwable t); - - public void info(@NotNull Throwable t) { - info(t.getMessage(), t); - } - public boolean assertTrue(boolean value, @NonNls Object message) { if (!value) { @NonNls StringBuilder resultMessage = new StringBuilder("Assertion failed"); @@ -107,5 +114,4 @@ public abstract class Logger { } public abstract void setLevel(Level level); - } diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java index 10b65fe7f0e4..ed67161b6773 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java @@ -18,13 +18,10 @@ package com.intellij.util.xml.impl; import com.intellij.ide.highlighter.DomSupportEnabled; import com.intellij.ide.startup.StartupManagerEx; import com.intellij.openapi.Disposable; -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; @@ -72,36 +69,44 @@ import java.util.Set; */ public final class DomManagerImpl extends DomManager { private static final Key MOCK = Key.create("MockElement"); + static final Key> CACHED_FILE_ELEMENT = Key.create("CACHED_FILE_ELEMENT"); static final Key MOCK_DESCRIPTION = Key.create("MockDescription"); - static final SemKey FILE_DESCRIPTION_KEY = SemKey.createKey("FILE_DESCRIPTION_KEY"); - public static final SemKey DOM_HANDLER_KEY = SemKey.createKey("DOM_HANDLER_KEY"); + static final SemKey DOM_HANDLER_KEY = SemKey.createKey("DOM_HANDLER_KEY"); static final SemKey DOM_INDEXED_HANDLER_KEY = DOM_HANDLER_KEY.subKey("DOM_INDEXED_HANDLER_KEY"); static final SemKey DOM_COLLECTION_HANDLER_KEY = DOM_HANDLER_KEY.subKey("DOM_COLLECTION_HANDLER_KEY"); static final SemKey DOM_CUSTOM_HANDLER_KEY = DOM_HANDLER_KEY.subKey("DOM_CUSTOM_HANDLER_KEY"); static final SemKey DOM_ATTRIBUTE_HANDLER_KEY = DOM_HANDLER_KEY.subKey("DOM_ATTRIBUTE_HANDLER_KEY"); private final EventDispatcher myListeners = EventDispatcher.create(DomEventListener.class); - private final ConverterManagerImpl myConverterManager; - private final GenericValueReferenceProvider myGenericValueReferenceProvider = new GenericValueReferenceProvider(); private final Project myProject; + private final SemService mySemService; + private final ConverterManager myConverterManager; private final DomApplicationComponent myApplicationComponent; private final PsiFileFactory myFileFactory; + private final ProjectFileIndex myFileIndex; private long myModificationCount; private boolean myChanging; - private final ProjectFileIndex myFileIndex; - private final SemService mySemService; - public DomManagerImpl(final Project project, final XmlAspect xmlAspect) { + public DomManagerImpl(Project project, + final XmlAspect xmlAspect, + SemService semService, + ConverterManager converterManager, + DomApplicationComponent appComponent, + PsiFileFactory fileFactory, + ProjectFileIndex fileIndex) { myProject = project; - mySemService = SemService.getSemService(project); - myConverterManager = (ConverterManagerImpl)ServiceManager.getService(ConverterManager.class); - myApplicationComponent = DomApplicationComponent.getInstance(); - final PomModel pomModel = PomManager.getModel(project); + mySemService = semService; + myConverterManager = converterManager; + myApplicationComponent = appComponent; + myFileFactory = fileFactory; + myFileIndex = fileIndex; + + PomModel pomModel = PomManager.getModel(project); pomModel.addModelListener(new PomModelListener() { public void modelChanged(PomModelEvent event) { final XmlChangeSet changeSet = (XmlChangeSet)event.getChangeSet(xmlAspect); @@ -120,11 +125,7 @@ public final class DomManagerImpl extends DomManager { } }, project); - myFileFactory = PsiFileFactory.getInstance(project); - - final PsiManager psiManager = PsiManager.getInstance(project); - - final Runnable setupVfsListeners = new Runnable() { + Runnable setupVfsListeners = new Runnable() { public void run() { final VirtualFileAdapter listener = new VirtualFileAdapter() { private final List myDeletionEvents = new SmartList(); @@ -140,7 +141,7 @@ public final class DomManagerImpl extends DomManager { } public void beforeFileDeletion(final VirtualFileEvent event) { - if (!project.isDisposed()) { + if (!myProject.isDisposed()) { beforeFileDeletion(event.getFile()); } } @@ -163,7 +164,7 @@ public final class DomManagerImpl extends DomManager { public void fileDeleted(VirtualFileEvent event) { if (!myDeletionEvents.isEmpty()) { - if (!project.isDisposed()) { + if (!myProject.isDisposed()) { for (DomEvent domEvent : myDeletionEvents) { fireEvent(domEvent); } @@ -179,18 +180,17 @@ public final class DomManagerImpl extends DomManager { } } }; - VirtualFileManager.getInstance().addVirtualFileListener(listener, project); + VirtualFileManager.getInstance().addVirtualFileListener(listener, myProject); } }; - final StartupManager startupManager = StartupManager.getInstance(project); + StartupManager startupManager = StartupManager.getInstance(project); if (!((StartupManagerEx)startupManager).startupActivityPassed()) { startupManager.registerStartupActivity(setupVfsListeners); - } else { + } + else { setupVfsListeners.run(); } - - myFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); } private void processVfsChange(final VirtualFile file) { @@ -522,7 +522,4 @@ public final class DomManagerImpl extends DomManager { public SemService getSemService() { return mySemService; } - - - private final static Logger LOG = Logger.getInstance(DomManagerImpl.class); } diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomAnnotationsTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomAnnotationsTest.java index 298bf9ea9a16..49110e2c0f4a 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomAnnotationsTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomAnnotationsTest.java @@ -23,13 +23,14 @@ import com.intellij.psi.PsiFileFactory; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.xml.highlighting.*; +import com.intellij.util.xml.impl.DomTestCase; import java.util.Arrays; /** * @author peter */ -public class DomAnnotationsTest extends DomTestCase{ +public class DomAnnotationsTest extends DomTestCase { @Override protected T createElement(final String xml, final Class aClass) { diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomChildrenTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomChildrenTest.java index ba33cf4ba00f..89229bf889c5 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomChildrenTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomChildrenTest.java @@ -26,6 +26,7 @@ import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xml.events.DomEvent; +import com.intellij.util.xml.impl.DomTestCase; import java.lang.reflect.Type; import java.util.ArrayList; diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomConcurrencyStressTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomConcurrencyStressTest.java index 8e78b570e9fb..4a94d0e5ba26 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomConcurrencyStressTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomConcurrencyStressTest.java @@ -28,6 +28,7 @@ import com.intellij.semantic.SemService; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.Timings; import com.intellij.util.xml.impl.DomFileElementImpl; +import com.intellij.util.xml.impl.DomTestCase; import com.intellij.util.xml.reflect.DomExtender; import com.intellij.util.xml.reflect.DomExtenderEP; import com.intellij.util.xml.reflect.DomExtensionsRegistrar; diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomExtensionsTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomExtensionsTest.java index e013091b79cf..5aa8c0b2255d 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomExtensionsTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomExtensionsTest.java @@ -21,6 +21,7 @@ import com.intellij.testFramework.IdeaTestUtil; import com.intellij.util.Consumer; import com.intellij.util.ParameterizedTypeImpl; import com.intellij.util.ReflectionUtil; +import com.intellij.util.xml.impl.DomTestCase; import com.intellij.util.xml.reflect.*; import org.jetbrains.annotations.NotNull; diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomHardCoreTestCase.java b/xml/dom-tests/tests/com/intellij/util/xml/DomHardCoreTestCase.java index e4d6d65be887..c2f13f6368cb 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomHardCoreTestCase.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomHardCoreTestCase.java @@ -26,8 +26,8 @@ import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlTagValue; import com.intellij.util.IncorrectOperationException; import com.intellij.util.xml.events.DomEvent; -import com.intellij.util.xml.impl.DomApplicationComponent; import com.intellij.util.xml.impl.DomManagerImpl; +import com.intellij.util.xml.impl.DomTestCase; /** * @author peter diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomHighlightingLiteTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomHighlightingLiteTest.java index 8a57ba6d8d64..623b11616f59 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomHighlightingLiteTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomHighlightingLiteTest.java @@ -34,6 +34,7 @@ import com.intellij.psi.xml.XmlTag; import com.intellij.testFramework.MockSchemesManagerFactory; import com.intellij.util.xml.highlighting.*; import com.intellij.util.xml.impl.DefaultDomAnnotator; +import com.intellij.util.xml.impl.DomTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomModelMergingTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomModelMergingTest.java index f94d568c26d5..9efc125bb83c 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomModelMergingTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomModelMergingTest.java @@ -16,13 +16,17 @@ package com.intellij.util.xml; import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.util.xml.impl.DomTestCase; -import java.util.*; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * @author peter */ -public class DomModelMergingTest extends DomTestCase{ +public class DomModelMergingTest extends DomTestCase { private ModelMerger myMerger; @Override diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomNamespacesTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomNamespacesTest.java index ae96a3b5062a..8d92c019129f 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomNamespacesTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomNamespacesTest.java @@ -20,6 +20,7 @@ import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.xml.impl.DomFileElementImpl; +import com.intellij.util.xml.impl.DomTestCase; import com.intellij.util.xml.reflect.DomGenericInfo; import java.util.List; diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomSimpleValuesTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomSimpleValuesTest.java index 5e42f0678f83..8911df1c22ac 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomSimpleValuesTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/DomSimpleValuesTest.java @@ -22,6 +22,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.xml.XmlTag; import com.intellij.util.IncorrectOperationException; import com.intellij.util.xml.events.DomEvent; +import com.intellij.util.xml.impl.DomTestCase; import com.intellij.util.xml.ui.DomUIFactory; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; diff --git a/xml/dom-tests/tests/com/intellij/util/xml/SimpleValuesIncrementalUpdateTest.java b/xml/dom-tests/tests/com/intellij/util/xml/SimpleValuesIncrementalUpdateTest.java index d85066b560d7..2a2bf1a4e2f3 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/SimpleValuesIncrementalUpdateTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/SimpleValuesIncrementalUpdateTest.java @@ -17,11 +17,12 @@ package com.intellij.util.xml; import com.intellij.util.IncorrectOperationException; import com.intellij.util.xml.events.DomEvent; +import com.intellij.util.xml.impl.DomTestCase; /** * @author peter */ -public class SimpleValuesIncrementalUpdateTest extends DomTestCase{ +public class SimpleValuesIncrementalUpdateTest extends DomTestCase { public void testAttributeChange() throws Throwable { final MyElement element = createElement(""); diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomTestCase.java b/xml/dom-tests/tests/com/intellij/util/xml/impl/DomTestCase.java similarity index 92% rename from xml/dom-tests/tests/com/intellij/util/xml/DomTestCase.java rename to xml/dom-tests/tests/com/intellij/util/xml/impl/DomTestCase.java index 16fedacfca67..37682943b3eb 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/DomTestCase.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/impl/DomTestCase.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.util.xml; +package com.intellij.util.xml.impl; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; @@ -25,11 +25,8 @@ import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.testFramework.LightIdeaTestCase; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.xml.*; import com.intellij.util.xml.events.DomEvent; -import com.intellij.util.xml.impl.DomApplicationComponent; -import com.intellij.util.xml.impl.DomFileElementImpl; -import com.intellij.util.xml.impl.DomInvocationHandler; -import com.intellij.util.xml.impl.DomManagerImpl; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -87,7 +84,7 @@ public abstract class DomTestCase extends LightIdeaTestCase { return element; } - protected static T createElement(final DomManager domManager, final String xml, final Class aClass) + public static T createElement(final DomManager domManager, final String xml, final Class aClass) throws IncorrectOperationException { final String name = "a.xml"; final XmlFile file = (XmlFile)PsiFileFactory.getInstance(domManager.getProject()).createFileFromText(name, xml); diff --git a/xml/dom-tests/tests/com/intellij/util/xml/impl/IncrementalUpdateEventsTest.java b/xml/dom-tests/tests/com/intellij/util/xml/impl/IncrementalUpdateEventsTest.java index e191e3eacfc0..2f7f2fefcd90 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/impl/IncrementalUpdateEventsTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/impl/IncrementalUpdateEventsTest.java @@ -19,7 +19,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.psi.xml.XmlTag; import com.intellij.util.IncorrectOperationException; import com.intellij.util.xml.DomElement; -import com.intellij.util.xml.DomTestCase; import com.intellij.util.xml.SubTag; import com.intellij.util.xml.events.DomEvent;