diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java index 05d509e746c7..8a9804ed5389 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java @@ -115,6 +115,9 @@ public class ITNReporter extends ErrorReportSubmitter { } errorBean.setDescription(buildDescription(event, description)); + if (event.getData() instanceof LogMessageEx) { + errorBean.setAttachments(((LogMessageEx)event.getData()).getAttachments()); + } ErrorReportSender.sendError(project, login, password, errorBean, new Consumer() { @SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"}) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index cca329706a9f..f9a347f22fb9 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -830,23 +830,11 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } private IdeaLoggingEvent getEvent(final AbstractMessage logMessage) { - StringBuilder msg = new StringBuilder(logMessage.getMessage()); if (logMessage instanceof LogMessageEx) { - final List attachments = ((LogMessageEx)logMessage).getAttachments(); - for (Attachment attachment : attachments) { - if (attachment.isIncluded()) { - int i = attachment.getPath().lastIndexOf(File.separator); - String name = i >= 0 ? attachment.getPath().substring(i + 1) : attachment.getPath(); - msg.append("\n+++++++++++++++++++++++++++++ Attachment: ").append(name).append("\n").append(attachment.getContent()); - } - } - if (!attachments.isEmpty()) { - msg.append("\n-----------------------------\n"); - } + return ((LogMessageEx)logMessage).toEvent(); } - return new IdeaLoggingEvent(msg.toString(), logMessage.getThrowable()); + return new IdeaLoggingEvent(logMessage.getMessage(), logMessage.getThrowable()); } - } protected void updateOnSubmit() { diff --git a/platform/platform-impl/src/com/intellij/diagnostic/LogMessageEx.java b/platform/platform-impl/src/com/intellij/diagnostic/LogMessageEx.java index 6520598d909e..96b6cfc3ad63 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/LogMessageEx.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/LogMessageEx.java @@ -14,6 +14,7 @@ import java.util.List; * @author ksafonov */ public class LogMessageEx extends LogMessage { + private final IdeaLoggingEvent myEvent; private final String myTitle; private final String myNotificationText; private List myAttachments = null; @@ -25,6 +26,7 @@ public class LogMessageEx extends LogMessage { */ public LogMessageEx(IdeaLoggingEvent aEvent, String title, String notificationText) { super(aEvent); + myEvent = aEvent; myTitle = title; myNotificationText = notificationText; } @@ -58,6 +60,10 @@ public class LogMessageEx extends LogMessage { return myAttachments != null ? myAttachments : Collections.emptyList(); } + public IdeaLoggingEvent toEvent() { + return myEvent; + } + /** * @param userMessage user-friendly message description (short, single line if possible) * @param details technical details (exception stack trace etc.) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/Attachment.java b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/Attachment.java index 0aab862efb56..9153217dc5c7 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/Attachment.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/Attachment.java @@ -1,50 +1,70 @@ package com.intellij.diagnostic.errordialog; import com.intellij.openapi.fileEditor.impl.LoadTextUtil; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; import com.intellij.util.Base64Converter; +import com.intellij.util.PathUtil; import org.jetbrains.annotations.NotNull; import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.text.MessageFormat; public class Attachment { + + private static final String ERROR_MESSAGE_PATTERN = "[[[Can't get file contents: {0}]]]"; + private final String myPath; - private String myContent; + private final byte[] myBytes; private boolean myIncluded = true; + private final String myDisplayText; public Attachment(String path, String content) { myPath = path; - myContent = content; + myDisplayText = content; + myBytes = getBytes(content); } public Attachment(@NotNull VirtualFile file) { - this(file.getPresentableUrl(), loadText(file)); + myPath = file.getPresentableUrl(); + myBytes = getBytes(file); + myDisplayText = file.getFileType().isBinary() ? "File is binary" : LoadTextUtil.loadText(file).toString(); } - private static String loadText(VirtualFile file) { - if (file.getFileType().isBinary()) { - try { - return "Binary file, base64 encoded: " + Base64Converter.encode(file.contentsToByteArray()); - } - catch (IOException e) { - return "Cannot load binary file content"; - } + private static byte[] getBytes(VirtualFile file) { + try { + return file.contentsToByteArray(); } - else { - return LoadTextUtil.loadText(file).toString(); + catch (IOException e) { + return getBytes(MessageFormat.format(ERROR_MESSAGE_PATTERN, e.getMessage())); } } + private static byte[] getBytes(String content) { + try { + return content.getBytes("UTF-8"); + } + catch (UnsupportedEncodingException ignored) { + return ArrayUtil.EMPTY_BYTE_ARRAY; + } + } + + public String getDisplayText() { + return myDisplayText; + } + public String getPath() { return myPath; } - public String getContent() { - return myContent; + public String getName() { + return PathUtil.getFileName(myPath); } - public void setContent(String content) { - myContent = content; + public String getEncodedBytes() { + return Base64Converter.encode(myBytes); } public boolean isIncluded() { diff --git a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/AttachmentsTabForm.java b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/AttachmentsTabForm.java index 218cad59484f..26f602a1ec72 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/AttachmentsTabForm.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/AttachmentsTabForm.java @@ -71,7 +71,7 @@ public class AttachmentsTabForm { } final Attachment selection = myTable.getSelectedObject(); if (selection != null) { - LabeledTextComponent.setText(myFileTextArea.getTextComponent(), selection.getContent(), true); + LabeledTextComponent.setText(myFileTextArea.getTextComponent(), selection.getDisplayText(), true); } else { LabeledTextComponent.setText(myFileTextArea.getTextComponent(), null, true); diff --git a/platform/platform-impl/src/com/intellij/errorreport/bean/ErrorBean.java b/platform/platform-impl/src/com/intellij/errorreport/bean/ErrorBean.java index 1eff39de4a2a..ffd36e9d54e9 100644 --- a/platform/platform-impl/src/com/intellij/errorreport/bean/ErrorBean.java +++ b/platform/platform-impl/src/com/intellij/errorreport/bean/ErrorBean.java @@ -15,12 +15,15 @@ */ package com.intellij.errorreport.bean; +import com.intellij.diagnostic.errordialog.Attachment; import com.intellij.util.SystemProperties; import org.jetbrains.annotations.NonNls; import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.util.Collections; import java.util.Date; +import java.util.List; /** * Created by IntelliJ IDEA. @@ -39,6 +42,7 @@ public class ErrorBean { private String stackTrace; private String exceptionClass = ""; + private List attachments = Collections.emptyList(); public ErrorBean(Throwable throwable, String lastAction) { if (throwable != null) { @@ -86,4 +90,12 @@ public class ErrorBean { public String getMessage() { return message; } + + public void setAttachments(List attachments) { + this.attachments = attachments; + } + + public List getAttachments() { + return attachments; + } } diff --git a/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java b/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java index 8680ce28b956..3fb251f94d7a 100644 --- a/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java +++ b/platform/platform-impl/src/com/intellij/errorreport/itn/ITNProxy.java @@ -16,6 +16,7 @@ package com.intellij.errorreport.itn; import com.intellij.diagnostic.DiagnosticBundle; +import com.intellij.diagnostic.errordialog.Attachment; import com.intellij.errorreport.bean.ErrorBean; import com.intellij.errorreport.error.InternalEAPException; import com.intellij.errorreport.error.NoSuchEAPUserException; @@ -23,6 +24,8 @@ import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.ex.ApplicationInfoEx; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.SystemProperties; import org.jetbrains.annotations.NonNls; @@ -34,8 +37,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.text.MessageFormat; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; /** * Created by IntelliJ IDEA. @@ -56,7 +59,7 @@ public class ITNProxy { @NonNls private static final String HTTP_WWW_FORM = "application/x-www-form-urlencoded"; @NonNls private static final String HTTP_POST = "POST"; - private static HttpURLConnection post (String url, Map params) throws IOException, MalformedURLException { + private static HttpURLConnection post (String url, List> params) throws IOException { HttpURLConnection connection = (HttpURLConnection) new URL (url).openConnection(); connection.setReadTimeout(10 * 1000); connection.setConnectTimeout(10 * 1000); @@ -65,12 +68,12 @@ public class ITNProxy { connection.setDoOutput(true); connection.setRequestProperty(HTTP_CONTENT_TYPE, HTTP_WWW_FORM); - StringBuffer buffer = new StringBuffer(); - for (String name : params.keySet()) { - if (params.containsKey(name) && params.get(name) != null) - buffer.append(name + "=" + URLEncoder.encode(params.get(name), ENCODE) + POST_DELIMETER); + StringBuilder buffer = new StringBuilder(); + for (Pair param : params) { + if (StringUtil.isNotEmpty(param.first) && StringUtil.isNotEmpty(param.second)) + buffer.append(param.first + "=" + URLEncoder.encode(param.second, ENCODE) + POST_DELIMETER); else - throw new IllegalArgumentException(name); + throw new IllegalArgumentException(param.toString()); } connection.setRequestProperty(HTTP_CONTENT_LENGTH, Integer.toString(buffer.length())); connection.getOutputStream().write(buffer.toString().getBytes()); @@ -101,25 +104,25 @@ public class ITNProxy { public static int postNewThread (String userName, String password, ErrorBean error, String compilationTimestamp) throws IOException, NoSuchEAPUserException, InternalEAPException { - @NonNls Map params = new HashMap(); - params.put("username", userName); - params.put("pwd", password); - params.put("_title", MessageFormat.format(THREAD_SUBJECT, + @NonNls List> params = new ArrayList>(); + params.add(Pair.create("username", userName)); + params.add(Pair.create("pwd", password)); + params.add(Pair.create("_title", MessageFormat.format(THREAD_SUBJECT, error.getLastAction() == null ? error.getExceptionClass() : - error.getLastAction() + ", " + error.getExceptionClass())); + error.getLastAction() + ", " + error.getExceptionClass()))); ApplicationInfoEx appInfo = (ApplicationInfoEx) ApplicationManager.getApplication().getComponent( ApplicationInfo.class); - params.put("_build", appInfo.getBuild().asString()); - params.put("_description", + params.add(Pair.create("_build", appInfo.getBuild().asString())); + params.add(Pair.create("_description", (compilationTimestamp != null ? ("Build time: " + compilationTimestamp + "\n") : "") + - error.getDescription() + "\n\n" + error.getStackTrace()); + error.getDescription() + "\n\n" + error.getStackTrace())); String jdkVersion = SystemProperties.getJavaVersion(); String jdkVendor = SystemProperties.getJavaVmVendor(); - if (jdkVendor.indexOf(SUN) != -1) { + if (jdkVendor.contains(SUN)) { if (jdkVersion.equals(JDK_1_4_2)) jdkVersion = "10"; else if (jdkVersion.equals(JDK_1_4_1)) @@ -143,33 +146,38 @@ public class ITNProxy { } else jdkVersion = "1"; - params.put("_jdk", jdkVersion); + params.add(Pair.create("_jdk", jdkVersion)); String os = error.getOs(); if (os == null) os = ""; - if (os.indexOf(WINDOWS_XP) != -1) + if (os.contains(WINDOWS_XP)) os = "4"; - else if (os.indexOf(WINDOWS_2000) != -1 || os.indexOf(WINDOWS_NT) != -1) + else if (os.contains(WINDOWS_2000) || os.contains(WINDOWS_NT)) os = "3"; - else if (os.indexOf(WINDOWS_95) != -1 || os.indexOf(WINDOWS_98) != -1 || os.indexOf(WINDOWS_ME) != -1) + else if (os.contains(WINDOWS_95) || os.contains(WINDOWS_98) || os.contains(WINDOWS_ME)) os = "2"; - else if (os.indexOf(SOLARIS) != -1) + else if (os.contains(SOLARIS)) os = "7"; - else if (os.indexOf(MAC_OS_X) != -1) + else if (os.contains(MAC_OS_X)) os = "6"; - else if (os.indexOf(LINUX) != -1) + else if (os.contains(LINUX)) os = "5"; else os = "1"; - params.put("_os", os); + params.add(Pair.create("_os", os)); - params.put("_product", ApplicationNamesInfo.getInstance().getProductName()); + params.add(Pair.create("_product", ApplicationNamesInfo.getInstance().getProductName())); + for (Attachment attachment : error.getAttachments()) { + params.add(Pair.create("_attachment_name", attachment.getName())); + params.add(Pair.create("_attachment_value", attachment.getEncodedBytes())); + } + HttpURLConnection connection = post(NEW_THREAD_URL, params); - int responce = connection.getResponseCode(); - switch (responce) { + int response = connection.getResponseCode(); + switch (response) { case HttpURLConnection.HTTP_OK: break; case HttpURLConnection.HTTP_BAD_REQUEST: @@ -178,7 +186,7 @@ public class ITNProxy { throw new NoSuchEAPUserException(userName); default: // some problems - throw new InternalEAPException(DiagnosticBundle.message("error.http.result.code", responce)); + throw new InternalEAPException(DiagnosticBundle.message("error.http.result.code", response)); } ByteArrayOutputStream baos = new ByteArrayOutputStream();