diff --git a/platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java b/platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java index 9c6b45a6833e..277c31630f89 100644 --- a/platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java +++ b/platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java @@ -59,7 +59,10 @@ public abstract class ErrorReportSubmitter implements PluginAware { */ public abstract SubmittedReportInfo submit(IdeaLoggingEvent[] events, Component parentComponent); - public void submitAsync(IdeaLoggingEvent[] events, Component parentComponent, Consumer consumer) { + public void submitAsync(IdeaLoggingEvent[] events, + String additionalInfo, + Component parentComponent, + Consumer consumer) { consumer.consume(submit(events, parentComponent)); } } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java b/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java index 50de1d415489..b426e50604f5 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java @@ -26,6 +26,7 @@ public abstract class AbstractMessage { private boolean myIsSubmitting = false; private SubmittedReportInfo mySubmissionInfo; private String myScrID; + private String myAdditionalInfo; private final Date myDate; @@ -67,6 +68,14 @@ public abstract class AbstractMessage { mySubmissionInfo.getStatus() == SubmittedReportInfo.SubmissionStatus.DUPLICATE); } + public String getAdditionalInfo() { + return myAdditionalInfo; + } + + public void setAdditionalInfo(String additionalInfo) { + myAdditionalInfo = additionalInfo; + } + public Date getDate() { return myDate; } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java index b41d02c1397e..e3e3d7f57428 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java @@ -24,6 +24,7 @@ import com.intellij.ide.DataManager; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.idea.IdeaLogger; import com.intellij.notification.Notification; +import com.intellij.notification.NotificationDisplayType; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.actionSystem.DataContext; @@ -35,6 +36,7 @@ import com.intellij.openapi.diagnostic.SubmittedReportInfo; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Consumer; import org.jetbrains.annotations.NonNls; @@ -58,14 +60,20 @@ public class ITNReporter extends ErrorReportSubmitter { } @Override - public void submitAsync(IdeaLoggingEvent[] events, Component parentComponent, Consumer consumer) { - sendError(events [0], parentComponent, consumer); + public void submitAsync(IdeaLoggingEvent[] events, + String additionalInfo, + Component parentComponent, + Consumer consumer) { + sendError(events [0], additionalInfo, parentComponent, consumer); } /** * @noinspection ThrowablePrintStackTrace */ - private static void sendError(IdeaLoggingEvent event, final Component parentComponent, final Consumer callback) { + private static void sendError(IdeaLoggingEvent event, + String additionalInfo, + final Component parentComponent, + final Consumer callback) { String newBuild = ErrorReportSender.checkNewBuild(); if (newBuild != null) { Messages.showMessageDialog(parentComponent, @@ -76,33 +84,36 @@ public class ITNReporter extends ErrorReportSubmitter { ErrorBean errorBean = new ErrorBean(event.getThrowable(), IdeaLogger.ourLastActionId); - String description = ""; - - doSubmit(event, parentComponent, callback, errorBean, description); + doSubmit(event, parentComponent, callback, errorBean, additionalInfo); } private static void doSubmit(final IdeaLoggingEvent event, final Component parentComponent, final Consumer callback, - final ErrorBean errorBean, final String description) { + final ErrorBean errorBean, + final String description) { final DataContext dataContext = DataManager.getInstance().getDataContext(parentComponent); - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - final EAPSendErrorDialog dlg = new EAPSendErrorDialog(); - dlg.setErrorDescription(description); - dlg.show(); - if (!dlg.isShouldSend()) { - return; + final ErrorReportConfigurable errorReportConfigurable = ErrorReportConfigurable.getInstance(); + if (!errorReportConfigurable.KEEP_ITN_PASSWORD && + !StringUtil.isEmpty(errorReportConfigurable.ITN_LOGIN) && + StringUtil.isEmpty(errorReportConfigurable.getPlainItnPassword())) { + final JetBrainsAccountDialog dlg = new JetBrainsAccountDialog(parentComponent); + dlg.show(); + if (!dlg.isOK()) { + return; + } } - @NonNls String login = ErrorReportConfigurable.getInstance().ITN_LOGIN; - @NonNls String password = ErrorReportConfigurable.getInstance().getPlainItnPassword(); + @NonNls String login = errorReportConfigurable.ITN_LOGIN; + @NonNls String password = errorReportConfigurable.getPlainItnPassword(); if (login.trim().length() == 0 && password.trim().length() == 0) { login = "idea_anonymous"; password = "guest"; } - errorBean.setDescription(buildDescription(event, dlg.getErrorDescription())); + errorBean.setDescription(buildDescription(event, description)); ErrorReportSender.sendError(project, login, password, errorBean, new Consumer() { @SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"}) @@ -118,7 +129,7 @@ public class ITNReporter extends ErrorReportSubmitter { Notification notification = new Notification(ReportMessages.ERROR_REPORT, ReportMessages.ERROR_REPORT, DiagnosticBundle.message("error.report.confirmation"), NotificationType.INFORMATION); - Notifications.Bus.notify(notification); + Notifications.Bus.notify(notification, NotificationDisplayType.BALLOON_ONLY, project); } }); } @@ -143,10 +154,13 @@ public class ITNReporter extends ErrorReportSubmitter { callback.consume(new SubmittedReportInfo(null, "0", SubmittedReportInfo.SubmissionStatus.FAILED)); } else { + if (e instanceof NoSuchEAPUserException) { + new JetBrainsAccountDialog(parentComponent).show(); + } ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - doSubmit(event, parentComponent, callback, errorBean, dlg.getErrorDescription()); + doSubmit(event, parentComponent, callback, errorBean, description); } }); } @@ -160,7 +174,7 @@ public class ITNReporter extends ErrorReportSubmitter { String message = event.getMessage(); @NonNls StringBuilder descBuilder = new StringBuilder(); - if (description.length() > 0) { + if (!StringUtil.isEmpty(description)) { descBuilder.append("User description: ").append(description).append("\n"); } if (message != null) { @@ -178,6 +192,10 @@ public class ITNReporter extends ErrorReportSubmitter { } } + if (IdeaLogger.ourLastActionId != null) { + descBuilder.append("Last action: ").append(IdeaLogger.ourLastActionId); + } + if (previousExceptionThreadId != 0) { descBuilder.append("Previous exception is: ").append(URL_HEADER).append(previousExceptionThreadId).append("\n"); } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 2eeed8dc10d5..f5c6e686f386 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -43,10 +43,12 @@ import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.LabeledComponent; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.DocumentAdapter; import com.intellij.ui.ScrollPaneFactory; import com.intellij.util.Consumer; import com.intellij.util.text.DateFormatUtil; @@ -54,8 +56,10 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.DocumentEvent; import java.awt.*; import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.math.BigInteger; import java.security.MessageDigest; @@ -68,17 +72,20 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private static final Logger LOG = Logger.getInstance("#com.intellij.diagnostic.IdeErrorsDialog"); private JTextPane myDetailsPane; + private JTextPane myMoreInfoPane; private List myFatalErrors; private final List> myModel = new ArrayList>(); private final MessagePool myMessagePool; private JLabel myCountLabel; private JLabel myInfoLabel; private JCheckBox myImmediatePopupCheckbox; + private JLabel myCredentialsLabel; private final BlameAction myBlameAction = new BlameAction(); private final DisablePluginAction myDisablePluginAction = new DisablePluginAction(); private int myIndex = 0; @NonNls public static final String IMMEDIATE_POPUP_OPTION = "IMMEDIATE_FATAL_ERROR_POPUP"; + private Box myCredentialsPane; public IdeErrorsDialog(MessagePool messagePool) { super(JOptionPane.getRootFrame(), false); @@ -168,8 +175,36 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene updateCountLabel(); updateInfoLabel(); updateDetailsPane(); + updateCredentialsPane(); myBlameAction.update(); myDisablePluginAction.update(); + final AbstractMessage selectedMessage = getSelectedMessage(); + if (selectedMessage == null) { + myMoreInfoPane.setEditable(false); + myMoreInfoPane.setText(""); + } + else { + myMoreInfoPane.setText(selectedMessage.getAdditionalInfo()); + myMoreInfoPane.setEditable(true); + } + } + + private void updateCredentialsPane() { + final AbstractMessage message = getSelectedMessage(); + final ErrorReportSubmitter submitter = message == null ? null : getSubmitter(message.getThrowable()); + if (submitter instanceof ITNReporter) { + myCredentialsPane.setVisible(true); + String userName = ErrorReportConfigurable.getInstance().ITN_LOGIN; + if (StringUtil.isEmpty(userName)) { + myCredentialsLabel.setText("Submit report anonymously"); + } + else { + myCredentialsLabel.setText("Submit report as " + userName); + } + } + else { + myCredentialsPane.setVisible(false); + } } private void updateInfoLabel() { @@ -305,8 +340,48 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene gapPanel.add(myInfoLabel); infoPanel.add(gapPanel, BorderLayout.NORTH); infoPanel.add(ScrollPaneFactory.createScrollPane(myDetailsPane), BorderLayout.CENTER); + + myMoreInfoPane = new JTextPane(); + final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myMoreInfoPane); + scrollPane.setPreferredSize(new Dimension(100, 50)); + final LabeledComponent labeledComponent = + LabeledComponent.create(scrollPane, "Additional information (steps to reproduce, what were you doing when the exception occurred):"); + labeledComponent.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0)); + infoPanel.add(labeledComponent, BorderLayout.SOUTH); + + myMoreInfoPane.getDocument().addDocumentListener(new DocumentAdapter() { + @Override + protected void textChanged(DocumentEvent e) { + if (myMoreInfoPane.isEditable()) { + final AbstractMessage message = getSelectedMessage(); + if (message != null) { + message.setAdditionalInfo(myMoreInfoPane.getText()); + } + } + } + }); + root.add(infoPanel, BorderLayout.CENTER); - root.add(myImmediatePopupCheckbox, BorderLayout.SOUTH); + + JPanel controlsPane = new JPanel(new BorderLayout()); + + myCredentialsPane = Box.createHorizontalBox(); + myCredentialsLabel = new JLabel("Submit report anonymously"); + myCredentialsPane.add(myCredentialsLabel); + myCredentialsPane.add(Box.createHorizontalGlue()); + JButton specifyCredentialsButton = new JButton("Use JetBrains Account"); + specifyCredentialsButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + new JetBrainsAccountDialog(getRootPane()).show(); + } + }); + myCredentialsPane.add(specifyCredentialsButton); + controlsPane.add(myCredentialsPane, BorderLayout.CENTER); + myCredentialsPane.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0)); + + controlsPane.add(myImmediatePopupCheckbox, BorderLayout.SOUTH); + root.add(controlsPane, BorderLayout.SOUTH); root.setPreferredSize(new Dimension(600, 550)); @@ -453,6 +528,11 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } public void actionPerformed(ActionEvent e) { + final boolean canRestart = ApplicationManager.getApplication().isRestartCapable(); + int rc = Messages.showYesNoDialog(getRootPane(), "Are you sure you would like to " + (canRestart ? "restart" : "shutdown") + + " " + ApplicationNamesInfo.getInstance().getFullProductName() + "?", + "Confirm", Messages.getQuestionIcon()); + if (rc != 0) return; myMessagePool.setJvmIsShuttingDown(); LaterInvocator.invokeLater(new Runnable() { public void run() { @@ -514,7 +594,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene if (submitter != null) { logMessage.setSubmitting(true); updateControls(); - submitter.submitAsync(getEvents(logMessage), getContentPane(), new Consumer() { + submitter.submitAsync(getEvents(logMessage), logMessage.getAdditionalInfo(), getContentPane(), new Consumer() { @Override public void consume(SubmittedReportInfo submittedReportInfo) { logMessage.setSubmitting(false); @@ -589,6 +669,11 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene super.doCancelAction(); } + @Override + public JComponent getPreferredFocusedComponent() { + return myMoreInfoPane; + } + protected class CloseAction extends AbstractAction { public CloseAction() { putValue(NAME, DiagnosticBundle.message("error.list.close.action")); @@ -657,9 +742,13 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene PluginManager.disablePlugin(pluginId.toString()); final Application app = ApplicationManager.getApplication(); final String pluginName = app.getPlugin(pluginId).getName(); + int rc = Messages.showYesNoDialog(getRootPane(), "Are you sure you would like to disable the plugin " + pluginName + + "? The features provided by the plugin will no longer be available.", + "Disable Plugin", Messages.getQuestionIcon()); + if (rc != 0) return; final String productName = ApplicationNamesInfo.getInstance().getFullProductName(); if (app.isRestartCapable()) { - int rc = Messages.showYesNoDialog(getRootPane(), pluginName + " has been disabled. Would you like to restart " + productName + " so that the changes would take effect?", + rc = Messages.showYesNoDialog(getRootPane(), pluginName + " has been disabled. Would you like to restart " + productName + " so that the changes would take effect?", "Disable Plugin", Messages.getInformationIcon()); if (rc == 0) { app.restart(); diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeMessagePanel.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeMessagePanel.java index 46e40f5d4a9f..7ac5219c95d1 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeMessagePanel.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeMessagePanel.java @@ -17,6 +17,7 @@ package com.intellij.diagnostic; import com.intellij.concurrency.JobScheduler; import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.wm.CustomStatusBarWidget; import com.intellij.openapi.wm.StatusBar; @@ -115,7 +116,7 @@ public class IdeMessagePanel extends JPanel implements MessagePoolListener, Cust } private void _openFatals() { - SwingUtilities.invokeLater(new Runnable() { + ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { myDialog = new IdeErrorsDialog(myMessagePool) { protected void doOKAction() { @@ -189,7 +190,7 @@ public class IdeMessagePanel extends JPanel implements MessagePoolListener, Cust } private void updateFatalErrorsIcon() { - if (myMessagePool.getFatalErrors(true, true).isEmpty()) { + if (myMessagePool.getFatalErrors(false, false).isEmpty()) { myNotificationPopupAlreadyShown = false; myIdeFatal.deactivate(); } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/EAPSendErrorDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java similarity index 64% rename from platform/platform-impl/src/com/intellij/diagnostic/EAPSendErrorDialog.java rename to platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java index c4ec765e39b4..e07f6992710d 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/EAPSendErrorDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java @@ -15,17 +15,12 @@ */ package com.intellij.diagnostic; -import com.intellij.CommonBundle; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.util.Disposer; -import com.intellij.ui.TextComponentUndoProvider; import com.intellij.util.net.HTTPProxySettingsDialog; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -36,7 +31,7 @@ import java.awt.event.MouseEvent; * Time: 3:49:50 PM * To change this template use Options | File Templates. */ -public class EAPSendErrorDialog extends DialogWrapper { +public class JetBrainsAccountDialog extends DialogWrapper { private JTextField myItnLoginTextField; private JPasswordField myItnPasswordTextField; private JCheckBox myRememberITNPasswordCheckBox; @@ -53,25 +48,15 @@ public class EAPSendErrorDialog extends DialogWrapper { myRememberITNPasswordCheckBox.setSelected(ErrorReportConfigurable.getInstance().KEEP_ITN_PASSWORD); } - public EAPSendErrorDialog() throws HeadlessException { - super(false); - + public JetBrainsAccountDialog(Component parent) throws HeadlessException { + super(parent, false); init (); } protected JPanel myMainPanel; - protected JTextArea myErrorDescriptionTextArea; - private Action mySendAction; - private Action myCancelAction; protected JLabel mySendingSettingsLabel; private JLabel myCreateAccountLabel; - private boolean myShouldSend = false; - - public boolean isShouldSend() { - return myShouldSend; - } - protected String getDimensionServiceKey() { return "#com.intellij.diagnostic.AbstractSendErrorDialog"; } @@ -79,22 +64,6 @@ public class EAPSendErrorDialog extends DialogWrapper { protected void init() { setTitle(ReportMessages.ERROR_REPORT); getContentPane().add(myMainPanel); - mySendAction = new AbstractAction(DiagnosticBundle.message("diagnostic.error.report.send")) { - public void actionPerformed(ActionEvent e) { - myShouldSend = true; - storeInfo(); - Disposer.dispose(myDisposable); - } - }; - mySendAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_S)); - mySendAction.putValue(DialogWrapper.DEFAULT_ACTION, Boolean.TRUE.toString()); - myCancelAction = new AbstractAction(CommonBundle.getCancelButtonText()) { - public void actionPerformed(ActionEvent e) { - myShouldSend = false; - Disposer.dispose(myDisposable); - } - }; - myCancelAction.putValue(Action.MNEMONIC_KEY, new Integer (KeyEvent.VK_C)); mySendingSettingsLabel.addMouseListener(new MouseAdapter () { public void mouseClicked(MouseEvent e) { @@ -116,25 +85,16 @@ public class EAPSendErrorDialog extends DialogWrapper { }); myCreateAccountLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); - new TextComponentUndoProvider(myErrorDescriptionTextArea); super.init (); } + @Override + protected void doOKAction() { + storeInfo(); + super.doOKAction(); + } + protected JComponent createCenterPanel() { return myMainPanel; } - - protected Action[] createActions() { - return new Action [] {mySendAction, myCancelAction}; - } - - public String getErrorDescription() { - return myErrorDescriptionTextArea.getText(); - } - - public void setErrorDescription (String description) { - myErrorDescriptionTextArea.setText(description); - } - - } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/EAPSendErrorForm.form b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form similarity index 79% rename from platform/platform-impl/src/com/intellij/diagnostic/EAPSendErrorForm.form rename to platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form index 42b6c6e1f60c..11a9b29e3ffe 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/EAPSendErrorForm.form +++ b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form @@ -1,45 +1,17 @@ -
- + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/platform/platform-impl/src/com/intellij/diagnostic/MessagePool.java b/platform/platform-impl/src/com/intellij/diagnostic/MessagePool.java index b972dd16fb64..d1f7bb57e349 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/MessagePool.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/MessagePool.java @@ -48,14 +48,9 @@ public class MessagePool { } public static MessagePool getInstance() { - return MessagePoolHolder.ourInstance; } - public void addIdeFatalMessage(LoggingEvent aEvent) { - addIdeFatalMessage(new LogMessage(aEvent)); - } - public void addIdeFatalMessage(IdeaLoggingEvent aEvent) { addIdeFatalMessage(new LogMessage(aEvent)); } @@ -69,13 +64,8 @@ public class MessagePool { } } - public boolean isFatalErrorsPoolEmpty() { - return myIdeFatals.isEmpty(); - } - public boolean hasUnreadMessages() { - for (int i = 0; i < myIdeFatals.size(); i++) { - AbstractMessage message = myIdeFatals.get(i); + for (AbstractMessage message : myIdeFatals) { if (!message.isRead()) return true; } return false; @@ -83,11 +73,11 @@ public class MessagePool { public List getFatalErrors(boolean aIncludeReadMessages, boolean aIncludeSubmittedMessages) { List result = new ArrayList(); - for (int i = 0; i < myIdeFatals.size(); i++) { - AbstractMessage each = myIdeFatals.get(i); + for (AbstractMessage each : myIdeFatals) { if (!each.isRead() && !each.isSubmitted()) { result.add(each); - } else if ((each.isRead() && aIncludeReadMessages) || (each.isSubmitted() && aIncludeSubmittedMessages)) { + } + else if ((each.isRead() && aIncludeReadMessages) || (each.isSubmitted() && aIncludeSubmittedMessages)) { result.add(each); } } @@ -111,15 +101,15 @@ public class MessagePool { if (ourJvmIsShuttingDown) return; final MessagePoolListener[] messagePoolListeners = myListeners.toArray(new MessagePoolListener[myListeners.size()]); - for (int i = 0; i < messagePoolListeners.length; i++) { - messagePoolListeners[i].newEntryAdded(); + for (MessagePoolListener messagePoolListener : messagePoolListeners) { + messagePoolListener.newEntryAdded(); } } private void notifyListenersClear() { final MessagePoolListener[] messagePoolListeners = myListeners.toArray(new MessagePoolListener[myListeners.size()]); - for (int i = 0; i < messagePoolListeners.length; i++) { - messagePoolListeners[i].poolCleared(); + for (MessagePoolListener messagePoolListener : messagePoolListeners) { + messagePoolListener.poolCleared(); } } diff --git a/platform/platform-resources-en/src/messages/DiagnosticBundle.properties b/platform/platform-resources-en/src/messages/DiagnosticBundle.properties index e2c2805199e5..9faa77a370c0 100644 --- a/platform/platform-resources-en/src/messages/DiagnosticBundle.properties +++ b/platform/platform-resources-en/src/messages/DiagnosticBundle.properties @@ -8,9 +8,9 @@ diagnostic.out.of.memory.currentValue.unknown=Unknown diagnostic.out.of.memory.shutdown=Shutdown diagnostic.out.of.memory.ignore=Ignore diagnostic.error.report.send=&Send -diagnostic.error.report.description=Fill in a short description of the error, how can it be reproduced.
If you would like to get notified when the error is fixed,
please fill in your JetBrains Account login/password. +diagnostic.error.report.description=If you would like to get notified when the exceptions you submit are fixed,
please fill in your JetBrains Account login/password. diagnostic.error.report.proxy.setup=Set up HTTP proxy settings -diagnostic.error.report.login.group=JetBrains Account (optional) +diagnostic.error.report.login.group=JetBrains Account diagnostic.error.report.login.remember.password.checkbox=Remember password diagnostic.error.report.login.name=Username: diagnostic.error.report.login.password=Password: diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java index e2da0d24508d..049acd6840ec 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java @@ -138,7 +138,7 @@ public class AntDomExtender extends DomExtender{ AbstractIntrospector parentIntrospector = null; if (classBasedIntrospector != null) { - parentIntrospector = new ClassIntrospectorAdapter(classBasedIntrospector); + parentIntrospector = new ClassIntrospectorAdapter(classBasedIntrospector, coreTaskDefs, coreTypeDefs); } else { if (isCustom) { @@ -438,9 +438,19 @@ public class AntDomExtender extends DomExtender{ private static class ClassIntrospectorAdapter extends AbstractIntrospector { private final AntIntrospector myIntrospector; + private final Map myCoreTaskDefs; + private final Map myCoreTypeDefs; + private List myNestedElements; + private Map myNestedElementTypes; private ClassIntrospectorAdapter(AntIntrospector introspector) { + this(introspector, null, null); + } + + public ClassIntrospectorAdapter(AntIntrospector introspector, Map coreTaskDefs, Map coreTypeDefs) { myIntrospector = introspector; + myCoreTaskDefs = coreTaskDefs != null? coreTaskDefs : Collections.emptyMap(); + myCoreTypeDefs = coreTypeDefs != null? coreTypeDefs : Collections.emptyMap(); } @NotNull @@ -458,11 +468,44 @@ public class AntDomExtender extends DomExtender{ @NotNull public Iterator getNestedElementsIterator() { - return new EnumerationToIteratorAdapter(myIntrospector.getNestedElements()); + initNestedElements(); + return myNestedElements.iterator(); } public Class getNestedElementType(String attribName) { - return myIntrospector.getElementType(attribName); + initNestedElements(); + return myNestedElementTypes.get(attribName); + } + + private void initNestedElements() { + if (myNestedElements != null) { + return; + } + myNestedElements = new ArrayList(); + myNestedElementTypes = new HashMap(); + final Enumeration nestedElements = myIntrospector.getNestedElements(); + while (nestedElements.hasMoreElements()) { + final String elemName = nestedElements.nextElement(); + myNestedElements.add(elemName); + myNestedElementTypes.put(elemName, myIntrospector.getElementType(elemName)); + } + + final Set extensionPointTypes = myIntrospector.getExtensionPointTypes(); + for (String extPoint : extensionPointTypes) { + processEntries(extPoint, myCoreTaskDefs); + processEntries(extPoint, myCoreTypeDefs); + } + } + + private void processEntries(String extPoint, final Map definitions) { + for (Map.Entry entry : definitions.entrySet()) { + final String elementName = entry.getKey(); + final Class taskClass = entry.getValue(); + if (isAssignableFrom(extPoint, taskClass)) { + myNestedElements.add(elementName); + myNestedElementTypes.put(elementName, taskClass); + } + } } }