2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.diagnostic
;
18 import com
.intellij
.openapi
.actionSystem
.AnAction
;
19 import com
.intellij
.openapi
.actionSystem
.AnActionEvent
;
20 import com
.intellij
.openapi
.actionSystem
.PlatformDataKeys
;
21 import com
.intellij
.openapi
.application
.ApplicationInfo
;
22 import com
.intellij
.openapi
.application
.ApplicationManager
;
23 import com
.intellij
.openapi
.application
.PathManager
;
24 import com
.intellij
.openapi
.progress
.ProgressIndicator
;
25 import com
.intellij
.openapi
.progress
.ProgressManager
;
26 import com
.intellij
.openapi
.progress
.Task
;
27 import com
.intellij
.openapi
.project
.DumbAware
;
28 import com
.intellij
.openapi
.project
.Project
;
29 import com
.intellij
.openapi
.ui
.Messages
;
30 import com
.intellij
.openapi
.util
.text
.StringUtil
;
31 import com
.intellij
.util
.SystemProperties
;
32 import com
.intellij
.util
.io
.ZipUtil
;
33 import org
.apache
.commons
.net
.ftp
.FTPClient
;
34 import org
.apache
.commons
.net
.ftp
.FTPReply
;
35 import org
.jetbrains
.annotations
.NonNls
;
36 import org
.jetbrains
.annotations
.NotNull
;
37 import org
.jetbrains
.annotations
.Nullable
;
40 import java
.text
.DateFormat
;
41 import java
.text
.SimpleDateFormat
;
42 import java
.util
.Date
;
43 import java
.util
.zip
.ZipOutputStream
;
48 public class SubmitPerformanceReportAction
extends AnAction
implements DumbAware
{
49 private final DateFormat myDateFormat
= new SimpleDateFormat("yyyyMMdd-HHmmss");
51 private static final String MESSAGE_TITLE
= "Submit Performance Report";
53 public void actionPerformed(final AnActionEvent e
) {
54 String reportFileName
= "perf_" + ApplicationInfo
.getInstance().getBuild().asString() + "_" +
55 SystemProperties
.getUserName() + "_" + myDateFormat
.format(new Date()) + ".zip";
56 final File reportPath
= new File(SystemProperties
.getUserHome(), reportFileName
);
57 final File logDir
= new File(PathManager
.getLogPath());
58 final Project project
= e
.getData(PlatformDataKeys
.PROJECT
);
60 final boolean[] archiveCreated
= new boolean[1];
61 final boolean completed
= ProgressManager
.getInstance().runProcessWithProgressSynchronously(new Runnable() {
64 ZipOutputStream zip
= new ZipOutputStream(new FileOutputStream(reportPath
));
65 ZipUtil
.addDirToZipRecursively(zip
, reportPath
, logDir
, "", new FileFilter() {
66 public boolean accept(final File pathname
) {
67 ProgressManager
.checkCanceled();
69 if (logDir
.equals(pathname
.getParentFile())) {
70 return pathname
.getPath().contains("threadDumps");
76 archiveCreated
[0] = true;
78 catch (final IOException ex
) {
79 ApplicationManager
.getApplication().invokeLater(new Runnable() {
81 Messages
.showErrorDialog(project
, "Failed to create performance report archive: " + ex
.getMessage(), MESSAGE_TITLE
);
86 }, "Collecting Performance Report data", true, project
);
93 int rc
= Messages
.showYesNoDialog(project
, "The performance report has been saved to\n" + reportPath
+
94 "\n\nWould you like to submit it to JetBrains?", MESSAGE_TITLE
,
95 Messages
.getQuestionIcon());
97 ProgressManager
.getInstance().run(new Task
.Backgroundable(project
, "Uploading Performance Report") {
98 public void run(@NotNull final ProgressIndicator indicator
) {
99 final String error
= uploadFileToFTP(reportPath
, "ftp.intellij.net", ".uploads", indicator
);
101 ApplicationManager
.getApplication().invokeLater(new Runnable() {
103 Messages
.showErrorDialog(error
, MESSAGE_TITLE
);
113 private static String
uploadFileToFTP(final File reportPath
, @NonNls final String ftpSite
, @NonNls final String directory
,
114 final ProgressIndicator indicator
) {
115 FTPClient ftp
= new FTPClient();
116 ftp
.setConnectTimeout(30 * 1000);
118 indicator
.setText("Connecting to server...");
119 ftp
.connect(ftpSite
);
120 indicator
.setText("Connected to server");
122 if (!ftp
.login("anonymous", "anonymous@jetbrains.com")) {
123 return "Failed to login";
125 indicator
.setText("Logged in");
127 // After connection attempt, you should check the reply code to verify
129 int reply
= ftp
.getReplyCode();
131 if (!FTPReply
.isPositiveCompletion(reply
)) {
133 return "FTP server refused connection: " + reply
;
135 if (!ftp
.changeWorkingDirectory(directory
)) {
136 return "Failed to change directory";
139 // else won't work behind FW
140 ftp
.enterLocalPassiveMode();
142 if (!ftp
.setFileType(FTPClient
.BINARY_FILE_TYPE
)) {
143 return "Failed to switch to binary mode";
146 indicator
.setText("Transferring (" + StringUtil
.formatFileSize(reportPath
.length()) + ")");
147 FileInputStream readStream
= new FileInputStream(reportPath
);
149 if (!ftp
.storeFile(reportPath
.getName(), readStream
)) {
150 return "Failed to upload file";
152 } catch (IOException e
) {
153 return "Error during transfer: " + e
.getMessage();
161 catch (IOException e
) {
162 return "Failed to upload: " + e
.getMessage();
165 if (ftp
.isConnected()) {
169 catch (IOException ioe
) {